diff --git a/include/video.h b/include/video.h index fab6cfdb..40656bc0 100644 --- a/include/video.h +++ b/include/video.h @@ -65,6 +65,7 @@ void GFX_Stop(void); void GFX_SwitchFullScreen(void); bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch); void GFX_EndUpdate( const Bit16u *changedLines ); +void GFX_GetSize(int &width, int &height, bool &fullscreen); #if defined (WIN32) bool GFX_SDLUsingWinDIB(void); diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 6efa58f9..d397a92e 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -6,5 +6,6 @@ libgui_a_SOURCES = sdlmain.cpp sdl_mapper.cpp dosbox_logo.h \ render_templates.h render_loops.h render_simple.h \ render_templates_sai.h render_templates_hq.h \ render_templates_hq2x.h render_templates_hq3x.h \ - midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h + midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h \ + sdl_gui.cpp diff --git a/src/gui/sdl_gui.cpp b/src/gui/sdl_gui.cpp new file mode 100644 index 00000000..cc745dbc --- /dev/null +++ b/src/gui/sdl_gui.cpp @@ -0,0 +1,625 @@ +/* + * Copyright (C) 2002-2007 The DOSBox Team + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* $Id: sdl_gui.cpp,v 1.1 2007-10-28 16:36:41 qbix79 Exp $ */ + +#include "SDL.h" +#include "../libs/gui_tk/gui_tk.h" + +#include "dosbox.h" +#include "keyboard.h" +#include "video.h" +#include "render.h" +#include "mapper.h" +#include "setup.h" +#include "shell.h" + +#include +#include +#include +#include +#include +#include + +extern Bit8u int10_font_14[256 * 14]; +extern Program * first_shell; +extern void MSG_Write(const char *); +extern void GFX_SetTitle(Bit32s cycles, Bits frameskip, bool paused); + +static int cursor, saved_bpp; +static int old_unicode; +static bool mousetoggle, running, shell_idle; + +static SDL_Surface *screenshot, *background; + +/* Prepare screen for UI */ +void UI_Init(void) { + GUI::Font::addFont("default",new GUI::BitmapFont(int10_font_14,14,10)); +} + +static void getPixel(Bitu x, Bitu y, int &r, int &g, int &b, int shift) +{ + if (x >= render.src.width) x = render.src.width-1; + if (y >= render.src.height) x = render.src.height-1; + if (x < 0) x = 0; + if (y < 0) y = 0; + + Bit8u* src = (Bit8u *)&scalerSourceCache; + Bit32u pixel; + switch (render.scale.inMode) { + case scalerMode8: + pixel = *(x+(Bit8u*)(src+y*render.scale.cachePitch)); + r += render.pal.rgb[pixel].red >> shift; + g += render.pal.rgb[pixel].green >> shift; + b += render.pal.rgb[pixel].blue >> shift; + break; + case scalerMode15: + pixel = *(x+(Bit16u*)(src+y*render.scale.cachePitch)); + r += (pixel >> (7+shift)) & (0xf8 >> shift); + g += (pixel >> (2+shift)) & (0xf8 >> shift); + b += (pixel << (3-shift)) & (0xf8 >> shift); + break; + case scalerMode16: + pixel = *(x+(Bit16u*)(src+y*render.scale.cachePitch)); + r += (pixel >> (8+shift)) & (0xf8 >> shift); + g += (pixel >> (3+shift)) & (0xfc >> shift); + b += (pixel << (3-shift)) & (0xf8 >> shift); + break; + case scalerMode32: + pixel = *(x+(Bit32u*)(src+y*render.scale.cachePitch)); + r += (pixel >> (16+shift)) & (0xff >> shift); + g += (pixel >> (8+shift)) & (0xff >> shift); + b += (pixel >> shift) & (0xff >> shift); + break; + } +} + +static GUI::ScreenSDL *UI_Startup(GUI::ScreenSDL *screen) { + GFX_EndUpdate(0); + GFX_SetTitle(-1,-1,true); + if(!screen) { //Coming from DOSBox. Clean up the keyboard buffer. + KEYBOARD_ClrBuffer();//Clear buffer + } + MAPPER_LosingFocus();//Release any keys pressed (buffer gets filled again). (could be in above if, but clearing the mapper input when exiting the mapper is sensible as well + SDL_Delay(500); + + // Comparable to the code of intro.com, but not the same! (the code of intro.com is called from within a com file) + shell_idle = first_shell && (DOS_PSP(dos.psp()).GetSegment() == DOS_PSP(dos.psp()).GetParent()); + + int w, h; + bool fs; + GFX_GetSize(w, h, fs); + if (w < 512) w = 640; + if (h < 350) h = 400; + + old_unicode = SDL_EnableUNICODE(1); + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL); + screenshot = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, GUI::Color::RedMask, GUI::Color::GreenMask, GUI::Color::BlueMask, 0); + + // create screenshot for fade effect + int rs = screenshot->format->Rshift, gs = screenshot->format->Gshift, bs = screenshot->format->Bshift, am = GUI::Color::AlphaMask; + for (int y = 0; y < h; y++) { + Bit32u *bg = (Bit32u*)(y*screenshot->pitch + (char*)screenshot->pixels); + for (int x = 0; x < w; x++) { + int r = 0, g = 0, b = 0; + getPixel(x *(int)render.src.width/w, y *(int)render.src.height/h, r, g, b, 0); + bg[x] = r << rs | g << gs | b << bs; + } + } + + background = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, GUI::Color::RedMask, GUI::Color::GreenMask, GUI::Color::BlueMask, GUI::Color::AlphaMask); + // use a blurred and sepia-toned screenshot as menu background + for (int y = 0; y < h; y++) { + Bit32u *bg = (Bit32u*)(y*background->pitch + (char*)background->pixels); + for (int x = 0; x < w; x++) { + int r = 0, g = 0, b = 0; + getPixel(x *(int)render.src.width/w, y *(int)render.src.height/h, r, g, b, 3); + getPixel((x-1)*(int)render.src.width/w, y *(int)render.src.height/h, r, g, b, 3); + getPixel(x *(int)render.src.width/w, (y-1)*(int)render.src.height/h, r, g, b, 3); + getPixel((x-1)*(int)render.src.width/w, (y-1)*(int)render.src.height/h, r, g, b, 3); + getPixel((x+1)*(int)render.src.width/w, y *(int)render.src.height/h, r, g, b, 3); + getPixel(x *(int)render.src.width/w, (y+1)*(int)render.src.height/h, r, g, b, 3); + getPixel((x+1)*(int)render.src.width/w, (y+1)*(int)render.src.height/h, r, g, b, 3); + getPixel((x-1)*(int)render.src.width/w, (y+1)*(int)render.src.height/h, r, g, b, 3); + int r1 = (int)((r * 393 + g * 769 + b * 189) / 1351); + int g1 = (int)((r * 349 + g * 686 + b * 168) / 1203); + int b1 = (int)((r * 272 + g * 534 + b * 131) / 2140); + bg[x] = r1 << rs | g1 << gs | b1 << bs | am; + } + } + + cursor = SDL_ShowCursor(SDL_QUERY); + SDL_ShowCursor(SDL_ENABLE); + + mousetoggle = mouselocked; + if (mouselocked) GFX_CaptureMouse(); + + SDL_Surface* sdlscreen = SDL_SetVideoMode(w, h, 32, SDL_SWSURFACE|(fs?SDL_FULLSCREEN:0)); + if (sdlscreen == NULL) E_Exit("Could not initialize video mode %ix%ix32 for UI: %s", w, h, SDL_GetError()); + + // fade out + SDL_Event event; + for (int i = 0xff; i > 0; i -= 0x11) { + SDL_SetAlpha(screenshot, SDL_SRCALPHA, i); + SDL_BlitSurface(background, NULL, sdlscreen, NULL); + SDL_BlitSurface(screenshot, NULL, sdlscreen, NULL); + SDL_UpdateRect(sdlscreen, 0, 0, 0, 0); + while (SDL_PollEvent(&event)); + SDL_Delay(40); + } + + SDL_BlitSurface(background, NULL, sdlscreen, NULL); + SDL_UpdateRect(sdlscreen, 0, 0, 0, 0); + + if (screen) screen->setSurface(sdlscreen); + else screen = new GUI::ScreenSDL(sdlscreen); + + saved_bpp = render.src.bpp; + render.src.bpp = 0; + running = true; + return screen; +} + +/* Restore screen */ +static void UI_Shutdown(GUI::ScreenSDL *screen) { + SDL_Surface *sdlscreen = screen->getSurface(); + render.src.bpp = saved_bpp; + + // fade in + SDL_Event event; + for (int i = 0x00; i < 0xff; i += 0x11) { + SDL_SetAlpha(screenshot, SDL_SRCALPHA, i); + SDL_BlitSurface(background, NULL, sdlscreen, NULL); + SDL_BlitSurface(screenshot, NULL, sdlscreen, NULL); + SDL_UpdateRect(sdlscreen, 0, 0, 0, 0); + while (SDL_PollEvent(&event)); + SDL_Delay(40); + } + + // clean up + if (mousetoggle) GFX_CaptureMouse(); + SDL_ShowCursor(cursor); + SDL_FreeSurface(background); + SDL_FreeSurface(screenshot); + SDL_FreeSurface(sdlscreen); + screen->setSurface(NULL); + GFX_ResetScreen(); + SDL_EnableUNICODE(old_unicode); + SDL_EnableKeyRepeat(0,0); + GFX_SetTitle(-1,-1,false); +} + +/* helper class for command execution */ +class VirtualBatch : public BatchFile { +protected: + std::istringstream lines; +public: + VirtualBatch(DOS_Shell *host, const std::string& cmds) : BatchFile(host, "CON", ""), lines(cmds) { + } + bool ReadLine(char *line) { + std::string l; + if (!std::getline(lines,l)) { + delete this; + return false; + } + strcpy(line,l.c_str()); + return true; + } +}; + +static void UI_RunCommands(GUI::ScreenSDL *s, const std::string &cmds) { + DOS_Shell temp; + temp.call = true; + UI_Shutdown(s); + temp.bf = new VirtualBatch(&temp, cmds); + temp.RunInternal(); + temp.ShowPrompt(); + UI_Startup(s); +} + + +/* stringification and conversion from the c++ FAQ */ +class BadConversion : public std::runtime_error { +public: BadConversion(const std::string& s) : std::runtime_error(s) { } +}; + +template inline std::string stringify(const T& x, std::ios_base& ( *pf )(std::ios_base&) = NULL) { + std::ostringstream o; + if (pf) o << pf; + if (!(o << x)) throw BadConversion(std::string("stringify(") + typeid(x).name() + ")"); + return o.str(); +} + +template inline void convert(const std::string& s, T& x, bool failIfLeftoverChars = true, std::ios_base& ( *pf )(std::ios_base&) = NULL) { + std::istringstream i(s); + if (pf) i >> pf; + char c; + if (!(i >> x) || (failIfLeftoverChars && i.get(c))) throw BadConversion(s); +} + +/*****************************************************************************************************************************************/ +/* UI classes */ + +class PropertyEditor : public GUI::Window, public GUI::ActionEventSource_Callback { +protected: + Section_prop * section; + Property *prop; +public: + PropertyEditor(Window *parent, int x, int y, Section_prop *section, Property *prop) : + Window(parent, x, y, 240, 30), section(section), prop(prop) { } + + virtual bool prepare(std::string &buffer) = 0; + + void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + std::string line; + if (prepare(line)) { + if (first_shell) section->ExecuteDestroy(false); + prop->SetValue(GUI::String(line)); + if (first_shell) section->ExecuteInit(false); + } + } +}; + +class PropertyEditorBool : public PropertyEditor { + GUI::Checkbox *input; +public: + PropertyEditorBool(Window *parent, int x, int y, Section_prop *section, Property *prop) : + PropertyEditor(parent, x, y, section, prop) { + input = new GUI::Checkbox(this, 0, 3, prop->propname.c_str()); + input->setChecked(prop->GetValue()._bool); + } + + bool prepare(std::string &buffer) { + if (input->isChecked() == prop->GetValue()._bool) return false; + buffer.append(input->isChecked()?"true":"false"); + return true; + } +}; + +class PropertyEditorString : public PropertyEditor { +protected: + GUI::Input *input; +public: + PropertyEditorString(Window *parent, int x, int y, Section_prop *section, Property *prop) : + PropertyEditor(parent, x, y, section, prop) { + new GUI::Label(this, 0, 5, prop->propname); + input = new GUI::Input(this, 130, 0, 110); + input->setText(prop->GetValue()._string); + } + + bool prepare(std::string &buffer) { + if (input->getText() == GUI::String(prop->GetValue()._string)) return false; + buffer.append((const std::string&)input->getText()); + return true; + } +}; + +class PropertyEditorFloat : public PropertyEditor { +protected: + GUI::Input *input; +public: + PropertyEditorFloat(Window *parent, int x, int y, Section_prop *section, Property *prop) : + PropertyEditor(parent, x, y, section, prop) { + new GUI::Label(this, 0, 5, prop->propname); + input = new GUI::Input(this, 130, 0, 50); + input->setText(stringify(prop->GetValue()._float)); + } + + bool prepare(std::string &buffer) { + float val; + convert(input->getText(), val, false); + if (val == prop->GetValue()._float) return false; + buffer.append(stringify(val)); + return true; + } +}; + +class PropertyEditorHex : public PropertyEditor { +protected: + GUI::Input *input; +public: + PropertyEditorHex(Window *parent, int x, int y, Section_prop *section, Property *prop) : + PropertyEditor(parent, x, y, section, prop) { + new GUI::Label(this, 0, 5, prop->propname); + input = new GUI::Input(this, 130, 0, 50); + input->setText(stringify(prop->GetValue()._hex, std::hex)); + } + + bool prepare(std::string &buffer) { + int val; + convert(input->getText(), val, false, std::hex); + if (val == prop->GetValue()._hex) return false; + buffer.append(stringify(val, std::hex)); + return true; + } +}; + +class PropertyEditorInt : public PropertyEditor { +protected: + GUI::Input *input; +public: + PropertyEditorInt(Window *parent, int x, int y, Section_prop *section, Property *prop) : + PropertyEditor(parent, x, y, section, prop) { + new GUI::Label(this, 0, 5, prop->propname); + input = new GUI::Input(this, 130, 0, 50); + input->setText(stringify(prop->GetValue()._int)); + } + + bool prepare(std::string &buffer) { + int val; + convert(input->getText(), val, false); + if (val == prop->GetValue()._int) return false; + buffer.append(stringify(val)); + return true; + } +}; + +class HelpWindow : public GUI::MessageBox { +public: + HelpWindow(GUI::Screen *parent, int x, int y, Section *section) : + MessageBox(parent, x, y, 580, "", "") { + std::string title(section->GetName()); + title[0] = std::toupper(title[0]); + setTitle("Help for "+title); + std::string name = section->GetName(); + std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))std::toupper); + name += "_CONFIGFILE_HELP"; + setText(MSG_Get(name.c_str())); + } +}; + +class SectionEditor : public GUI::ToplevelWindow { + Section_prop * section; +public: + SectionEditor(GUI::Screen *parent, int x, int y, Section_prop *section) : + ToplevelWindow(parent, x, y, 510, 300, ""), section(section) { + std::string title(section->GetName()); + title[0] = std::toupper(title[0]); + setTitle("Configuration for "+title); + new GUI::Label(this, 5, 10, "Settings:"); + GUI::Button *b = new GUI::Button(this, 120, 220, "Cancel", 70); + b->addActionHandler(this); + b = new GUI::Button(this, 200, 220, "Help", 70); + b->addActionHandler(this); + b = new GUI::Button(this, 280, 220, "OK", 70); + + int i = 0; + Property *prop; + while ((prop = section->Get_prop(i))) { + Prop_bool *pbool = dynamic_cast(prop); + Prop_int *pint = dynamic_cast(prop); + Prop_float *pfloat = dynamic_cast(prop); + Prop_hex *phex = dynamic_cast(prop); + Prop_string *pstring = dynamic_cast(prop); + + PropertyEditor *p; + if (pbool) p = new PropertyEditorBool(this, 5+250*(i/6), 40+(i%6)*30, section, prop); + else if (phex) p = new PropertyEditorHex(this, 5+250*(i/6), 40+(i%6)*30, section, prop); + else if (pint) p = new PropertyEditorInt(this, 5+250*(i/6), 40+(i%6)*30, section, prop); + else if (pfloat) p = new PropertyEditorFloat(this, 5+250*(i/6), 40+(i%6)*30, section, prop); + else if (pstring) p = new PropertyEditorString(this, 5+250*(i/6), 40+(i%6)*30, section, prop); + else { i++; continue; } + b->addActionHandler(p); + i++; + } + b->addActionHandler(this); + } + + void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + if (arg == "OK" || arg == "Cancel") close(); + else if (arg == "Help") new HelpWindow(static_cast(parent), getX()-10, getY()-10, section); + else ToplevelWindow::actionExecuted(b, arg); + } +}; + +class AutoexecEditor : public GUI::ToplevelWindow { + Section_line * section; + GUI::Input *content; +public: + AutoexecEditor(GUI::Screen *parent, int x, int y, Section_line *section) : + ToplevelWindow(parent, x, y, 450, 300, ""), section(section) { + std::string title(section->GetName()); + title[0] = std::toupper(title[0]); + setTitle("Edit "+title); + new GUI::Label(this, 5, 10, "Content:"); + content = new GUI::Input(this, 5, 30, 420, 185); + content->setText(section->data); + if (first_shell) (new GUI::Button(this, 5, 220, "Append History"))->addActionHandler(this); + if (shell_idle) (new GUI::Button(this, 180, 220, "Execute Now"))->addActionHandler(this); + (new GUI::Button(this, 290, 220, "Cancel", 70))->addActionHandler(this); + (new GUI::Button(this, 360, 220, "OK", 70))->addActionHandler(this); + } + + void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + if (arg == "OK") section->data = *(std::string*)content->getText(); + if (arg == "OK" || arg == "Cancel") close(); + else if (arg == "Append Shell Commands") { + DOS_Shell *s = static_cast(first_shell); + std::list::reverse_iterator i = s->l_history.rbegin(); + std::string lines = *(std::string*)content->getText(); + while (i != s->l_history.rend()) { + lines += "\n"; + lines += *i; + ++i; + } + content->setText(lines); + } else if (arg == "Execute Now") { + UI_RunCommands(dynamic_cast(getScreen()), content->getText()); + } else ToplevelWindow::actionExecuted(b, arg); + } +}; + +class SaveDialog : public GUI::ToplevelWindow { +protected: + GUI::Input *name; +public: + SaveDialog(GUI::Screen *parent, int x, int y, const char *title) : + ToplevelWindow(parent, x, y, 400, 150, title) { + new GUI::Label(this, 5, 10, "Enter filename for configuration file:"); + name = new GUI::Input(this, 5, 30, 350); + name->setText("dosbox.conf"); + (new GUI::Button(this, 120, 70, "Cancel", 70))->addActionHandler(this); + (new GUI::Button(this, 210, 70, "OK", 70))->addActionHandler(this); + } + + void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + if (arg == "OK") control->PrintConfig(name->getText()); + close(); + } +}; + +class SaveLangDialog : public GUI::ToplevelWindow { +protected: + GUI::Input *name; +public: + SaveLangDialog(GUI::Screen *parent, int x, int y, const char *title) : + ToplevelWindow(parent, x, y, 400, 150, title) { + new GUI::Label(this, 5, 10, "Enter filename for language file:"); + name = new GUI::Input(this, 5, 30, 350); + name->setText("messages.txt"); + (new GUI::Button(this, 120, 70, "Cancel", 70))->addActionHandler(this); + (new GUI::Button(this, 210, 70, "OK", 70))->addActionHandler(this); + } + + void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + if (arg == "OK") MSG_Write(name->getText()); + close(); + } +}; + +class ConfigurationWindow : public GUI::ToplevelWindow { +public: + ConfigurationWindow(GUI::Screen *parent, GUI::Size x, GUI::Size y, GUI::String title) : + GUI::ToplevelWindow(parent, x, y, 470, 290, title) { + + (new GUI::Button(this, 180, 215, "Close", 70))->addActionHandler(this); + + GUI::Menubar *bar = new GUI::Menubar(this, 0, 0, getWidth()); + bar->addMenu("Configuration"); + bar->addItem(0,"Save..."); + bar->addItem(0,"Save Language File..."); + bar->addItem(0,""); + bar->addItem(0,"Close"); + bar->addMenu("Settings"); + bar->addMenu("Help"); + bar->addItem(2,"Introduction"); + bar->addItem(2,"Getting Started"); + bar->addItem(2,"CD-ROM Support"); + bar->addItem(2,"Special Keys"); + bar->addItem(2,""); + bar->addItem(2,"About"); + bar->addActionHandler(this); + + new GUI::Label(this, 10, 30, "Choose a settings group to configure:"); + + Section *sec; + int i = 0; + while ((sec = control->GetSection(i))) { + std::string name = sec->GetName(); + name[0] = std::toupper(name[0]); + GUI::Button *b = new GUI::Button(this, 12+(i/5)*160, 50+(i%5)*30, name, 100); + b->addActionHandler(this); + bar->addItem(1, name); + i++; + } + + if (first_shell) { + (new GUI::Button(this, 12+(i/5)*160, 50+(i%5)*30, "Keyboard", 100))->addActionHandler(this); + bar->addItem(1, ""); + bar->addItem(1, "Keyboard"); + } + } + + ~ConfigurationWindow() { running = false; } + + void actionExecuted(GUI::ActionEventSource *b, const GUI::String &arg) { + GUI::String sname = arg; + sname[0] = std::tolower(sname[0]); + Section *sec; + if (arg == "Close" || arg == "Cancel") { + running = false; + } else if (arg == "Keyboard") { + UI_Shutdown(dynamic_cast(getScreen())); + MAPPER_Run(true); + UI_Startup(dynamic_cast(getScreen())); + } else if (sname == "autoexec") { + Section_line *section = static_cast(control->GetSection((const char *)sname)); + new AutoexecEditor(getScreen(), 50, 30, section); + } else if ((sec = control->GetSection((const char *)sname))) { + Section_prop *section = static_cast(sec); + new SectionEditor(getScreen(), 50, 30, section); + } else if (arg == "About") { + new GUI::MessageBox(getScreen(), 200, 150, 280, "About DOSBox", "\nDOSBox 0.72\nAn emulator for old DOS Games\n\nCopyright 2002-2007\nThe DOSBox Team"); + } else if (arg == "Introduction") { + new GUI::MessageBox(getScreen(), 20, 50, 600, "Introduction", MSG_Get("PROGRAM_INTRO")); + } else if (arg == "Getting Started") { + std::string msg = MSG_Get("PROGRAM_INTRO_MOUNT_START"); +#ifdef WIN32 + msg += MSG_Get("PROGRAM_INTRO_MOUNT_WINDOWS"); +#else + msg += MSG_Get("PROGRAM_INTRO_MOUNT_OTHER"); +#endif + msg += MSG_Get("PROGRAM_INTRO_MOUNT_END"); + + new GUI::MessageBox(getScreen(), 20, 50, 600, std::string("Introduction"), msg); + } else if (arg == "CD-ROM Support") { + new GUI::MessageBox(getScreen(), 20, 50, 600, "Introduction", MSG_Get("PROGRAM_INTRO_CDROM")); + } else if (arg == "Special Keys") { + new GUI::MessageBox(getScreen(), 20, 50, 600, "Introduction", MSG_Get("PROGRAM_INTRO_SPECIAL")); + } else if (arg == "Save...") { + new SaveDialog(getScreen(), 90, 100, "Save Configuration..."); + } else if (arg == "Save Language File...") { + new SaveLangDialog(getScreen(), 90, 100, "Save Language File..."); + } else { + return ToplevelWindow::actionExecuted(b, arg); + } + } +}; + +/*********************************************************************************************************************/ +/* UI control functions */ + +static void UI_Execute(GUI::ScreenSDL *screen) { + SDL_Surface *sdlscreen = screen->getSurface(); + new ConfigurationWindow(screen, 30, 30, "DOSBox Configuration"); + + // event loop + SDL_Event event; + while (running) { + while (SDL_PollEvent(&event)) { + if (!screen->event(event)) { + if (event.type == SDL_QUIT) running = false; + } + } + //Selecting keyboard will create a new surface. + sdlscreen = screen->getSurface(); + SDL_BlitSurface(background, NULL, sdlscreen, NULL); + screen->update(4); + SDL_UpdateRect(sdlscreen, 0, 0, 0, 0); + + SDL_Delay(40); + } +} + +void UI_Run(bool pressed) { + if (pressed) return; + GUI::ScreenSDL *screen = UI_Startup(NULL); + UI_Execute(screen); + UI_Shutdown(screen); + delete screen; +} diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 909382c4..6462aa8a 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.44 2007-08-17 18:49:56 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.45 2007-10-28 16:36:41 qbix79 Exp $ */ #include #include @@ -2229,7 +2229,9 @@ void MAPPER_Run(bool pressed) { for (CEventVector_it evit=events.begin();evit!=events.end();evit++) { (*evit)->DeActivateAll(); } - + + int cursor = SDL_ShowCursor(SDL_QUERY); + SDL_ShowCursor(SDL_ENABLE); bool mousetoggle=false; if(mouselocked) { mousetoggle=true; @@ -2266,6 +2268,7 @@ void MAPPER_Run(bool pressed) { SDL_JoystickEventState(SDL_DISABLE); #endif if(mousetoggle) GFX_CaptureMouse(); + SDL_ShowCursor(cursor); GFX_ResetScreen(); } @@ -2364,6 +2367,5 @@ void MAPPER_StartUp(Section * sec) { } mapper.filename=section->Get_string("mapperfile"); - MAPPER_AddHandler(&MAPPER_Run,MK_f1,MMOD1,"mapper","Mapper"); } diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index abf6d134..de7f6ec9 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdlmain.cpp,v 1.134 2007-08-26 18:03:25 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.135 2007-10-28 16:36:42 qbix79 Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -238,32 +238,6 @@ void GFX_SetTitle(Bit32s cycles,Bits frameskip,bool paused){ SDL_WM_SetCaption(title,VERSION); } -static void PauseDOSBox(bool pressed) { - if (!pressed) - return; - GFX_SetTitle(-1,-1,true); - bool paused = true; - KEYBOARD_ClrBuffer(); - SDL_Delay(500); - SDL_Event event; - while (SDL_PollEvent(&event)) { - // flush event queue. - } - while (paused) { - SDL_WaitEvent(&event); // since we're not polling, cpu usage drops to 0. - switch (event.type) { - case SDL_QUIT: throw(0); break; - case SDL_KEYDOWN: // Must use Pause/Break Key to resume. - case SDL_KEYUP: - if(event.key.keysym.sym==SDLK_PAUSE){ - paused=false; - GFX_SetTitle(-1,-1,false); - break; - } - } - } -} - #if defined (WIN32) bool GFX_SDLUsingWinDIB(void) { return sdl.using_windib; @@ -942,6 +916,7 @@ static unsigned char logo[32*32*4]= { #include "dosbox_logo.h" }; +extern void UI_Run(bool); static void GUI_StartUp(Section * sec) { sec->AddDestroyFunction(&GUI_ShutDown); Section_prop * section=static_cast(sec); @@ -1131,7 +1106,7 @@ static void GUI_StartUp(Section * sec) { #if C_DEBUG /* Pause binds with activate-debugger */ #else - MAPPER_AddHandler(PauseDOSBox,MK_pause,MMOD2,"pause","Pause"); + MAPPER_AddHandler(&UI_Run, MK_pause, MMOD2, "ui", "UI"); #endif /* Get Keyboard state of numlock and capslock */ SDLMod keystate = SDL_GetModState(); @@ -1345,6 +1320,8 @@ void GFX_ShowMsg(char const* format,...) { if(!no_stdout) printf(buf); }; +extern void UI_Init(void); + int main(int argc, char* argv[]) { try { CommandLine com_line(argc,argv); @@ -1503,6 +1480,8 @@ int main(int argc, char* argv[]) { #if (ENVIRON_LINKED) control->ParseEnv(environ); #endif + UI_Init(); + if (control->cmdline->FindExist("-startui")) UI_Run(false); /* Init all the sections */ control->Init(); /* Some extra SDL Functions */ @@ -1514,8 +1493,6 @@ int main(int argc, char* argv[]) { /* Init the keyMapper */ MAPPER_Init(); - if (control->cmdline->FindExist("-startmapper")) MAPPER_Run(true); - /* Start up main machine */ control->StartUp(); /* Shutdown everything */ @@ -1543,3 +1520,9 @@ int main(int argc, char* argv[]) { SDL_Quit();//Let's hope sdl will quit as well when it catches an exception return 0; }; + +void GFX_GetSize(int &width, int &height, bool &fullscreen) { + width = sdl.draw.width; + height = sdl.draw.height; + fullscreen = sdl.desktop.fullscreen; +}