1 //=============================================================================
2 //
3 // Adventure Game Studio (AGS)
4 //
5 // Copyright (C) 1999-2011 Chris Jones and 2011-20xx others
6 // The full list of copyright holders can be found in the Copyright.txt
7 // file, which is part of this source code distribution.
8 //
9 // The AGS source code is provided under the Artistic License 2.0.
10 // A copy of this license can be found in the file License.txt and at
11 // http://www.opensource.org/licenses/artistic-license-2.0.php
12 //
13 //=============================================================================
14 
15 #include <cctype>
16 #include "util/wgt2allg.h"
17 #include "ac/common.h"
18 #include "ac/draw.h"
19 #include "ac/gamesetup.h"
20 #include "ac/gamestate.h"
21 #include "ac/gui.h"
22 #include "ac/keycode.h"
23 #include "ac/mouse.h"
24 #include "ac/record.h"
25 #include "ac/runtime_defines.h"
26 #include "font/fonts.h"
27 #include "gui/cscidialog.h"
28 #include "gui/guidialog.h"
29 #include "gui/guimain.h"
30 #include "gui/mycontrols.h"
31 #include "main/game_run.h"
32 #include "media/audio/audio.h"
33 #include "gfx/graphicsdriver.h"
34 #include "gfx/bitmap.h"
35 
36 using AGS::Common::Bitmap;
37 namespace BitmapHelper = AGS::Common::BitmapHelper;
38 
39 extern char ignore_bounds; // from mousew32
40 extern IGraphicsDriver *gfxDriver;
41 extern volatile int timerloop; // ac_timer
42 extern GameSetup usetup;
43 
44 //extern void get_save_game_path(int slotNum, char *buffer);
45 //extern char saveGameDirectory[260];
46 
47 
48 //-----------------------------------------------------------------------------
49 // DIALOG SYSTEM STUFF below
50 
51 int windowbackgroundcolor = COL254, pushbuttondarkcolor = COL255;
52 int pushbuttonlightcolor = COL253;
53 int topwindowhandle = -1;
54 int cbuttfont;
55 
56 int acdialog_font;
57 
58 int smcode = 0;
59 
60 #define MAXCONTROLS 20
61 #define MAXSCREENWINDOWS 5
62 NewControl *vobjs[MAXCONTROLS];
63 OnScreenWindow oswi[MAXSCREENWINDOWS];
64 
65 int controlid = 0;
66 
67 
68 //-----------------------------------------------------------------------------
69 
__my_wbutt(Bitmap * ds,int x1,int y1,int x2,int y2)70 void __my_wbutt(Bitmap *ds, int x1, int y1, int x2, int y2)
71 {
72     color_t draw_color = ds->GetCompatibleColor(COL254);            //wsetcolor(15);
73     ds->FillRect(Rect(x1, y1, x2, y2), draw_color);
74     draw_color = ds->GetCompatibleColor(0);
75     ds->DrawRect(Rect(x1, y1, x2, y2), draw_color);
76 }
77 
78 //-----------------------------------------------------------------------------
79 
CSCIGetVersion()80 int WINAPI _export CSCIGetVersion()
81 {
82     return 0x0100;
83 }
84 
85 int windowcount = 0, curswas = 0;
86 int win_x = 0, win_y = 0, win_width = 0, win_height = 0;
CSCIDrawWindow(Bitmap * ds,int xx,int yy,int wid,int hit)87 int WINAPI _export CSCIDrawWindow(Bitmap *ds, int xx, int yy, int wid, int hit)
88 {
89     ignore_bounds++;
90     multiply_up(&xx, &yy, &wid, &hit);
91     int drawit = -1;
92     for (int aa = 0; aa < MAXSCREENWINDOWS; aa++) {
93         if (oswi[aa].buffer == NULL) {
94             drawit = aa;
95             break;
96         }
97     }
98 
99     if (drawit < 0)
100         quit("Too many windows created.");
101 
102     windowcount++;
103     //  domouse(2);
104     xx -= 2;
105     yy -= 2;
106     wid += 4;
107     hit += 4;
108     oswi[drawit].buffer = wnewblock(ds, xx, yy, xx + wid, yy + hit);
109     oswi[drawit].x = xx;
110     oswi[drawit].y = yy;
111     __my_wbutt(ds, xx + 1, yy + 1, xx + wid - 1, yy + hit - 1);    // wbutt goes outside its area
112     //  domouse(1);
113     oswi[drawit].oldtop = topwindowhandle;
114     topwindowhandle = drawit;
115     win_x = xx;
116     win_y = yy;
117     win_width = wid;
118     win_height = hit;
119     return drawit;
120 }
121 
CSCIEraseWindow(Bitmap * ds,int handl)122 void WINAPI _export CSCIEraseWindow(Bitmap *ds, int handl)
123 {
124     //  domouse(2);
125     ignore_bounds--;
126     topwindowhandle = oswi[handl].oldtop;
127     wputblock(ds, oswi[handl].x, oswi[handl].y, oswi[handl].buffer, 0);
128     delete oswi[handl].buffer;
129     //  domouse(1);
130     oswi[handl].buffer = NULL;
131     windowcount--;
132 }
133 
CSCIWaitMessage(Bitmap * ds,CSCIMessage * cscim)134 int WINAPI _export CSCIWaitMessage(Bitmap *ds, CSCIMessage * cscim)
135 {
136     NextIteration();
137     for (int uu = 0; uu < MAXCONTROLS; uu++) {
138         if (vobjs[uu] != NULL) {
139             //      domouse(2);
140             vobjs[uu]->drawifneeded();
141             //      domouse(1);
142         }
143     }
144 
145     prepare_gui_screen(win_x, win_y, win_width, win_height, true);
146 
147     while (1) {
148         timerloop = 0;
149         NextIteration();
150         refresh_gui_screen();
151 
152         cscim->id = -1;
153         cscim->code = 0;
154         smcode = 0;
155         int keywas;
156         if (run_service_key_controls(keywas)) {
157             if (keywas == 13) {
158                 cscim->id = finddefaultcontrol(CNF_DEFAULT);
159                 cscim->code = CM_COMMAND;
160             } else if (keywas == 27) {
161                 cscim->id = finddefaultcontrol(CNF_CANCEL);
162                 cscim->code = CM_COMMAND;
163             } else if ((keywas < 32) && (keywas != 8)) ;
164             else if ((keywas >= 372) & (keywas <= 381) & (finddefaultcontrol(CNT_LISTBOX) >= 0))
165                 vobjs[finddefaultcontrol(CNT_LISTBOX)]->processmessage(CTB_KEYPRESS, keywas, 0);
166             else if (finddefaultcontrol(CNT_TEXTBOX) >= 0)
167                 vobjs[finddefaultcontrol(CNT_TEXTBOX)]->processmessage(CTB_KEYPRESS, keywas, 0);
168 
169             if (cscim->id < 0) {
170                 cscim->code = CM_KEYPRESS;
171                 cscim->wParam = keywas;
172             }
173         }
174 
175         if (rec_mgetbutton() != NONE) {
176             if (checkcontrols()) {
177                 cscim->id = controlid;
178                 cscim->code = CM_COMMAND;
179             }
180         }
181 
182         if (smcode) {
183             cscim->code = smcode;
184             cscim->id = controlid;
185         }
186 
187         if (cscim->code > 0)
188             break;
189 
190         update_polled_audio_and_crossfade();
191         WaitForNextFrame();
192     }
193 
194     clear_gui_screen();
195     return 0;
196 }
197 
CSCICreateControl(int typeandflags,int xx,int yy,int wii,int hii,const char * title)198 int WINAPI _export CSCICreateControl(int typeandflags, int xx, int yy, int wii, int hii, const char *title)
199 {
200     multiply_up(&xx, &yy, &wii, &hii);
201     int usec = -1;
202     for (int hh = 1; hh < MAXCONTROLS; hh++) {
203         if (vobjs[hh] == NULL) {
204             usec = hh;
205             break;
206         }
207     }
208 
209     if (usec < 0)
210         quit("Too many controls created");
211 
212     int type = typeandflags & 0x00ff;     // 256 control types
213     if (type == CNT_PUSHBUTTON) {
214         if (wii == -1)
215             wii = wgettextwidth(title, cbuttfont) + 20;
216 
217         vobjs[usec] = new MyPushButton(xx, yy, wii, hii, title);
218 
219     } else if (type == CNT_LISTBOX) {
220         vobjs[usec] = new MyListBox(xx, yy, wii, hii);
221     } else if (type == CNT_LABEL) {
222         vobjs[usec] = new MyLabel(xx, yy, wii, title);
223     } else if (type == CNT_TEXTBOX) {
224         vobjs[usec] = new MyTextBox(xx, yy, wii, title);
225     } else
226         quit("Unknown control type requested");
227 
228     vobjs[usec]->typeandflags = typeandflags;
229     vobjs[usec]->wlevel = topwindowhandle;
230     //  domouse(2);
231     vobjs[usec]->draw(GetVirtualScreen());
232     //  domouse(1);
233     return usec;
234 }
235 
CSCIDeleteControl(int haa)236 void WINAPI _export CSCIDeleteControl(int haa)
237 {
238     delete vobjs[haa];
239     vobjs[haa] = NULL;
240 }
241 
CSCISendControlMessage(int haa,int mess,int wPar,long lPar)242 int WINAPI _export CSCISendControlMessage(int haa, int mess, int wPar, long lPar)
243 {
244     if (vobjs[haa] == NULL)
245         return -1;
246     return vobjs[haa]->processmessage(mess, wPar, lPar);
247 }
248 
multiply_up_to_game_res(int * x,int * y)249 void multiply_up_to_game_res(int *x, int *y)
250 {
251     x[0] = get_fixed_pixel_size(x[0]);
252     y[0] = get_fixed_pixel_size(y[0]);
253 }
254 
multiply_up(int * x1,int * y1,int * x2,int * y2)255 void multiply_up(int *x1, int *y1, int *x2, int *y2)
256 {
257     multiply_up_to_game_res(x1, y1);
258     multiply_up_to_game_res(x2, y2);
259 
260     // adjust for 800x600
261     if ((GetBaseWidth() == 400) || (GetBaseWidth() == 800)) {
262         x1[0] = (x1[0] * 5) / 4;
263         x2[0] = (x2[0] * 5) / 4;
264         y1[0] = (y1[0] * 3) / 2;
265         y2[0] = (y2[0] * 3) / 2;
266     }
267     else if (GetBaseWidth() == 1024)
268     {
269         x1[0] = (x1[0] * 16) / 10;
270         x2[0] = (x2[0] * 16) / 10;
271         y1[0] = (y1[0] * 384) / 200;
272         y2[0] = (y2[0] * 384) / 200;
273     }
274 }
275 
checkcontrols()276 int checkcontrols()
277 {
278     smcode = 0;
279     for (int kk = 0; kk < MAXCONTROLS; kk++) {
280         if (vobjs[kk] != NULL) {
281             if (vobjs[kk]->mouseisinarea()) {
282                 controlid = kk;
283                 return vobjs[kk]->pressedon();
284             }
285         }
286     }
287     return 0;
288 }
289 
finddefaultcontrol(int flagmask)290 int finddefaultcontrol(int flagmask)
291 {
292     for (int ff = 0; ff < MAXCONTROLS; ff++) {
293         if (vobjs[ff] == NULL)
294             continue;
295 
296         if (vobjs[ff]->wlevel != topwindowhandle)
297             continue;
298 
299         if (vobjs[ff]->typeandflags & flagmask)
300             return ff;
301     }
302 
303     return -1;
304 }
305 
GetBaseWidth()306 int GetBaseWidth () {
307     return BASEWIDTH;
308 }
309