From 9213fd5bd6d5429c13b9d8dedec9bbfc0dd10ca8 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 10 Jun 2004 07:18:53 +0000 Subject: [PATCH] New rendering changes New mapper changes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1817 --- include/render.h | 14 +- include/video.h | 25 +- src/gui/Makefile.am | 4 +- src/gui/render.cpp | 308 ++++------ src/gui/render_normal.h | 59 -- src/gui/render_scale2x.h | 118 ---- src/gui/render_scalers.cpp | 121 ++++ src/gui/render_scalers.h | 51 ++ src/gui/render_templates.h | 325 ++++++++-- src/gui/sdl_mapper.cpp | 1187 ++++++++++++++++++++++++++++++++++++ src/gui/sdlmain.cpp | 297 +++------ 11 files changed, 1858 insertions(+), 651 deletions(-) delete mode 100644 src/gui/render_normal.h delete mode 100644 src/gui/render_scale2x.h create mode 100644 src/gui/render_scalers.cpp create mode 100644 src/gui/render_scalers.h create mode 100644 src/gui/sdl_mapper.cpp diff --git a/include/render.h b/include/render.h index 9782f6a8..1c25a5c2 100644 --- a/include/render.h +++ b/include/render.h @@ -19,22 +19,14 @@ #ifndef __RENDER_H #define __RENDER_H -enum RENDER_Operation { - OP_None, - OP_Shot, - OP_Normal2x, - OP_AdvMame2x, -}; +typedef void (* RENDER_Line_Handler)(const Bit8u * src); -typedef void (* RENDER_Line_Handler)(Bit8u * src); - -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,Bitu scalew,Bitu scaleh); +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,bool dblw,bool dblh); bool RENDER_StartUpdate(void); void RENDER_EndUpdate(void); void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue); extern RENDER_Line_Handler RENDER_DrawLine; -extern Bit8u * RENDER_TempLine; - + #endif diff --git a/include/video.h b/include/video.h index 9ccc0e89..9caa2bef 100644 --- a/include/video.h +++ b/include/video.h @@ -28,15 +28,32 @@ struct GFX_PalEntry { Bit8u unused; }; -#define GFX_HASSCALING 0x0001 -#define GFX_HASCONVERT 0x0002 +#define CAN_8 0x0001 +#define CAN_16 0x0002 +#define CAN_32 0x0004 + +#define CAN_ALL (CAN_8|CAN_16|CAN_32) + +#define LOVE_8 0x0010 +#define LOVE_16 0x0020 +#define LOVE_32 0x0040 + +#define NEED_RGB 0x0100 +#define DONT_ASPECT 0x0200 + +#define HAVE_SCALING 0x1000 + + +enum GFX_Modes { + GFX_8,GFX_15,GFX_16,GFX_32,GFX_NONE, +}; void GFX_Events(void); void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries); -Bitu GFX_GetBestMode(Bitu bpp,Bitu & gfx_flags); +Bitu GFX_GetBestMode(Bitu flags); Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue); -void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,double scalex,double scaley,GFX_ResetCallBack cb_reset); +GFX_Modes GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_ResetCallBack cb_reset); void GFX_ResetScreen(void); void GFX_Start(void); diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 0aea3749..8d76e38d 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,7 +1,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libgui.a -libgui_a_SOURCES = sdlmain.cpp \ - render.cpp render_normal.h render_scale2x.h render_templates.h \ +libgui_a_SOURCES = sdlmain.cpp sdl_mapper.cpp \ + render.cpp render_scalers.cpp render_scalers.h render_templates.h \ midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 2fcaab42..65ea4341 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: render.cpp,v 1.26 2004-02-07 18:50:10 harekiet Exp $ */ +/* $Id: render.cpp,v 1.27 2004-06-10 07:18:19 harekiet Exp $ */ #include #include @@ -27,12 +27,11 @@ #include "video.h" #include "render.h" #include "setup.h" -#include "keyboard.h" +#include "mapper.h" #include "cross.h" #include "support.h" -#define RENDER_MAXWIDTH 1280 -#define RENDER_MAXHEIGHT 1024 +#include "render_scalers.h" struct PalData { struct { @@ -43,51 +42,36 @@ struct PalData { } rgb[256]; volatile Bitu first; volatile Bitu last; - union { - Bit32u bpp32[256]; - Bit16u bpp16[256]; - Bit32u yuv[256]; - } lookup; }; - static struct { struct { Bitu width; Bitu height; Bitu bpp; - Bitu scalew; - Bitu scaleh; + bool dblw,dblh; double ratio; } src; struct { Bitu width; Bitu height; Bitu pitch; - Bitu line; - Bitu bpp; + GFX_Modes mode; RENDER_Operation type; RENDER_Operation want_type; RENDER_Line_Handler line_handler; - Bit8u * draw; - Bit8u * buffer; - Bit8u * pixels; } op; struct { Bitu count; Bitu max; } frameskip; PalData pal; - struct { - Bit8u hlines[RENDER_MAXHEIGHT]; - } normal; #if (C_SSHOT) struct { - RENDER_Operation type; - Bitu bpp,width,height,line; + Bitu bpp,width,height,rowlen; const char * dir; Bit8u * buffer,* draw; - bool usesrc; + bool take,taking; } shot; #endif bool active; @@ -95,27 +79,15 @@ static struct { bool updating; } render; -Bit8u render_line_cache[4][RENDER_MAXWIDTH*4]; //Bit32u pixels RENDER_Line_Handler RENDER_DrawLine; -Bit8u * RENDER_TempLine; - -/* Forward declerations */ -static void RENDER_ResetPal(void); - -/* Include the different rendering routines */ -#include "render_templates.h" -#include "render_normal.h" -#include "render_scale2x.h" - #if (C_SSHOT) #include -static void RENDER_ShotDraw(Bit8u * src) { - if (render.shot.usesrc) { - memcpy(render.shot.draw,src,render.shot.line); - render.shot.draw+=render.shot.line; - } else render.op.line_handler(src); +static void RENDER_ShotDraw(const Bit8u * src) { + memcpy(render.shot.draw,src,render.shot.rowlen); + render.shot.draw+=render.shot.rowlen; + render.op.line_handler(src); } /* Take a screenshot of the data that should be rendered */ @@ -153,7 +125,6 @@ static void TakeScreenShot(Bit8u * bitmap) { LOG_MSG("Can't open file %s for snapshot",file_name); return; } - /* First try to alloacte the png structures */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL, NULL); if (!png_ptr) return; @@ -192,7 +163,7 @@ static void TakeScreenShot(Bit8u * bitmap) { /*Allocate an array of scanline pointers*/ row_pointers=(png_bytep*)malloc(render.shot.height*sizeof(png_bytep)); for (i=0;irender.pal.last) return; Bitu i; - switch (render.op.bpp) { - case 8: + switch (render.op.mode) { + case GFX_8: GFX_SetPalette(render.pal.first,render.pal.last-render.pal.first+1,(GFX_PalEntry *)&render.pal.rgb[render.pal.first]); break; - case 16: + case GFX_15: + case GFX_16: for (i=render.pal.first;i<=render.pal.last;i++) { Bit8u r=render.pal.rgb[i].red; Bit8u g=render.pal.rgb[i].green; Bit8u b=render.pal.rgb[i].blue; - render.pal.lookup.bpp16[i]=GFX_GetRGB(r,g,b); + Scaler_PaletteLut.b16[i]=GFX_GetRGB(r,g,b); } break; - case 24: - case 32: + case GFX_32: for (i=render.pal.first;i<=render.pal.last;i++) { Bit8u r=render.pal.rgb[i].red; Bit8u g=render.pal.rgb[i].green; Bit8u b=render.pal.rgb[i].blue; - render.pal.lookup.bpp32[i]=GFX_GetRGB(r,g,b); + Scaler_PaletteLut.b32[i]=GFX_GetRGB(r,g,b); } break; } @@ -262,7 +232,7 @@ void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue) { if (render.pal.last=miny) { + Bitu templines=(Bitu)lines; + lines-=templines; + linesadded+=templines; + Scaler_Data[i]=templines-miny; + } else Scaler_Data[i]=0; + } + return linesadded; } void RENDER_ReInit(void) { if (render.updating) RENDER_EndUpdate(); Bitu width=render.src.width; Bitu height=render.src.height; - - Bitu scalew=render.src.scalew; - Bitu scaleh=render.src.scaleh; + bool dblw=render.src.dblw; + bool dblh=render.src.dblh; double gfx_scalew=1.0; double gfx_scaleh=1.0; @@ -351,105 +318,59 @@ void RENDER_ReInit(void) { else gfx_scalew*=(1/render.src.ratio); Bitu gfx_flags; - Bitu bpp=GFX_GetBestMode(render.src.bpp,gfx_flags); - Bitu index; - switch (bpp) { - case 8: index=0;break; - case 16:index=1;break; - case 24:index=2;break; - case 32:index=3;break; - } - /* Initial scaler testing */ - switch (render.op.want_type) { - case OP_Normal2x: - case OP_None: + ScalerBlock * block; + if (dblh && dblw) { render.op.type=render.op.want_type; -normalop: - if (gfx_flags & GFX_HASSCALING) { - gfx_scalew*=scalew; - gfx_scaleh*=scaleh; - render.op.line_handler=Normal_8[index]; - for (Bitu i=0;i1 && (render.op.type==OP_None)) { - render.op.line_handler=Normal_8[index]; - scalew>>=1;gfx_scaleh/=2; - } else { - render.op.line_handler=Normal_2x_8[index]; - } - } else render.op.line_handler=Normal_8[index]; - width*=scalew; - double lines=0.0; - height=0; - for (Bitu i=0;i0) ? temp_lines-1 : 0; - height+=temp_lines; - } - } - break; - case OP_AdvMame2x: - if (scalew!=2){ - render.op.type=OP_Normal2x; - goto normalop; - } - if (gfx_flags & GFX_HASSCALING) { - height=scaleh*height; - } else { - height=(Bitu)(gfx_scaleh*scaleh*height); - } - width<<=1; - { - Bits i; - double src_add=(double)height/(double)render.src.height; - double src_index=0; - double src_lines=0; - Bitu src_done=0; - Bitu height=0; - am2x.cmd_index=am2x.cmd_data; - am2x.buf_pos=0;am2x.buf_used=0; - for (i=0;i<=(Bits)render.src.height;i++) { - src_lines+=src_add; - Bitu lines=(Bitu)src_lines; - src_lines-=lines; - switch (lines) { - case 0: - break; - case 1: - AdvMame2x_AddLine(i,i,i); - break; - case 2: - AdvMame2x_AddLine(i-1,i,i+1); - AdvMame2x_AddLine(i+1,i,i-1); - break; - default: - AdvMame2x_AddLine(i-1,i,i+1); - for (lines-=2;lines>0;lines--) AdvMame2x_AddLine(i,i,i); - AdvMame2x_AddLine(i+1,i,i-1); - break; - } - AdvMame2x_CheckLines(i); - } - render.op.line_handler=AdvMame2x_8_Table[index]; - } - break; + } else if (dblw) { + render.op.type=OP_Normal2x; + } else if (dblh) { + render.op.type=OP_Normal; + gfx_scaleh*=2; + } else { +forcenormal: + render.op.type=OP_Normal; } - render.op.bpp=bpp; + switch (render.op.type) { + case OP_Normal:block=&Normal_8;break; + case OP_Normal2x:block=(dblh) ? &Normal2x_8 : &NormalDbl_8;break; + case OP_AdvMame2x:block=&AdvMame2x_8;break; + case OP_AdvMame3x:block=&AdvMame3x_8;break; + case OP_Interp2x:block=&Interp2x_8;break; + case OP_AdvInterp2x:block=&AdvInterp2x_8;break; + case OP_TV2x:block=&TV2x_8;break; + } + gfx_flags=GFX_GetBestMode(block->flags); + if (!gfx_flags) { + if (render.op.type==OP_Normal) E_Exit("Failed to create a rendering output"); + else goto forcenormal; + } + /* Special test for normal2x to switch to normal with hardware scaling */ + if (gfx_flags & HAVE_SCALING && render.op.type==OP_Normal2x) { + if (dblw) gfx_scalew*=2; + if (dblh) gfx_scaleh*=2; + block=&Normal_8; + render.op.type=OP_Normal; + } + width*=block->xscale; + if (gfx_flags & HAVE_SCALING) { + height=MakeAspectTable(render.src.height,block->yscale,block->miny); + } else { + gfx_scaleh*=block->yscale; + height=MakeAspectTable(render.src.height,gfx_scaleh,block->miny); + } +/* Setup the scaler variables */ + render.op.mode=GFX_SetSize(width,height,gfx_flags,gfx_scalew,gfx_scaleh,&RENDER_ReInit);; + if (render.op.mode==GFX_NONE) E_Exit("Failed to create a rendering output"); + render.op.line_handler=block->handlers[render.op.mode]; render.op.width=width; render.op.height=height; - GFX_SetSize(width,height,bpp,gfx_scalew,gfx_scaleh,&RENDER_ReInit); + Scaler_SrcWidth=render.src.width; + Scaler_SrcHeight=render.src.height; RENDER_ResetPal(); render.active=true; } - -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,Bitu scalew,Bitu scaleh) { +void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,bool dblw,bool dblh) { if (!width || !height) { render.active=false; return; @@ -457,9 +378,9 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,Bitu scalew,Bit render.src.width=width; render.src.height=height; render.src.bpp=bpp; + render.src.dblw=dblw; + render.src.dblh=dblh; render.src.ratio=render.aspect ? ratio : 1.0; - render.src.scalew=scalew; - render.src.scaleh=scaleh; RENDER_ReInit(); } @@ -487,8 +408,7 @@ void RENDER_Init(Section * sec) { render.updating=true; #if (C_SSHOT) render.shot.dir=section->Get_string("snapdir"); - render.shot.usesrc=true; - KEYBOARD_AddEvent(KBD_f5,KBD_MOD_CTRL,EnableScreenShot); + MAPPER_AddHandler(EnableScreenShot,MK_f5,MMOD1,"scrshot","Screenshot"); #endif const char * scaler;std::string cline; if (control->cmdline->FindString("-scaler",cline,false)) { @@ -496,15 +416,19 @@ void RENDER_Init(Section * sec) { } else { scaler=section->Get_string("scaler"); } - if (!strcasecmp(scaler,"none")) render.op.want_type=OP_None; + if (!strcasecmp(scaler,"none")) render.op.want_type=OP_Normal; else if (!strcasecmp(scaler,"normal2x")) render.op.want_type=OP_Normal2x; else if (!strcasecmp(scaler,"advmame2x")) render.op.want_type=OP_AdvMame2x; + else if (!strcasecmp(scaler,"advmame3x")) render.op.want_type=OP_AdvMame3x; + else if (!strcasecmp(scaler,"advinterp2x")) render.op.want_type=OP_AdvInterp2x; + else if (!strcasecmp(scaler,"interp2x")) render.op.want_type=OP_Interp2x; + else if (!strcasecmp(scaler,"tv2x")) render.op.want_type=OP_TV2x; else { - render.op.want_type=OP_None; - LOG_MSG("Illegal scaler type %s,falling back to none.",scaler); + render.op.want_type=OP_Normal; + LOG_MSG("Illegal scaler type %s,falling back to normal.",scaler); } - KEYBOARD_AddEvent(KBD_f7,KBD_MOD_CTRL,DecreaseFrameSkip); - KEYBOARD_AddEvent(KBD_f8,KBD_MOD_CTRL,IncreaseFrameSkip); + MAPPER_AddHandler(DecreaseFrameSkip,MK_f7,MMOD1,"decfskip","Dec Fskip"); + MAPPER_AddHandler(IncreaseFrameSkip,MK_f8,MMOD1,"incfskip","Inc Fskip"); GFX_SetTitle(-1,render.frameskip.max); } diff --git a/src/gui/render_normal.h b/src/gui/render_normal.h deleted file mode 100644 index 95ae4ea9..00000000 --- a/src/gui/render_normal.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2002-2004 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 Library 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. - */ - -static Bit8u normal_cache[RENDER_MAXWIDTH*2*4]; - -template -static void Normal(Bit8u * src) { - Bitu line_size=LineSize(render.src.width) * (xdouble ? 2 : 1); - Bit8u * line; - if (sbpp == dbpp && !xdouble) { - line=src; - BituMove(render.op.pixels,line,line_size); - } else { - Bit8u * line_dst=&normal_cache[0]; - Bit8u * real_dst=render.op.pixels; - line=line_dst; - Bit8u * temp_src=src; - for (Bitu tempx=render.src.width;tempx;tempx--) { - Bitu val=ConvBPP(LoadSrc(temp_src)); - AddDst(line_dst,val); - AddDst(real_dst,val); - if (xdouble) { - AddDst(line_dst,val); - AddDst(real_dst,val); - } - } - } - render.op.pixels+=render.op.pitch; - for (Bitu lines=render.normal.hlines[render.op.line++];lines;lines--) { - BituMove(render.op.pixels,line,line_size); - render.op.pixels+=render.op.pitch; - } -} - - -static RENDER_Line_Handler Normal_8[4]={ - Normal<8,8 ,false>,Normal<8,16,false>, - Normal<8,24,false>,Normal<8,32,false>, -}; - -static RENDER_Line_Handler Normal_2x_8[4]={ - Normal<8,8 ,true>,Normal<8,16,true>, - Normal<8,24,true>,Normal<8,32,true>, -}; diff --git a/src/gui/render_scale2x.h b/src/gui/render_scale2x.h deleted file mode 100644 index 00705f41..00000000 --- a/src/gui/render_scale2x.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * This file is part of the Scale2x project. - * - * Copyright (C) 2001-2002 Andrea Mazzoleni - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * In addition, as a special exception, Andrea Mazzoleni - * gives permission to link the code of this program with - * the MAME library (or with modified versions of MAME that use the - * same license as MAME), and distribute linked combinations including - * the two. You must obey the GNU General Public License in all - * respects for all of the code used other than MAME. If you modify - * this file, you may extend this exception to your version of the - * file, but you are not obligated to do so. If you do not wish to - * do so, delete this exception statement from your version. - */ - -/* - * This algorithm was based on the scale2x/advmame2x effect. - * http://scale2x.sourceforge.net/scale2x.html - */ - -#ifndef __SCALE2X_H -#define __SCALE2X_H - -#define AM2XBUF 16 - -static struct { - Bits buf[AM2XBUF][4]; - Bitu buf_used;Bitu buf_pos; - Bit8u cmd_data[4096]; //1024 lines should be enough? - Bit8u * cmd_index; - Bit8u * cache[4]; - Bitu cache_index; -} am2x; - - -static void AdvMame2x_AddLine(Bits s0,Bits s1,Bits s2) { - if (s0<0) s0=0; - if (s1<0) s1=0; - if (s2<0) s2=0; - if (s0>=(Bits)render.src.height) s0=render.src.height-1; - if (s1>=(Bits)render.src.height) s1=render.src.height-1; - if (s2>=(Bits)render.src.height) s2=render.src.height-1; - Bitu pos=(am2x.buf_used+am2x.buf_pos)&(AM2XBUF-1); - am2x.buf[pos][0]=s0; - am2x.buf[pos][1]=s1; - am2x.buf[pos][2]=s2; - s0=s0 > s1 ? s0 : s1; - s0=s0 > s2 ? s0 : s2; - am2x.buf[pos][3]=s0; - am2x.buf_used++; -} - -static void AdvMame2x_CheckLines(Bits last) { - Bitu lines=0;Bit8u * line_count=am2x.cmd_index++; - while (am2x.buf_used) { - if (am2x.buf[am2x.buf_pos][3]>last) break; - *am2x.cmd_index++=am2x.buf[am2x.buf_pos][0]&3; - *am2x.cmd_index++=am2x.buf[am2x.buf_pos][1]&3; - *am2x.cmd_index++=am2x.buf[am2x.buf_pos][2]&3; - am2x.buf_used--;lines++; - am2x.buf_pos=(am2x.buf_pos+1)&(AM2XBUF-1); - } - *line_count=lines; -} - -template -static void AdvMame2x_line(Bit8u * dst, const Bit8u * src0, const Bit8u * src1, const Bit8u * src2, Bitu count) { - AddDst(dst,ConvBPP(src1[0])); - AddDst(dst,ConvBPP((src1[1] == src0[0] && src2[0] != src0[0]) ? src0[0] : src1[0])); - src0++;src1++;src2++;count-=2; - /* central pixels */ - while (count) { - AddDst(dst,ConvBPP((src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0]) ? src0[0] : src1[0])); - AddDst(dst,ConvBPP((src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0]) ? src0[0] : src1[0])); - src0++;src1++;src2++;count--; - } - /* last pixel */ - AddDst(dst,ConvBPP((src1[-1] == src0[0] && src2[0] != src0[0]) ? src0[0] : src1[0])); - AddDst(dst,ConvBPP(src1[0])); -} - -template -static void AdvMame2x(Bit8u * src) { - RENDER_TempLine=render_line_cache[render.op.line&3]; - am2x.cache[render.op.line&3]=src; - Bitu lines=*am2x.cmd_index++; - while (lines--) { - Bit8u * src0=am2x.cache[*am2x.cmd_index++]; - Bit8u * src1=am2x.cache[*am2x.cmd_index++]; - Bit8u * src2=am2x.cache[*am2x.cmd_index++]; - AdvMame2x_line(render.op.pixels,src0,src1,src2,render.src.width); - render.op.pixels+=render.op.pitch; - } - render.op.line++; -} - - -static RENDER_Line_Handler AdvMame2x_8_Table[4]={ - AdvMame2x<8,8>,AdvMame2x<8,16>,AdvMame2x<8,24>,AdvMame2x<8,32> -}; - - -#endif diff --git a/src/gui/render_scalers.cpp b/src/gui/render_scalers.cpp new file mode 100644 index 00000000..a0cedbc3 --- /dev/null +++ b/src/gui/render_scalers.cpp @@ -0,0 +1,121 @@ +#include "dosbox.h" +#include "render_scalers.h" + +Bitu Scaler_Line; +Bitu Scaler_SrcWidth; +Bitu Scaler_SrcHeight; +Bitu Scaler_DstPitch; +Bit8u * Scaler_DstWrite; +Bit8u * Scaler_Index; +Bit8u Scaler_Data[SCALER_MAXHEIGHT*5]; //5cmds/line +PaletteLut Scaler_PaletteLut; + +static union { + Bit32u b32 [4][SCALER_MAXWIDTH]; + Bit16u b16 [4][SCALER_MAXWIDTH]; + Bit8u b8 [4][SCALER_MAXWIDTH]; +} line_cache; +static union { + Bit32u b32 [4][SCALER_MAXWIDTH*3]; + Bit16u b16 [4][SCALER_MAXWIDTH*3]; + Bit8u b8 [4][SCALER_MAXWIDTH*3]; +} write_cache; + +static Bit8u * ln[3]; + +#define _conc2(A,B) A ## B +#define _conc3(A,B,C) A ## B ## C +#define _conc4(A,B,C,D) A ## B ## C ## D +#define _conc5(A,B,C,D,E) A ## B ## C ## D ## E + +#define conc2(A,B) _conc2(A,B) +#define conc3(A,B,C) _conc3(A,B,C) +#define conc4(A,B,C,D) _conc4(A,B,C,D) +#define conc2d(A,B) _conc3(A,_,B) +#define conc3d(A,B,C) _conc5(A,_,B,_,C) + +#define BituMove(_DST,_SRC,_SIZE) \ +{ \ + Bitu bsize=(_SIZE)/sizeof(Bitu); \ + Bitu * bdst=(Bitu *)(_DST); \ + Bitu * bsrc=(Bitu *)(_SRC); \ + while (bsize--) *bdst++=*bsrc++; \ +} + +#define interp_w2(P0,P1,W0,W1) \ + ((((P0&redblueMask)*W0+(P1&redblueMask)*W1)/(W0+W1)) & redblueMask) | \ + ((((P0& greenMask)*W0+(P1& greenMask)*W1)/(W0+W1)) & greenMask) +#define interp_w3(P0,P1,P2,W0,W1,W2) \ + ((((P0&redblueMask)*W0+(P1&redblueMask)*W1+(P2&redblueMask)*W2)/(W0+W1+W2)) & redblueMask) | \ + ((((P0& greenMask)*W0+(P1& greenMask)*W1+(P2& greenMask)*W2)/(W0+W1+W2)) & greenMask) +#define interp_w4(P0,P1,P2,P3,W0,W1,W2,W3) \ + ((((P0&redblueMask)*W0+(P1&redblueMask)*W1+(P2&redblueMask)*W2+(P3&redblueMask)*W3)/(W0+W1+W2+W3)) & redblueMask) | \ + ((((P0& greenMask)*W0+(P1& greenMask)*W1+(P2& greenMask)*W2+(P3& greenMask)*W3)/(W0+W1+W2+W3)) & greenMask) + +/* Include the different rendering routines */ +#define SBPP 8 +#define DBPP 8 +#include "render_templates.h" +#undef DBPP +#define DBPP 15 +#include "render_templates.h" +#undef DBPP +#define DBPP 16 +#include "render_templates.h" +#undef DBPP +#define DBPP 32 +#include "render_templates.h" +#undef SBPP +#undef DBPP + + + +ScalerBlock Normal_8={ + CAN_8|CAN_16|CAN_32|LOVE_8, + 1,1,1, + Normal_8_8,Normal_8_16,Normal_8_16,Normal_8_32 +}; + +ScalerBlock NormalDbl_8= { + CAN_8|CAN_16|CAN_32|LOVE_8, + 2,1,1, + Normal2x_8_8,Normal2x_8_16,Normal2x_8_16,Normal2x_8_32 +}; + +ScalerBlock Normal2x_8={ + CAN_8|CAN_16|CAN_32|LOVE_8, + 2,2,1, + Normal2x_8_8,Normal2x_8_16,Normal2x_8_16,Normal2x_8_32 +}; + +ScalerBlock AdvMame2x_8={ + CAN_8|CAN_16|CAN_32|LOVE_8, + 2,2,1, + AdvMame2x_8_8,AdvMame2x_8_16,AdvMame2x_8_16,AdvMame2x_8_32 +}; + +ScalerBlock AdvMame3x_8={ + CAN_8|CAN_16|CAN_32|LOVE_8, + 3,3,2, + AdvMame3x_8_8,AdvMame3x_8_16,AdvMame3x_8_16,AdvMame3x_8_32 +}; + +ScalerBlock Interp2x_8={ + CAN_16|CAN_32|LOVE_32|NEED_RGB, + 2,2,1, + 0,Interp2x_8_16,Interp2x_8_16,Interp2x_8_32 +}; + +ScalerBlock AdvInterp2x_8={ + CAN_16|CAN_32|LOVE_32|NEED_RGB, + 2,2,1, + 0,AdvInterp2x_8_16,AdvInterp2x_8_16,AdvInterp2x_8_32 +}; + +ScalerBlock TV2x_8={ + CAN_16|CAN_32|LOVE_32|NEED_RGB, + 2,2,1, + 0,TV2x_8_16,TV2x_8_16,TV2x_8_32 +}; + + diff --git a/src/gui/render_scalers.h b/src/gui/render_scalers.h new file mode 100644 index 00000000..bb6de83d --- /dev/null +++ b/src/gui/render_scalers.h @@ -0,0 +1,51 @@ +#ifndef _RENDER_SCALERS_H +#define _RENDER_SCALERS_H + +#include "render.h" +#include "video.h" + +#define SCALER_MAXWIDTH 1280 +#define SCALER_MAXHEIGHT 1024 + +extern Bitu Scaler_Line; +extern Bitu Scaler_SrcWidth; +extern Bitu Scaler_SrcHeight; +extern Bitu Scaler_DstPitch; +extern Bit8u * Scaler_DstWrite; +extern Bit8u Scaler_Data[]; +extern Bit8u * Scaler_Index; + +union PaletteLut { + Bit16u b16[256]; + Bit32u b32[256]; +}; + +extern PaletteLut Scaler_PaletteLut; + +enum RENDER_Operation { + OP_Normal, + OP_Normal2x, + OP_AdvMame2x, + OP_AdvMame3x, + OP_AdvInterp2x, + OP_Interp2x, + OP_TV2x, +}; + +struct ScalerBlock { + Bitu flags; + Bitu xscale,yscale,miny; + RENDER_Line_Handler handlers[4]; +}; + +extern ScalerBlock Normal_8; +extern ScalerBlock NormalDbl_8; +extern ScalerBlock Normal2x_8; +extern ScalerBlock AdvMame2x_8; +extern ScalerBlock AdvMame3x_8; +extern ScalerBlock AdvInterp2x_8; +extern ScalerBlock Interp2x_8; +extern ScalerBlock TV2x_8; + + +#endif diff --git a/src/gui/render_templates.h b/src/gui/render_templates.h index d5228cdb..67d181ed 100644 --- a/src/gui/render_templates.h +++ b/src/gui/render_templates.h @@ -1,59 +1,294 @@ -#ifdef __GNUC__ -template static INLINE void AddDst(Bit8u * & dst,Bitu val) __attribute__ ((always_inline)); -template static INLINE Bitu LineSize(Bitu pixels) __attribute__ ((always_inline)); -template static INLINE Bitu LoadSrc(Bit8u * & src) __attribute__ ((always_inline)); -template static INLINE Bitu ConvBPP(Bitu val) __attribute__ ((always_inline)); +#if DBPP == 8 +#define PSIZE 1 +#define PTYPE Bit8u +#define WC write_cache.b8 +#define LC line_cache.b8 +#define redblueMask 0 +#define greenMask 0 +#elif DBPP == 15 || DBPP == 16 +#define PSIZE 2 +#define PTYPE Bit16u +#define WC write_cache.b16 +#define LC line_cache.b16 +#if DBPP == 15 +#define redblueMask 0x7C1F +#define greenMask 0x03E0 +#elif DBPP == 16 +#define redblueMask 0xF81F +#define greenMask 0x07E0 +#endif +#elif DBPP == 32 +#define PSIZE 4 +#define PTYPE Bit32u +#define WC write_cache.b32 +#define LC line_cache.b32 +#define redblueMask 0xff00ff +#define greenMask 0xff00 #endif -template static INLINE void AddDst(Bit8u * & dst,Bitu val) { - switch (dbpp) { - case 8: *(Bit8u*)dst=val;dst+=1;break; - case 16:*(Bit16u*)dst=val;dst+=2;break; - case 24:*(Bit32u*)dst=val;dst+=3;break; - case 32:*(Bit32u*)dst=val;dst+=4;break; +#if SBPP == 8 +#if DBPP == 8 +#define PMAKE(_VAL) _VAL +#elif DBPP == 15 +#define PMAKE(_VAL) Scaler_PaletteLut.b16[_VAL] +#elif DBPP == 16 +#define PMAKE(_VAL) Scaler_PaletteLut.b16[_VAL] +#elif DBPP == 32 +#define PMAKE(_VAL) Scaler_PaletteLut.b32[_VAL] +#endif +#endif + +#define C0 LC[0][x-1] +#define C1 LC[0][x+0] +#define C2 LC[0][x+1] +#define C3 LC[1][x-1] +#define C4 LC[1][x+0] +#define C5 LC[1][x+1] +#define C6 LC[2][x-1] +#define C7 LC[2][x+0] +#define C8 LC[2][x+1] + +static void conc3d(Normal,SBPP,DBPP) (const Bit8u * src) { + const Bit8u * line; +#if SBPP == DBPP + line=src; + BituMove(Scaler_DstWrite,line,Scaler_SrcWidth*PSIZE); +#else + PTYPE * dst=(PTYPE *)Scaler_DstWrite; + line=line_cache.b8[0]; + for (Bitu x=0;x -static INLINE Bitu LineSize(Bitu pixels) { - switch (bpp) { - case 8:return pixels; - case 16:return pixels*2; - case 24:return pixels*3; - case 32:return pixels*4; +static void conc3d(Normal2x,SBPP,DBPP) (const Bit8u * src) { + PTYPE * dst=(PTYPE *)Scaler_DstWrite; + for (Bitu x=0;x -static INLINE Bitu LoadSrc(Bit8u * & src) { - Bitu val; - switch (sbpp) { - case 8:val=*(Bit8u *) src;src+=1;break; - case 16:val=*(Bit16u *) src;src+=2;break; - case 24:val=(*(Bit32u *)src)&0xffffff;src+=3;break; - case 32:val=*(Bit32u *)src;src+=4;break; +#if (DBPP > 8) +static void conc3d(TV2x,SBPP,DBPP) (const Bit8u * src) { + PTYPE * dst=(PTYPE *)Scaler_DstWrite; + for (Bitu x=0;x> 3) & redblueMask; + halfpixel|=(((pixel & greenMask) * 7) >> 3) & greenMask; + dst[x*2+0]=dst[x*2+1]=halfpixel; + LC[0][x*2+0]=LC[0][x*2+1]=pixel; + } + Scaler_DstWrite+=Scaler_DstPitch; + for (Bitu lines=*Scaler_Index++;lines;lines--) { + BituMove(Scaler_DstWrite,LC[0],Scaler_SrcWidth*2*PSIZE); + Scaler_DstWrite+=Scaler_DstPitch; } - return val; } - -template -static INLINE Bitu ConvBPP(Bitu val) { - if (sbpp==8) switch (dbpp) { - case 8:return val; - case 16:return render.pal.lookup.bpp16[val]; - case 24:return render.pal.lookup.bpp32[val]; - case 32:return render.pal.lookup.bpp32[val]; +static void conc3d(Interp2x,SBPP,DBPP) (const Bit8u * src) { + if (!Scaler_Line) { + Scaler_Line++; + for (Bitu tempx=Scaler_SrcWidth;tempx>0;tempx--) { + LC[1][tempx] = LC[2][tempx] = PMAKE(src[tempx]); + } + return; } - return 0; +lastagain: + Bitu x=0; + PTYPE * dst=(PTYPE *)Scaler_DstWrite; + C1=C4;C4=C7;C7=PMAKE(src[x]); + C2=C5;C5=C8;C8=PMAKE(src[x+1]); + dst[0] = interp_w2(C4,C1,3,1); + dst[1] = interp_w4(C4,C1,C2,C5,5,1,1,1); + WC[1][0] = interp_w2(C4,C7,3,1); + WC[1][1] = interp_w4(C4,C5,C8,C7,5,1,1,1); + for (x=1;x0;tempx--) { + LC[1][tempx]=LC[2][tempx]=PMAKE(src[tempx]); + } + return; + } +lastagain: + Bitu x=0; + PTYPE * dst=(PTYPE *)Scaler_DstWrite; + C1=C4;C4=C7;C7=PMAKE(src[x]); + C2=C5;C5=C8;C8=PMAKE(src[x+1]); + dst[0]=C4; + WC[1][0]=C4; + dst[1] = C5 == C1 && C7 != C1 ? C2 : C4; + WC[1][1]= C5 == C7 && C1 != C7 ? C7 : C4; + for (x=1;x0;lines--) { + BituMove(Scaler_DstWrite,&WC[1],2*Scaler_SrcWidth*PSIZE); + Scaler_DstWrite+=Scaler_DstPitch; + } + if (++Scaler_Line==Scaler_SrcHeight) goto lastagain; +} + +#endif //DBPP > 8 + +static void conc3d(AdvMame2x,SBPP,DBPP) (const Bit8u * src) { + if (!Scaler_Line) { + Scaler_Line++; + for (Bitu tempx=Scaler_SrcWidth;tempx>0;tempx--) { + LC[1][tempx]=LC[2][tempx]=PMAKE(src[tempx]); + } + return; + } +lastagain: + Bitu x=0; + PTYPE * dst=(PTYPE *)Scaler_DstWrite; + C1=C4;C4=C7;C7=PMAKE(src[x]); + C2=C5;C5=C8;C8=PMAKE(src[x+1]); + dst[0]=C4; + WC[1][0]=C4; + dst[1] = C5 == C1 && C7 != C1 ? C2 : C4; + WC[1][1]= C5 == C7 && C1 != C7 ? C7 : C4; + for (x=1;x0;lines--) { + BituMove(Scaler_DstWrite,&WC[1],2*Scaler_SrcWidth*PSIZE); + Scaler_DstWrite+=Scaler_DstPitch; + } + if (++Scaler_Line==Scaler_SrcHeight) goto lastagain; +} + +static void conc3d(AdvMame3x,SBPP,DBPP) (const Bit8u * src) { + if (!Scaler_Line) { + Scaler_Line++; + for (Bitu tempx=Scaler_SrcWidth;tempx>0;tempx--) { + LC[1][tempx]=LC[2][tempx]=PMAKE(src[tempx]); + } + return; + } +lastagain: + PTYPE * dst=(PTYPE *)Scaler_DstWrite; + LC[0][0]=LC[1][0];LC[1][0]=LC[2][0];LC[2][0]=PMAKE(src[0]); + LC[0][1]=LC[1][1];LC[1][1]=LC[2][1];LC[2][1]=PMAKE(src[1]); + /* first pixel */ + dst[0] = LC[1][0]; + dst[1] = LC[1][0]; + dst[2] = (LC[1][1] == LC[0][0] && LC[2][0] != LC[0][0]) ? LC[0][0] : LC[1][0]; + WC[1][0] = LC[1][0]; + WC[1][1] = LC[1][0]; + WC[1][2] = (LC[0][0] != LC[2][0]) ? (((LC[1][1] == LC[0][0] && LC[1][0] != LC[2][1]) || (LC[1][1] == LC[2][0] && LC[1][0] != LC[0][1])) ? LC[1][1] : LC[1][0]) : LC[1][0]; + WC[2][0] = LC[1][0]; + WC[2][1] = LC[1][0]; + WC[2][2] = (LC[1][1] == LC[2][0] && LC[0][0] != LC[2][0]) ? LC[2][0] : LC[1][0]; + Bitu x; + for (x=1;x0;lines--) { + BituMove(Scaler_DstWrite,&WC[2],3*Scaler_SrcWidth*PSIZE); + Scaler_DstWrite+=Scaler_DstPitch; + } + if (++Scaler_Line==Scaler_SrcHeight) goto lastagain; +} + +#undef PSIZE +#undef PTYPE +#undef PMAKE +#undef WC +#undef LC +#undef greenMask +#undef redblueMask + + diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp new file mode 100644 index 00000000..92bc9eda --- /dev/null +++ b/src/gui/sdl_mapper.cpp @@ -0,0 +1,1187 @@ +/* + * Copyright (C) 2002-2004 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 Library 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. + */ + +#include +#include +#include +#include +#include +#include +#include + + +#include "SDL.h" +#include "SDL_thread.h" + +#include "dosbox.h" +#include "video.h" +#include "keyboard.h" +#include "joystick.h" +#include "support.h" +#include "mapper.h" +#include "setup.h" + +enum { + CLR_BLACK=0, + CLR_WHITE=1, + CLR_RED=2, +}; + +enum BB_Types { + BB_Next,BB_Prev,BB_Add,BB_Del, + BB_Save,BB_Reset +}; + +enum BC_Types { + BC_Mod1,BC_Mod2,BC_Mod3, + BC_Hold, +}; + +#define BMOD_Mod1 0x0001 +#define BMOD_Mod2 0x0002 +#define BMOD_Mod3 0x0004 + +#define BFLG_Hold 0x0001 +#define BFLG_Repeat 0x0004 + + +#define MAXSTICKS 8 +#define MAXACTIVE 16 + +class CEvent; +class CHandlerEvent; +class CButton; +class CBind; +class CBindGroup; + +static void SetActiveEvent(CEvent * event); +static void SetActiveBind(CBind * _bind); +extern Bit8u int10_font_14[256 * 14]; + +static std::vector events; +static std::vector buttons; +static std::vector bindgroups; +static std::vector handlergroup; +typedef std::list CBindList; +typedef std::list::iterator CEventList_it; +typedef std::list::iterator CBindList_it; +typedef std::vector::iterator CButton_it; +typedef std::vector::iterator CEventVector_it; +typedef std::vector::iterator CHandlerEventVector_it; +typedef std::vector::iterator CBindGroup_it; + +static CBindList holdlist; + + +class CEvent { +public: + CEvent(char * _entry) { + strncpy(entry,_entry,16); + events.push_back(this); + bindlist.clear(); + activity=0; + } + void AddBind(CBind * bind); + virtual ~CEvent() {} + virtual void Active(bool yesno)=0; + INLINE void Activate(void) { + if (!activity) Active(true); + activity++; + } + INLINE void DeActivate(void) { + activity--; + if (!activity) Active(false); + } + void DeActivateAll(void); + void SetValue(Bits value){ + }; + char * GetName(void) { return entry;} + CBindList bindlist; +protected: + Bitu activity; + char entry[16]; +}; + +class CBind { +public: + virtual ~CBind () { + list->remove(this); +// event->bindlist.remove(this); + } + CBind(CBindList * _list) { + list=_list; + _list->push_back(this); + mods=flags=0; + event=0; + active=holding=false; + } + void AddFlags(char * buf) { + if (mods & BMOD_Mod1) strcat(buf," mod1"); + if (mods & BMOD_Mod2) strcat(buf," mod2"); + if (mods & BMOD_Mod3) strcat(buf," mod3"); + if (flags & BFLG_Hold) strcat(buf," hold"); + } + void SetFlags(char * buf) { + char * word; + while (*(word=StripWord(buf))) { + if (!strcasecmp(word,"mod1")) mods|=BMOD_Mod1; + if (!strcasecmp(word,"mod2")) mods|=BMOD_Mod2; + if (!strcasecmp(word,"mod3")) mods|=BMOD_Mod2; + if (!strcasecmp(word,"hold")) flags|=BFLG_Hold; + } + } + void Activate(Bits value) { + event->SetValue(value); + if (active) return; + event->Activate(); + active=true; + } + void DeActivate(void) { + if (!active) return; + active=false; + if (flags & BFLG_Hold) { + if (!holding) { + holdlist.push_back(this); + holding=true; + return; + } else { + holdlist.remove(this); + holding=false; + } + } + event->DeActivate(); + } + virtual void ConfigName(char * buf)=0; + virtual void BindName(char * buf)=0; + Bitu mods,flags; + Bit16s value; + CEvent * event; + CBindList * list; + bool active,holding; +}; + + +void CEvent::AddBind(CBind * bind) { + bindlist.push_front(bind); + bind->event=this; +} +void CEvent::DeActivateAll(void) { + for (CBindList_it bit=bindlist.begin();bit!=bindlist.end();bit++) { + (*bit)->DeActivate(); + } +} + + + +class CBindGroup { +public: + CBindGroup() { + bindgroups.push_back(this); + } + void ActivateBindList(CBindList * list,Bits value); + void DeactivateBindList(CBindList * list); + virtual CBind * CreateConfigBind(char *&buf)=0; + virtual CBind * CreateEventBind(SDL_Event * event)=0; + + virtual bool CheckEvent(SDL_Event * event)=0; + virtual char * ConfigStart(void)=0; + virtual char * BindStart(void)=0; +protected: + +}; + +class CKeyBind; +class CKeyBindGroup; + +class CKeyBind : public CBind { +public: + CKeyBind(CBindList * _list,SDLKey _key) : CBind(_list) { + key = _key; + } + void BindName(char * buf) { + sprintf(buf,"Key %s%",SDL_GetKeyName(key)); + } + void ConfigName(char * buf) { + sprintf(buf,"key %d",key); + } +public: + SDLKey key; +}; + +class CKeyBindGroup : public CBindGroup { +public: + CKeyBindGroup(Bitu _keys) : CBindGroup (){ + lists=new CBindList[_keys]; + for (Bitu i=0;i<_keys;i++) lists[i].clear(); + keys=_keys; + configname="key"; + } + ~CKeyBindGroup() { delete[] lists; } + CBind * CreateConfigBind(char *& buf) { + if (strncasecmp(buf,configname,strlen(configname))) return 0; + StripWord(buf);char * num=StripWord(buf); + CBind * bind=CreateKeyBind((SDLKey)ConvDecWord(num)); + return bind; + } + CBind * CreateEventBind(SDL_Event * event) { + if (event->type!=SDL_KEYDOWN) return 0; + return CreateKeyBind(event->key.keysym.sym); + }; + bool CheckEvent(SDL_Event * event) { + if (event->type!=SDL_KEYDOWN && event->type!=SDL_KEYUP) return false; + Bitu key=(Bitu)event->key.keysym.sym; + assert(keytype==SDL_KEYDOWN) ActivateBindList(&lists[key],0x7fff); + else DeactivateBindList(&lists[key]); + return 0; + } +private: + CBind * CreateKeyBind(SDLKey _key) { + assert((Bitu)_keyConfigStart(),axis,positive ? 1 : 0); + } + void BindName(char * buf) { + sprintf(buf,"%s Axis %d%s",group->BindStart(),axis,positive ? "+" : "-"); + } +protected: + CBindGroup * group; + Bitu axis; + bool positive; +}; + +class CJButtonBind : public CBind { +public: + CJButtonBind(CBindList * _list,CBindGroup * _group,Bitu _button) : CBind(_list) { + group = _group; + button=_button; + } + void ConfigName(char * buf) { + sprintf(buf,"%s button %d",group->ConfigStart(),button); + } + void BindName(char * buf) { + sprintf(buf,"%s Button %d",group->BindStart(),button); + } +protected: + CBindGroup * group; + Bitu button; +}; + +class CJHatBind : public CBind { +public: + CJHatBind(CBindList * _list,CBindGroup * _group,Bitu _hat) : CBind(_list) { + group = _group; + hat=_hat; + } + void ConfigName(char * buf) { + sprintf(buf,"%s hat %d",group->ConfigStart(),hat); + } + void BindName(char * buf) { + sprintf(buf,"%s hat %d",group->BindStart(),hat); + } +protected: + CBindGroup * group; + Bitu hat; + Bitu mask; +}; + +class CStickBindGroup : public CBindGroup { +public: + CStickBindGroup(Bitu _stick) : CBindGroup (){ + stick=_stick; + sprintf(configname,"stick_%d",stick); + assert(sdl_joystick=SDL_JoystickOpen(stick)); + axes=SDL_JoystickNumAxes(sdl_joystick); + buttons=SDL_JoystickNumButtons(sdl_joystick); + hats=SDL_JoystickNumHats(sdl_joystick); + pos_axis_lists=new CBindList[axes]; + neg_axis_lists=new CBindList[axes]; + button_lists=new CBindList[buttons]; + hat_lists=new CBindList[hats]; + } + ~CStickBindGroup() { + SDL_JoystickClose(sdl_joystick); + delete[] pos_axis_lists; + delete[] neg_axis_lists; + delete[] button_lists; + delete[] hat_lists; + } + CBind * CreateConfigBind(char *& buf) { + if (strncasecmp(configname,buf,strlen(configname))) return 0; + StripWord(buf);char * type=StripWord(buf); + CBind * bind=0; + if (!strcasecmp(type,"axis")) { + Bitu ax=ConvDecWord(StripWord(buf)); + bool pos=ConvDecWord(StripWord(buf)) > 0; + bind=CreateAxisBind(ax,pos); + } else if (!strcasecmp(type,"button")) { + Bitu but=ConvDecWord(StripWord(buf)); + bind=CreateButtonBind(but); + } + return bind; + } + CBind * CreateEventBind(SDL_Event * event) { + if (event->type==SDL_JOYAXISMOTION) { + if (event->jaxis .which!=stick) return 0; + if (abs(event->jaxis.value)<25000) return 0; + return CreateAxisBind(event->jaxis.axis,event->jaxis.value>0); + } else if (event->type==SDL_JOYBUTTONDOWN) { + if (event->jaxis .which!=stick) return 0; + return CreateButtonBind(event->jbutton.button); + } else return 0; + } + bool CheckEvent(SDL_Event * event) { + + return false; + } +private: + CBind * CreateAxisBind(Bitu axis,bool positive) { + assert(axisbegin();it!=list->end();it++) { + if (((*it)->mods & mapper.mods) == (*it)->mods) { + if (validmod<(*it)->mods) validmod=(*it)->mods; + } + } + for (it=list->begin();it!=list->end();it++) { + if (validmod==(*it)->mods) (*it)->Activate(value); + } +} + +void CBindGroup::DeactivateBindList(CBindList * list) { + Bitu validmod=0; + CBindList_it it; + for (it=list->begin();it!=list->end();it++) { + (*it)->DeActivate(); + } +} + +static void DrawText(Bitu x,Bitu y,const char * text,Bit8u color) { + Bit8u * draw=((Bit8u *)mapper.surface->pixels)+(y*mapper.surface->pitch)+x; + while (*text) { + Bit8u * font=&int10_font_14[(*text)*14]; + Bitu i,j;Bit8u * draw_line=draw; + for (i=0;i<14;i++) { + Bit8u map=*font++; + for (j=0;j<8;j++) { + if (map & 0x80) *(draw_line+j)=color; + else *(draw_line+j)=CLR_BLACK; + map<<=1; + } + draw_line+=mapper.surface->pitch; + } + text++;draw+=8; + } +} + +class CButton { +public: + virtual ~CButton(){}; + CButton(Bitu _x,Bitu _y,Bitu _dx,Bitu _dy) { + x=_x;y=_y;dx=_dx;dy=_dy; + buttons.push_back(this); + color=CLR_WHITE; + enabled=true; + } + virtual void Draw(void) { + if (!enabled) return; + Bit8u * point=((Bit8u *)mapper.surface->pixels)+(y*mapper.surface->pitch)+x; + for (Bitu lines=0;linespitch; + } + } + virtual bool OnTop(Bitu _x,Bitu _y) { + return ( enabled && (_x>=x) && (_x=y) && (_ybindlist.end()) { + delete (*mapper.abindit); + mapper.abindit=mapper.aevent->bindlist.erase(mapper.abindit); + if (mapper.abindit==mapper.aevent->bindlist.end()) + mapper.abindit=mapper.aevent->bindlist.begin(); + } + if (mapper.abindit!=mapper.aevent->bindlist.end()) SetActiveBind(*(mapper.abindit)); + else SetActiveBind(0); + break; + case BB_Next: + if (mapper.abindit!=mapper.aevent->bindlist.end()) + mapper.abindit++; + if (mapper.abindit==mapper.aevent->bindlist.end()) + mapper.abindit=mapper.aevent->bindlist.begin(); + SetActiveBind(*(mapper.abindit)); + break; + case BB_Save: + MAPPER_SaveBinds(); + break; + } + } +protected: + BB_Types type; +}; + +class CCheckButton : public CTextButton { +public: + CCheckButton(Bitu _x,Bitu _y,Bitu _dx,Bitu _dy,const char * _text,BC_Types _type) + : CTextButton(_x,_y,_dx,_dy,_text) { + type=_type; + } + void Draw(void) { + if (!enabled) return; + bool checked; + switch (type) { + case BC_Mod1: + checked=(mapper.abind->mods&BMOD_Mod1)>0; + break; + case BC_Mod2: + checked=(mapper.abind->mods&BMOD_Mod2)>0; + break; + case BC_Mod3: + checked=(mapper.abind->mods&BMOD_Mod3)>0; + break; + case BC_Hold: + checked=(mapper.abind->flags&BFLG_Hold)>0; + break; + } + if (checked) { + Bit8u * point=((Bit8u *)mapper.surface->pixels)+((y+2)*mapper.surface->pitch)+x+dx-dy+2; + for (Bitu lines=0;lines<(dy-4);lines++) { + memset(point,color,dy-4); + point+=mapper.surface->pitch; + } + } + CTextButton::Draw(); + } + void Click(void) { + switch (type) { + case BC_Mod1: + mapper.abind->mods^=BMOD_Mod1; + break; + case BC_Mod2: + mapper.abind->mods^=BMOD_Mod2; + break; + case BC_Mod3: + mapper.abind->mods^=BMOD_Mod3; + break; + case BC_Hold: + mapper.abind->flags^=BFLG_Hold; + break; + } + mapper.redraw=true; + } +protected: + BC_Types type; +}; + +class CKeyEvent : public CEvent { +public: + CKeyEvent(char * _entry,KBD_KEYS _key) : CEvent(_entry) { + key=_key; + } + void Active(bool yesno) { + KEYBOARD_AddKey(key,yesno); + }; + KBD_KEYS key; +}; + +class CJAxisEvent : public CEvent { +public: + CJAxisEvent(char * _entry,Bitu _stick,bool _yaxis,bool _positive) : CEvent(_entry) { + stick=_stick; + yaxis=_yaxis; + positive=_positive; + } + void Active(bool yesno) { + }; + Bitu stick; + bool yaxis,positive; +}; + +class CJButtonEvent : public CEvent { +public: + CJButtonEvent(char * _entry,Bitu _stick,Bitu _button) : CEvent(_entry) { + stick=_stick; + button=_button; + } + void Active(bool yesno) { + }; + Bitu stick,button; +}; + + +class CModEvent : public CEvent { +public: + CModEvent(char * _entry,Bitu _wmod) : CEvent(_entry) { + wmod=_wmod; + } + void Active(bool yesno) { + if (yesno) mapper.mods|=(1 << (wmod-1)); + else mapper.mods&=~(1 << (wmod-1)); + }; +protected: + Bitu wmod; +}; + +class CHandlerEvent : public CEvent { +public: + CHandlerEvent(char * _entry,MAPPER_Handler * _handler,MapKeys _key,Bitu _mod,char * _buttonname) : CEvent(_entry) { + handler=_handler; + defmod=_mod; + defkey=_key; + buttonname=_buttonname; + handlergroup.push_back(this); + } + void Active(bool yesno) { + if (yesno) (*handler)(); + }; + char * ButtonName(void) { + return buttonname; + } + void MakeDefaultBind(char * buf) { + Bitu key=0; + switch (defkey) { + case MK_f1:case MK_f2:case MK_f3:case MK_f4: + case MK_f5:case MK_f6:case MK_f7:case MK_f8: + case MK_f9:case MK_f10:case MK_f11:case MK_f12: + key=SDLK_F1+(defkey-MK_f1); + break; + case MK_return: + key=SDLK_RETURN; + break; + case MK_kpminus: + key=SDLK_KP_MINUS; + break; + } + sprintf(buf,"%s \"key %d%s%s%s\"", + entry, + key, + defmod & 1 ? " mod1" : "", + defmod & 2 ? " mod2" : "", + defmod & 4 ? " mod3" : "" + ); + } +protected: + MapKeys defkey; + Bitu defmod; + char * buttonname; + MAPPER_Handler * handler; +}; + + +struct { + CCaptionButton * event_title; + CCaptionButton * bind_title; + CCaptionButton * selected; + CCaptionButton * action; + CBindButton * save; + CBindButton * add; + CBindButton * del; + CBindButton * next; + CBindButton * prev; + CCheckButton * mod1,* mod2,* mod3,* hold; +} bind_but; + +static void SetActiveBind(CBind * _bind) { + mapper.abind=_bind; + if (_bind) { + bind_but.bind_title->Enable(true); + char buf[256];_bind->BindName(buf); + bind_but.bind_title->Change("BIND:%s",buf); + bind_but.del->Enable(true); + bind_but.next->Enable(true); + bind_but.mod1->Enable(true); + bind_but.mod2->Enable(true); + bind_but.mod3->Enable(true); + bind_but.hold->Enable(true); + } else { + bind_but.bind_title->Enable(false); + bind_but.del->Enable(false); + bind_but.prev->Enable(false); + bind_but.next->Enable(false); + bind_but.mod1->Enable(false); + bind_but.mod2->Enable(false); + bind_but.mod3->Enable(false); + bind_but.hold->Enable(false); + } +} + +static void SetActiveEvent(CEvent * event) { + mapper.aevent=event; + mapper.redraw=true; + mapper.addbind=false; + bind_but.event_title->Change("EVENT:%s",event ? event->GetName(): "none"); + if (!event) { + bind_but.action->Change("Select an event to change"); + bind_but.add->Enable(false); + SetActiveBind(0); + } else { + mapper.abindit=event->bindlist.begin(); + if (mapper.abindit!=event->bindlist.end()) { + SetActiveBind(*(mapper.abindit)); + } else SetActiveBind(0); + bind_but.add->Enable(true); + } +} + +static void DrawButtons(void) { + SDL_FillRect(mapper.surface,0,0); + SDL_LockSurface(mapper.surface); + for (CButton_it but_it = buttons.begin();but_it!=buttons.end();but_it++) { + (*but_it)->Draw(); + } + SDL_UnlockSurface(mapper.surface); + SDL_Flip(mapper.surface); +} + +static void AddKeyButtonEvent(Bitu x,Bitu y,Bitu dx,Bitu dy,const char * title,const char * entry,KBD_KEYS key) { + char buf[64]; + strcpy(buf,"key_"); + strcat(buf,entry); + CKeyEvent * event=new CKeyEvent(buf,key); + CButton * button=new CEventButton(x,y,dx,dy,title,event); +} + +static void AddJAxisButton(Bitu x,Bitu y,Bitu dx,Bitu dy,const char * title,Bitu stick,bool yaxis,bool positive) { + char buf[64]; + sprintf(buf,"jaxis_%d%s%s",stick,yaxis ? "Y":"X",positive ? "+" : "-"); + CJAxisEvent * event=new CJAxisEvent(buf,stick,yaxis,positive); + CButton * button=new CEventButton(x,y,dx,dy,title,event); +} + +static void AddJButtonButton(Bitu x,Bitu y,Bitu dx,Bitu dy,const char * title,Bitu _stick,Bitu _button) { + char buf[64]; + sprintf(buf,"jbutton_%d_%d",_stick,_button); + CJButtonEvent * event=new CJButtonEvent(buf,_stick,_button); + CButton * button=new CEventButton(x,y,dx,dy,title,event); +} + + +static void AddModButton(Bitu x,Bitu y,Bitu dx,Bitu dy,const char * title,Bitu _mod) { + char buf[64]; + sprintf(buf,"mod_%d",_mod); + CModEvent * event=new CModEvent(buf,_mod); + CButton * button=new CEventButton(x,y,dx,dy,title,event); +} + +struct KeyBlock { + const char * title; + const char * entry; + KBD_KEYS key; +}; +static KeyBlock combo_f[12]={ + {"F1","f1",KBD_f1}, {"F2","f2",KBD_f2}, {"F3","f3",KBD_f3}, + {"F4","f4",KBD_f4}, {"F5","f5",KBD_f5}, {"F6","f6",KBD_f6}, + {"F7","f7",KBD_f7}, {"F8","f8",KBD_f8}, {"F9","f9",KBD_f9}, + {"F10","f10",KBD_f10}, {"F11","f11",KBD_f11}, {"F12","f12",KBD_f12}, +}; + +static KeyBlock combo_1[14]={ + {"`~","grave",KBD_grave}, {"1!","1",KBD_1}, {"2@","2",KBD_2}, + {"3#","3",KBD_3}, {"4$","4",KBD_4}, {"5%","5",KBD_5}, + {"6^","6",KBD_6}, {"7&","7",KBD_7}, {"8*","8",KBD_8}, + {"9(","9",KBD_9}, {"0)","0",KBD_0}, {"-_","minus",KBD_minus}, + {"=+","equals",KBD_equals}, {"\x1B","bspace",KBD_backspace}, +}; + +static KeyBlock combo_2[12]={ + {"q","q",KBD_q}, {"w","w",KBD_w}, {"e","e",KBD_e}, + {"r","r",KBD_r}, {"t","t",KBD_t}, {"y","y",KBD_y}, + {"u","u",KBD_u}, {"i","i",KBD_i}, {"o","o",KBD_o}, + {"p","p",KBD_p}, {"[","lbracket",KBD_leftbracket}, + {"]","rbracket",KBD_rightbracket}, +}; + +static KeyBlock combo_3[12]={ + {"a","a",KBD_a}, {"s","s",KBD_s}, {"d","d",KBD_d}, + {"f","f",KBD_f}, {"g","g",KBD_g}, {"h","h",KBD_h}, + {"j","j",KBD_j}, {"k","k",KBD_k}, {"l","l",KBD_l}, + {";","semicolon",KBD_semicolon}, {"'","quote",KBD_quote}, + {"\\","backslash",KBD_backslash}, +}; + +static KeyBlock combo_4[10]={ + {"z","z",KBD_z}, {"x","x",KBD_x}, {"c","c",KBD_c}, + {"v","v",KBD_v}, {"b","b",KBD_b}, {"n","n",KBD_n}, + {"m","m",KBD_m}, {",","comma",KBD_comma}, + {".","period",KBD_period}, {"/","slash",KBD_slash}, +}; + + +static void CreateLayout(void) { + Bitu i; + /* Create the buttons for the Keyboard */ +#define BW 28 +#define BH 20 +#define PX(_X_) ((_X_)*BW) +#define PY(_Y_) (30+(_Y_)*BH) + AddKeyButtonEvent(PX(0),PY(0),BW,BH,"ESC","esc",KBD_esc); + for (i=0;i<12;i++) AddKeyButtonEvent(PX(2+i),PY(0),BW,BH,combo_f[i].title,combo_f[i].entry,combo_f[i].key); + for (i=0;i<14;i++) AddKeyButtonEvent(PX( i),PY(1),BW,BH,combo_1[i].title,combo_1[i].entry,combo_1[i].key); + + AddKeyButtonEvent(PX(0),PY(2),BW*2,BH,"TAB","tab",KBD_tab); + for (i=0;i<12;i++) AddKeyButtonEvent(PX(2+i),PY(2),BW,BH,combo_2[i].title,combo_2[i].entry,combo_2[i].key); + + AddKeyButtonEvent(PX(14),PY(2),BW*2,BH*2,"ENTER","enter",KBD_enter); + + AddKeyButtonEvent(PX(0),PY(3),BW*2,BH,"CLCK","capslock",KBD_capslock); + for (i=0;i<12;i++) AddKeyButtonEvent(PX(2+i),PY(3),BW,BH,combo_3[i].title,combo_3[i].entry,combo_3[i].key); + + AddKeyButtonEvent(0,PY(4),BW*3,BH,"SHIFT","lshift",KBD_leftshift); + for (i=0;i<10;i++) AddKeyButtonEvent(PX(3+i),PY(4),BW,BH,combo_4[i].title,combo_4[i].entry,combo_4[i].key); + AddKeyButtonEvent(PX(13),PY(4),BW*3,BH,"SHIFT","rshift",KBD_rightshift); + + /* Last Row */ + AddKeyButtonEvent(PX(0) ,PY(5),BW*2,BH,"CTRL","lctrl",KBD_leftctrl); + AddKeyButtonEvent(PX(3) ,PY(5),BW*2,BH,"ALT","lalt",KBD_leftalt); + AddKeyButtonEvent(PX(5) ,PY(5),BW*6,BH,"SPACE","space",KBD_space); + AddKeyButtonEvent(PX(11),PY(5),BW*2,BH,"ALT","ralt",KBD_rightalt); + AddKeyButtonEvent(PX(14),PY(5),BW*2,BH,"CTRL","rctrl",KBD_rightctrl); + + /* Arrow Keys */ + AddKeyButtonEvent(PX(0),PY(7),BW,BH,"INS","insert",KBD_insert); + AddKeyButtonEvent(PX(1),PY(7),BW,BH,"HOM","home",KBD_home); + AddKeyButtonEvent(PX(2),PY(7),BW,BH,"PUP","pageup",KBD_pageup); + AddKeyButtonEvent(PX(0),PY(8),BW,BH,"DEL","delete",KBD_delete); + AddKeyButtonEvent(PX(1),PY(8),BW,BH,"END","end",KBD_end); + AddKeyButtonEvent(PX(2),PY(8),BW,BH,"PDN","pagedown",KBD_pagedown); + AddKeyButtonEvent(PX(1),PY(10),BW,BH,"\x18","up",KBD_up); + AddKeyButtonEvent(PX(0),PY(11),BW,BH,"\x1B","left",KBD_left); + AddKeyButtonEvent(PX(1),PY(11),BW,BH,"\x19","down",KBD_down); + AddKeyButtonEvent(PX(2),PY(11),BW,BH,"\x1A","right",KBD_right); + /* Numeric KeyPad */ + AddKeyButtonEvent(PX(4),PY(7),BW,BH,"NUM","numlock",KBD_numlock); + AddKeyButtonEvent(PX(5),PY(7),BW,BH,"/","kp_divide",KBD_kpdivide); + AddKeyButtonEvent(PX(6),PY(7),BW,BH,"*","kp_multiply",KBD_kpmultiply); + AddKeyButtonEvent(PX(7),PY(7),BW,BH,"-","kp_minus",KBD_kpminus); + AddKeyButtonEvent(PX(4),PY(8),BW,BH,"7","kp_7",KBD_kp7); + AddKeyButtonEvent(PX(5),PY(8),BW,BH,"8","kp_8",KBD_kp8); + AddKeyButtonEvent(PX(6),PY(8),BW,BH,"9","kp_9",KBD_kp9); + AddKeyButtonEvent(PX(7),PY(8),BW,BH*2,"+","kp_plus",KBD_kpplus); + AddKeyButtonEvent(PX(4),PY(9),BW,BH,"4","kp_4",KBD_kp4); + AddKeyButtonEvent(PX(5),PY(9),BW,BH,"5","kp_5",KBD_kp5); + AddKeyButtonEvent(PX(6),PY(9),BW,BH,"6","kp_6",KBD_kp6); + AddKeyButtonEvent(PX(4),PY(10),BW,BH,"1","kp_1",KBD_kp1); + AddKeyButtonEvent(PX(5),PY(10),BW,BH,"2","kp_2",KBD_kp2); + AddKeyButtonEvent(PX(6),PY(10),BW,BH,"3","kp_3",KBD_kp3); + AddKeyButtonEvent(PX(7),PY(10),BW,BH*2,"ENT","kp_enter",KBD_kpenter); + AddKeyButtonEvent(PX(4),PY(11),BW*2,BH,"0","kp_0",KBD_kp0); + AddKeyButtonEvent(PX(6),PY(11),BW,BH,".","kp_period",KBD_kpperiod); + + + /* Joystick Buttons/Texts */ + AddJButtonButton(PX(17),PY(0),BW,BH,"1" ,0,0); + AddJAxisButton (PX(18),PY(0),BW,BH,"Y-",0,true,false); + AddJButtonButton(PX(19),PY(0),BW,BH,"2" ,0,1); + AddJAxisButton (PX(17),PY(1),BW,BH,"X-",0,false,false); + AddJAxisButton (PX(18),PY(1),BW,BH,"Y+",0,true,true); + AddJAxisButton (PX(19),PY(1),BW,BH,"X+",0,false,true); + + AddJButtonButton(PX(17),PY(3),BW,BH,"1" ,1,0); + AddJAxisButton (PX(18),PY(3),BW,BH,"Y-",1,true,false); + AddJButtonButton(PX(19),PY(3),BW,BH,"2" ,1,1); + AddJAxisButton (PX(17),PY(4),BW,BH,"X-",1,false,false); + AddJAxisButton (PX(18),PY(4),BW,BH,"Y+",1,true,true); + AddJAxisButton (PX(19),PY(4),BW,BH,"X+",1,false,true); /* The modifier buttons */ + AddModButton(PX(0),PY(13),50,20,"Mod1",1); + AddModButton(PX(2),PY(13),50,20,"Mod2",2); + AddModButton(PX(4),PY(13),50,20,"Mod3",3); + /* Create Handler buttons */ + Bitu xpos=3;Bitu ypos=7; + for (CHandlerEventVector_it hit=handlergroup.begin();hit!=handlergroup.end();hit++) { + new CEventButton(PX(xpos*3),PY(ypos),BW*3,BH,(*hit)->ButtonName(),(*hit)); + xpos++; + if (xpos>6) { + xpos=3;ypos++; + } + } + /* Create some text buttons */ + new CTextButton(200,00,124,20,"Keyboard Layout"); + + bind_but.action=new CCaptionButton(200,330,0,0); + + bind_but.event_title=new CCaptionButton(0,350,0,0); + bind_but.bind_title=new CCaptionButton(00,365,0,0); + + /* Create binding support buttons */ + + bind_but.mod1=new CCheckButton(20,410,60,20, "mod1",BC_Mod1); + bind_but.mod2=new CCheckButton(20,432,60,20, "mod2",BC_Mod2); + bind_but.mod3=new CCheckButton(20,454,60,20, "mod3",BC_Mod3); + bind_but.hold=new CCheckButton(100,410,60,20,"hold",BC_Hold); + + bind_but.prev=new CBindButton(200,400,50,20,"Prev",BB_Prev); + bind_but.next=new CBindButton(250,400,50,20,"Next",BB_Next); + + bind_but.add=new CBindButton(250,380,50,20,"Add",BB_Add); + bind_but.del=new CBindButton(300,380,50,20,"Del",BB_Del); + + bind_but.save=new CBindButton(400,450,50,20,"Save",BB_Save); + + bind_but.bind_title->Change("Bind Title"); +} + +static SDL_Color map_pal[4]={ + {0x00,0x00,0x00,0x00}, //0=black + {0xff,0xff,0xff,0x00}, //1=white + {0xff,0x00,0x00,0x00}, //2=red +}; + +static void CreateStringBind(char * line) { + line=trim(line); + char * eventname=StripWord(line); + CEvent * event; + for (CEventVector_it ev_it=events.begin();ev_it!=events.end();ev_it++) { + if (!strcasecmp((*ev_it)->GetName(),eventname)) { + event=*ev_it; + goto foundevent; + } + } + LOG_MSG("Can't find matching event for %s",eventname); + return ; +foundevent: + CBind * bind; + for (char * bindline=StripWord(line);*bindline;bindline=StripWord(line)) { + for (CBindGroup_it it=bindgroups.begin();it!=bindgroups.end();it++) { + bind=(*it)->CreateConfigBind(bindline); + if (bind) { + event->AddBind(bind); + bind->SetFlags(bindline); + break; + } + } + } +} + +static struct { + char * eventend; + Bitu key; +} DefaultKeys[]={ + {"f1",SDLK_F1}, {"f2",SDLK_F2}, {"f3",SDLK_F3}, {"f4",SDLK_F4}, + {"f5",SDLK_F1}, {"f6",SDLK_F6}, {"f7",SDLK_F7}, {"f8",SDLK_F8}, + {"f9",SDLK_F9}, {"f10",SDLK_F10}, {"f11",SDLK_F11}, {"f12",SDLK_F12}, + + {"1",SDLK_1}, {"2",SDLK_2}, {"3",SDLK_3}, {"4",SDLK_4}, + {"5",SDLK_5}, {"6",SDLK_6}, {"7",SDLK_7}, {"8",SDLK_8}, + {"9",SDLK_9}, {"0",SDLK_0}, + + {"a",SDLK_a}, {"b",SDLK_b}, {"c",SDLK_c}, {"d",SDLK_d}, + {"e",SDLK_e}, {"f",SDLK_f}, {"g",SDLK_g}, {"h",SDLK_h}, + {"i",SDLK_i}, {"j",SDLK_j}, {"k",SDLK_k}, {"l",SDLK_l}, + {"m",SDLK_m}, {"n",SDLK_n}, {"o",SDLK_o}, {"p",SDLK_p}, + {"q",SDLK_q}, {"r",SDLK_r}, {"s",SDLK_s}, {"t",SDLK_t}, + {"u",SDLK_u}, {"v",SDLK_v}, {"w",SDLK_w}, {"x",SDLK_x}, + {"y",SDLK_y}, {"z",SDLK_z}, {"space",SDLK_SPACE}, + {"esc",SDLK_ESCAPE}, {"equals",SDLK_EQUALS}, {"grave",SDLK_BACKQUOTE}, + {"tab",SDLK_TAB}, {"enter",SDLK_RETURN}, {"bspace",SDLK_BACKSPACE}, + {"lbracket",SDLK_LEFTBRACKET}, {"rbracket",SDLK_RIGHTBRACKET}, + {"minus",SDLK_MINUS}, {"capslock",SDLK_CAPSLOCK}, {"semicolon",SDLK_SEMICOLON}, + {"quote", SDLK_QUOTE}, {"backslash",SDLK_BACKSLASH}, {"lshift",SDLK_LSHIFT}, + {"rshift",SDLK_RSHIFT}, {"lalt",SDLK_LALT}, {"ralt",SDLK_RALT}, + {"lctrl",SDLK_LCTRL}, {"rctrl",SDLK_RCTRL}, {"comma",SDLK_COMMA}, + {"period",SDLK_PERIOD}, {"slash",SDLK_SLASH}, {"pagedown",SDLK_PAGEDOWN}, + {"pageup",SDLK_PAGEUP}, {"insert",SDLK_INSERT}, {"home",SDLK_HOME}, + {"delete",SDLK_DELETE}, {"end",SDLK_END}, {"up",SDLK_UP}, + {"left",SDLK_LEFT}, {"down",SDLK_DOWN}, {"right",SDLK_RIGHT}, + {"kp_0",SDLK_KP0}, {"kp_1",SDLK_KP1}, {"kp_2",SDLK_KP2}, {"kp_3",SDLK_KP3}, + {"kp_4",SDLK_KP4}, {"kp_5",SDLK_KP5}, {"kp_6",SDLK_KP6}, {"kp_7",SDLK_KP7}, + {"kp_8",SDLK_KP8}, {"kp_9",SDLK_KP9}, {"numlock",SDLK_NUMLOCK}, + {"kp_divide",SDLK_KP_DIVIDE}, {"kp_multiply",SDLK_KP_MULTIPLY}, + {"kp_minus",SDLK_KP_MINUS}, {"kp_plus",SDLK_KP_PLUS}, + {"kp_period",SDLK_KP_PERIOD}, {"kp_enter",SDLK_KP_ENTER}, + {0,0} +}; + +static void CreateDefaultBinds(void) { + char buffer[512]; + Bitu i=0; + while (DefaultKeys[i].eventend) { + sprintf(buffer,"key_%s \"key %d\"",DefaultKeys[i].eventend,DefaultKeys[i].key); + CreateStringBind(buffer); + i++; + } + sprintf(buffer,"mod_1 \"key %d\"",SDLK_RCTRL);CreateStringBind(buffer); + sprintf(buffer,"mod_1 \"key %d\"",SDLK_LCTRL);CreateStringBind(buffer); + sprintf(buffer,"mod_2 \"key %d\"",SDLK_LALT);CreateStringBind(buffer); + for (CHandlerEventVector_it hit=handlergroup.begin();hit!=handlergroup.end();hit++) { + (*hit)->MakeDefaultBind(buffer); + CreateStringBind(buffer); + } +} + +void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char * eventname,char * buttonname) { + char tempname[17]; + strcpy(tempname,"hand_"); + strcat(tempname,eventname); + new CHandlerEvent(tempname,handler,key,mods,buttonname); +} + +static void MAPPER_SaveBinds(void) { + FILE * savefile=fopen(mapper.filename,"wb+"); + if (!savefile) { + LOG_MSG("Can't open %s for saving the mappings",mapper.filename); + return; + } + char buf[128]; + for (CEventVector_it event_it=events.begin();event_it!=events.end();event_it++) { + CEvent * event=*(event_it); + fprintf(savefile,"%s ",event->GetName()); + for (CBindList_it bind_it=event->bindlist.begin();bind_it!=event->bindlist.end();bind_it++) { + CBind * bind=*(bind_it); + bind->ConfigName(buf); + bind->AddFlags(buf); + fprintf(savefile,"\"%s\" ",buf); + } + fprintf(savefile,"\n"); + } + fclose(savefile); +} + +static bool MAPPER_LoadBinds(void) { + FILE * loadfile=fopen(mapper.filename,"rb+"); + if (!loadfile) return false; + char linein[512]; + while (fgets(linein,512,loadfile)) { + CreateStringBind(linein); + } + fclose(loadfile); + return true; +} + +void MAPPER_CheckEvent(SDL_Event * event) { + for (CBindGroup_it it=bindgroups.begin();it!=bindgroups.end();it++) { + if ((*it)->CheckEvent(event)) return; + } +} + +void BIND_MappingEvents(void) { + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_MOUSEBUTTONDOWN: + /* Check the press */ + for (CButton_it but_it = buttons.begin();but_it!=buttons.end();but_it++) { + if ((*but_it)->OnTop(event.button.x,event.button.y)) { + (*but_it)->Click(); + } + } + break; + case SDL_QUIT: + mapper.exit=true; + break; + default: + if (mapper.addbind) for (CBindGroup_it it=bindgroups.begin();it!=bindgroups.end();it++) { + CBind * newbind=(*it)->CreateEventBind(&event); + if (!newbind) continue; + mapper.aevent->AddBind(newbind); + SetActiveEvent(mapper.aevent); + mapper.addbind=false; + break; + } + } + } +} + +static void CreateBindGroups(void) { + bindgroups.clear(); + new CKeyBindGroup(SDLK_LAST); + Bitu numsticks=SDL_NumJoysticks(); + if (numsticks) SDL_JoystickEventState(SDL_ENABLE); + for (Bitu i=0;iDeActivateAll(); + } + mapper.surface=SDL_SetVideoMode(640,480,8,0); + /* Set some palette entries */ + SDL_SetPalette(mapper.surface, SDL_LOGPAL|SDL_PHYSPAL, map_pal, 0, 4); + /* Go in the event loop */ + mapper.exit=false; + mapper.redraw=true; + SetActiveEvent(0); + while (!mapper.exit) { + if (mapper.redraw) { + mapper.redraw=false; + DrawButtons(); + } + BIND_MappingEvents(); + SDL_Delay(1); + } + GFX_ResetScreen(); +} + +void MAPPER_Init(void) { + CreateLayout(); + CreateBindGroups(); + if (!MAPPER_LoadBinds()) CreateDefaultBinds(); +} + +void MAPPER_StartUp(Section * sec) { + Section_prop * section=static_cast(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 95c04792..e02e4525 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.65 2004-06-05 11:17:23 qbix79 Exp $ */ +/* $Id: sdlmain.cpp,v 1.66 2004-06-10 07:18:19 harekiet Exp $ */ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -32,14 +32,13 @@ #include "dosbox.h" #include "video.h" -#include "keyboard.h" #include "mouse.h" -#include "joystick.h" #include "pic.h" #include "timer.h" #include "setup.h" #include "support.h" #include "debug.h" +#include "mapper.h" //#define DISABLE_JOYSTICK @@ -104,6 +103,9 @@ extern char** environ; #define DEFAULT_CONFIG_FILE "/.dosboxrc" #endif +void MAPPER_Init(void); +void MAPPER_StartUp(Section * sec); + enum SCREEN_TYPES { SCREEN_SURFACE, SCREEN_OVERLAY, @@ -117,7 +119,8 @@ struct SDL_Block { struct { Bit32u width; Bit32u height; - Bitu bpp; + Bitu flags; + GFX_Modes mode; double scalex,scaley; GFX_ResetCallBack reset; } draw; @@ -149,7 +152,6 @@ struct SDL_Block { SDL_Rect clip; SDL_Surface * surface; SDL_Overlay * overlay; - SDL_Joystick * joy; SDL_cond *cond; struct { bool autolock; @@ -163,45 +165,63 @@ struct SDL_Block { static SDL_Block sdl; static void CaptureMouse(void); +extern const char * RunningProgram; void GFX_SetTitle(Bits cycles,Bits frameskip){ 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; - sprintf(title,"DOSBox %s, Cpu Cycles: %8d, Frameskip %2d",VERSION,internal_cycles,internal_frameskip); + sprintf(title,"DOSBox %s,Cpu Cycles: %8d, Frameskip %2d, Program: %s",VERSION,internal_cycles,internal_frameskip,RunningProgram); SDL_WM_SetCaption(title,VERSION); } /* Reset the screen with current values in the sdl structure */ -Bitu GFX_GetBestMode(Bitu bpp,Bitu & gfx_flags) { - gfx_flags=0; +Bitu GFX_GetBestMode(Bitu flags) { + Bitu testbpp,gotbpp,setflags; switch (sdl.desktop.want_type) { case SCREEN_SURFACE: - if (sdl.desktop.fullscreen) { - bpp=SDL_VideoModeOK(640,480,bpp,SDL_FULLSCREEN|SDL_HWSURFACE | - (sdl.desktop.doublebuf ? SDL_DOUBLEBUF : 0) | ((bpp==8) ? SDL_HWPALETTE : 0) ); - } else { - bpp=sdl.desktop.bpp; +check_surface: + /* Check if we can satisfy the depth it loves */ + if (flags & LOVE_8) testbpp=8; + else if (flags & LOVE_16) testbpp=16; + else if (flags & LOVE_32) testbpp=32; + 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: + if (flags & CAN_8) flags&=~(CAN_16|CAN_32); + break; + case 15: + case 16: + if (flags & CAN_16) flags&=~(CAN_8|CAN_32); + break; + case 24: + case 32: + if (flags & CAN_32) flags&=~(CAN_8|CAN_16); + break; } - gfx_flags|=GFX_HASCONVERT; + /* Not a valid display depth found? Let's just hope sdl provides conversions */ break; case SCREEN_OVERLAY: - bpp=32; - gfx_flags|=GFX_HASSCALING; + if (flags & NEED_RGB || !(flags&CAN_32)) goto check_surface; + flags|=HAVE_SCALING; + flags&=~(CAN_8,CAN_16); break; #if C_OPENGL case SCREEN_OPENGL: - bpp=32; - gfx_flags|=GFX_HASSCALING; + if (flags & NEED_RGB || !(flags&CAN_32)) goto check_surface; + flags|=HAVE_SCALING; + flags&=~(CAN_8,CAN_16); break; #endif } - return bpp; + return flags; } -static void ResetScreen(void) { +void GFX_ResetScreen(void) { GFX_Stop(); if (sdl.draw.reset) (sdl.draw.reset)(); GFX_Start(); @@ -214,18 +234,23 @@ static int int_log2 (int val) { return log; } -void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,double scalex,double scaley,GFX_ResetCallBack reset) { +GFX_Modes GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_ResetCallBack reset) { if (sdl.updating) GFX_EndUpdate(); sdl.draw.width=width; sdl.draw.height=height; - sdl.draw.bpp=bpp; + sdl.draw.flags=flags; + sdl.draw.mode=GFX_NONE; sdl.draw.reset=reset; sdl.draw.scalex=scalex; sdl.draw.scaley=scaley; + Bitu bpp; switch (sdl.desktop.want_type) { case SCREEN_SURFACE: dosurface: + if (flags & CAN_8) bpp=8; + if (flags & CAN_16) bpp=16; + if (flags & CAN_32) bpp=32; sdl.desktop.type=SCREEN_SURFACE; sdl.clip.w=width; sdl.clip.h=height; @@ -234,21 +259,29 @@ dosurface: sdl.clip.x=(Sint16)((sdl.desktop.width-width)/2); sdl.clip.y=(Sint16)((sdl.desktop.height-height)/2); sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,bpp, - SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF : 0)|SDL_HWPALETTE); + SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE); } else { sdl.clip.x=0;sdl.clip.y=0; sdl.surface=SDL_SetVideoMode(width,height,bpp, - SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF : 0)|SDL_HWPALETTE); + SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE); } } else { sdl.clip.x=0;sdl.clip.y=0; sdl.surface=SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE); } + if (sdl.surface) switch (sdl.surface->format->BitsPerPixel) { + case 8:sdl.draw.mode=GFX_8;break; + case 15:sdl.draw.mode=GFX_15;break; + case 16:sdl.draw.mode=GFX_16;break; + case 32:sdl.draw.mode=GFX_32;break; + default: + break; + } break; case SCREEN_OVERLAY: if (sdl.overlay) SDL_FreeYUVOverlay(sdl.overlay); sdl.overlay=0; - if (bpp!=32) goto dosurface; + if (!(flags&CAN_32) || (flags & NEED_RGB)) goto dosurface; if (sdl.desktop.fullscreen) { if (sdl.desktop.fixed) { double ratio_w=(double)sdl.desktop.width/(width*scalex); @@ -283,6 +316,7 @@ dosurface: goto dosurface; } sdl.desktop.type=SCREEN_OVERLAY; + sdl.draw.mode=GFX_32; break; #if C_OPENGL case SCREEN_OPENGL: @@ -295,7 +329,7 @@ dosurface: free(sdl.opengl.framebuf); } sdl.opengl.framebuf=0; - if (bpp!=32) goto dosurface; + if (!(flags&CAN_32) || (flags & NEED_RGB)) goto dosurface; 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); @@ -368,6 +402,8 @@ dosurface: glClearColor (0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); + SDL_GL_SwapBuffers(); + glClear(GL_COLOR_BUFFER_BIT); glShadeModel (GL_FLAT); glDisable (GL_DEPTH_TEST); glDisable (GL_LIGHTING); @@ -395,11 +431,13 @@ dosurface: glEnd(); glEndList(); sdl.desktop.type=SCREEN_OPENGL; + sdl.draw.mode=GFX_32; break; }//OPENGL #endif //C_OPENGL }//CASE - GFX_Start(); + if (sdl.draw.mode!=GFX_NONE) GFX_Start(); + return sdl.draw.mode; } @@ -421,7 +459,7 @@ static void SwitchFullScreen(void) { } else { if (sdl.mouse.locked) CaptureMouse(); } - ResetScreen(); + GFX_ResetScreen(); } void GFX_SwitchFullScreen(void) { @@ -630,14 +668,11 @@ static void GUI_StartUp(Section * sec) { if (sdl.desktop.bpp==24) { LOG_MSG("SDL:You are running in 24 bpp mode, this will slow down things!"); } - GFX_SetSize(640,400,8,1.0,1.0,0); - SDL_EnableKeyRepeat(250,40); - SDL_EnableUNICODE(1); -/* Get some Keybinds */ - KEYBOARD_AddEvent(KBD_f9,KBD_MOD_CTRL,KillSwitch); - KEYBOARD_AddEvent(KBD_f10,KBD_MOD_CTRL,CaptureMouse); - KEYBOARD_AddEvent(KBD_enter,KBD_MOD_ALT,SwitchFullScreen); - + 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"); } void Mouse_AutoLock(bool enable) { @@ -646,143 +681,6 @@ void Mouse_AutoLock(bool enable) { else sdl.mouse.requestlock=false; } -static void HandleKey(SDL_KeyboardEvent * key) { - KBD_KEYS code; - switch (key->keysym.sym) { - case SDLK_1:code=KBD_1;break; - case SDLK_2:code=KBD_2;break; - case SDLK_3:code=KBD_3;break; - case SDLK_4:code=KBD_4;break; - case SDLK_5:code=KBD_5;break; - case SDLK_6:code=KBD_6;break; - case SDLK_7:code=KBD_7;break; - case SDLK_8:code=KBD_8;break; - case SDLK_9:code=KBD_9;break; - case SDLK_0:code=KBD_0;break; - - case SDLK_q:code=KBD_q;break; - case SDLK_w:code=KBD_w;break; - case SDLK_e:code=KBD_e;break; - case SDLK_r:code=KBD_r;break; - case SDLK_t:code=KBD_t;break; - case SDLK_y:code=KBD_y;break; - case SDLK_u:code=KBD_u;break; - case SDLK_i:code=KBD_i;break; - case SDLK_o:code=KBD_o;break; - case SDLK_p:code=KBD_p;break; - - case SDLK_a:code=KBD_a;break; - case SDLK_s:code=KBD_s;break; - case SDLK_d:code=KBD_d;break; - case SDLK_f:code=KBD_f;break; - case SDLK_g:code=KBD_g;break; - case SDLK_h:code=KBD_h;break; - case SDLK_j:code=KBD_j;break; - case SDLK_k:code=KBD_k;break; - case SDLK_l:code=KBD_l;break; - - case SDLK_z:code=KBD_z;break; - case SDLK_x:code=KBD_x;break; - case SDLK_c:code=KBD_c;break; - case SDLK_v:code=KBD_v;break; - case SDLK_b:code=KBD_b;break; - case SDLK_n:code=KBD_n;break; - case SDLK_m:code=KBD_m;break; - - - case SDLK_F1:code=KBD_f1;break; - case SDLK_F2:code=KBD_f2;break; - case SDLK_F3:code=KBD_f3;break; - case SDLK_F4:code=KBD_f4;break; - case SDLK_F5:code=KBD_f5;break; - case SDLK_F6:code=KBD_f6;break; - case SDLK_F7:code=KBD_f7;break; - case SDLK_F8:code=KBD_f8;break; - case SDLK_F9:code=KBD_f9;break; - case SDLK_F10:code=KBD_f10;break; - case SDLK_F11:code=KBD_f11;break; - case SDLK_F12:code=KBD_f12;break; - - case SDLK_ESCAPE:code=KBD_esc;break; - case SDLK_TAB:code=KBD_tab;break; - case SDLK_BACKSPACE:code=KBD_backspace;break; - case SDLK_RETURN:code=KBD_enter;break; - case SDLK_SPACE:code=KBD_space;break; - - case SDLK_LALT:code=KBD_leftalt;break; - case SDLK_RALT:code=KBD_rightalt;break; - case SDLK_LCTRL:code=KBD_leftctrl;break; - case SDLK_RCTRL:code=KBD_rightctrl;break; - case SDLK_LSHIFT:code=KBD_leftshift;break; - case SDLK_RSHIFT:code=KBD_rightshift;break; - - case SDLK_CAPSLOCK:code=KBD_capslock;break; - case SDLK_SCROLLOCK:code=KBD_scrolllock;break; - case SDLK_NUMLOCK:code=KBD_numlock;break; - - case SDLK_BACKQUOTE:code=KBD_grave;break; - case SDLK_MINUS:code=KBD_minus;break; - case SDLK_EQUALS:code=KBD_equals;break; - case SDLK_BACKSLASH:code=KBD_backslash;break; - case SDLK_LEFTBRACKET:code=KBD_leftbracket;break; - case SDLK_RIGHTBRACKET:code=KBD_rightbracket;break; - - case SDLK_SEMICOLON:code=KBD_semicolon;break; - case SDLK_QUOTE:code=KBD_quote;break; - case SDLK_PERIOD:code=KBD_period;break; - case SDLK_COMMA:code=KBD_comma;break; - case SDLK_SLASH:code=KBD_slash;break; - - case SDLK_INSERT:code=KBD_insert;break; - case SDLK_HOME:code=KBD_home;break; - case SDLK_PAGEUP:code=KBD_pageup;break; - case SDLK_DELETE:code=KBD_delete;break; - case SDLK_END:code=KBD_end;break; - case SDLK_PAGEDOWN:code=KBD_pagedown;break; - case SDLK_LEFT:code=KBD_left;break; - case SDLK_UP:code=KBD_up;break; - case SDLK_DOWN:code=KBD_down;break; - case SDLK_RIGHT:code=KBD_right;break; - - case SDLK_KP1:code=KBD_kp1;break; - case SDLK_KP2:code=KBD_kp2;break; - case SDLK_KP3:code=KBD_kp3;break; - case SDLK_KP4:code=KBD_kp4;break; - case SDLK_KP5:code=KBD_kp5;break; - case SDLK_KP6:code=KBD_kp6;break; - case SDLK_KP7:code=KBD_kp7;break; - case SDLK_KP8:code=KBD_kp8;break; - case SDLK_KP9:code=KBD_kp9;break; - case SDLK_KP0:code=KBD_kp0;break; - - case SDLK_KP_DIVIDE:code=KBD_kpslash;break; - case SDLK_KP_MULTIPLY:code=KBD_kpmultiply;break; - case SDLK_KP_MINUS:code=KBD_kpminus;break; - case SDLK_KP_PLUS:code=KBD_kpplus;break; - case SDLK_KP_ENTER:code=KBD_kpenter;break; - case SDLK_KP_PERIOD:code=KBD_kpperiod;break; - - /* Special Keys */ - default: - code=KBD_1; - LOG(LOG_KEYBOARD,LOG_ERROR)("Unhandled SDL keysym %d",key->keysym.sym); - break; - } - /* Check the modifiers */ - Bitu mod= - ((key->keysym.mod & KMOD_CTRL) ? KBD_MOD_CTRL : 0) | - ((key->keysym.mod & KMOD_ALT) ? KBD_MOD_ALT : 0) | - ((key->keysym.mod & KMOD_SHIFT) ? KBD_MOD_SHIFT : 0); - Bitu ascii=key->keysym.unicode<128 ? key->keysym.unicode : 0; -#ifdef MACOSX - // HACK: Fix backspace on Mac OS X - // REMOVE ME oneday - if (code==KBD_backspace) - ascii=8; -#endif - KEYBOARD_AddKey(code,ascii,mod,(key->state==SDL_PRESSED)); -} - static void HandleMouseMotion(SDL_MouseMotionEvent * motion) { if (sdl.mouse.locked) Mouse_CursorMoved((float)motion->xrel*sdl.mouse.sensitivity/100,(float)motion->yrel*sdl.mouse.sensitivity/100); @@ -824,30 +722,7 @@ static void HandleMouseButton(SDL_MouseButtonEvent * button) { } } -static void HandleJoystickAxis(SDL_JoyAxisEvent * jaxis) { - switch (jaxis->axis) { - case 0: - JOYSTICK_Move_X(0,(float)(jaxis->value/32768.0)); - break; - case 1: - JOYSTICK_Move_Y(0,(float)(jaxis->value/32768.0)); - break; - } -} - -static void HandleJoystickButton(SDL_JoyButtonEvent * jbutton) { - bool state; - state=jbutton->type==SDL_JOYBUTTONDOWN; - if (jbutton->button<2) { - JOYSTICK_Button(0,jbutton->button,state); - } -} - - -static Bit8u laltstate = SDL_KEYUP; - void GFX_Events() { - SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { @@ -858,13 +733,6 @@ void GFX_Events() { } } break; - case SDL_KEYDOWN: - case SDL_KEYUP: - // ignore event lalt+tab - if (event.key.keysym.sym==SDLK_LALT) laltstate = event.key.type; - if ((event.key.keysym.sym==SDLK_TAB) && (laltstate==SDL_KEYDOWN)) break; - HandleKey(&event.key); - break; case SDL_MOUSEMOTION: HandleMouseMotion(&event.motion); break; @@ -872,19 +740,15 @@ void GFX_Events() { case SDL_MOUSEBUTTONUP: HandleMouseButton(&event.button); break; - case SDL_JOYAXISMOTION: - HandleJoystickAxis(&event.jaxis); - break; - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - HandleJoystickButton(&event.jbutton); - break; case SDL_VIDEORESIZE: // HandleVideoResize(&event.resize); break; case SDL_QUIT: throw(0); break; + default: + void MAPPER_CheckEvent(SDL_Event * event); + MAPPER_CheckEvent(&event); } } } @@ -931,11 +795,9 @@ int main(int argc, char* argv[]) { } } #endif //defined(WIN32) && !(C_DEBUG) - #if C_DEBUG DEBUG_SetupConsole(); #endif - if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM #ifndef DISABLE_JOYSTICK |SDL_INIT_JOYSTICK @@ -943,6 +805,7 @@ int main(int argc, char* argv[]) { #endif ) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError()); Section_prop * sdl_sec=control->AddSection_prop("sdl",&GUI_StartUp); + sdl_sec->AddInitFunction(&MAPPER_StartUp); sdl_sec->Add_bool("fullscreen",false); sdl_sec->Add_bool("fulldouble",false); sdl_sec->Add_bool("fullfixed",false); @@ -953,6 +816,7 @@ int main(int argc, char* argv[]) { sdl_sec->Add_bool("autolock",true); sdl_sec->Add_int("sensitivity",100); sdl_sec->Add_bool("waitonerror",true); + sdl_sec->Add_string("mapperfile","mapper.txt"); MSG_Add("SDL_CONFIGFILE_HELP", "fullscreen -- Start dosbox directly in fullscreen.\n" @@ -996,19 +860,12 @@ int main(int argc, char* argv[]) { /* Init all the sections */ control->Init(); /* Some extra SDL Functions */ -#ifndef DISABLE_JOYSTICK - if (SDL_NumJoysticks()>0) { - SDL_JoystickEventState(SDL_ENABLE); - sdl.joy=SDL_JoystickOpen(0); - LOG_MSG("Using joystick %s with %d axes and %d buttons",SDL_JoystickName(0),SDL_JoystickNumAxes(sdl.joy),SDL_JoystickNumButtons(sdl.joy)); - JOYSTICK_Enable(0,true); - } -#endif if (control->cmdline->FindExist("-fullscreen") || sdl_sec->Get_bool("fullscreen")) { if(!sdl.desktop.fullscreen) { //only switch if not allready in fullscreen SwitchFullScreen(); } } + MAPPER_Init(); /* Start up main machine */ control->StartUp(); /* Shutdown everything */