2009-05-02 23:03:37 +02:00
|
|
|
/*
|
2009-05-03 00:18:08 +02:00
|
|
|
* Copyright (C) 2002-2006 The DOSBox Team
|
2009-05-02 23:03:37 +02:00
|
|
|
*
|
|
|
|
* 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
|
2009-05-03 00:02:15 +02:00
|
|
|
* GNU General Public License for more details.
|
2009-05-02 23:03:37 +02:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
2009-05-02 23:43:00 +02:00
|
|
|
|
2009-05-03 00:18:08 +02:00
|
|
|
/* $Id: sdlmain.cpp,v 1.113 2006/03/29 12:26:07 qbix79 Exp $ */
|
2009-05-02 23:43:00 +02:00
|
|
|
|
2009-05-02 23:35:44 +02:00
|
|
|
#ifndef _GNU_SOURCE
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#endif
|
2009-05-02 23:03:37 +02:00
|
|
|
|
2009-05-02 23:43:00 +02:00
|
|
|
#include <stdlib.h>
|
2009-05-02 23:03:37 +02:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
2009-05-02 23:35:44 +02:00
|
|
|
#include <unistd.h>
|
2009-05-02 23:43:00 +02:00
|
|
|
#include <stdarg.h>
|
2009-05-03 00:08:43 +02:00
|
|
|
#include <sys/types.h>
|
2009-05-02 23:35:44 +02:00
|
|
|
|
|
|
|
#include "SDL.h"
|
2009-05-02 23:20:05 +02:00
|
|
|
|
2009-05-02 23:03:37 +02:00
|
|
|
#include "dosbox.h"
|
|
|
|
#include "video.h"
|
|
|
|
#include "mouse.h"
|
|
|
|
#include "pic.h"
|
|
|
|
#include "timer.h"
|
2009-05-02 23:20:05 +02:00
|
|
|
#include "setup.h"
|
2009-05-02 23:53:27 +02:00
|
|
|
#include "support.h"
|
2009-05-02 23:20:05 +02:00
|
|
|
#include "debug.h"
|
2009-05-03 00:02:15 +02:00
|
|
|
#include "mapper.h"
|
2009-05-03 00:18:08 +02:00
|
|
|
#include "vga.h"
|
|
|
|
#include "keyboard.h"
|
2009-05-03 00:02:15 +02:00
|
|
|
|
|
|
|
//#define DISABLE_JOYSTICK
|
2009-05-02 23:03:37 +02:00
|
|
|
|
2009-05-02 23:53:27 +02:00
|
|
|
#if C_OPENGL
|
|
|
|
#include "SDL_opengl.h"
|
|
|
|
|
|
|
|
#ifndef APIENTRY
|
|
|
|
#define APIENTRY
|
|
|
|
#endif
|
|
|
|
#ifndef APIENTRYP
|
|
|
|
#define APIENTRYP APIENTRY *
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __WIN32__
|
|
|
|
#define NVIDIA_PixelDataRange 1
|
2009-05-03 00:02:15 +02:00
|
|
|
|
2009-05-02 23:53:27 +02:00
|
|
|
#ifndef WGL_NV_allocate_memory
|
|
|
|
#define WGL_NV_allocate_memory 1
|
|
|
|
typedef void * (APIENTRY * PFNWGLALLOCATEMEMORYNVPROC) (int size, float readfreq, float writefreq, float priority);
|
|
|
|
typedef void (APIENTRY * PFNWGLFREEMEMORYNVPROC) (void *pointer);
|
2009-05-03 00:02:15 +02:00
|
|
|
#endif
|
|
|
|
|
2009-05-02 23:53:27 +02:00
|
|
|
PFNWGLALLOCATEMEMORYNVPROC db_glAllocateMemoryNV = NULL;
|
|
|
|
PFNWGLFREEMEMORYNVPROC db_glFreeMemoryNV = NULL;
|
2009-05-03 00:02:15 +02:00
|
|
|
|
2009-05-02 23:53:27 +02:00
|
|
|
#else
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(NVIDIA_PixelDataRange)
|
2009-05-03 00:02:15 +02:00
|
|
|
|
2009-05-02 23:53:27 +02:00
|
|
|
#ifndef GL_NV_pixel_data_range
|
|
|
|
#define GL_NV_pixel_data_range 1
|
|
|
|
#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878
|
|
|
|
typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer);
|
|
|
|
typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target);
|
|
|
|
#endif
|
2009-05-03 00:02:15 +02:00
|
|
|
|
|
|
|
PFNGLPIXELDATARANGENVPROC glPixelDataRangeNV = NULL;
|
|
|
|
|
2009-05-02 23:53:27 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif //C_OPENGL
|
|
|
|
|
2009-05-02 23:43:00 +02:00
|
|
|
#if !(ENVIRON_INCLUDED)
|
2009-05-02 23:35:44 +02:00
|
|
|
extern char** environ;
|
|
|
|
#endif
|
2009-05-02 23:03:37 +02:00
|
|
|
|
2009-05-02 23:43:00 +02:00
|
|
|
#ifdef WIN32
|
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
|
|
#endif
|
|
|
|
#include <windows.h>
|
2009-05-03 00:18:08 +02:00
|
|
|
#if (HAVE_DDRAW_H)
|
2009-05-03 00:02:15 +02:00
|
|
|
#include <ddraw.h>
|
|
|
|
struct private_hwdata {
|
|
|
|
LPDIRECTDRAWSURFACE3 dd_surface;
|
|
|
|
LPDIRECTDRAWSURFACE3 dd_writebuf;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2009-05-02 23:43:00 +02:00
|
|
|
#define STDOUT_FILE TEXT("stdout.txt")
|
|
|
|
#define STDERR_FILE TEXT("stderr.txt")
|
2009-05-02 23:53:27 +02:00
|
|
|
#define DEFAULT_CONFIG_FILE "/dosbox.conf"
|
|
|
|
#elif defined(MACOSX)
|
|
|
|
#define DEFAULT_CONFIG_FILE "/Library/Preferences/DOSBox Preferences"
|
|
|
|
#else /*linux freebsd*/
|
|
|
|
#define DEFAULT_CONFIG_FILE "/.dosboxrc"
|
2009-05-02 23:43:00 +02:00
|
|
|
#endif
|
|
|
|
|
2009-05-03 00:02:15 +02:00
|
|
|
#if C_SET_PRIORITY
|
|
|
|
#include <sys/resource.h>
|
|
|
|
#define PRIO_TOTAL (PRIO_MAX-PRIO_MIN)
|
|
|
|
#endif
|
|
|
|
|
2009-05-03 00:18:08 +02:00
|
|
|
#ifdef OS2
|
|
|
|
#define INCL_DOS
|
|
|
|
#define INCL_WIN
|
|
|
|
#include <os2.h>
|
|
|
|
#endif
|
|
|
|
|
2009-05-02 23:53:27 +02:00
|
|
|
enum SCREEN_TYPES {
|
|
|
|
SCREEN_SURFACE,
|
2009-05-03 00:02:15 +02:00
|
|
|
SCREEN_SURFACE_DDRAW,
|
2009-05-02 23:53:27 +02:00
|
|
|
SCREEN_OVERLAY,
|
|
|
|
SCREEN_OPENGL
|
|
|
|
};
|
|
|
|
|
2009-05-03 00:02:15 +02:00
|
|
|
enum PRIORITY_LEVELS {
|
2009-05-03 00:18:08 +02:00
|
|
|
PRIORITY_LEVEL_LOWEST,
|
2009-05-03 00:02:15 +02:00
|
|
|
PRIORITY_LEVEL_LOWER,
|
|
|
|
PRIORITY_LEVEL_NORMAL,
|
|
|
|
PRIORITY_LEVEL_HIGHER,
|
|
|
|
PRIORITY_LEVEL_HIGHEST
|
|
|
|
};
|
|
|
|
|
2009-05-02 23:53:27 +02:00
|
|
|
|
2009-05-02 23:03:37 +02:00
|
|
|
struct SDL_Block {
|
2009-05-02 23:53:27 +02:00
|
|
|
bool active; //If this isn't set don't draw
|
|
|
|
bool updating;
|
|
|
|
struct {
|
|
|
|
Bit32u width;
|
|
|
|
Bit32u height;
|
2009-05-03 00:18:08 +02:00
|
|
|
Bit32u bpp;
|
2009-05-03 00:02:15 +02:00
|
|
|
Bitu flags;
|
2009-05-02 23:53:27 +02:00
|
|
|
double scalex,scaley;
|
2009-05-03 00:18:08 +02:00
|
|
|
GFX_CallBack_t callback;
|
2009-05-02 23:53:27 +02:00
|
|
|
} draw;
|
2009-05-02 23:43:00 +02:00
|
|
|
bool wait_on_error;
|
2009-05-02 23:53:27 +02:00
|
|
|
struct {
|
2009-05-03 00:18:08 +02:00
|
|
|
struct {
|
|
|
|
Bit16u width, height;
|
|
|
|
bool fixed;
|
|
|
|
} full;
|
|
|
|
struct {
|
|
|
|
Bit16u width, height;
|
|
|
|
} window;
|
|
|
|
Bit8u bpp;
|
2009-05-02 23:53:27 +02:00
|
|
|
bool fullscreen;
|
|
|
|
bool doublebuf;
|
|
|
|
SCREEN_TYPES type;
|
|
|
|
SCREEN_TYPES want_type;
|
|
|
|
} desktop;
|
|
|
|
#if C_OPENGL
|
|
|
|
struct {
|
|
|
|
Bitu pitch;
|
|
|
|
void * framebuf;
|
|
|
|
GLuint texture;
|
|
|
|
GLuint displaylist;
|
|
|
|
GLint max_texsize;
|
|
|
|
bool bilinear;
|
|
|
|
bool packed_pixel;
|
|
|
|
bool paletted_texture;
|
|
|
|
#if defined(NVIDIA_PixelDataRange)
|
|
|
|
bool pixel_data_range;
|
|
|
|
#endif
|
|
|
|
} opengl;
|
|
|
|
#endif
|
2009-05-03 00:02:15 +02:00
|
|
|
struct {
|
|
|
|
SDL_Surface * surface;
|
2009-05-03 00:18:08 +02:00
|
|
|
#if (HAVE_DDRAW_H) && defined(WIN32)
|
2009-05-03 00:02:15 +02:00
|
|
|
RECT rect;
|
|
|
|
#endif
|
2009-05-03 00:18:08 +02:00
|
|
|
} blit;
|
2009-05-03 00:02:15 +02:00
|
|
|
struct {
|
|
|
|
PRIORITY_LEVELS focus;
|
|
|
|
PRIORITY_LEVELS nofocus;
|
|
|
|
} priority;
|
2009-05-02 23:53:27 +02:00
|
|
|
SDL_Rect clip;
|
2009-05-02 23:03:37 +02:00
|
|
|
SDL_Surface * surface;
|
2009-05-02 23:53:27 +02:00
|
|
|
SDL_Overlay * overlay;
|
2009-05-02 23:35:44 +02:00
|
|
|
SDL_cond *cond;
|
2009-05-02 23:20:05 +02:00
|
|
|
struct {
|
|
|
|
bool autolock;
|
|
|
|
bool autoenable;
|
|
|
|
bool requestlock;
|
|
|
|
bool locked;
|
|
|
|
Bitu sensitivity;
|
|
|
|
} mouse;
|
2009-05-03 00:18:08 +02:00
|
|
|
SDL_Rect updateRects[1024];
|
2009-05-02 23:03:37 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static SDL_Block sdl;
|
|
|
|
|
2009-05-03 00:02:15 +02:00
|
|
|
extern char * RunningProgram;
|
2009-05-03 00:18:08 +02:00
|
|
|
extern bool CPU_CycleAuto;
|
2009-05-03 00:08:43 +02:00
|
|
|
//Globals for keyboard initialisation
|
|
|
|
bool startup_state_numlock=false;
|
|
|
|
bool startup_state_capslock=false;
|
2009-05-03 00:02:15 +02:00
|
|
|
void GFX_SetTitle(Bits cycles,Bits frameskip,bool paused){
|
2009-05-02 23:43:00 +02:00
|
|
|
char title[200]={0};
|
|
|
|
static Bits internal_cycles=0;
|
|
|
|
static Bits internal_frameskip=0;
|
|
|
|
if(cycles != -1) internal_cycles = cycles;
|
|
|
|
if(frameskip != -1) internal_frameskip = frameskip;
|
2009-05-03 00:18:08 +02:00
|
|
|
if(CPU_CycleAuto)
|
|
|
|
sprintf(title,"DOSBox %s, Cpu Cycles: auto, Frameskip %2d, Program: %8s",VERSION,internal_frameskip,RunningProgram);
|
2009-05-03 00:02:15 +02:00
|
|
|
else
|
2009-05-03 00:18:08 +02:00
|
|
|
sprintf(title,"DOSBox %s, Cpu Cycles: %8d, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram);
|
|
|
|
|
|
|
|
if(paused) strcat(title," PAUSED");
|
2009-05-02 23:43:00 +02:00
|
|
|
SDL_WM_SetCaption(title,VERSION);
|
|
|
|
}
|
|
|
|
|
2009-05-03 00:18:08 +02:00
|
|
|
static void PauseDOSBox(bool pressed) {
|
|
|
|
if (!pressed)
|
|
|
|
return;
|
2009-05-03 00:02:15 +02:00
|
|
|
GFX_SetTitle(-1,-1,true);
|
|
|
|
bool paused = true;
|
2009-05-03 00:18:08 +02:00
|
|
|
KEYBOARD_ClrBuffer();
|
2009-05-03 00:02:15 +02:00
|
|
|
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_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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-05-02 23:03:37 +02:00
|
|
|
/* Reset the screen with current values in the sdl structure */
|
2009-05-03 00:02:15 +02:00
|
|
|
Bitu GFX_GetBestMode(Bitu flags) {
|
|
|
|
Bitu testbpp,gotbpp;
|
2009-05-02 23:53:27 +02:00
|
|
|
switch (sdl.desktop.want_type) {
|
|
|
|
case SCREEN_SURFACE:
|
2009-05-03 00:02:15 +02:00
|
|
|
check_surface:
|
|
|
|
/* Check if we can satisfy the depth it loves */
|
2009-05-03 00:18:08 +02:00
|
|
|
if (flags & GFX_LOVE_8) testbpp=8;
|
|
|
|
else if (flags & GFX_LOVE_15) testbpp=15;
|
|
|
|
else if (flags & GFX_LOVE_16) testbpp=16;
|
|
|
|
else if (flags & GFX_LOVE_32) testbpp=32;
|
2009-05-03 00:02:15 +02:00
|
|
|
check_gotbpp:
|
|
|
|
if (sdl.desktop.fullscreen) gotbpp=SDL_VideoModeOK(640,480,testbpp,SDL_FULLSCREEN|SDL_HWSURFACE|SDL_HWPALETTE);
|
|
|
|
else gotbpp=sdl.desktop.bpp;
|
|
|
|
/* If we can't get our favorite mode check for another working one */
|
|
|
|
switch (gotbpp) {
|
|
|
|
case 8:
|
2009-05-03 00:18:08 +02:00
|
|
|
if (flags & GFX_CAN_8) flags&=~(GFX_CAN_15|GFX_CAN_16|GFX_CAN_32);
|
2009-05-03 00:02:15 +02:00
|
|
|
break;
|
|
|
|
case 15:
|
2009-05-03 00:18:08 +02:00
|
|
|
if (flags & GFX_CAN_15) flags&=~(GFX_CAN_8|GFX_CAN_16|GFX_CAN_32);
|
|
|
|
break;
|
2009-05-03 00:02:15 +02:00
|
|
|
case 16:
|
2009-05-03 00:18:08 +02:00
|
|
|
if (flags & GFX_CAN_16) flags&=~(GFX_CAN_8|GFX_CAN_15|GFX_CAN_32);
|
2009-05-03 00:02:15 +02:00
|
|
|
break;
|
|
|
|
case 24:
|
|
|
|
case 32:
|
2009-05-03 00:18:08 +02:00
|
|
|
if (flags & GFX_CAN_32) flags&=~(GFX_CAN_8|GFX_CAN_15|GFX_CAN_16);
|
2009-05-03 00:02:15 +02:00
|
|
|
break;
|
2009-05-02 23:35:44 +02:00
|
|
|
}
|
2009-05-03 00:18:08 +02:00
|
|
|
flags |= GFX_CAN_RANDOM;
|
2009-05-02 23:53:27 +02:00
|
|
|
break;
|
2009-05-03 00:18:08 +02:00
|
|
|
#if (HAVE_DDRAW_H) && defined(WIN32)
|
2009-05-03 00:02:15 +02:00
|
|
|
case SCREEN_SURFACE_DDRAW:
|
2009-05-03 00:18:08 +02:00
|
|
|
if (!(flags&(GFX_CAN_15|GFX_CAN_16|GFX_CAN_32))) goto check_surface;
|
|
|
|
if (flags & GFX_LOVE_15) testbpp=15;
|
|
|
|
else if (flags & GFX_LOVE_16) testbpp=16;
|
|
|
|
else if (flags & GFX_LOVE_32) testbpp=32;
|
2009-05-03 00:02:15 +02:00
|
|
|
else testbpp=0;
|
2009-05-03 00:18:08 +02:00
|
|
|
flags|=GFX_SCALING;
|
2009-05-03 00:02:15 +02:00
|
|
|
goto check_gotbpp;
|
|
|
|
#endif
|
2009-05-02 23:53:27 +02:00
|
|
|
case SCREEN_OVERLAY:
|
2009-05-03 00:18:08 +02:00
|
|
|
if (flags & GFX_RGBONLY || !(flags&GFX_CAN_32)) goto check_surface;
|
|
|
|
flags|=GFX_SCALING;
|
|
|
|
flags&=~(GFX_CAN_8|GFX_CAN_15|GFX_CAN_16);
|
2009-05-02 23:53:27 +02:00
|
|
|
break;
|
|
|
|
#if C_OPENGL
|
|
|
|
case SCREEN_OPENGL:
|
2009-05-03 00:18:08 +02:00
|
|
|
if (flags & GFX_RGBONLY || !(flags&GFX_CAN_32)) goto check_surface;
|
|
|
|
flags|=GFX_SCALING;
|
|
|
|
flags&=~(GFX_CAN_8|GFX_CAN_15|GFX_CAN_16);
|
2009-05-02 23:53:27 +02:00
|
|
|
break;
|
|
|
|
#endif
|
2009-05-02 23:03:37 +02:00
|
|
|
}
|
2009-05-03 00:02:15 +02:00
|
|
|
return flags;
|
2009-05-02 23:53:27 +02:00
|
|
|
}
|
2009-05-02 23:35:44 +02:00
|
|
|
|
|
|
|
|
2009-05-03 00:02:15 +02:00
|
|
|
void GFX_ResetScreen(void) {
|
2009-05-02 23:53:27 +02:00
|
|
|
GFX_Stop();
|
2009-05-03 00:18:08 +02:00
|
|
|
if (sdl.draw.callback) (sdl.draw.callback)( GFX_CallBackReset );
|
2009-05-02 23:27:47 +02:00
|
|
|
GFX_Start();
|
2009-05-02 23:03:37 +02:00
|
|
|
}
|
|
|
|
|
2009-05-02 23:53:27 +02:00
|
|
|
static int int_log2 (int val) {
|
|
|
|
int log = 0;
|
|
|
|
while ((val >>= 1) != 0)
|
|
|
|
log++;
|
|
|
|
return log;
|
|
|
|
}
|
2009-05-02 23:03:37 +02:00
|
|
|
|
2009-05-03 00:02:15 +02:00
|
|
|
|
2009-05-03 00:18:08 +02:00
|
|
|
static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags, Bit32u bpp) {
|
|
|
|
Bit16u fixedWidth;
|
|
|
|
Bit16u fixedHeight;
|
|
|
|
|
2009-05-03 00:02:15 +02:00
|
|
|
if (sdl.desktop.fullscreen) {
|
2009-05-03 00:18:08 +02:00
|
|
|
fixedWidth = sdl.desktop.full.fixed ? sdl.desktop.full.width : 0;
|
|
|
|
fixedHeight = sdl.desktop.full.fixed ? sdl.desktop.full.height : 0;
|
|
|
|
sdl_flags |= SDL_FULLSCREEN|SDL_HWSURFACE;
|
|
|
|
} else {
|
|
|
|
fixedWidth = sdl.desktop.window.width;
|
|
|
|
fixedHeight = sdl.desktop.window.height;
|
|
|
|
sdl_flags |= SDL_HWSURFACE;
|
|
|
|
}
|
|
|
|
if (fixedWidth && fixedHeight) {
|
|
|
|
double ratio_w=(double)fixedWidth/(sdl.draw.width*sdl.draw.scalex);
|
|
|
|
double ratio_h=(double)fixedHeight/(sdl.draw.height*sdl.draw.scaley);
|
|
|
|
if ( ratio_w < ratio_h) {
|
|
|
|
sdl.clip.w=fixedWidth;
|
|
|
|
sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*ratio_w);
|
2009-05-03 00:02:15 +02:00
|
|
|
} else {
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*ratio_h);
|
|
|
|
sdl.clip.h=(Bit16u)fixedHeight;
|
2009-05-03 00:02:15 +02:00
|
|
|
}
|
2009-05-03 00:18:08 +02:00
|
|
|
if (sdl.desktop.fullscreen)
|
|
|
|
sdl.surface = SDL_SetVideoMode(fixedWidth,fixedHeight,bpp,sdl_flags);
|
|
|
|
else
|
|
|
|
sdl.surface = SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags);
|
|
|
|
if (sdl.surface && sdl.surface->flags & SDL_FULLSCREEN) {
|
|
|
|
sdl.clip.x=(Sint16)((sdl.surface->w-sdl.clip.w)/2);
|
|
|
|
sdl.clip.y=(Sint16)((sdl.surface->h-sdl.clip.h)/2);
|
|
|
|
} else {
|
|
|
|
sdl.clip.x = 0;
|
|
|
|
sdl.clip.y = 0;
|
|
|
|
}
|
|
|
|
return sdl.surface;
|
2009-05-03 00:02:15 +02:00
|
|
|
} else {
|
|
|
|
sdl.clip.x=0;sdl.clip.y=0;
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex);
|
|
|
|
sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley);
|
|
|
|
sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags);
|
|
|
|
return sdl.surface;
|
2009-05-03 00:02:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-03 00:18:08 +02:00
|
|
|
Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_CallBack_t callback) {
|
|
|
|
if (sdl.updating)
|
|
|
|
GFX_EndUpdate( 0 );
|
|
|
|
|
2009-05-02 23:53:27 +02:00
|
|
|
sdl.draw.width=width;
|
|
|
|
sdl.draw.height=height;
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.draw.callback=callback;
|
2009-05-02 23:53:27 +02:00
|
|
|
sdl.draw.scalex=scalex;
|
|
|
|
sdl.draw.scaley=scaley;
|
|
|
|
|
2009-05-03 00:02:15 +02:00
|
|
|
Bitu bpp;
|
2009-05-03 00:18:08 +02:00
|
|
|
Bitu retFlags;
|
|
|
|
|
|
|
|
if (sdl.blit.surface) {
|
|
|
|
SDL_FreeSurface(sdl.blit.surface);
|
|
|
|
sdl.blit.surface=0;
|
|
|
|
}
|
2009-05-02 23:53:27 +02:00
|
|
|
switch (sdl.desktop.want_type) {
|
|
|
|
case SCREEN_SURFACE:
|
|
|
|
dosurface:
|
2009-05-03 00:18:08 +02:00
|
|
|
if (flags & GFX_CAN_8) bpp=8;
|
|
|
|
if (flags & GFX_CAN_15) bpp=15;
|
|
|
|
if (flags & GFX_CAN_16) bpp=16;
|
|
|
|
if (flags & GFX_CAN_32) bpp=32;
|
2009-05-02 23:53:27 +02:00
|
|
|
sdl.desktop.type=SCREEN_SURFACE;
|
|
|
|
sdl.clip.w=width;
|
|
|
|
sdl.clip.h=height;
|
|
|
|
if (sdl.desktop.fullscreen) {
|
2009-05-03 00:18:08 +02:00
|
|
|
if (sdl.desktop.full.fixed) {
|
|
|
|
sdl.clip.x=(Sint16)((sdl.desktop.full.width-width)/2);
|
|
|
|
sdl.clip.y=(Sint16)((sdl.desktop.full.height-height)/2);
|
|
|
|
sdl.surface=SDL_SetVideoMode(sdl.desktop.full.width,sdl.desktop.full.height,bpp,
|
|
|
|
SDL_FULLSCREEN | ((flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) |
|
|
|
|
(sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0) | SDL_HWPALETTE);
|
|
|
|
if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",sdl.desktop.full.width,sdl.desktop.full.height,bpp,SDL_GetError());
|
2009-05-02 23:53:27 +02:00
|
|
|
} else {
|
|
|
|
sdl.clip.x=0;sdl.clip.y=0;
|
|
|
|
sdl.surface=SDL_SetVideoMode(width,height,bpp,
|
2009-05-03 00:18:08 +02:00
|
|
|
SDL_FULLSCREEN | ((flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) |
|
|
|
|
(sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE);
|
|
|
|
if (sdl.surface == NULL)
|
|
|
|
E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError());
|
2009-05-02 23:53:27 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
sdl.clip.x=0;sdl.clip.y=0;
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.surface=SDL_SetVideoMode(width,height,bpp,(flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE);
|
|
|
|
#ifdef WIN32
|
|
|
|
if (sdl.surface == NULL) {
|
|
|
|
LOG_MSG("Failed to create hardware surface.\nRestarting video subsystem with windib enabled.");
|
|
|
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
|
|
|
putenv("SDL_VIDEODRIVER=windib");
|
|
|
|
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
|
|
|
sdl.surface = SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (sdl.surface == NULL)
|
|
|
|
E_Exit("Could not set windowed video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError());
|
2009-05-02 23:53:27 +02:00
|
|
|
}
|
2009-05-03 00:18:08 +02:00
|
|
|
if (sdl.surface) {
|
|
|
|
switch (sdl.surface->format->BitsPerPixel) {
|
|
|
|
case 8:
|
|
|
|
retFlags = GFX_CAN_8;
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
retFlags = GFX_CAN_15;
|
2009-05-03 00:02:15 +02:00
|
|
|
break;
|
2009-05-03 00:18:08 +02:00
|
|
|
case 16:
|
|
|
|
retFlags = GFX_CAN_16;
|
|
|
|
break;
|
|
|
|
case 32:
|
|
|
|
retFlags = GFX_CAN_32;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (retFlags && (sdl.surface->flags & SDL_HWSURFACE))
|
|
|
|
retFlags |= GFX_HARDWARE;
|
|
|
|
if (retFlags && (sdl.surface->flags & SDL_DOUBLEBUF)) {
|
|
|
|
sdl.blit.surface=SDL_CreateRGBSurface(SDL_HWSURFACE,
|
|
|
|
sdl.draw.width, sdl.draw.height,
|
|
|
|
sdl.surface->format->BitsPerPixel,
|
|
|
|
sdl.surface->format->Rmask,
|
|
|
|
sdl.surface->format->Gmask,
|
|
|
|
sdl.surface->format->Bmask,
|
|
|
|
0);
|
|
|
|
/* If this one fails be ready for some flickering... */
|
|
|
|
}
|
2009-05-03 00:02:15 +02:00
|
|
|
}
|
2009-05-02 23:53:27 +02:00
|
|
|
break;
|
2009-05-03 00:18:08 +02:00
|
|
|
#if (HAVE_DDRAW_H) && defined(WIN32)
|
2009-05-03 00:02:15 +02:00
|
|
|
case SCREEN_SURFACE_DDRAW:
|
2009-05-03 00:18:08 +02:00
|
|
|
if (flags & GFX_CAN_15) bpp=15;
|
|
|
|
if (flags & GFX_CAN_16) bpp=16;
|
|
|
|
if (flags & GFX_CAN_32) bpp=32;
|
2009-05-03 00:02:15 +02:00
|
|
|
if (!GFX_SetupSurfaceScaled((sdl.desktop.doublebuf && sdl.desktop.fullscreen) ? SDL_DOUBLEBUF : 0,bpp)) goto dosurface;
|
|
|
|
sdl.blit.rect.top=sdl.clip.y;
|
|
|
|
sdl.blit.rect.left=sdl.clip.x;
|
|
|
|
sdl.blit.rect.right=sdl.clip.x+sdl.clip.w;
|
|
|
|
sdl.blit.rect.bottom=sdl.clip.y+sdl.clip.h;
|
|
|
|
sdl.blit.surface=SDL_CreateRGBSurface(SDL_HWSURFACE,sdl.draw.width,sdl.draw.height,
|
|
|
|
sdl.surface->format->BitsPerPixel,
|
|
|
|
sdl.surface->format->Rmask,
|
|
|
|
sdl.surface->format->Gmask,
|
|
|
|
sdl.surface->format->Bmask,
|
|
|
|
0);
|
|
|
|
if (!sdl.blit.surface || (!sdl.blit.surface->flags&SDL_HWSURFACE)) {
|
|
|
|
LOG_MSG("Failed to create ddraw surface, back to normal surface.");
|
|
|
|
goto dosurface;
|
|
|
|
}
|
|
|
|
switch (sdl.surface->format->BitsPerPixel) {
|
2009-05-03 00:18:08 +02:00
|
|
|
case 15:
|
|
|
|
retFlags = GFX_CAN_15 | GFX_SCALING | GFX_HARDWARE;
|
|
|
|
break;
|
|
|
|
case 16:
|
|
|
|
retFlags = GFX_CAN_16 | GFX_SCALING | GFX_HARDWARE;
|
|
|
|
break;
|
|
|
|
case 32:
|
|
|
|
retFlags = GFX_CAN_32 | GFX_SCALING | GFX_HARDWARE;
|
|
|
|
break;
|
2009-05-03 00:02:15 +02:00
|
|
|
}
|
|
|
|
sdl.desktop.type=SCREEN_SURFACE_DDRAW;
|
|
|
|
break;
|
|
|
|
#endif
|
2009-05-02 23:53:27 +02:00
|
|
|
case SCREEN_OVERLAY:
|
2009-05-03 00:02:15 +02:00
|
|
|
if (sdl.overlay) {
|
|
|
|
SDL_FreeYUVOverlay(sdl.overlay);
|
|
|
|
sdl.overlay=0;
|
2009-05-02 23:53:27 +02:00
|
|
|
}
|
2009-05-03 00:18:08 +02:00
|
|
|
if (!(flags&GFX_CAN_32) || (flags & GFX_RGBONLY)) goto dosurface;
|
2009-05-03 00:02:15 +02:00
|
|
|
if (!GFX_SetupSurfaceScaled(0,0)) goto dosurface;
|
2009-05-02 23:53:27 +02:00
|
|
|
sdl.overlay=SDL_CreateYUVOverlay(width*2,height,SDL_UYVY_OVERLAY,sdl.surface);
|
|
|
|
if (!sdl.overlay) {
|
|
|
|
LOG_MSG("SDL:Failed to create overlay, switching back to surface");
|
|
|
|
goto dosurface;
|
|
|
|
}
|
|
|
|
sdl.desktop.type=SCREEN_OVERLAY;
|
2009-05-03 00:18:08 +02:00
|
|
|
retFlags = GFX_CAN_32 | GFX_SCALING | GFX_HARDWARE;
|
2009-05-02 23:53:27 +02:00
|
|
|
break;
|
|
|
|
#if C_OPENGL
|
|
|
|
case SCREEN_OPENGL:
|
|
|
|
{
|
|
|
|
if (sdl.opengl.framebuf) {
|
|
|
|
#if defined(NVIDIA_PixelDataRange)
|
|
|
|
if (sdl.opengl.pixel_data_range) db_glFreeMemoryNV(sdl.opengl.framebuf);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
free(sdl.opengl.framebuf);
|
|
|
|
}
|
|
|
|
sdl.opengl.framebuf=0;
|
2009-05-03 00:18:08 +02:00
|
|
|
if (!(flags&GFX_CAN_32) || (flags & GFX_RGBONLY)) goto dosurface;
|
2009-05-02 23:53:27 +02:00
|
|
|
int texsize=2 << int_log2(width > height ? width : height);
|
|
|
|
if (texsize>sdl.opengl.max_texsize) {
|
|
|
|
LOG_MSG("SDL:OPENGL:No support for texturesize of %d, falling back to surface",texsize);
|
|
|
|
goto dosurface;
|
|
|
|
}
|
|
|
|
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
|
2009-05-03 00:02:15 +02:00
|
|
|
GFX_SetupSurfaceScaled(SDL_OPENGL,0);
|
2009-05-02 23:53:27 +02:00
|
|
|
if (!sdl.surface || sdl.surface->format->BitsPerPixel<15) {
|
|
|
|
LOG_MSG("SDL:OPENGL:Can't open drawing surface, are you running in 16bpp(or higher) mode?");
|
|
|
|
goto dosurface;
|
|
|
|
}
|
|
|
|
/* Create the texture and display list */
|
|
|
|
#if defined(NVIDIA_PixelDataRange)
|
|
|
|
if (sdl.opengl.pixel_data_range) {
|
|
|
|
sdl.opengl.framebuf=db_glAllocateMemoryNV(width*height*4,0.0,1.0,1.0);
|
|
|
|
glPixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV,width*height*4,sdl.opengl.framebuf);
|
|
|
|
glEnableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV);
|
|
|
|
} else {
|
|
|
|
#else
|
|
|
|
{
|
|
|
|
#endif
|
|
|
|
sdl.opengl.framebuf=malloc(width*height*4); //32 bit color
|
|
|
|
}
|
|
|
|
sdl.opengl.pitch=width*4;
|
|
|
|
glViewport(sdl.clip.x,sdl.clip.y,sdl.clip.w,sdl.clip.h);
|
|
|
|
glMatrixMode (GL_PROJECTION);
|
|
|
|
glDeleteTextures(1,&sdl.opengl.texture);
|
|
|
|
glGenTextures(1,&sdl.opengl.texture);
|
|
|
|
glBindTexture(GL_TEXTURE_2D,sdl.opengl.texture);
|
|
|
|
// No borders
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
|
|
|
if (sdl.opengl.bilinear) {
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
} else {
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
|
}
|
|
|
|
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texsize, texsize, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 0);
|
|
|
|
|
|
|
|
glClearColor (0.0, 0.0, 0.0, 1.0);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
2009-05-03 00:02:15 +02:00
|
|
|
SDL_GL_SwapBuffers();
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
2009-05-02 23:53:27 +02:00
|
|
|
glShadeModel (GL_FLAT);
|
|
|
|
glDisable (GL_DEPTH_TEST);
|
|
|
|
glDisable (GL_LIGHTING);
|
|
|
|
glDisable(GL_CULL_FACE);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
glMatrixMode (GL_MODELVIEW);
|
|
|
|
glLoadIdentity ();
|
|
|
|
|
|
|
|
GLfloat tex_width=((GLfloat)(width)/(GLfloat)texsize);
|
|
|
|
GLfloat tex_height=((GLfloat)(height)/(GLfloat)texsize);
|
|
|
|
|
|
|
|
if (glIsList(sdl.opengl.displaylist)) glDeleteLists(sdl.opengl.displaylist, 1);
|
|
|
|
sdl.opengl.displaylist = glGenLists(1);
|
|
|
|
glNewList(sdl.opengl.displaylist, GL_COMPILE);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture);
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
// lower left
|
|
|
|
glTexCoord2f(0,tex_height); glVertex2f(-1.0f,-1.0f);
|
|
|
|
// lower right
|
|
|
|
glTexCoord2f(tex_width,tex_height); glVertex2f(1.0f, -1.0f);
|
|
|
|
// upper right
|
|
|
|
glTexCoord2f(tex_width,0); glVertex2f(1.0f, 1.0f);
|
|
|
|
// upper left
|
|
|
|
glTexCoord2f(0,0); glVertex2f(-1.0f, 1.0f);
|
|
|
|
glEnd();
|
|
|
|
glEndList();
|
|
|
|
sdl.desktop.type=SCREEN_OPENGL;
|
2009-05-03 00:18:08 +02:00
|
|
|
retFlags = GFX_CAN_32 | GFX_SCALING;
|
|
|
|
#if defined(NVIDIA_PixelDataRange)
|
|
|
|
if (sdl.opengl.pixel_data_range)
|
|
|
|
retFlags |= GFX_HARDWARE;
|
|
|
|
#endif
|
|
|
|
break;
|
2009-05-02 23:53:27 +02:00
|
|
|
}//OPENGL
|
|
|
|
#endif //C_OPENGL
|
|
|
|
}//CASE
|
2009-05-03 00:18:08 +02:00
|
|
|
if (retFlags)
|
|
|
|
GFX_Start();
|
|
|
|
if (!sdl.mouse.autoenable) SDL_ShowCursor(sdl.mouse.autolock?SDL_DISABLE:SDL_ENABLE);
|
|
|
|
return retFlags;
|
2009-05-02 23:03:37 +02:00
|
|
|
}
|
|
|
|
|
2009-05-03 00:18:08 +02:00
|
|
|
void GFX_CaptureMouse(void) {
|
2009-05-02 23:20:05 +02:00
|
|
|
sdl.mouse.locked=!sdl.mouse.locked;
|
|
|
|
if (sdl.mouse.locked) {
|
2009-05-02 23:03:37 +02:00
|
|
|
SDL_WM_GrabInput(SDL_GRAB_ON);
|
|
|
|
SDL_ShowCursor(SDL_DISABLE);
|
|
|
|
} else {
|
|
|
|
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
2009-05-03 00:18:08 +02:00
|
|
|
if (sdl.mouse.autoenable || !sdl.mouse.autolock) SDL_ShowCursor(SDL_ENABLE);
|
2009-05-02 23:03:37 +02:00
|
|
|
}
|
2009-05-03 00:02:15 +02:00
|
|
|
mouselocked=sdl.mouse.locked;
|
|
|
|
}
|
|
|
|
|
2009-05-03 00:18:08 +02:00
|
|
|
bool mouselocked; //Global variable for mapper
|
|
|
|
static void CaptureMouse(bool pressed) {
|
|
|
|
if (!pressed)
|
|
|
|
return;
|
|
|
|
GFX_CaptureMouse();
|
2009-05-02 23:03:37 +02:00
|
|
|
}
|
|
|
|
|
2009-05-03 00:18:08 +02:00
|
|
|
void GFX_SwitchFullScreen(void) {
|
2009-05-02 23:53:27 +02:00
|
|
|
sdl.desktop.fullscreen=!sdl.desktop.fullscreen;
|
|
|
|
if (sdl.desktop.fullscreen) {
|
2009-05-03 00:18:08 +02:00
|
|
|
if (!sdl.mouse.locked) GFX_CaptureMouse();
|
2009-05-02 23:27:47 +02:00
|
|
|
} else {
|
2009-05-03 00:18:08 +02:00
|
|
|
if (sdl.mouse.locked) GFX_CaptureMouse();
|
2009-05-02 23:03:37 +02:00
|
|
|
}
|
2009-05-03 00:02:15 +02:00
|
|
|
GFX_ResetScreen();
|
2009-05-02 23:03:37 +02:00
|
|
|
}
|
2009-05-02 23:35:44 +02:00
|
|
|
|
2009-05-03 00:18:08 +02:00
|
|
|
static void SwitchFullScreen(bool pressed) {
|
|
|
|
if (!pressed)
|
|
|
|
return;
|
|
|
|
GFX_SwitchFullScreen();
|
2009-05-02 23:20:05 +02:00
|
|
|
}
|
2009-05-02 23:03:37 +02:00
|
|
|
|
2009-05-03 00:18:08 +02:00
|
|
|
|
2009-05-02 23:53:27 +02:00
|
|
|
bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) {
|
|
|
|
if (!sdl.active || sdl.updating) return false;
|
|
|
|
switch (sdl.desktop.type) {
|
|
|
|
case SCREEN_SURFACE:
|
2009-05-03 00:18:08 +02:00
|
|
|
if (sdl.blit.surface) {
|
|
|
|
if (SDL_MUSTLOCK(sdl.blit.surface) && SDL_LockSurface(sdl.blit.surface))
|
2009-05-02 23:53:27 +02:00
|
|
|
return false;
|
2009-05-03 00:18:08 +02:00
|
|
|
pixels=(Bit8u *)sdl.blit.surface->pixels;
|
|
|
|
pitch=sdl.blit.surface->pitch;
|
|
|
|
} else {
|
|
|
|
if (SDL_MUSTLOCK(sdl.surface) && SDL_LockSurface(sdl.surface))
|
|
|
|
return false;
|
|
|
|
pixels=(Bit8u *)sdl.surface->pixels;
|
|
|
|
pixels+=sdl.clip.y*sdl.surface->pitch;
|
|
|
|
pixels+=sdl.clip.x*sdl.surface->format->BytesPerPixel;
|
|
|
|
pitch=sdl.surface->pitch;
|
2009-05-02 23:35:44 +02:00
|
|
|
}
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.updating=true;
|
2009-05-02 23:53:27 +02:00
|
|
|
return true;
|
2009-05-03 00:18:08 +02:00
|
|
|
#if (HAVE_DDRAW_H) && defined(WIN32)
|
2009-05-03 00:02:15 +02:00
|
|
|
case SCREEN_SURFACE_DDRAW:
|
|
|
|
if (SDL_LockSurface(sdl.blit.surface)) {
|
|
|
|
// LOG_MSG("SDL Lock failed");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
pixels=(Bit8u *)sdl.blit.surface->pixels;
|
|
|
|
pitch=sdl.blit.surface->pitch;
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.updating=true;
|
2009-05-03 00:02:15 +02:00
|
|
|
return true;
|
|
|
|
#endif
|
2009-05-02 23:53:27 +02:00
|
|
|
case SCREEN_OVERLAY:
|
|
|
|
SDL_LockYUVOverlay(sdl.overlay);
|
|
|
|
pixels=(Bit8u *)*(sdl.overlay->pixels);
|
|
|
|
pitch=*(sdl.overlay->pitches);
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.updating=true;
|
2009-05-02 23:53:27 +02:00
|
|
|
return true;
|
|
|
|
#if C_OPENGL
|
|
|
|
case SCREEN_OPENGL:
|
|
|
|
pixels=(Bit8u *)sdl.opengl.framebuf;
|
|
|
|
pitch=sdl.opengl.pitch;
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.updating=true;
|
2009-05-02 23:53:27 +02:00
|
|
|
return true;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-05-03 00:18:08 +02:00
|
|
|
|
|
|
|
void GFX_EndUpdate( const Bit16u *changedLines ) {
|
2009-05-03 00:02:15 +02:00
|
|
|
int ret;
|
2009-05-02 23:53:27 +02:00
|
|
|
if (!sdl.updating) return;
|
|
|
|
sdl.updating=false;
|
|
|
|
switch (sdl.desktop.type) {
|
|
|
|
case SCREEN_SURFACE:
|
2009-05-02 23:35:44 +02:00
|
|
|
if (SDL_MUSTLOCK(sdl.surface)) {
|
2009-05-03 00:18:08 +02:00
|
|
|
if (sdl.blit.surface) {
|
|
|
|
SDL_UnlockSurface(sdl.blit.surface);
|
|
|
|
int Blit = SDL_BlitSurface( sdl.blit.surface, 0, sdl.surface, &sdl.clip );
|
|
|
|
LOG(LOG_MISC,LOG_WARN)("BlitSurface returned %d",Blit);
|
|
|
|
} else {
|
|
|
|
SDL_UnlockSurface(sdl.surface);
|
|
|
|
}
|
|
|
|
SDL_Flip(sdl.surface);
|
|
|
|
} else if (changedLines) {
|
|
|
|
Bitu y = 0, index = 0, rectCount = 0;
|
|
|
|
while (y < sdl.draw.height) {
|
|
|
|
if (!(index & 1)) {
|
|
|
|
y += changedLines[index];
|
|
|
|
} else {
|
|
|
|
SDL_Rect *rect = &sdl.updateRects[rectCount++];
|
|
|
|
rect->x = sdl.clip.x;
|
|
|
|
rect->y = sdl.clip.y + y;
|
|
|
|
rect->w = (Bit16u)sdl.draw.width;
|
|
|
|
rect->h = changedLines[index];
|
|
|
|
#if 0
|
|
|
|
if (rect->h + rect->y > sdl.surface->h) {
|
|
|
|
LOG_MSG("WTF");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
y += changedLines[index];
|
|
|
|
}
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
if (rectCount)
|
|
|
|
SDL_UpdateRects( sdl.surface, rectCount, sdl.updateRects );
|
|
|
|
} else {
|
|
|
|
SDL_Flip(sdl.surface);
|
2009-05-02 23:35:44 +02:00
|
|
|
}
|
2009-05-02 23:53:27 +02:00
|
|
|
break;
|
2009-05-03 00:18:08 +02:00
|
|
|
#if (HAVE_DDRAW_H) && defined(WIN32)
|
2009-05-03 00:02:15 +02:00
|
|
|
case SCREEN_SURFACE_DDRAW:
|
|
|
|
if (SDL_MUSTLOCK(sdl.blit.surface)) {
|
|
|
|
SDL_UnlockSurface(sdl.blit.surface);
|
|
|
|
}
|
|
|
|
ret=IDirectDrawSurface3_Blt(
|
|
|
|
sdl.surface->hwdata->dd_writebuf,&sdl.blit.rect,
|
|
|
|
sdl.blit.surface->hwdata->dd_surface,0,
|
|
|
|
DDBLT_WAIT, NULL);
|
|
|
|
switch (ret) {
|
|
|
|
case DD_OK:
|
|
|
|
break;
|
|
|
|
case DDERR_SURFACELOST:
|
|
|
|
IDirectDrawSurface3_Restore(sdl.blit.surface->hwdata->dd_surface);
|
2009-05-03 00:18:08 +02:00
|
|
|
IDirectDrawSurface3_Restore(sdl.surface->hwdata->dd_surface);
|
2009-05-03 00:02:15 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
LOG_MSG("DDRAW:Failed to blit, error %X",ret);
|
|
|
|
}
|
|
|
|
SDL_Flip(sdl.surface);
|
|
|
|
break;
|
|
|
|
#endif
|
2009-05-02 23:53:27 +02:00
|
|
|
case SCREEN_OVERLAY:
|
|
|
|
SDL_UnlockYUVOverlay(sdl.overlay);
|
|
|
|
SDL_DisplayYUVOverlay(sdl.overlay,&sdl.clip);
|
|
|
|
break;
|
|
|
|
#if C_OPENGL
|
|
|
|
case SCREEN_OPENGL:
|
2009-05-03 00:18:08 +02:00
|
|
|
#if defined(NVIDIA_PixelDataRange)
|
|
|
|
if (sdl.opengl.pixel_data_range) {
|
|
|
|
glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture);
|
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
|
|
|
|
sdl.draw.width, sdl.draw.height, GL_BGRA_EXT,
|
|
|
|
GL_UNSIGNED_INT_8_8_8_8_REV, sdl.opengl.framebuf);
|
|
|
|
glCallList(sdl.opengl.displaylist);
|
|
|
|
SDL_GL_SwapBuffers();
|
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
if (changedLines) {
|
|
|
|
Bitu y = 0, index = 0;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture);
|
|
|
|
while (y < sdl.draw.height) {
|
|
|
|
if (!(index & 1)) {
|
|
|
|
y += changedLines[index];
|
|
|
|
} else {
|
|
|
|
Bit8u *pixels = (Bit8u *)sdl.opengl.framebuf + y * sdl.opengl.pitch;
|
|
|
|
Bitu height = changedLines[index];
|
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, y,
|
|
|
|
sdl.draw.width, height, GL_BGRA_EXT,
|
|
|
|
GL_UNSIGNED_INT_8_8_8_8_REV, pixels );
|
|
|
|
y += height;
|
|
|
|
}
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
glCallList(sdl.opengl.displaylist);
|
|
|
|
SDL_GL_SwapBuffers();
|
|
|
|
}
|
2009-05-02 23:53:27 +02:00
|
|
|
break;
|
2009-05-02 23:35:44 +02:00
|
|
|
#endif
|
2009-05-02 23:03:37 +02:00
|
|
|
|
2009-05-02 23:53:27 +02:00
|
|
|
}
|
2009-05-02 23:03:37 +02:00
|
|
|
}
|
|
|
|
|
2009-05-02 23:27:47 +02:00
|
|
|
|
2009-05-02 23:03:37 +02:00
|
|
|
void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries) {
|
2009-05-02 23:35:44 +02:00
|
|
|
/* I should probably not change the GFX_PalEntry :) */
|
2009-05-02 23:53:27 +02:00
|
|
|
if (sdl.surface->flags & SDL_HWPALETTE) {
|
2009-05-02 23:03:37 +02:00
|
|
|
if (!SDL_SetPalette(sdl.surface,SDL_PHYSPAL,(SDL_Color *)entries,start,count)) {
|
|
|
|
E_Exit("SDL:Can't set palette");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!SDL_SetPalette(sdl.surface,SDL_LOGPAL,(SDL_Color *)entries,start,count)) {
|
|
|
|
E_Exit("SDL:Can't set palette");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-02 23:27:47 +02:00
|
|
|
Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue) {
|
2009-05-02 23:53:27 +02:00
|
|
|
switch (sdl.desktop.type) {
|
|
|
|
case SCREEN_SURFACE:
|
2009-05-03 00:02:15 +02:00
|
|
|
case SCREEN_SURFACE_DDRAW:
|
2009-05-02 23:53:27 +02:00
|
|
|
return SDL_MapRGB(sdl.surface->format,red,green,blue);
|
|
|
|
case SCREEN_OVERLAY:
|
|
|
|
{
|
|
|
|
Bit8u y = ( 9797*(red) + 19237*(green) + 3734*(blue) ) >> 15;
|
|
|
|
Bit8u u = (18492*((blue)-(y)) >> 15) + 128;
|
|
|
|
Bit8u v = (23372*((red)-(y)) >> 15) + 128;
|
2009-05-03 00:02:15 +02:00
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
|
|
return (y << 0) | (v << 8) | (y << 16) | (u << 24);
|
|
|
|
#else
|
2009-05-02 23:53:27 +02:00
|
|
|
return (u << 0) | (y << 8) | (v << 16) | (y << 24);
|
2009-05-03 00:02:15 +02:00
|
|
|
#endif
|
2009-05-02 23:53:27 +02:00
|
|
|
}
|
|
|
|
case SCREEN_OPENGL:
|
|
|
|
// return ((red << 0) | (green << 8) | (blue << 16)) | (255 << 24);
|
|
|
|
//USE BGRA
|
|
|
|
return ((blue << 0) | (green << 8) | (red << 16)) | (255 << 24);
|
|
|
|
}
|
|
|
|
return 0;
|
2009-05-02 23:03:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void GFX_Stop() {
|
2009-05-03 00:18:08 +02:00
|
|
|
if (sdl.updating)
|
|
|
|
GFX_EndUpdate( 0 );
|
2009-05-02 23:03:37 +02:00
|
|
|
sdl.active=false;
|
2009-05-02 23:35:44 +02:00
|
|
|
}
|
2009-05-02 23:03:37 +02:00
|
|
|
|
|
|
|
void GFX_Start() {
|
|
|
|
sdl.active=true;
|
|
|
|
}
|
|
|
|
|
2009-05-02 23:20:05 +02:00
|
|
|
static void GUI_ShutDown(Section * sec) {
|
|
|
|
GFX_Stop();
|
2009-05-03 00:18:08 +02:00
|
|
|
if (sdl.draw.callback) (sdl.draw.callback)( GFX_CallBackStop );
|
|
|
|
if (sdl.mouse.locked) GFX_CaptureMouse();
|
|
|
|
if (sdl.desktop.fullscreen) GFX_SwitchFullScreen();
|
2009-05-02 23:35:44 +02:00
|
|
|
}
|
|
|
|
|
2009-05-03 00:18:08 +02:00
|
|
|
static void KillSwitch(bool pressed) {
|
|
|
|
if (!pressed)
|
|
|
|
return;
|
2009-05-02 23:35:44 +02:00
|
|
|
throw 1;
|
2009-05-02 23:20:05 +02:00
|
|
|
}
|
2009-05-02 23:03:37 +02:00
|
|
|
|
2009-05-03 00:02:15 +02:00
|
|
|
static void SetPriority(PRIORITY_LEVELS level) {
|
2009-05-03 00:08:43 +02:00
|
|
|
|
|
|
|
#if C_SET_PRIORITY
|
|
|
|
// Do nothing if priorties are not the same and not root, else the highest
|
|
|
|
// priority can not be set as users can only lower priority (not restore it)
|
|
|
|
|
|
|
|
if((sdl.priority.focus != sdl.priority.nofocus ) &&
|
|
|
|
(getuid()!=0) ) return;
|
|
|
|
|
|
|
|
#endif
|
2009-05-03 00:02:15 +02:00
|
|
|
switch (level) {
|
|
|
|
#ifdef WIN32
|
2009-05-03 00:18:08 +02:00
|
|
|
case PRIORITY_LEVEL_LOWEST:
|
|
|
|
SetPriorityClass(GetCurrentProcess(),IDLE_PRIORITY_CLASS);
|
|
|
|
break;
|
2009-05-03 00:02:15 +02:00
|
|
|
case PRIORITY_LEVEL_LOWER:
|
|
|
|
SetPriorityClass(GetCurrentProcess(),BELOW_NORMAL_PRIORITY_CLASS);
|
|
|
|
break;
|
|
|
|
case PRIORITY_LEVEL_NORMAL:
|
|
|
|
SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS);
|
|
|
|
break;
|
|
|
|
case PRIORITY_LEVEL_HIGHER:
|
|
|
|
SetPriorityClass(GetCurrentProcess(),ABOVE_NORMAL_PRIORITY_CLASS);
|
|
|
|
break;
|
|
|
|
case PRIORITY_LEVEL_HIGHEST:
|
|
|
|
SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS);
|
|
|
|
break;
|
|
|
|
#elif C_SET_PRIORITY
|
2009-05-03 00:08:43 +02:00
|
|
|
/* Linux use group as dosbox has mulitple threads under linux */
|
2009-05-03 00:18:08 +02:00
|
|
|
case PRIORITY_LEVEL_LOWEST:
|
|
|
|
setpriority (PRIO_PGRP, 0,PRIO_MAX);
|
|
|
|
break;
|
2009-05-03 00:02:15 +02:00
|
|
|
case PRIORITY_LEVEL_LOWER:
|
2009-05-03 00:08:43 +02:00
|
|
|
setpriority (PRIO_PGRP, 0,PRIO_MAX-(PRIO_TOTAL/3));
|
2009-05-03 00:02:15 +02:00
|
|
|
break;
|
|
|
|
case PRIORITY_LEVEL_NORMAL:
|
2009-05-03 00:08:43 +02:00
|
|
|
setpriority (PRIO_PGRP, 0,PRIO_MAX-(PRIO_TOTAL/2));
|
2009-05-03 00:02:15 +02:00
|
|
|
break;
|
|
|
|
case PRIORITY_LEVEL_HIGHER:
|
2009-05-03 00:08:43 +02:00
|
|
|
setpriority (PRIO_PGRP, 0,PRIO_MAX-((3*PRIO_TOTAL)/5) );
|
2009-05-03 00:02:15 +02:00
|
|
|
break;
|
|
|
|
case PRIORITY_LEVEL_HIGHEST:
|
2009-05-03 00:08:43 +02:00
|
|
|
setpriority (PRIO_PGRP, 0,PRIO_MAX-((3*PRIO_TOTAL)/4) );
|
2009-05-03 00:02:15 +02:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-03 00:18:08 +02:00
|
|
|
static unsigned char logo[32*32*4]= {
|
|
|
|
#include "dosbox_logo.h"
|
|
|
|
};
|
|
|
|
|
2009-05-02 23:20:05 +02:00
|
|
|
static void GUI_StartUp(Section * sec) {
|
|
|
|
sec->AddDestroyFunction(&GUI_ShutDown);
|
|
|
|
Section_prop * section=static_cast<Section_prop *>(sec);
|
2009-05-02 23:03:37 +02:00
|
|
|
sdl.active=false;
|
2009-05-02 23:53:27 +02:00
|
|
|
sdl.updating=false;
|
2009-05-03 00:18:08 +02:00
|
|
|
|
|
|
|
/* Set Icon (must be done before any sdl_setvideomode call) */
|
|
|
|
#if WORDS_BIGENDIAN
|
|
|
|
SDL_Surface* logos= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,32,128,0xff000000,0x00ff0000,0x0000ff00,0);
|
|
|
|
#else
|
|
|
|
SDL_Surface* logos= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,32,128,0x000000ff,0x0000ff00,0x00ff0000,0);
|
|
|
|
#endif
|
|
|
|
SDL_WM_SetIcon(logos,NULL);
|
|
|
|
|
2009-05-02 23:53:27 +02:00
|
|
|
sdl.desktop.fullscreen=section->Get_bool("fullscreen");
|
2009-05-02 23:43:00 +02:00
|
|
|
sdl.wait_on_error=section->Get_bool("waitonerror");
|
2009-05-03 00:02:15 +02:00
|
|
|
const char * priority=section->Get_string("priority");
|
|
|
|
if (priority && priority[0]) {
|
|
|
|
Bitu next;
|
2009-05-03 00:18:08 +02:00
|
|
|
if (!strncasecmp(priority,"lowest",6)) {
|
|
|
|
sdl.priority.focus=PRIORITY_LEVEL_LOWEST;next=6;
|
|
|
|
} else if (!strncasecmp(priority,"lower",5)) {
|
2009-05-03 00:02:15 +02:00
|
|
|
sdl.priority.focus=PRIORITY_LEVEL_LOWER;next=5;
|
|
|
|
} else if (!strncasecmp(priority,"normal",6)) {
|
|
|
|
sdl.priority.focus=PRIORITY_LEVEL_NORMAL;next=6;
|
|
|
|
} else if (!strncasecmp(priority,"higher",6)) {
|
|
|
|
sdl.priority.focus=PRIORITY_LEVEL_HIGHER;next=6;
|
|
|
|
} else if (!strncasecmp(priority,"highest",7)) {
|
|
|
|
sdl.priority.focus=PRIORITY_LEVEL_HIGHEST;next=7;
|
|
|
|
} else {
|
|
|
|
next=0;sdl.priority.focus=PRIORITY_LEVEL_HIGHER;
|
|
|
|
}
|
|
|
|
priority=&priority[next];
|
|
|
|
if (next && priority[0]==',' && priority[1]) {
|
|
|
|
priority++;
|
2009-05-03 00:18:08 +02:00
|
|
|
if (!strncasecmp(priority,"lowest",6)) {
|
|
|
|
sdl.priority.nofocus=PRIORITY_LEVEL_LOWEST;
|
|
|
|
} else if (!strncasecmp(priority,"lower",5)) {
|
2009-05-03 00:02:15 +02:00
|
|
|
sdl.priority.nofocus=PRIORITY_LEVEL_LOWER;
|
|
|
|
} else if (!strncasecmp(priority,"normal",6)) {
|
|
|
|
sdl.priority.nofocus=PRIORITY_LEVEL_NORMAL;
|
|
|
|
} else if (!strncasecmp(priority,"higher",6)) {
|
|
|
|
sdl.priority.nofocus=PRIORITY_LEVEL_HIGHER;
|
|
|
|
} else if (!strncasecmp(priority,"highest",7)) {
|
|
|
|
sdl.priority.nofocus=PRIORITY_LEVEL_HIGHEST;
|
|
|
|
} else {
|
|
|
|
sdl.priority.nofocus=PRIORITY_LEVEL_NORMAL;
|
|
|
|
}
|
|
|
|
} else sdl.priority.nofocus=sdl.priority.focus;
|
|
|
|
} else {
|
|
|
|
sdl.priority.focus=PRIORITY_LEVEL_HIGHER;
|
|
|
|
sdl.priority.nofocus=PRIORITY_LEVEL_NORMAL;
|
|
|
|
}
|
2009-05-03 00:08:43 +02:00
|
|
|
SetPriority(sdl.priority.focus); //Assume focus on startup
|
2009-05-02 23:20:05 +02:00
|
|
|
sdl.mouse.locked=false;
|
2009-05-03 00:02:15 +02:00
|
|
|
mouselocked=false; //Global for mapper
|
2009-05-02 23:20:05 +02:00
|
|
|
sdl.mouse.requestlock=false;
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.desktop.full.fixed=false;
|
2009-05-03 00:02:15 +02:00
|
|
|
const char* fullresolution=section->Get_string("fullresolution");
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.desktop.full.width = 0;
|
|
|
|
sdl.desktop.full.height = 0;
|
2009-05-03 00:02:15 +02:00
|
|
|
if(fullresolution && *fullresolution) {
|
2009-05-03 00:18:08 +02:00
|
|
|
char res[100];
|
|
|
|
strncpy( res, fullresolution, sizeof( res ));
|
2009-05-03 00:02:15 +02:00
|
|
|
fullresolution = lowcase (res);//so x and X are allowed
|
2009-05-03 00:18:08 +02:00
|
|
|
if(strcmp(fullresolution,"original")) {
|
|
|
|
sdl.desktop.full.fixed = true;
|
|
|
|
char* height = const_cast<char*>(strchr(fullresolution,'x'));
|
|
|
|
if(height && * height) {
|
|
|
|
*height = 0;
|
|
|
|
sdl.desktop.full.height = atoi(height+1);
|
|
|
|
sdl.desktop.full.width = atoi(res);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-05-03 00:02:15 +02:00
|
|
|
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.desktop.window.width = 0;
|
|
|
|
sdl.desktop.window.height = 0;
|
|
|
|
const char* windowresolution=section->Get_string("windowresolution");
|
|
|
|
if(windowresolution && *windowresolution) {
|
|
|
|
char res[100];
|
|
|
|
strncpy( res,windowresolution, sizeof( res ));
|
|
|
|
windowresolution = lowcase (res);//so x and X are allowed
|
|
|
|
if(strcmp(windowresolution,"original")) {
|
|
|
|
char* height = const_cast<char*>(strchr(windowresolution,'x'));
|
|
|
|
if(height && *height) {
|
|
|
|
*height = 0;
|
|
|
|
sdl.desktop.window.height = atoi(height+1);
|
|
|
|
sdl.desktop.window.width = atoi(res);
|
|
|
|
}
|
2009-05-03 00:02:15 +02:00
|
|
|
}
|
|
|
|
}
|
2009-05-02 23:53:27 +02:00
|
|
|
sdl.desktop.doublebuf=section->Get_bool("fulldouble");
|
2009-05-03 00:18:08 +02:00
|
|
|
if (!sdl.desktop.full.width) {
|
2009-05-02 23:53:27 +02:00
|
|
|
#ifdef WIN32
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.desktop.full.width=GetSystemMetrics(SM_CXSCREEN);
|
2009-05-02 23:53:27 +02:00
|
|
|
#else
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.desktop.full.width=1024;
|
2009-05-02 23:53:27 +02:00
|
|
|
#endif
|
|
|
|
}
|
2009-05-03 00:18:08 +02:00
|
|
|
if (!sdl.desktop.full.height) {
|
2009-05-02 23:53:27 +02:00
|
|
|
#ifdef WIN32
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.desktop.full.height=GetSystemMetrics(SM_CYSCREEN);
|
2009-05-02 23:53:27 +02:00
|
|
|
#else
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.desktop.full.height=768;
|
2009-05-02 23:53:27 +02:00
|
|
|
#endif
|
|
|
|
}
|
2009-05-03 00:08:43 +02:00
|
|
|
sdl.mouse.autoenable=section->Get_bool("autolock");
|
2009-05-03 00:18:08 +02:00
|
|
|
if (!sdl.mouse.autoenable) SDL_ShowCursor(SDL_DISABLE);
|
2009-05-02 23:20:05 +02:00
|
|
|
sdl.mouse.autolock=false;
|
|
|
|
sdl.mouse.sensitivity=section->Get_int("sensitivity");
|
2009-05-02 23:53:27 +02:00
|
|
|
const char * output=section->Get_string("output");
|
|
|
|
if (!strcasecmp(output,"surface")) {
|
|
|
|
sdl.desktop.want_type=SCREEN_SURFACE;
|
2009-05-03 00:18:08 +02:00
|
|
|
#if (HAVE_DDRAW_H) && defined(WIN32)
|
2009-05-03 00:02:15 +02:00
|
|
|
} else if (!strcasecmp(output,"ddraw")) {
|
|
|
|
sdl.desktop.want_type=SCREEN_SURFACE_DDRAW;
|
|
|
|
#endif
|
2009-05-02 23:53:27 +02:00
|
|
|
} else if (!strcasecmp(output,"overlay")) {
|
|
|
|
sdl.desktop.want_type=SCREEN_OVERLAY;
|
|
|
|
#if C_OPENGL
|
|
|
|
} else if (!strcasecmp(output,"opengl")) {
|
|
|
|
sdl.desktop.want_type=SCREEN_OPENGL;
|
|
|
|
sdl.opengl.bilinear=true;
|
|
|
|
} else if (!strcasecmp(output,"openglnb")) {
|
|
|
|
sdl.desktop.want_type=SCREEN_OPENGL;
|
|
|
|
sdl.opengl.bilinear=false;
|
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
LOG_MSG("SDL:Unsupported output device %s, switching back to surface",output);
|
|
|
|
sdl.desktop.want_type=SCREEN_SURFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
sdl.overlay=0;
|
|
|
|
#if C_OPENGL
|
2009-05-03 00:02:15 +02:00
|
|
|
if(sdl.desktop.want_type==SCREEN_OPENGL){ /* OPENGL is requested */
|
2009-05-02 23:53:27 +02:00
|
|
|
sdl.surface=SDL_SetVideoMode(640,400,0,SDL_OPENGL);
|
2009-05-03 00:18:08 +02:00
|
|
|
if (sdl.surface == NULL) {
|
|
|
|
LOG_MSG("Could not initialize OpenGL, switching back to surface");
|
|
|
|
sdl.desktop.want_type=SCREEN_SURFACE;
|
|
|
|
} else {
|
2009-05-02 23:53:27 +02:00
|
|
|
sdl.opengl.framebuf=0;
|
|
|
|
sdl.opengl.texture=0;
|
|
|
|
sdl.opengl.displaylist=0;
|
|
|
|
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &sdl.opengl.max_texsize);
|
|
|
|
#if defined(__WIN32__) && defined(NVIDIA_PixelDataRange)
|
|
|
|
glPixelDataRangeNV = (PFNGLPIXELDATARANGENVPROC) wglGetProcAddress("glPixelDataRangeNV");
|
|
|
|
db_glAllocateMemoryNV = (PFNWGLALLOCATEMEMORYNVPROC) wglGetProcAddress("wglAllocateMemoryNV");
|
|
|
|
db_glFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC) wglGetProcAddress("wglFreeMemoryNV");
|
|
|
|
#endif
|
|
|
|
const char * gl_ext = (const char *)glGetString (GL_EXTENSIONS);
|
2009-05-03 00:02:15 +02:00
|
|
|
if(gl_ext && *gl_ext){
|
|
|
|
sdl.opengl.packed_pixel=(strstr(gl_ext,"EXT_packed_pixels") > 0);
|
|
|
|
sdl.opengl.paletted_texture=(strstr(gl_ext,"EXT_paletted_texture") > 0);
|
2009-05-02 23:53:27 +02:00
|
|
|
#if defined(NVIDIA_PixelDataRange)
|
2009-05-03 00:02:15 +02:00
|
|
|
sdl.opengl.pixel_data_range=(strstr(gl_ext,"GL_NV_pixel_data_range") >0 ) &&
|
|
|
|
glPixelDataRangeNV && db_glAllocateMemoryNV && db_glFreeMemoryNV;
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl.opengl.pixel_data_range = 0;
|
2009-05-02 23:35:44 +02:00
|
|
|
#endif
|
2009-05-03 00:02:15 +02:00
|
|
|
} else {
|
|
|
|
sdl.opengl.packed_pixel=sdl.opengl.paletted_texture=false;
|
|
|
|
}
|
2009-05-03 00:18:08 +02:00
|
|
|
}
|
2009-05-03 00:02:15 +02:00
|
|
|
} /* OPENGL is requested end */
|
|
|
|
|
2009-05-02 23:53:27 +02:00
|
|
|
#endif //OPENGL
|
2009-05-02 23:35:44 +02:00
|
|
|
/* Initialize screen for first time */
|
2009-05-02 23:43:00 +02:00
|
|
|
sdl.surface=SDL_SetVideoMode(640,400,0,0);
|
2009-05-03 00:18:08 +02:00
|
|
|
if (sdl.surface == NULL) E_Exit("Could not initialize video: %s",SDL_GetError());
|
2009-05-02 23:53:27 +02:00
|
|
|
sdl.desktop.bpp=sdl.surface->format->BitsPerPixel;
|
|
|
|
if (sdl.desktop.bpp==24) {
|
2009-05-02 23:43:00 +02:00
|
|
|
LOG_MSG("SDL:You are running in 24 bpp mode, this will slow down things!");
|
|
|
|
}
|
2009-05-03 00:02:15 +02:00
|
|
|
GFX_Stop();
|
|
|
|
/* Get some Event handlers */
|
|
|
|
MAPPER_AddHandler(KillSwitch,MK_f9,MMOD1,"shutdown","ShutDown");
|
|
|
|
MAPPER_AddHandler(CaptureMouse,MK_f10,MMOD1,"capmouse","Cap Mouse");
|
|
|
|
MAPPER_AddHandler(SwitchFullScreen,MK_return,MMOD2,"fullscr","Fullscreen");
|
|
|
|
#if C_DEBUG
|
|
|
|
/* Pause binds with activate-debugger */
|
|
|
|
#else
|
2009-05-03 00:18:08 +02:00
|
|
|
MAPPER_AddHandler(PauseDOSBox,MK_pause,MMOD2,"pause","Pause");
|
2009-05-03 00:02:15 +02:00
|
|
|
#endif
|
2009-05-03 00:08:43 +02:00
|
|
|
/* Get Keyboard state of numlock and capslock */
|
|
|
|
SDLMod keystate = SDL_GetModState();
|
|
|
|
if(keystate&KMOD_NUM) startup_state_numlock = true;
|
|
|
|
if(keystate&KMOD_CAPS) startup_state_capslock = true;
|
2009-05-02 23:03:37 +02:00
|
|
|
}
|
|
|
|
|
2009-05-02 23:20:05 +02:00
|
|
|
void Mouse_AutoLock(bool enable) {
|
|
|
|
sdl.mouse.autolock=enable;
|
2009-05-03 00:18:08 +02:00
|
|
|
if (sdl.mouse.autoenable) sdl.mouse.requestlock=enable;
|
|
|
|
else {
|
|
|
|
SDL_ShowCursor(enable?SDL_DISABLE:SDL_ENABLE);
|
|
|
|
sdl.mouse.requestlock=false;
|
|
|
|
}
|
2009-05-02 23:20:05 +02:00
|
|
|
}
|
2009-05-02 23:03:37 +02:00
|
|
|
|
|
|
|
static void HandleMouseMotion(SDL_MouseMotionEvent * motion) {
|
2009-05-03 00:18:08 +02:00
|
|
|
if (sdl.mouse.locked || !sdl.mouse.autoenable)
|
|
|
|
Mouse_CursorMoved((float)motion->xrel*sdl.mouse.sensitivity/100,(float)motion->yrel*sdl.mouse.sensitivity/100,(float)(motion->x-sdl.clip.x)/(sdl.clip.w-1)*sdl.mouse.sensitivity/100,(float)(motion->y-sdl.clip.y)/(sdl.clip.h-1)*sdl.mouse.sensitivity/100.0,sdl.mouse.locked);
|
2009-05-02 23:03:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void HandleMouseButton(SDL_MouseButtonEvent * button) {
|
|
|
|
switch (button->state) {
|
|
|
|
case SDL_PRESSED:
|
2009-05-02 23:27:47 +02:00
|
|
|
if (sdl.mouse.requestlock && !sdl.mouse.locked) {
|
2009-05-03 00:18:08 +02:00
|
|
|
GFX_CaptureMouse();
|
2009-05-02 23:27:47 +02:00
|
|
|
// Dont pass klick to mouse handler
|
|
|
|
break;
|
|
|
|
}
|
2009-05-03 00:18:08 +02:00
|
|
|
if (!sdl.mouse.autoenable && sdl.mouse.autolock && button->button == SDL_BUTTON_MIDDLE) {
|
|
|
|
GFX_CaptureMouse();
|
|
|
|
break;
|
|
|
|
}
|
2009-05-02 23:03:37 +02:00
|
|
|
switch (button->button) {
|
|
|
|
case SDL_BUTTON_LEFT:
|
|
|
|
Mouse_ButtonPressed(0);
|
|
|
|
break;
|
|
|
|
case SDL_BUTTON_RIGHT:
|
|
|
|
Mouse_ButtonPressed(1);
|
|
|
|
break;
|
|
|
|
case SDL_BUTTON_MIDDLE:
|
|
|
|
Mouse_ButtonPressed(2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDL_RELEASED:
|
|
|
|
switch (button->button) {
|
|
|
|
case SDL_BUTTON_LEFT:
|
|
|
|
Mouse_ButtonReleased(0);
|
|
|
|
break;
|
|
|
|
case SDL_BUTTON_RIGHT:
|
|
|
|
Mouse_ButtonReleased(1);
|
|
|
|
break;
|
|
|
|
case SDL_BUTTON_MIDDLE:
|
|
|
|
Mouse_ButtonReleased(2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-02 23:35:44 +02:00
|
|
|
static Bit8u laltstate = SDL_KEYUP;
|
2009-05-03 00:02:15 +02:00
|
|
|
static Bit8u raltstate = SDL_KEYUP;
|
|
|
|
|
2009-05-02 23:03:37 +02:00
|
|
|
void GFX_Events() {
|
|
|
|
SDL_Event event;
|
|
|
|
while (SDL_PollEvent(&event)) {
|
|
|
|
switch (event.type) {
|
2009-05-02 23:20:05 +02:00
|
|
|
case SDL_ACTIVEEVENT:
|
|
|
|
if (event.active.state & SDL_APPINPUTFOCUS) {
|
2009-05-03 00:02:15 +02:00
|
|
|
if (event.active.gain) {
|
|
|
|
if (sdl.desktop.fullscreen && !sdl.mouse.locked)
|
2009-05-03 00:18:08 +02:00
|
|
|
GFX_CaptureMouse();
|
2009-05-03 00:02:15 +02:00
|
|
|
SetPriority(sdl.priority.focus);
|
|
|
|
} else {
|
2009-05-03 00:18:08 +02:00
|
|
|
if (sdl.mouse.locked) {
|
|
|
|
#ifdef WIN32
|
|
|
|
if (sdl.desktop.fullscreen) {
|
|
|
|
VGA_KillDrawing();
|
|
|
|
sdl.desktop.fullscreen=false;
|
|
|
|
GFX_ResetScreen();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
GFX_CaptureMouse();
|
|
|
|
}
|
2009-05-03 00:02:15 +02:00
|
|
|
SetPriority(sdl.priority.nofocus);
|
2009-05-03 00:18:08 +02:00
|
|
|
MAPPER_LosingFocus();
|
2009-05-02 23:20:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2009-05-02 23:03:37 +02:00
|
|
|
case SDL_MOUSEMOTION:
|
|
|
|
HandleMouseMotion(&event.motion);
|
|
|
|
break;
|
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
|
|
case SDL_MOUSEBUTTONUP:
|
|
|
|
HandleMouseButton(&event.button);
|
|
|
|
break;
|
|
|
|
case SDL_VIDEORESIZE:
|
2009-05-02 23:53:27 +02:00
|
|
|
// HandleVideoResize(&event.resize);
|
2009-05-02 23:03:37 +02:00
|
|
|
break;
|
|
|
|
case SDL_QUIT:
|
2009-05-02 23:43:00 +02:00
|
|
|
throw(0);
|
2009-05-02 23:03:37 +02:00
|
|
|
break;
|
2009-05-03 00:18:08 +02:00
|
|
|
case SDL_VIDEOEXPOSE:
|
|
|
|
if (sdl.draw.callback) sdl.draw.callback( GFX_CallBackRedraw );
|
|
|
|
break;
|
2009-05-03 00:02:15 +02:00
|
|
|
#ifdef WIN32
|
|
|
|
case SDL_KEYDOWN:
|
|
|
|
case SDL_KEYUP:
|
|
|
|
// ignore event alt+tab
|
|
|
|
if (event.key.keysym.sym==SDLK_LALT) laltstate = event.key.type;
|
|
|
|
if (event.key.keysym.sym==SDLK_RALT) raltstate = event.key.type;
|
|
|
|
if (((event.key.keysym.sym==SDLK_TAB)) &&
|
|
|
|
((laltstate==SDL_KEYDOWN) || (raltstate==SDL_KEYDOWN))) break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
void MAPPER_CheckEvent(SDL_Event * event);
|
|
|
|
MAPPER_CheckEvent(&event);
|
2009-05-02 23:03:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-03 00:18:08 +02:00
|
|
|
/* static variable to show wether there is not a valid stdout.
|
|
|
|
* Fixes some bugs when -noconsole is used in a read only directory */
|
|
|
|
static bool no_stdout = false;
|
|
|
|
|
2009-05-02 23:43:00 +02:00
|
|
|
void GFX_ShowMsg(char * format,...) {
|
|
|
|
char buf[512];
|
|
|
|
va_list msg;
|
|
|
|
va_start(msg,format);
|
|
|
|
vsprintf(buf,format,msg);
|
|
|
|
strcat(buf,"\n");
|
|
|
|
va_end(msg);
|
2009-05-03 00:18:08 +02:00
|
|
|
if(!no_stdout) printf(buf);
|
2009-05-02 23:03:37 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
int main(int argc, char* argv[]) {
|
2009-05-02 23:20:05 +02:00
|
|
|
try {
|
|
|
|
CommandLine com_line(argc,argv);
|
|
|
|
Config myconf(&com_line);
|
|
|
|
control=&myconf;
|
2009-05-03 00:02:15 +02:00
|
|
|
if (control->cmdline->FindExist("-version") ||
|
|
|
|
control->cmdline->FindExist("--version") ) {
|
|
|
|
printf(VERSION "\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-05-02 23:43:00 +02:00
|
|
|
|
|
|
|
/* Can't disable the console with debugger enabled */
|
|
|
|
#if defined(WIN32) && !(C_DEBUG)
|
|
|
|
if (control->cmdline->FindExist("-noconsole")) {
|
|
|
|
FreeConsole();
|
|
|
|
/* Redirect standard input and standard output */
|
2009-05-03 00:18:08 +02:00
|
|
|
if(freopen(STDOUT_FILE, "w", stdout) == NULL)
|
|
|
|
no_stdout = true; // No stdout so don't write messages
|
2009-05-02 23:43:00 +02:00
|
|
|
freopen(STDERR_FILE, "w", stderr);
|
|
|
|
setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* Line buffered */
|
|
|
|
setbuf(stderr, NULL); /* No buffering */
|
|
|
|
} else {
|
|
|
|
if (AllocConsole()) {
|
|
|
|
fclose(stdin);
|
|
|
|
fclose(stdout);
|
|
|
|
fclose(stderr);
|
|
|
|
freopen("CONIN$","w",stdin);
|
|
|
|
freopen("CONOUT$","w",stdout);
|
|
|
|
freopen("CONOUT$","w",stderr);
|
|
|
|
}
|
2009-05-03 00:18:08 +02:00
|
|
|
SetConsoleTitle("DOSBox Status Window");
|
2009-05-02 23:43:00 +02:00
|
|
|
}
|
|
|
|
#endif //defined(WIN32) && !(C_DEBUG)
|
2009-05-02 23:35:44 +02:00
|
|
|
#if C_DEBUG
|
|
|
|
DEBUG_SetupConsole();
|
|
|
|
#endif
|
2009-05-03 00:18:08 +02:00
|
|
|
|
|
|
|
#ifdef OS2
|
|
|
|
PPIB pib;
|
|
|
|
PTIB tib;
|
|
|
|
DosGetInfoBlocks(&tib, &pib);
|
|
|
|
if (pib->pib_ultype == 2) pib->pib_ultype = 3;
|
|
|
|
setbuf(stdout, NULL);
|
|
|
|
setbuf(stderr, NULL);
|
|
|
|
#endif
|
|
|
|
|
2009-05-03 00:02:15 +02:00
|
|
|
if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM
|
2009-05-03 00:18:08 +02:00
|
|
|
|SDL_INIT_NOPARACHUTE
|
2009-05-02 23:03:37 +02:00
|
|
|
#ifndef DISABLE_JOYSTICK
|
|
|
|
|SDL_INIT_JOYSTICK
|
|
|
|
#endif
|
2009-05-02 23:20:05 +02:00
|
|
|
) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError());
|
|
|
|
Section_prop * sdl_sec=control->AddSection_prop("sdl",&GUI_StartUp);
|
2009-05-03 00:02:15 +02:00
|
|
|
sdl_sec->AddInitFunction(&MAPPER_StartUp);
|
2009-05-02 23:20:05 +02:00
|
|
|
sdl_sec->Add_bool("fullscreen",false);
|
2009-05-02 23:53:27 +02:00
|
|
|
sdl_sec->Add_bool("fulldouble",false);
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl_sec->Add_string("fullresolution","original");
|
|
|
|
sdl_sec->Add_string("windowresolution","original");
|
2009-05-02 23:53:27 +02:00
|
|
|
sdl_sec->Add_string("output","surface");
|
2009-05-02 23:20:05 +02:00
|
|
|
sdl_sec->Add_bool("autolock",true);
|
|
|
|
sdl_sec->Add_int("sensitivity",100);
|
2009-05-02 23:43:00 +02:00
|
|
|
sdl_sec->Add_bool("waitonerror",true);
|
2009-05-03 00:02:15 +02:00
|
|
|
sdl_sec->Add_string("priority","higher,normal");
|
|
|
|
sdl_sec->Add_string("mapperfile","mapper.txt");
|
2009-05-03 00:18:08 +02:00
|
|
|
sdl_sec->Add_bool("usescancodes",true);
|
2009-05-02 23:53:27 +02:00
|
|
|
|
2009-05-02 23:43:00 +02:00
|
|
|
MSG_Add("SDL_CONFIGFILE_HELP",
|
|
|
|
"fullscreen -- Start dosbox directly in fullscreen.\n"
|
2009-05-02 23:53:27 +02:00
|
|
|
"fulldouble -- Use double buffering in fullscreen.\n"
|
2009-05-03 00:18:08 +02:00
|
|
|
"fullresolution -- What resolution to use for fullscreen: original or fixed size (e.g. 1024x768).\n"
|
|
|
|
"windowresolution -- Scale the window to this size IF the output device supports hardware scaling.\n"
|
2009-05-02 23:53:27 +02:00
|
|
|
"output -- What to use for output: surface,overlay"
|
|
|
|
#if C_OPENGL
|
|
|
|
",opengl,openglnb"
|
2009-05-03 00:02:15 +02:00
|
|
|
#endif
|
2009-05-03 00:18:08 +02:00
|
|
|
#if (HAVE_DDRAW_H) && defined(WIN32)
|
2009-05-03 00:02:15 +02:00
|
|
|
",ddraw"
|
2009-05-02 23:53:27 +02:00
|
|
|
#endif
|
|
|
|
".\n"
|
2009-05-02 23:43:00 +02:00
|
|
|
"autolock -- Mouse will automatically lock, if you click on the screen.\n"
|
|
|
|
"sensitiviy -- Mouse sensitivity.\n"
|
|
|
|
"waitonerror -- Wait before closing the console if dosbox has an error.\n"
|
2009-05-03 00:18:08 +02:00
|
|
|
"priority -- Priority levels for dosbox: lowest,lower,normal,higher,highest.\n"
|
2009-05-03 00:02:15 +02:00
|
|
|
" Second entry behind the comma is for when dosbox is not focused/minimized.\n"
|
|
|
|
"mapperfile -- File used to load/save the key/event mappings from.\n"
|
2009-05-03 00:18:08 +02:00
|
|
|
"usescancodes -- Avoid usage of symkeys, might not work on all operating systems.\n"
|
2009-05-03 00:02:15 +02:00
|
|
|
);
|
2009-05-02 23:53:27 +02:00
|
|
|
/* Init all the dosbox subsystems */
|
2009-05-02 23:20:05 +02:00
|
|
|
DOSBOX_Init();
|
|
|
|
std::string config_file;
|
|
|
|
if (control->cmdline->FindString("-conf",config_file,true)) {
|
|
|
|
|
|
|
|
} else {
|
|
|
|
config_file="dosbox.conf";
|
|
|
|
}
|
2009-05-02 23:53:27 +02:00
|
|
|
/* Parse the config file
|
|
|
|
* try open config file in $HOME if can't open dosbox.conf or specified file
|
|
|
|
*/
|
|
|
|
if (control->ParseConfigFile(config_file.c_str()) == false) {
|
|
|
|
if ((getenv("HOME") != NULL)) {
|
|
|
|
config_file = (std::string)getenv("HOME") +
|
|
|
|
(std::string)DEFAULT_CONFIG_FILE;
|
|
|
|
if (control->ParseConfigFile(config_file.c_str()) == false) {
|
|
|
|
LOG_MSG("CONFIG: Using default settings. Create a configfile to change them");
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2009-05-02 23:43:00 +02:00
|
|
|
#if (ENVIRON_LINKED)
|
2009-05-02 23:35:44 +02:00
|
|
|
control->ParseEnv(environ);
|
2009-05-02 23:43:00 +02:00
|
|
|
#endif
|
2009-05-02 23:20:05 +02:00
|
|
|
/* Init all the sections */
|
|
|
|
control->Init();
|
|
|
|
/* Some extra SDL Functions */
|
|
|
|
if (control->cmdline->FindExist("-fullscreen") || sdl_sec->Get_bool("fullscreen")) {
|
2009-05-02 23:53:27 +02:00
|
|
|
if(!sdl.desktop.fullscreen) { //only switch if not allready in fullscreen
|
2009-05-03 00:18:08 +02:00
|
|
|
GFX_SwitchFullScreen();
|
2009-05-02 23:53:27 +02:00
|
|
|
}
|
2009-05-02 23:20:05 +02:00
|
|
|
}
|
2009-05-03 00:02:15 +02:00
|
|
|
|
|
|
|
/* Init the keyMapper */
|
|
|
|
MAPPER_Init();
|
2009-05-03 00:18:08 +02:00
|
|
|
if (control->cmdline->FindExist("-startmapper")) MAPPER_Run(true);
|
2009-05-03 00:02:15 +02:00
|
|
|
|
2009-05-02 23:20:05 +02:00
|
|
|
/* Start up main machine */
|
|
|
|
control->StartUp();
|
|
|
|
/* Shutdown everything */
|
|
|
|
} catch (char * error) {
|
2009-05-03 00:18:08 +02:00
|
|
|
GFX_ShowMsg("Exit to error: %s",error);
|
|
|
|
fflush(NULL);
|
2009-05-02 23:43:00 +02:00
|
|
|
if(sdl.wait_on_error) {
|
|
|
|
//TODO Maybe look for some way to show message in linux?
|
|
|
|
#if (C_DEBUG)
|
2009-05-03 00:18:08 +02:00
|
|
|
GFX_ShowMsg("Press enter to continue");
|
|
|
|
fflush(NULL);
|
2009-05-02 23:43:00 +02:00
|
|
|
fgetc(stdin);
|
|
|
|
#elif defined(WIN32)
|
|
|
|
Sleep(5000);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2009-05-02 23:03:37 +02:00
|
|
|
}
|
2009-05-02 23:43:00 +02:00
|
|
|
catch (int){
|
2009-05-03 00:02:15 +02:00
|
|
|
;//nothing pressed killswitch
|
|
|
|
}
|
2009-05-03 00:08:43 +02:00
|
|
|
catch(...){
|
|
|
|
throw;//dunno what happened. rethrow for sdl to catch
|
2009-05-02 23:35:44 +02:00
|
|
|
}
|
2009-05-03 00:08:43 +02:00
|
|
|
SDL_Quit();//Let's hope sdl will quit as well when it catches an exception
|
2009-05-02 23:53:27 +02:00
|
|
|
return 0;
|
2009-05-02 23:20:05 +02:00
|
|
|
};
|