From c156efb73dcd7b3456126b450998749a270f8986 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 10 Jul 2006 21:03:59 +0000 Subject: [PATCH 001/241] SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%401937 From 96afe9541cfba0883604dadd879533ca870e2e87 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 10 Jul 2006 21:23:11 +0000 Subject: [PATCH 002/241] Updated the snapshot build target to reflect the new source location --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%401939 --- Makefile.in | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Makefile.in b/Makefile.in index 4795229db..d7acd2547 100644 --- a/Makefile.in +++ b/Makefile.in @@ -169,10 +169,9 @@ rpm: $(distfile) # Create a SVN snapshot that people can run update on snapshot: - svn co svn://libsdl.org/trunk/SDL - (cd SDL && ./autogen.sh && rm -rf autom4te.cache) - cp SDL/include/SDL_config.h.default SDL/include/SDL_config.h - mv SDL SDL-1.2 + svn co svn://libsdl.org/branches/SDL-1.2 + (cd SDL-1.2 && ./autogen.sh && rm -rf autom4te.cache) + cp SDL-1.2/include/SDL_config.h.default SDL-1.2/include/SDL_config.h tar zcf $(HOME)/SDL-1.2.tar.gz SDL-1.2 rm -f $(HOME)/SDL-1.2.zip zip -r $(HOME)/SDL-1.2.zip SDL-1.2 From ce0491587b8addf4bce520d99feaa9bccbfd7383 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 24 Jul 2006 23:29:01 +0000 Subject: [PATCH 003/241] Patched to compile. Fixes Bugzilla #285. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%401980 --- src/video/qtopia/SDL_sysvideo.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/qtopia/SDL_sysvideo.cc b/src/video/qtopia/SDL_sysvideo.cc index c556d79d3..193ade460 100644 --- a/src/video/qtopia/SDL_sysvideo.cc +++ b/src/video/qtopia/SDL_sysvideo.cc @@ -227,8 +227,8 @@ extern "C" { desktop_size.height(), desktop_size.width()); /* Determine the current screen size */ - this->info.current_w = desktop_size.width(); - this->info.current_h = desktop_size.height(); + _this->info.current_w = desktop_size.width(); + _this->info.current_h = desktop_size.height(); /* Create the window / widget */ SDL_Win = new SDL_QWin(QSize(QT_HIDDEN_SIZE, QT_HIDDEN_SIZE)); From d5e84bbf7cc2a41a993b2316a004bdd274cd5cd3 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 2 Aug 2006 21:26:31 +0000 Subject: [PATCH 004/241] Add teamtap support (4 joypads adapter on 1 port) --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402010 --- README.MiNT | 6 +- src/joystick/mint/SDL_sysjoystick.c | 166 ++++++++++++++++++---------- 2 files changed, 111 insertions(+), 61 deletions(-) diff --git a/README.MiNT b/README.MiNT index 25a7d5658..b258065be 100644 --- a/README.MiNT +++ b/README.MiNT @@ -127,12 +127,12 @@ SDL_JOYSTICK_ATARI: 'ikbd-joy1-[on|off]' for IKBD joystick on port 1 (hardware access) 'xbios-joy1-[on|off]' for IKBD joystick on port 1 (xbios access) - 'porta-pad-[on|off]' for joypad on port A + 'porta-pad-[on|off]' for joypad and/or teamtap on port A 'porta-joy0-[on|off]' for joystick 0 on port A 'porta-joy1-[on|off]' for joystick 1 on port A 'porta-lp-[on|off]' for lightpen on port A 'porta-anpad-[on|off]' for analog paddle on port A - 'portb-pad-[on|off]' for joypad on port B + 'portb-pad-[on|off]' for joypad and/or teamtap on port B 'portb-joy0-[on|off]' for joystick 0 on port B 'portb-joy1-[on|off]' for joystick 1 on port B 'portb-anpad-[on|off]' for analog paddle on port B @@ -213,7 +213,7 @@ Mouse and joystick xbios driver: Available on all machines (I think). Joypad driver: - Available if _MCH cookie is STE or Falcon. + Available if _MCH cookie is STE or Falcon. Supports teamtap. PTH timer driver: Available with multitasking OS. diff --git a/src/joystick/mint/SDL_sysjoystick.c b/src/joystick/mint/SDL_sysjoystick.c index 0a129fe81..364e568b3 100644 --- a/src/joystick/mint/SDL_sysjoystick.c +++ b/src/joystick/mint/SDL_sysjoystick.c @@ -44,19 +44,28 @@ /* We can have: 1 joystick on IKBD port 1, read via hardware I/O - or same joystick on IKBD port 1, read via xbios - 2 joypads on ports A,B - or 4 joysticks on joypads ports A,B + or same joystick on IKBD port 1, read via xbios + 1 joypad on port A (up to 4 with teamtap) + or 2 joysticks on joypad port A + or 1 analog paddle on joypad port A or 1 lightpen on joypad port A - or 2 analog paddles on joypads ports A,B + 1 joypad on port B (up to 4 with teamtap) + or 2 joysticks on joypad port B + or 1 analog paddle on joypad port B 2 joysticks on parallel port */ enum { IKBD_JOY1=0, XBIOS_JOY1, - PORTA_PAD, - PORTB_PAD, + PORTA_PAD0, + PORTA_PAD1, + PORTA_PAD2, + PORTA_PAD3, + PORTB_PAD0, + PORTB_PAD1, + PORTB_PAD2, + PORTB_PAD3, PORTA_JOY0, PORTA_JOY1, PORTB_JOY0, @@ -116,8 +125,14 @@ typedef struct { static atarijoy_t atarijoysticks[MAX_JOYSTICKS]={ {SDL_FALSE,"IKBD joystick port 1",0}, {SDL_FALSE,"Xbios joystick port 1",0}, - {SDL_FALSE,"Joypad port A",0}, - {SDL_FALSE,"Joypad port B",0}, + {SDL_FALSE,"Joypad 0 port A",0}, + {SDL_FALSE,"Joypad 1 port A",0}, + {SDL_FALSE,"Joypad 2 port A",0}, + {SDL_FALSE,"Joypad 3 port A",0}, + {SDL_FALSE,"Joypad 0 port B",0}, + {SDL_FALSE,"Joypad 1 port B",0}, + {SDL_FALSE,"Joypad 2 port B",0}, + {SDL_FALSE,"Joypad 3 port B",0}, {SDL_FALSE,"Joystick 0 port A",0}, {SDL_FALSE,"Joystick 1 port A",0}, {SDL_FALSE,"Joystick 0 port B",0}, @@ -146,7 +161,7 @@ static Uint16 jp_paddles[4]; static Uint16 jp_lightpens[2]; static Uint16 jp_directions; static Uint16 jp_fires; -static Uint32 jp_joypads[2]; +static Uint32 jp_joypads[8]; /*--- Functions prototypes ---*/ @@ -181,8 +196,14 @@ int SDL_SYS_JoystickInit(void) atarijoysticks[IKBD_JOY1].enabled=(SDL_AtariIkbd_enabled!=0); } if ((cookie_mch == MCH_STE<<16) || (cookie_mch == MCH_F30<<16)) { - atarijoysticks[PORTA_PAD].enabled=SDL_TRUE; - atarijoysticks[PORTB_PAD].enabled=SDL_TRUE; + atarijoysticks[PORTA_PAD0].enabled = + atarijoysticks[PORTA_PAD1].enabled = + atarijoysticks[PORTA_PAD2].enabled = + atarijoysticks[PORTA_PAD3].enabled = + atarijoysticks[PORTB_PAD0].enabled = + atarijoysticks[PORTB_PAD1].enabled = + atarijoysticks[PORTB_PAD2].enabled = + atarijoysticks[PORTB_PAD3].enabled = SDL_TRUE; } if (!atarijoysticks[IKBD_JOY1].enabled) { atarijoysticks[XBIOS_JOY1].enabled=(SDL_AtariXbios_enabled!=0); @@ -200,8 +221,8 @@ int SDL_SYS_JoystickInit(void) } /* Joypads ports only on STE and Falcon */ if ((cookie_mch == MCH_STE<<16) || (cookie_mch == MCH_F30<<16)) { - TEST_JOY_ENABLED(envr, "porta-pad", PORTA_PAD); - if (!atarijoysticks[PORTA_PAD].enabled) { + TEST_JOY_ENABLED(envr, "porta-pad", PORTA_PAD0); + if (!atarijoysticks[PORTA_PAD0].enabled) { TEST_JOY_ENABLED(envr, "porta-joy0", PORTA_JOY0); TEST_JOY_ENABLED(envr, "porta-joy1", PORTA_JOY1); if (!(atarijoysticks[PORTA_JOY0].enabled) && !(atarijoysticks[PORTA_JOY1].enabled)) { @@ -212,8 +233,8 @@ int SDL_SYS_JoystickInit(void) } } - TEST_JOY_ENABLED(envr, "portb-pad", PORTB_PAD); - if (!atarijoysticks[PORTB_PAD].enabled) { + TEST_JOY_ENABLED(envr, "portb-pad", PORTB_PAD0); + if (!atarijoysticks[PORTB_PAD0].enabled) { TEST_JOY_ENABLED(envr, "portb-joy0", PORTB_JOY0); TEST_JOY_ENABLED(envr, "portb-joy1", PORTB_JOY1); if (!(atarijoysticks[PORTB_JOY0].enabled) && !(atarijoysticks[PORTB_JOY1].enabled)) { @@ -239,7 +260,7 @@ int SDL_SYS_JoystickInit(void) /* Need to update joypad ports ? */ joypad_ports_enabled=SDL_FALSE; - for (i=PORTA_PAD;i<=PORTB_ANPAD;i++) { + for (i=PORTA_PAD0;i<=PORTB_ANPAD;i++) { if (atarijoysticks[i].enabled) { joypad_ports_enabled=SDL_TRUE; break; @@ -303,8 +324,14 @@ int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) joystick->nballs=0; switch(numjoystick) { - case PORTA_PAD: - case PORTB_PAD: + case PORTA_PAD0: + case PORTA_PAD1: + case PORTA_PAD2: + case PORTA_PAD3: + case PORTB_PAD0: + case PORTB_PAD1: + case PORTB_PAD2: + case PORTB_PAD3: joystick->nhats=1; joystick->nbuttons=JP_NUM_BUTTONS; break; @@ -379,13 +406,36 @@ void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) atarijoysticks[numjoystick].prevstate = curstate; } break; - case PORTA_PAD: - case PORTB_PAD: + case PORTA_PAD0: + case PORTA_PAD1: + case PORTA_PAD2: + case PORTA_PAD3: + case PORTB_PAD0: + case PORTB_PAD1: + case PORTB_PAD2: + case PORTB_PAD3: { int numjoypad,i; - numjoypad=0; - if (numjoystick==PORTB_PAD) numjoypad=1; + numjoypad = 0; + switch(numjoystick) { + case PORTA_PAD0: + numjoypad = 0; break; + case PORTA_PAD1: + numjoypad = 1; break; + case PORTA_PAD2: + numjoypad = 2; break; + case PORTA_PAD3: + numjoypad = 3; break; + case PORTB_PAD0: + numjoypad = 4; break; + case PORTB_PAD1: + numjoypad = 5; break; + case PORTB_PAD2: + numjoypad = 6; break; + case PORTB_PAD3: + numjoypad = 7; break; + } curstate=jp_joypads[numjoypad]; if (curstate!=prevstate) { @@ -561,9 +611,21 @@ struct JOYPAD_IO_S { }; #define JOYPAD_IO ((*(volatile struct JOYPAD_IO_S *)JOYPAD_IO_BASE)) +static const Uint16 joypad_masks[8*4]={ + 0xfffe, 0xfffd, 0xfffb, 0xfff7, + 0xfff0, 0xfff1, 0xfff2, 0xfff3, + 0xfff4, 0xfff5, 0xfff6, 0xfff8, + 0xfff9, 0xfffa, 0xfffc, 0xffff, + 0xffef, 0xffdf, 0xffbf, 0xff7f, + 0xff0f, 0xff1f, 0xff2f, 0xff3f, + 0xff4f, 0xff5f, 0xff6f, 0xff8f, + 0xff9f, 0xffaf, 0xffcf, 0xffff +}; + static void UpdateJoypads(void) { - Uint16 tmp; + Uint16 tmp, i, j; + Uint32 cur_fire, cur_dir; /*--- This function is called in supervisor mode ---*/ @@ -587,47 +649,35 @@ static void UpdateJoypads(void) tmp = (JOYPAD_IO.paddles[3] & 255); jp_paddles[3] = (tmp<<8) | tmp; - /* Update joypad 0 */ - JOYPAD_IO.directions=0xfffe; - jp_joypads[0]=((~(JOYPAD_IO.fires)) & 3)<<(16); - JOYPAD_IO.directions=0xfffe; - jp_joypads[0] |= ((~(JOYPAD_IO.directions))>>8) & 15; + /* Update joypads on teamtap port A */ + for (i=0; i<4; i++) { + jp_joypads[i] = 0; + for (j=0; j<4; j++) { + JOYPAD_IO.directions = joypad_masks[(i*4)+j]; - JOYPAD_IO.directions=0xfffd; - jp_joypads[0] |= ((~(JOYPAD_IO.fires)) & 3)<<(16+2); - JOYPAD_IO.directions=0xfffd; - jp_joypads[0] |= (((~(JOYPAD_IO.directions))>>8) & 15)<<4; + cur_fire = (~(JOYPAD_IO.fires) & 3)<<16; + cur_dir = (~(JOYPAD_IO.directions)>>8) & 15; - JOYPAD_IO.directions=0xfffb; - jp_joypads[0] |= ((~(JOYPAD_IO.fires)) & 3)<<(16+4); - JOYPAD_IO.directions=0xfffb; - jp_joypads[0] |= (((~(JOYPAD_IO.directions))>>8) & 15)<<8; + jp_joypads[i] |= cur_fire<<(j*2); + jp_joypads[i] |= cur_dir<<(j*4); + } + } - JOYPAD_IO.directions=0xfff7; - jp_joypads[0] |= ((~(JOYPAD_IO.fires)) & 3)<<(16+6); - JOYPAD_IO.directions=0xfff7; - jp_joypads[0] |= (((~(JOYPAD_IO.directions))>>8) & 15)<<12; + /* Update joypads on teamtap port B */ + for (i=4; i<8; i++) { + jp_joypads[i] = 0; + for (j=0; j<4; j++) { + JOYPAD_IO.directions = joypad_masks[(i*4)+j]; - /* Update joypad 1 */ - JOYPAD_IO.directions=0xffef; - jp_joypads[1]=((~(JOYPAD_IO.fires)) & (3<<2))<<(16-2); - JOYPAD_IO.directions=0xffef; - jp_joypads[1] |= ((~(JOYPAD_IO.directions))>>12) & 15; + cur_fire = (~(JOYPAD_IO.fires) & 0xc)<<14; + cur_dir = (~(JOYPAD_IO.directions)>>12) & 15; - JOYPAD_IO.directions=0xffdf; - jp_joypads[1] |= ((~(JOYPAD_IO.fires)) & (3<<2))<<(16); - JOYPAD_IO.directions=0xffdf; - jp_joypads[1] |= (((~(JOYPAD_IO.directions))>>12) & 15)<<4; + jp_joypads[i] |= cur_fire<<(j*2); + jp_joypads[i] |= cur_dir<<(j*4); + } + } - JOYPAD_IO.directions=0xffbf; - jp_joypads[1] |= ((~(JOYPAD_IO.fires)) & (3<<2))<<(16+2); - JOYPAD_IO.directions=0xffbf; - jp_joypads[1] |= (((~(JOYPAD_IO.directions))>>12) & 15)<<8; - - JOYPAD_IO.directions=0xff7f; - jp_joypads[1] |= ((~(JOYPAD_IO.fires)) & (3<<2))<<(16+4); - JOYPAD_IO.directions=0xff7f; - jp_joypads[1] |= (((~(JOYPAD_IO.directions))>>12) & 15)<<12; + JOYPAD_IO.directions=0xffff; } #endif /* SDL_JOYSTICK_MINT */ From 212dbcb764564f9d77d7c80bff3c7789da407e8a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 1 Sep 2006 22:50:24 +0000 Subject: [PATCH 005/241] Backport from 1.3: most of the audio drivers can now handle data conversion at a higher level when they can't open the hardware in the exact format requested. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402063 --- src/audio/amigaos/SDL_ahiaudio.c | 73 ++++++++------- src/audio/baudio/SDL_beaudio.cc | 77 ++++++++++------ src/audio/dart/SDL_dart.c | 41 ++++++--- src/audio/dc/SDL_dcaudio.c | 31 +++++-- src/audio/dmedia/SDL_irixaudio.c | 132 ++++++++++++++++----------- src/audio/mint/SDL_mintaudio_dma8.c | 3 + src/audio/mint/SDL_mintaudio_gsxb.c | 64 ++++++++----- src/audio/mint/SDL_mintaudio_mcsn.c | 4 + src/audio/mint/SDL_mintaudio_stfa.c | 4 + src/audio/mint/SDL_mintaudio_xbios.c | 4 + 10 files changed, 273 insertions(+), 160 deletions(-) diff --git a/src/audio/amigaos/SDL_ahiaudio.c b/src/audio/amigaos/SDL_ahiaudio.c index c9a4c1a4f..1db0f8457 100644 --- a/src/audio/amigaos/SDL_ahiaudio.c +++ b/src/audio/amigaos/SDL_ahiaudio.c @@ -220,47 +220,50 @@ static void AHI_CloseAudio(_THIS) static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec) { -// int width; + SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); + int valid_datatype = 1; - D(bug("AHI opening...\n")); + D(bug("AHI opening...\n")); - /* Determine the audio parameters from the AudioSpec */ - switch ( spec->format & 0xFF ) { + /* Determine the audio parameters from the AudioSpec */ + while ((!valid_datatype) && (test_format)) { + valid_datatype = 1; + switch (test_format) { + case AUDIO_S8: + D(bug("AUDIO_S8...\n")); + spec->format = AUDIO_S8; + this->hidden->bytespersample = 1; + if (spec->channels < 2) + this->hidden->type = AHIST_M8S; + else + this->hidden->type = AHIST_S8S; + break; - case 8: { /* Signed 8 bit audio data */ - D(bug("Samples a 8 bit...\n")); - spec->format = AUDIO_S8; - this->hidden->bytespersample=1; - if(spec->channels<2) - this->hidden->type = AHIST_M8S; - else - this->hidden->type = AHIST_S8S; - } - break; + case AUDIO_S16MSB: + D(bug("AUDIO_S16MSB...\n")); + spec->format = AUDIO_S16MSB; + this->hidden->bytespersample = 2; + if (spec->channels < 2) + this->hidden->type = AHIST_M16S; + else + this->hidden->type = AHIST_S16S; + break; - case 16: { /* Signed 16 bit audio data */ - D(bug("Samples a 16 bit...\n")); - spec->format = AUDIO_S16MSB; - this->hidden->bytespersample=2; - if(spec->channels<2) - this->hidden->type = AHIST_M16S; - else - this->hidden->type = AHIST_S16S; - } - break; + default: + valid_datatype = 0; + test_format = SDL_NextAudioFormat(); + break; + } + } - default: { - SDL_SetError("Unsupported audio format"); - return(-1); - } - } + if (!valid_datatype) { /* shouldn't happen, but just in case... */ + SDL_SetError("Unsupported audio format"); + return (-1); + } - if(spec->channels!=1 && spec->channels!=2) - { - D(bug("Wrong channel number!\n")); - SDL_SetError("Channel number non supported"); - return -1; - } + if (spec->channels > 2) { + spec->channels = 2; /* will convert at higher level. */ + } D(bug("Before CalculateAudioSpec\n")); /* Update the fragment size as size in bytes */ diff --git a/src/audio/baudio/SDL_beaudio.cc b/src/audio/baudio/SDL_beaudio.cc index b074f9c2b..a88d09759 100644 --- a/src/audio/baudio/SDL_beaudio.cc +++ b/src/audio/baudio/SDL_beaudio.cc @@ -152,38 +152,55 @@ void BE_CloseAudio(_THIS) int BE_OpenAudio(_THIS, SDL_AudioSpec *spec) { - media_raw_audio_format format; + int valid_datatype = 0; + media_raw_audio_format format; + SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); - /* Initialize the Be Application, if it's not already started */ - if ( SDL_InitBeApp() < 0 ) { - return(-1); - } + /* Parse the audio format and fill the Be raw audio format */ + memset(&format, '\0', sizeof (media_raw_audio_format)); + format.byte_order = B_MEDIA_LITTLE_ENDIAN; + format.frame_rate = (float) spec->freq; + format.channel_count = spec->channels; /* !!! FIXME: support > 2? */ + while ((!valid_datatype) && (test_format)) { + valid_datatype = 1; + spec->format = test_format; + switch (test_format) { + case AUDIO_S8: + format.format = media_raw_audio_format::B_AUDIO_CHAR; + break; + + case AUDIO_U8: + format.format = media_raw_audio_format::B_AUDIO_UCHAR; + break; + + case AUDIO_S16LSB: + format.format = media_raw_audio_format::B_AUDIO_SHORT; + break; + + case AUDIO_S16MSB: + format.format = media_raw_audio_format::B_AUDIO_SHORT; + format.byte_order = B_MEDIA_BIG_ENDIAN; + break; + + default: + valid_datatype = 0; + test_format = SDL_NextAudioFormat(); + break; + } + } + + if (!valid_datatype) { /* shouldn't happen, but just in case... */ + SDL_SetError("Unsupported audio format"); + return (-1); + } + + /* Initialize the Be Application, if it's not already started */ + if (SDL_InitBeApp() < 0) { + return (-1); + } + + format.buffer_size = spec->samples; - /* Parse the audio format and fill the Be raw audio format */ - format.frame_rate = (float)spec->freq; - format.channel_count = spec->channels; - switch (spec->format&~0x1000) { - case AUDIO_S8: - /* Signed 8-bit audio unsupported, convert to U8 */ - spec->format = AUDIO_U8; - case AUDIO_U8: - format.format = media_raw_audio_format::B_AUDIO_UCHAR; - format.byte_order = 0; - break; - case AUDIO_U16: - /* Unsigned 16-bit audio unsupported, convert to S16 */ - spec->format ^= 0x8000; - case AUDIO_S16: - format.format = media_raw_audio_format::B_AUDIO_SHORT; - if ( spec->format & 0x1000 ) { - format.byte_order = 1; /* Big endian */ - } else { - format.byte_order = 2; /* Little endian */ - } - break; - } - format.buffer_size = spec->samples; - /* Calculate the final parameters for this audio specification */ SDL_CalculateAudioSpec(spec); diff --git a/src/audio/dart/SDL_dart.c b/src/audio/dart/SDL_dart.c index 6381de161..8cdf68aba 100644 --- a/src/audio/dart/SDL_dart.c +++ b/src/audio/dart/SDL_dart.c @@ -75,6 +75,8 @@ LONG APIENTRY DARTEventFunc(ULONG ulStatus, int DART_OpenAudio(_THIS, SDL_AudioSpec *spec) { + SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); + int valid_datatype = 0; MCI_AMP_OPEN_PARMS AmpOpenParms; MCI_GENERIC_PARMS GenericParms; int iDeviceOrd = 0; // Default device to be used @@ -106,26 +108,39 @@ int DART_OpenAudio(_THIS, SDL_AudioSpec *spec) iDeviceOrd = AmpOpenParms.usDeviceID; // Determine the audio parameters from the AudioSpec - switch ( spec->format & 0xFF ) - { - case 8: - /* Unsigned 8 bit audio data */ - spec->format = AUDIO_U8; + if (spec->channels > 2) + spec->channels = 2; // !!! FIXME: more than stereo support in OS/2? + + while ((!valid_datatype) && (test_format)) { + spec->format = test_format; + valid_datatype = 1; + switch (test_format) { + case AUDIO_U8: + // Unsigned 8 bit audio data iSilence = 0x80; iBits = 8; break; - case 16: - /* Signed 16 bit audio data */ - spec->format = AUDIO_S16; + + case AUDIO_S16LSB: + // Signed 16 bit audio data iSilence = 0x00; iBits = 16; break; - default: - // Close DART, and exit with error code! - mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); - SDL_SetError("Unsupported audio format"); - return(-1); + + default: + valid_datatype = 0; + test_format = SDL_NextAudioFormat(); + break; + } } + + if (!valid_datatype) { // shouldn't happen, but just in case... + // Close DART, and exit with error code! + mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); + SDL_SetError("Unsupported audio format"); + return (-1); + } + iFreq = spec->freq; iChannels = spec->channels; /* Update the fragment size as size in bytes */ diff --git a/src/audio/dc/SDL_dcaudio.c b/src/audio/dc/SDL_dcaudio.c index 8715376fa..7dc8410d0 100644 --- a/src/audio/dc/SDL_dcaudio.c +++ b/src/audio/dc/SDL_dcaudio.c @@ -201,13 +201,30 @@ static void DCAUD_CloseAudio(_THIS) static int DCAUD_OpenAudio(_THIS, SDL_AudioSpec *spec) { - switch(spec->format&0xff) { - case 8: spec->format = AUDIO_S8; break; - case 16: spec->format = AUDIO_S16LSB; break; - default: - SDL_SetError("Unsupported audio format"); - return(-1); - } + SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); + int valid_datatype = 0; + while ((!valid_datatype) && (test_format)) { + spec->format = test_format; + switch (test_format) { + /* only formats Dreamcast accepts... */ + case AUDIO_S8: + case AUDIO_S16LSB: + valid_datatype = 1; + break; + + default: + test_format = SDL_NextAudioFormat(); + break; + } + } + + if (!valid_datatype) { /* shouldn't happen, but just in case... */ + SDL_SetError("Unsupported audio format"); + return (-1); + } + + if (spec->channels > 2) + spec->channels = 2; /* no more than stereo on the Dreamcast. */ /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(spec); diff --git a/src/audio/dmedia/SDL_irixaudio.c b/src/audio/dmedia/SDL_irixaudio.c index 96cbaef67..37352ae55 100644 --- a/src/audio/dmedia/SDL_irixaudio.c +++ b/src/audio/dmedia/SDL_irixaudio.c @@ -139,78 +139,104 @@ static void AL_CloseAudio(_THIS) } } -static int AL_OpenAudio(_THIS, SDL_AudioSpec *spec) +static int AL_OpenAudio(_THIS, SDL_AudioSpec * spec) { - ALconfig audio_config; + SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); + long width = 0; + long fmt = 0; + int valid = 0; + #ifdef OLD_IRIX_AUDIO - long audio_param[2]; + { + long audio_param[2]; + audio_param[0] = AL_OUTPUT_RATE; + audio_param[1] = spec->freq; + valid = (ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2) < 0); + } #else - ALpv audio_param; + { + ALpv audio_param; + audio_param.param = AL_RATE; + audio_param.value.i = spec->freq; + valid = (alSetParams(AL_DEFAULT_OUTPUT, &audio_param, 1) < 0); + } #endif - int width; - /* Determine the audio parameters from the AudioSpec */ - switch ( spec->format & 0xFF ) { + while ((!valid) && (test_format)) { + valid = 1; + spec->format = test_format; - case 8: { /* Signed 8 bit audio data */ - spec->format = AUDIO_S8; - width = AL_SAMPLE_8; + switch (test_format) { + case AUDIO_S8: + width = AL_SAMPLE_8; + fmt = AL_SAMPFMT_TWOSCOMP; + break; + + case AUDIO_S16SYS: + width = AL_SAMPLE_16; + fmt = AL_SAMPFMT_TWOSCOMP; + break; + + default: + valid = 0; + test_format = SDL_NextAudioFormat(); + break; } - break; - case 16: { /* Signed 16 bit audio data */ - spec->format = AUDIO_S16MSB; - width = AL_SAMPLE_16; - } - break; + if (valid) { + ALconfig audio_config = alNewConfig(); + valid = 0; + if (audio_config) { + if (alSetChannels(audio_config, spec->channels) < 0) { + if (spec->channels > 2) { /* can't handle > stereo? */ + spec->channels = 2; /* try again below. */ + } + } - default: { - SDL_SetError("Unsupported audio format"); - return(-1); + if ((alSetSampFmt(audio_config, fmt) >= 0) && + ((!width) || (alSetWidth(audio_config, width) >= 0)) && + (alSetQueueSize(audio_config, spec->samples * 2) >= 0) && + (alSetChannels(audio_config, spec->channels) >= 0)) { + + audio_port = alOpenPort("SDL audio", "w", audio_config); + if (audio_port == NULL) { + /* docs say AL_BAD_CHANNELS happens here, too. */ + int err = oserror(); + if (err == AL_BAD_CHANNELS) { + spec->channels = 2; + alSetChannels(audio_config, spec->channels); + audio_port = alOpenPort("SDL audio", "w", + audio_config); + } + } + + if (audio_port != NULL) { + valid = 1; + } + } + + alFreeConfig(audio_config); + } } } + if (!valid) { + SDL_SetError("Unsupported audio format"); + return (-1); + } + /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(spec); - /* Set output frequency */ -#ifdef OLD_IRIX_AUDIO - audio_param[0] = AL_OUTPUT_RATE; - audio_param[1] = spec->freq; - if( ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2) < 0 ) { -#else - audio_param.param = AL_RATE; - audio_param.value.i = spec->freq; - if( alSetParams(AL_DEFAULT_OUTPUT, &audio_param, 1) < 0 ) { -#endif - SDL_SetError("alSetParams failed"); - return(-1); - } - - /* Open the audio port with the requested frequency */ - audio_port = NULL; - audio_config = alNewConfig(); - if ( audio_config && - (alSetSampFmt(audio_config, AL_SAMPFMT_TWOSCOMP) >= 0) && - (alSetWidth(audio_config, width) >= 0) && - (alSetQueueSize(audio_config, spec->samples*2) >= 0) && - (alSetChannels(audio_config, spec->channels) >= 0) ) { - audio_port = alOpenPort("SDL audio", "w", audio_config); - } - alFreeConfig(audio_config); - if( audio_port == NULL ) { - SDL_SetError("Unable to open audio port"); - return(-1); - } - /* Allocate mixing buffer */ - mixbuf = (Uint8 *)SDL_AllocAudioMem(spec->size); - if ( mixbuf == NULL ) { + mixbuf = (Uint8 *) SDL_AllocAudioMem(spec->size); + if (mixbuf == NULL) { SDL_OutOfMemory(); - return(-1); + return (-1); } SDL_memset(mixbuf, spec->silence, spec->size); /* We're ready to rock and roll. :-) */ - return(0); + return (0); } + diff --git a/src/audio/mint/SDL_mintaudio_dma8.c b/src/audio/mint/SDL_mintaudio_dma8.c index 39e7a6d22..b5e97039a 100644 --- a/src/audio/mint/SDL_mintaudio_dma8.c +++ b/src/audio/mint/SDL_mintaudio_dma8.c @@ -217,6 +217,9 @@ static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) DEBUG_PRINT(("channels=%d, ", spec->channels)); DEBUG_PRINT(("freq=%d\n", spec->freq)); + if (spec->channels > 2) + spec->channels = 2; + /* Check formats available */ spec->format = AUDIO_S8; diff --git a/src/audio/mint/SDL_mintaudio_gsxb.c b/src/audio/mint/SDL_mintaudio_gsxb.c index de35debf5..742ff439e 100644 --- a/src/audio/mint/SDL_mintaudio_gsxb.c +++ b/src/audio/mint/SDL_mintaudio_gsxb.c @@ -201,6 +201,8 @@ static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) { long snd_format; int i, resolution, format_signed, format_bigendian; + SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); + int valid_datatype = 0; resolution = spec->format & 0x00ff; format_signed = ((spec->format & 0x8000)!=0); @@ -212,28 +214,46 @@ static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) DEBUG_PRINT(("channels=%d, ", spec->channels)); DEBUG_PRINT(("freq=%d\n", spec->freq)); - /* Check formats available */ - snd_format = Sndstatus(SND_QUERYFORMATS); - switch (resolution) { - case 8: - if ((snd_format & SND_FORMAT8)==0) { - SDL_SetError("Mint_CheckAudio: 8 bits samples not supported"); - return -1; - } - snd_format = Sndstatus(SND_QUERY8BIT); - break; - case 16: - if ((snd_format & SND_FORMAT16)==0) { - SDL_SetError("Mint_CheckAudio: 16 bits samples not supported"); - return -1; - } - snd_format = Sndstatus(SND_QUERY16BIT); - break; - default: - SDL_SetError("Mint_CheckAudio: Unsupported sample resolution"); - return -1; - break; - } + if (spec->channels > 2) { + spec->channels = 2; /* no more than stereo! */ + } + + while ((!valid_datatype) && (test_format)) { + /* Check formats available */ + snd_format = Sndstatus(SND_QUERYFORMATS); + spec->format = test_format; + resolution = SDL_AUDIO_BITSIZE(spec->format); + format_signed = SDL_AUDIO_ISSIGNED(spec->format); + format_bigendian = SDL_AUDIO_ISBIGENDIAN(spec->format); + switch (test_format) { + case AUDIO_U8: + case AUDIO_S8: + if (snd_format & SND_FORMAT8) { + valid_datatype = 1; + snd_format = Sndstatus(SND_QUERY8BIT); + } + break; + + case AUDIO_U16LSB: + case AUDIO_S16LSB: + case AUDIO_U16MSB: + case AUDIO_S16MSB: + if (snd_format & SND_FORMAT16) { + valid_datatype = 1; + snd_format = Sndstatus(SND_QUERY16BIT); + } + break; + + default: + test_format = SDL_NextAudioFormat(); + break; + } + } + + if (!valid_datatype) { + SDL_SetError("Unsupported audio format"); + return (-1); + } /* Check signed/unsigned format */ if (format_signed) { diff --git a/src/audio/mint/SDL_mintaudio_mcsn.c b/src/audio/mint/SDL_mintaudio_mcsn.c index 9741a3bea..cbaa6be5d 100644 --- a/src/audio/mint/SDL_mintaudio_mcsn.c +++ b/src/audio/mint/SDL_mintaudio_mcsn.c @@ -224,6 +224,10 @@ static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) DEBUG_PRINT(("channels=%d, ", spec->channels)); DEBUG_PRINT(("freq=%d\n", spec->freq)); + if (spec->channels > 2) { + spec->channels = 2; /* no more than stereo! */ + } + /* Check formats available */ MINTAUDIO_freqcount=0; switch(cookie_mcsn->play) { diff --git a/src/audio/mint/SDL_mintaudio_stfa.c b/src/audio/mint/SDL_mintaudio_stfa.c index 552a7b224..80c76f7e0 100644 --- a/src/audio/mint/SDL_mintaudio_stfa.c +++ b/src/audio/mint/SDL_mintaudio_stfa.c @@ -205,6 +205,10 @@ static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) DEBUG_PRINT(("channels=%d, ", spec->channels)); DEBUG_PRINT(("freq=%d\n", spec->freq)); + if (spec->channels > 2) { + spec->channels = 2; /* no more than stereo! */ + } + /* Check formats available */ MINTAUDIO_freqcount=0; for (i=0;i<16;i++) { diff --git a/src/audio/mint/SDL_mintaudio_xbios.c b/src/audio/mint/SDL_mintaudio_xbios.c index 016d4fa59..e1bfed7f9 100644 --- a/src/audio/mint/SDL_mintaudio_xbios.c +++ b/src/audio/mint/SDL_mintaudio_xbios.c @@ -341,6 +341,10 @@ static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) DEBUG_PRINT(("channels=%d, ", spec->channels)); DEBUG_PRINT(("freq=%d\n", spec->freq)); + if (spec->channels > 2) { + spec->channels = 2; /* no more than stereo! */ + } + spec->format |= 0x8000; /* Audio is always signed */ if ((spec->format & 0x00ff)==16) { spec->format |= 0x1000; /* Audio is always big endian */ From b601827c977f22ed96eb9ab76183831adca3be59 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 3 Sep 2006 21:34:11 +0000 Subject: [PATCH 006/241] Removed some new 1.3 symbols from code backported to 1.2. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402066 --- src/audio/amigaos/SDL_ahiaudio.c | 2 +- src/audio/baudio/SDL_beaudio.cc | 2 +- src/audio/dart/SDL_dart.c | 2 +- src/audio/dc/SDL_dcaudio.c | 2 +- src/audio/dmedia/SDL_irixaudio.c | 2 +- src/audio/mint/SDL_mintaudio_gsxb.c | 8 ++++---- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/audio/amigaos/SDL_ahiaudio.c b/src/audio/amigaos/SDL_ahiaudio.c index 1db0f8457..f2efe1c2f 100644 --- a/src/audio/amigaos/SDL_ahiaudio.c +++ b/src/audio/amigaos/SDL_ahiaudio.c @@ -220,7 +220,7 @@ static void AHI_CloseAudio(_THIS) static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec) { - SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); + Uint16 test_format = SDL_FirstAudioFormat(spec->format); int valid_datatype = 1; D(bug("AHI opening...\n")); diff --git a/src/audio/baudio/SDL_beaudio.cc b/src/audio/baudio/SDL_beaudio.cc index a88d09759..fce0ecb32 100644 --- a/src/audio/baudio/SDL_beaudio.cc +++ b/src/audio/baudio/SDL_beaudio.cc @@ -154,7 +154,7 @@ int BE_OpenAudio(_THIS, SDL_AudioSpec *spec) { int valid_datatype = 0; media_raw_audio_format format; - SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); + Uint16 test_format = SDL_FirstAudioFormat(spec->format); /* Parse the audio format and fill the Be raw audio format */ memset(&format, '\0', sizeof (media_raw_audio_format)); diff --git a/src/audio/dart/SDL_dart.c b/src/audio/dart/SDL_dart.c index 8cdf68aba..a37a5e222 100644 --- a/src/audio/dart/SDL_dart.c +++ b/src/audio/dart/SDL_dart.c @@ -75,7 +75,7 @@ LONG APIENTRY DARTEventFunc(ULONG ulStatus, int DART_OpenAudio(_THIS, SDL_AudioSpec *spec) { - SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); + Uint16 test_format = SDL_FirstAudioFormat(spec->format); int valid_datatype = 0; MCI_AMP_OPEN_PARMS AmpOpenParms; MCI_GENERIC_PARMS GenericParms; diff --git a/src/audio/dc/SDL_dcaudio.c b/src/audio/dc/SDL_dcaudio.c index 7dc8410d0..a28ea5a7f 100644 --- a/src/audio/dc/SDL_dcaudio.c +++ b/src/audio/dc/SDL_dcaudio.c @@ -201,7 +201,7 @@ static void DCAUD_CloseAudio(_THIS) static int DCAUD_OpenAudio(_THIS, SDL_AudioSpec *spec) { - SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); + Uint16 test_format = SDL_FirstAudioFormat(spec->format); int valid_datatype = 0; while ((!valid_datatype) && (test_format)) { spec->format = test_format; diff --git a/src/audio/dmedia/SDL_irixaudio.c b/src/audio/dmedia/SDL_irixaudio.c index 37352ae55..f9bd31047 100644 --- a/src/audio/dmedia/SDL_irixaudio.c +++ b/src/audio/dmedia/SDL_irixaudio.c @@ -141,7 +141,7 @@ static void AL_CloseAudio(_THIS) static int AL_OpenAudio(_THIS, SDL_AudioSpec * spec) { - SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); + Uint16 test_format = SDL_FirstAudioFormat(spec->format); long width = 0; long fmt = 0; int valid = 0; diff --git a/src/audio/mint/SDL_mintaudio_gsxb.c b/src/audio/mint/SDL_mintaudio_gsxb.c index 742ff439e..4bac88d25 100644 --- a/src/audio/mint/SDL_mintaudio_gsxb.c +++ b/src/audio/mint/SDL_mintaudio_gsxb.c @@ -201,7 +201,7 @@ static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) { long snd_format; int i, resolution, format_signed, format_bigendian; - SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); + Uint16 test_format = SDL_FirstAudioFormat(spec->format); int valid_datatype = 0; resolution = spec->format & 0x00ff; @@ -222,9 +222,9 @@ static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) /* Check formats available */ snd_format = Sndstatus(SND_QUERYFORMATS); spec->format = test_format; - resolution = SDL_AUDIO_BITSIZE(spec->format); - format_signed = SDL_AUDIO_ISSIGNED(spec->format); - format_bigendian = SDL_AUDIO_ISBIGENDIAN(spec->format); + resolution = spec->format & 0xff; + format_signed = (spec->format & (1<<15)); + format_bigendian = (spec->format & (1<<12)); switch (test_format) { case AUDIO_U8: case AUDIO_S8: From 473f24de3d3ed50a65fe9f70e2aee20de06c0fac Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 5 Sep 2006 19:31:48 +0000 Subject: [PATCH 007/241] Use correct function to free allocated mem --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402067 --- src/cdrom/linux/SDL_syscdrom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cdrom/linux/SDL_syscdrom.c b/src/cdrom/linux/SDL_syscdrom.c index 4d3e70cd0..2535b2803 100644 --- a/src/cdrom/linux/SDL_syscdrom.c +++ b/src/cdrom/linux/SDL_syscdrom.c @@ -218,7 +218,7 @@ static void CheckMounts(const char *mtab) if ( SDL_strcmp(mnt_type, MNTTYPE_SUPER) == 0 ) { tmp = SDL_strstr(mntent->mnt_opts, "fs="); if ( tmp ) { - SDL_free(mnt_type); + SDL_stack_free(mnt_type); mnt_type = SDL_strdup(tmp + SDL_strlen("fs=")); if ( mnt_type ) { tmp = SDL_strchr(mnt_type, ','); @@ -229,7 +229,7 @@ static void CheckMounts(const char *mtab) } tmp = SDL_strstr(mntent->mnt_opts, "dev="); if ( tmp ) { - SDL_free(mnt_dev); + SDL_stack_free(mnt_dev); mnt_dev = SDL_strdup(tmp + SDL_strlen("dev=")); if ( mnt_dev ) { tmp = SDL_strchr(mnt_dev, ','); From 8d211fac7767501d8251aa8838df77c83bf49987 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 7 Sep 2006 20:52:31 +0000 Subject: [PATCH 008/241] /me dumb, sizeof(keymap) != number of elements --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402070 --- src/video/ataricommon/SDL_biosevents.c | 2 +- src/video/ataricommon/SDL_gemdosevents.c | 2 +- src/video/ataricommon/SDL_ikbdevents.c | 2 +- src/video/gem/SDL_gemevents.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/ataricommon/SDL_biosevents.c b/src/video/ataricommon/SDL_biosevents.c index af4b7b72c..41efcabf9 100644 --- a/src/video/ataricommon/SDL_biosevents.c +++ b/src/video/ataricommon/SDL_biosevents.c @@ -74,7 +74,7 @@ void AtariBios_InitOSKeymap(_THIS) SDL_memset(bios_previouskeyboard, 0, sizeof(bios_previouskeyboard)); /* Initialize keymap */ - for ( i=0; i Date: Fri, 8 Sep 2006 19:17:03 +0000 Subject: [PATCH 009/241] Forgot to reshow mouse cursor when exiting grab/hide mode --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402071 --- src/video/gem/SDL_gemmouse.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/gem/SDL_gemmouse.c b/src/video/gem/SDL_gemmouse.c index cc41bc5c3..98ae264e4 100644 --- a/src/video/gem/SDL_gemmouse.c +++ b/src/video/gem/SDL_gemmouse.c @@ -181,5 +181,6 @@ void GEM_CheckMouseMode(_THIS) GEM_mouse_relative = SDL_TRUE; } else { GEM_mouse_relative = SDL_FALSE; + graf_mouse(M_ON, NULL); } } From 7cfc406eb800281ccb219461f4309351c17d1ae9 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 12 Sep 2006 19:20:50 +0000 Subject: [PATCH 010/241] Disable MiNT thread usage and use hw access for updating DMA audio pointers --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402074 --- src/audio/mint/SDL_mintaudio_xbios.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/audio/mint/SDL_mintaudio_xbios.c b/src/audio/mint/SDL_mintaudio_xbios.c index e1bfed7f9..09ff639f0 100644 --- a/src/audio/mint/SDL_mintaudio_xbios.c +++ b/src/audio/mint/SDL_mintaudio_xbios.c @@ -82,7 +82,8 @@ static int Audio_Available(void) unsigned long dummy; const char *envr = SDL_getenv("SDL_AUDIODRIVER"); - SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND); + /*SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND);*/ + SDL_MintAudio_mint_present = SDL_FALSE; /* We can't use XBIOS in interrupt with Magic, don't know about thread */ if (Getcookie(C_MagX, &dummy) == C_FOUND) { @@ -437,7 +438,8 @@ static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) } else { /* Install interrupt */ Jdisint(MFP_DMASOUND); - Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt); + /*Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt);*/ + Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_Dma8Interrupt); Jenabint(MFP_DMASOUND); if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) { From 8eba29d8342853b5becbc722e5ee74055a3b6dee Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 12 Sep 2006 19:28:54 +0000 Subject: [PATCH 011/241] Allow mouse to be locked when grabbed with GEM driver --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402076 --- src/video/ataricommon/SDL_xbiosevents.c | 8 +++++++- src/video/ataricommon/SDL_xbiosevents_c.h | 1 + src/video/ataricommon/SDL_xbiosinterrupt.S | 11 +++++++++-- src/video/ataricommon/SDL_xbiosinterrupt_s.h | 1 + 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/video/ataricommon/SDL_xbiosevents.c b/src/video/ataricommon/SDL_xbiosevents.c index b744252fc..5d1fa3c51 100644 --- a/src/video/ataricommon/SDL_xbiosevents.c +++ b/src/video/ataricommon/SDL_xbiosevents.c @@ -49,7 +49,8 @@ void SDL_AtariXbios_InstallVectors(int vectors_mask) void *oldpile; /* Clear variables */ - SDL_AtariXbios_mouseb = + SDL_AtariXbios_mouselock = + SDL_AtariXbios_mouseb = SDL_AtariXbios_mousex = SDL_AtariXbios_mousey = SDL_AtariXbios_joystick = @@ -146,3 +147,8 @@ void SDL_AtariXbios_PostMouseEvents(_THIS, SDL_bool buttonEvents) atari_prevmouseb = SDL_AtariXbios_mouseb; } } + +void SDL_AtariXbios_LockMousePosition(SDL_bool lockPosition) +{ + SDL_AtariXbios_mouselock = lockPosition; +} diff --git a/src/video/ataricommon/SDL_xbiosevents_c.h b/src/video/ataricommon/SDL_xbiosevents_c.h index 05761bde4..9f746fbbd 100644 --- a/src/video/ataricommon/SDL_xbiosevents_c.h +++ b/src/video/ataricommon/SDL_xbiosevents_c.h @@ -43,5 +43,6 @@ extern int SDL_AtariXbios_enabled; extern void SDL_AtariXbios_InstallVectors(int vectors_mask); extern void SDL_AtariXbios_RestoreVectors(void); extern void SDL_AtariXbios_PostMouseEvents(_THIS, SDL_bool buttonEvents); +extern void SDL_AtariXbios_LockMousePosition(SDL_bool lockPosition); #endif /* _SDL_XBIOSEVENTS_H_ */ diff --git a/src/video/ataricommon/SDL_xbiosinterrupt.S b/src/video/ataricommon/SDL_xbiosinterrupt.S index 548561ca4..a76df3768 100644 --- a/src/video/ataricommon/SDL_xbiosinterrupt.S +++ b/src/video/ataricommon/SDL_xbiosinterrupt.S @@ -33,6 +33,7 @@ .globl _SDL_AtariXbios_MouseVector .globl _SDL_AtariXbios_JoystickVector + .globl _SDL_AtariXbios_mouselock .globl _SDL_AtariXbios_mouseb .globl _SDL_AtariXbios_mousex .globl _SDL_AtariXbios_mousey @@ -125,6 +126,13 @@ _SDL_AtariXbios_MouseVector: extw d0 addw d0,_SDL_AtariXbios_mousey + /* Lock mouse position ? */ + tstw _SDL_AtariXbios_mouselock + beq.s no_mouse_lock + clrb a0@(1) + clrb a0@(2) +no_mouse_lock: + /* Jump through old vector */ movel sp@+,d0 @@ -133,10 +141,9 @@ _SDL_AtariXbios_MouseVector: .data .even + .comm _SDL_AtariXbios_mouselock,2*1 .comm _SDL_AtariXbios_mousex,2*1 - .even .comm _SDL_AtariXbios_mousey,2*1 - .even .comm _SDL_AtariXbios_mouseb,2*1 /*--- Our joystick vector ---*/ diff --git a/src/video/ataricommon/SDL_xbiosinterrupt_s.h b/src/video/ataricommon/SDL_xbiosinterrupt_s.h index cee4260b5..429c1705e 100644 --- a/src/video/ataricommon/SDL_xbiosinterrupt_s.h +++ b/src/video/ataricommon/SDL_xbiosinterrupt_s.h @@ -36,6 +36,7 @@ /* Variables */ +extern volatile Uint16 SDL_AtariXbios_mouselock; /* mouse lock position */ extern volatile Uint16 SDL_AtariXbios_mouseb; /* buttons */ extern volatile Sint16 SDL_AtariXbios_mousex; /* X relative motion */ extern volatile Sint16 SDL_AtariXbios_mousey; /* Y relative motion */ From faf3d7ce00cb336f23be64e2bc7032bd5522b885 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 12 Sep 2006 19:33:33 +0000 Subject: [PATCH 012/241] Reenable xbios usage to get relative mouse motion --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402077 --- src/video/gem/SDL_gemvideo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/gem/SDL_gemvideo.c b/src/video/gem/SDL_gemvideo.c index fea61dbd0..eea9863d3 100644 --- a/src/video/gem/SDL_gemvideo.c +++ b/src/video/gem/SDL_gemvideo.c @@ -197,9 +197,9 @@ static SDL_VideoDevice *GEM_CreateDevice(int devindex) if (!(device->hidden->use_dev_mouse)) { vectors_mask |= ATARI_XBIOS_MOUSEEVENTS; /* XBIOS mouse events */ } - if (Getcookie(C_MiNT, &dummy)==C_FOUND) { +/* if (Getcookie(C_MiNT, &dummy)==C_FOUND) { vectors_mask = 0; - } + }*/ SDL_AtariXbios_InstallVectors(vectors_mask); From e5b239feec73a247f6fee9222f9f27c25390365b Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 12 Sep 2006 19:34:18 +0000 Subject: [PATCH 013/241] Allow grabing mouse by locking its position --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402078 --- src/video/gem/SDL_gemmouse.c | 4 +++- src/video/gem/SDL_gemwm.c | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/video/gem/SDL_gemmouse.c b/src/video/gem/SDL_gemmouse.c index 98ae264e4..e8b1e0b0f 100644 --- a/src/video/gem/SDL_gemmouse.c +++ b/src/video/gem/SDL_gemmouse.c @@ -176,10 +176,12 @@ void GEM_CheckMouseMode(_THIS) /* If the mouse is hidden and input is grabbed, we use relative mode */ if ( (!(SDL_cursorstate & CURSOR_VISIBLE)) && - /*(this->input_grab != SDL_GRAB_OFF) && */ /* Damn GEM can not grab */ + (this->input_grab != SDL_GRAB_OFF) && (SDL_GetAppState() & SDL_APPACTIVE) ) { + SDL_AtariXbios_LockMousePosition(SDL_TRUE); GEM_mouse_relative = SDL_TRUE; } else { + SDL_AtariXbios_LockMousePosition(SDL_FALSE); GEM_mouse_relative = SDL_FALSE; graf_mouse(M_ON, NULL); } diff --git a/src/video/gem/SDL_gemwm.c b/src/video/gem/SDL_gemwm.c index 28d26443b..c6b299839 100644 --- a/src/video/gem/SDL_gemwm.c +++ b/src/video/gem/SDL_gemwm.c @@ -108,5 +108,9 @@ int GEM_IconifyWindow(_THIS) SDL_GrabMode GEM_GrabInput(_THIS, SDL_GrabMode mode) { - return SDL_GRAB_OFF; + if (this->screen == NULL) { + return SDL_GRAB_OFF; + } + + return mode; } From fc46c0ae5d01ba29b065203944d3ca163dd55718 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 13 Sep 2006 21:18:35 +0000 Subject: [PATCH 014/241] Factorize keyboard mapping between drivers --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402083 --- src/video/ataricommon/SDL_atarievents.c | 75 +++++++++++++ src/video/ataricommon/SDL_atarievents_c.h | 19 ++++ src/video/ataricommon/SDL_biosevents.c | 90 +-------------- src/video/ataricommon/SDL_gemdosevents.c | 88 +-------------- src/video/ataricommon/SDL_ikbdevents.c | 129 +--------------------- 5 files changed, 110 insertions(+), 291 deletions(-) diff --git a/src/video/ataricommon/SDL_atarievents.c b/src/video/ataricommon/SDL_atarievents.c index 66657441b..5c1dd4e39 100644 --- a/src/video/ataricommon/SDL_atarievents.c +++ b/src/video/ataricommon/SDL_atarievents.c @@ -30,10 +30,13 @@ */ #include +#include +#include #include "../../events/SDL_sysevents.h" #include "../../events/SDL_events_c.h" +#include "SDL_atarikeys.h" #include "SDL_atarievents_c.h" #include "SDL_biosevents_c.h" #include "SDL_gemdosevents_c.h" @@ -48,6 +51,14 @@ enum { MCH_ARANYM }; +#ifndef KT_NOCHANGE +# define KT_NOCHANGE -1 +#endif + +/* The translation tables from a console scancode to a SDL keysym */ +static SDLKey keymap[ATARIBIOS_MAXKEYS]; +static unsigned char *keytab_normal; + void (*Atari_ShutdownEvents)(void); static void Atari_InitializeEvents(_THIS) @@ -108,10 +119,52 @@ void Atari_InitOSKeymap(_THIS) { Atari_InitializeEvents(this); + SDL_Atari_InitInternalKeymap(this); + /* Call choosen routine */ this->InitOSKeymap(this); } +void SDL_Atari_InitInternalKeymap(_THIS) +{ + int i; + _KEYTAB *key_tables; + + /* Read system tables for scancode -> ascii translation */ + key_tables = (_KEYTAB *) Keytbl(KT_NOCHANGE, KT_NOCHANGE, KT_NOCHANGE); + keytab_normal = key_tables->unshift; + + /* Initialize keymap */ + for ( i=0; iscancode = scancode; + keysym->mod = KMOD_NONE; + keysym->sym = keymap[scancode]; + keysym->unicode = 0; + + if (keysym->sym == SDLK_UNKNOWN) { + keysym->sym = asciicode = keytab_normal[scancode]; + } + + if (SDL_TranslateUNICODE && pressed) { + keysym->unicode = SDL_AtariToUnicodeTable[asciicode]; + } + + return(keysym); +} diff --git a/src/video/ataricommon/SDL_atarievents_c.h b/src/video/ataricommon/SDL_atarievents_c.h index 527b91c15..36f06ecf4 100644 --- a/src/video/ataricommon/SDL_atarievents_c.h +++ b/src/video/ataricommon/SDL_atarievents_c.h @@ -35,12 +35,31 @@ /* Hidden "this" pointer for the video functions */ #define _THIS SDL_VideoDevice *this +#define ATARIBIOS_MAXKEYS 128 + +/* Special keys state */ +#ifndef K_RSHIFT +enum { + K_RSHIFT=0, + K_LSHIFT, + K_CTRL, + K_ALT, + K_CAPSLOCK, + K_CLRHOME, + K_INSERT +}; +#endif + extern void (*Atari_ShutdownEvents)(void); extern void Atari_InitOSKeymap(_THIS); extern void Atari_PumpEvents(_THIS); +extern void SDL_Atari_InitInternalKeymap(_THIS); + /* Atari to Unicode charset translation table */ extern Uint16 SDL_AtariToUnicodeTable[256]; +SDL_keysym *SDL_Atari_TranslateKey(int scancode, SDL_keysym *keysym, + SDL_bool pressed); #endif /* _SDL_ATARI_EVENTS_H_ */ diff --git a/src/video/ataricommon/SDL_biosevents.c b/src/video/ataricommon/SDL_biosevents.c index 41efcabf9..6fdf1e150 100644 --- a/src/video/ataricommon/SDL_biosevents.c +++ b/src/video/ataricommon/SDL_biosevents.c @@ -39,30 +39,10 @@ #include "SDL_xbiosevents_c.h" #include "SDL_ataridevmouse_c.h" -/* To save state of keyboard */ -#define ATARIBIOS_MAXKEYS 128 - static unsigned char bios_currentkeyboard[ATARIBIOS_MAXKEYS]; static unsigned char bios_previouskeyboard[ATARIBIOS_MAXKEYS]; -static unsigned char bios_currentascii[ATARIBIOS_MAXKEYS]; static SDL_bool use_dev_mouse = SDL_FALSE; -/* Special keys state */ -enum { - K_RSHIFT=0, - K_LSHIFT, - K_CTRL, - K_ALT, - K_CAPSLOCK, - K_CLRHOME, - K_INSERT -}; - -/* The translation tables from a console scancode to a SDL keysym */ -static SDLKey keymap[ATARIBIOS_MAXKEYS]; - -static SDL_keysym *TranslateKey(int scancode, int asciicode, SDL_keysym *keysym, - SDL_bool pressed); static void UpdateSpecialKeys(int special_keys_state); void AtariBios_InitOSKeymap(_THIS) @@ -73,45 +53,15 @@ void AtariBios_InitOSKeymap(_THIS) SDL_memset(bios_currentkeyboard, 0, sizeof(bios_currentkeyboard)); SDL_memset(bios_previouskeyboard, 0, sizeof(bios_previouskeyboard)); - /* Initialize keymap */ - for ( i=0; i> 16; - - bios_currentkeyboard[scancode]=0xFF; - bios_currentascii[scancode]=asciicode; + bios_currentkeyboard[(key_pressed>>16)&(ATARIBIOS_MAXKEYS-1)]=0xFF; } /* Read special keys */ @@ -145,12 +88,12 @@ void AtariBios_PumpEvents(_THIS) /* Key pressed ? */ if (bios_currentkeyboard[i] && !bios_previouskeyboard[i]) SDL_PrivateKeyboard(SDL_PRESSED, - TranslateKey(i, bios_currentascii[i], &keysym, SDL_TRUE)); + SDL_Atari_TranslateKey(i, &keysym, SDL_TRUE)); /* Key unpressed ? */ if (bios_previouskeyboard[i] && !bios_currentkeyboard[i]) SDL_PrivateKeyboard(SDL_RELEASED, - TranslateKey(i, bios_currentascii[i], &keysym, SDL_FALSE)); + SDL_Atari_TranslateKey(i, &keysym, SDL_FALSE)); } if (use_dev_mouse) { @@ -160,7 +103,7 @@ void AtariBios_PumpEvents(_THIS) } /* Will be previous table */ - SDL_memcpy(bios_previouskeyboard, bios_currentkeyboard, ATARIBIOS_MAXKEYS); + SDL_memcpy(bios_previouskeyboard, bios_currentkeyboard, sizeof(bios_previouskeyboard)); } static void UpdateSpecialKeys(int special_keys_state) @@ -169,7 +112,6 @@ static void UpdateSpecialKeys(int special_keys_state) { \ if (special_keys_state & (1<<(numbit))) { \ bios_currentkeyboard[scancode]=0xFF; \ - bios_currentascii[scancode]=0; \ } \ } @@ -180,26 +122,6 @@ static void UpdateSpecialKeys(int special_keys_state) UPDATE_SPECIAL_KEYS(K_CAPSLOCK, SCANCODE_CAPSLOCK); } -static SDL_keysym *TranslateKey(int scancode, int asciicode, SDL_keysym *keysym, - SDL_bool pressed) -{ - /* Set the keysym information */ - keysym->scancode = scancode; - - if (asciicode) - keysym->sym = asciicode; - else - keysym->sym = keymap[scancode]; - - keysym->mod = KMOD_NONE; - keysym->unicode = 0; - if (SDL_TranslateUNICODE && pressed) { - keysym->unicode = SDL_AtariToUnicodeTable[asciicode]; - } - - return(keysym); -} - void AtariBios_ShutdownEvents(void) { SDL_AtariXbios_RestoreVectors(); diff --git a/src/video/ataricommon/SDL_gemdosevents.c b/src/video/ataricommon/SDL_gemdosevents.c index d4c209fc9..598dff788 100644 --- a/src/video/ataricommon/SDL_gemdosevents.c +++ b/src/video/ataricommon/SDL_gemdosevents.c @@ -40,34 +40,16 @@ #include "SDL_ataridevmouse_c.h" /* To save state of keyboard */ -#define ATARIBIOS_MAXKEYS 128 static unsigned char gemdos_currentkeyboard[ATARIBIOS_MAXKEYS]; static unsigned char gemdos_previouskeyboard[ATARIBIOS_MAXKEYS]; -static unsigned char gemdos_currentascii[ATARIBIOS_MAXKEYS]; static SDL_bool use_dev_mouse = SDL_FALSE; -/* Special keys state */ -enum { - K_RSHIFT=0, - K_LSHIFT, - K_CTRL, - K_ALT, - K_CAPSLOCK, - K_CLRHOME, - K_INSERT -}; - enum { DEV_BUSY=0, DEV_READY }; -/* The translation tables from a console scancode to a SDL keysym */ -static SDLKey keymap[ATARIBIOS_MAXKEYS]; - -static SDL_keysym *TranslateKey(int scancode, int asciicode, SDL_keysym *keysym, - SDL_bool pressed); static void UpdateSpecialKeys(int special_keys_state); void AtariGemdos_InitOSKeymap(_THIS) @@ -78,45 +60,15 @@ void AtariGemdos_InitOSKeymap(_THIS) SDL_memset(gemdos_currentkeyboard, 0, sizeof(gemdos_currentkeyboard)); SDL_memset(gemdos_previouskeyboard, 0, sizeof(gemdos_previouskeyboard)); - /* Initialize keymap */ - for ( i=0; i> 16; - - gemdos_currentkeyboard[scancode]=0xFF; - gemdos_currentascii[scancode]=asciicode; + gemdos_currentkeyboard[(key_pressed>>16)&(ATARIBIOS_MAXKEYS-1)]=0xFF; } /* Read special keys */ @@ -149,12 +94,12 @@ void AtariGemdos_PumpEvents(_THIS) /* Key pressed ? */ if (gemdos_currentkeyboard[i] && !gemdos_previouskeyboard[i]) SDL_PrivateKeyboard(SDL_PRESSED, - TranslateKey(i, gemdos_currentascii[i], &keysym, SDL_TRUE)); + SDL_Atari_TranslateKey(i, &keysym, SDL_TRUE)); /* Key unpressed ? */ if (gemdos_previouskeyboard[i] && !gemdos_currentkeyboard[i]) SDL_PrivateKeyboard(SDL_RELEASED, - TranslateKey(i, gemdos_currentascii[i], &keysym, SDL_FALSE)); + SDL_Atari_TranslateKey(i, &keysym, SDL_FALSE)); } if (use_dev_mouse) { @@ -164,7 +109,7 @@ void AtariGemdos_PumpEvents(_THIS) } /* Will be previous table */ - SDL_memcpy(gemdos_previouskeyboard, gemdos_currentkeyboard, ATARIBIOS_MAXKEYS); + SDL_memcpy(gemdos_previouskeyboard, gemdos_currentkeyboard, sizeof(gemdos_previouskeyboard)); } static void UpdateSpecialKeys(int special_keys_state) @@ -173,7 +118,6 @@ static void UpdateSpecialKeys(int special_keys_state) { \ if (special_keys_state & (1<<(numbit))) { \ gemdos_currentkeyboard[scancode]=0xFF; \ - gemdos_currentascii[scancode]=0; \ } \ } @@ -184,26 +128,6 @@ static void UpdateSpecialKeys(int special_keys_state) UPDATE_SPECIAL_KEYS(K_CAPSLOCK, SCANCODE_CAPSLOCK); } -static SDL_keysym *TranslateKey(int scancode, int asciicode, SDL_keysym *keysym, - SDL_bool pressed) -{ - /* Set the keysym information */ - keysym->scancode = scancode; - - if (asciicode) - keysym->sym = asciicode; - else - keysym->sym = keymap[scancode]; - - keysym->mod = KMOD_NONE; - keysym->unicode = 0; - if (SDL_TranslateUNICODE && pressed) { - keysym->unicode = SDL_AtariToUnicodeTable[asciicode]; - } - - return(keysym); -} - void AtariGemdos_ShutdownEvents(void) { SDL_AtariXbios_RestoreVectors(); diff --git a/src/video/ataricommon/SDL_ikbdevents.c b/src/video/ataricommon/SDL_ikbdevents.c index 928a3bab5..d3a766098 100644 --- a/src/video/ataricommon/SDL_ikbdevents.c +++ b/src/video/ataricommon/SDL_ikbdevents.c @@ -37,85 +37,17 @@ #include "SDL_atarievents_c.h" #include "SDL_ikbdinterrupt_s.h" -/* Special keys state */ -enum { - K_RSHIFT=0, - K_LSHIFT, - K_CTRL, - K_ALT, - K_CAPSLOCK, - K_CLRHOME, - K_INSERT -}; - -#define ATARIBIOS_MAXKEYS 128 - #define KEY_PRESSED 0xff #define KEY_UNDEFINED 0x80 #define KEY_RELEASED 0x00 -/* The translation tables from a console scancode to a SDL keysym */ -#define KT_NOCHANGE -1 - -enum { - KT_UNSHIFT=0, - KT_SHIFT=1, - KT_CAPS=2 -}; - static Uint16 atari_prevmouseb; /* save state of mouse buttons */ -static int caps_state; /* caps lock state */ -_KEYTAB *curtables; -static unsigned char *tab_unshift, *tab_shift, *tab_caps; -static SDLKey keymap[ATARIBIOS_MAXKEYS]; - -static SDL_keysym *TranslateKey(int scancode, int numkeytable, SDL_keysym *keysym, - SDL_bool pressed); void AtariIkbd_InitOSKeymap(_THIS) { int i; - SDL_memset(SDL_AtariIkbd_keyboard, KEY_UNDEFINED, ATARIBIOS_MAXKEYS); - - /* Initialize keymap */ - for ( i=0; i ascii translation */ - curtables=Keytbl(KT_NOCHANGE, KT_NOCHANGE, KT_NOCHANGE); - tab_unshift=curtables->unshift; - tab_shift=curtables->shift; - tab_caps=curtables->caps; - - /* Set Caps lock initial state */ - caps_state=(Kbshift(-1) & (1<scancode = scancode; - - asciicode=0; - switch(numkeytable) { - case KT_UNSHIFT: - asciicode=tab_unshift[scancode]; - break; - case KT_SHIFT: - asciicode=tab_shift[scancode]; - break; - case KT_CAPS: - asciicode=tab_caps[scancode]; - break; - } - - if (asciicode) - keysym->sym = asciicode; - else - keysym->sym = keymap[scancode]; - - keysym->mod = KMOD_NONE; - keysym->unicode = 0; - if (SDL_TranslateUNICODE && pressed) { - keysym->unicode = SDL_AtariToUnicodeTable[asciicode]; - } - - return(keysym); -} - void AtariIkbd_ShutdownEvents(void) { Supexec(SDL_AtariIkbdUninstall); From ca12676b88bb1543936357eac6469ab4fd4678a6 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 13 Sep 2006 21:19:13 +0000 Subject: [PATCH 015/241] Use new keyboard mapping routines --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402084 --- src/video/gem/SDL_gemevents.c | 76 +++-------------------------------- 1 file changed, 6 insertions(+), 70 deletions(-) diff --git a/src/video/gem/SDL_gemevents.c b/src/video/gem/SDL_gemevents.c index c59a6ee50..0e029eca7 100644 --- a/src/video/gem/SDL_gemevents.c +++ b/src/video/gem/SDL_gemevents.c @@ -41,89 +41,28 @@ #include "../ataricommon/SDL_xbiosevents_c.h" #include "../ataricommon/SDL_ataridevmouse_c.h" -/* Defines */ - -#define ATARIBIOS_MAXKEYS 128 - /* Variables */ static unsigned char gem_currentkeyboard[ATARIBIOS_MAXKEYS]; static unsigned char gem_previouskeyboard[ATARIBIOS_MAXKEYS]; -static unsigned char gem_currentascii[ATARIBIOS_MAXKEYS]; - -/* The translation tables from a console scancode to a SDL keysym */ -static SDLKey keymap[ATARIBIOS_MAXKEYS]; /* Functions prototypes */ -static SDL_keysym *TranslateKey(int scancode, int asciicode, SDL_keysym *keysym, - SDL_bool pressed); static int do_messages(_THIS, short *message); static void do_keyboard(short kc, short ks); static void do_mouse(_THIS, short mx, short my, short mb, short ks); /* Functions */ -static SDL_keysym *TranslateKey(int scancode, int asciicode, SDL_keysym *keysym, - SDL_bool pressed) -{ - /* Set the keysym information */ - keysym->scancode = scancode; - - if (asciicode) - keysym->sym = asciicode; - else - keysym->sym = keymap[scancode]; - - keysym->mod = KMOD_NONE; - keysym->unicode = 0; - if (SDL_TranslateUNICODE && pressed) { - keysym->unicode = SDL_AtariToUnicodeTable[asciicode]; - } - - return(keysym); -} - void GEM_InitOSKeymap(_THIS) { - int i; - SDL_memset(gem_currentkeyboard, 0, sizeof(gem_currentkeyboard)); SDL_memset(gem_previouskeyboard, 0, sizeof(gem_previouskeyboard)); - SDL_memset(gem_currentascii, 0, sizeof(gem_currentascii)); - - /* Initialize keymap */ - for ( i=0; i>8) & 127; - asciicode=kc & 255; - + scancode=(kc>>8) & (ATARIBIOS_MAXKEYS-1); gem_currentkeyboard[scancode]=0xFF; - gem_currentascii[scancode]=asciicode; } /* Read special keys */ From bd51c7328360f797d58787841d0e6979bfd01995 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 15 Sep 2006 21:26:36 +0000 Subject: [PATCH 016/241] Update to reflect driver changes --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402085 --- README.MiNT | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/README.MiNT b/README.MiNT index b258065be..34bddda54 100644 --- a/README.MiNT +++ b/README.MiNT @@ -68,14 +68,14 @@ OpenGL (using Mesa offscreen rendering driver) - Dependent driver combinations: Video Kbd Mouse Timer Joysticks xbios ikbd ikbd vbl(2) ikbd -xbios gemdos xbios vbl(2) xbios(3) -xbios bios xbios vbl(2) xbios(3) -gem gem gem(1) vbl(2) xbios(3) +xbios gemdos xbios vbl(2) xbios +xbios bios xbios vbl(2) xbios +gem gem gem(1) vbl(2) xbios Audio O/S Misc dma8 All Uses MFP Timer A interrupt xbios TOS Uses MFP Timer A interrupt -xbios MiNT Uses MiNT thread +xbios MiNT Uses MFP Timer A interrupt xbios Magic Disabled stfa All Uses MFP interrupt mcsn TOS Uses MFP Timer A interrupt @@ -87,16 +87,13 @@ Joypad driver always uses hardware access. OpenGL driver always uses OSMesa. (1) GEM does not report relative mouse motion, so xbios mouse driver is used -to report this type event. Under MiNT, using XBIOS mouse driver is not possible. +to report this type event. A preliminary driver for /dev/mouse device driver is present, but is disabled till it can be used with other applications simultaneously. (2) If you build SDL with threads using the GNU pth library, timers are supported via the pth library. -(3) Redirecting XBIOS vectors does not work under MiNT, so it is disabled in -this case. - ============================================================================== V. Environment variables: From c588ef327198df06b6e73d31912c20337303edbd Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 16 Sep 2006 09:14:25 +0000 Subject: [PATCH 017/241] Only convert endianness if both src and dest are 16bits --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402086 --- src/audio/SDL_audiocvt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 3c361155e..24afd0f0a 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -1374,7 +1374,7 @@ int SDL_BuildAudioCVT(SDL_AudioCVT *cvt, /* First filter: Endian conversion from src to dst */ if ( (src_format & 0x1000) != (dst_format & 0x1000) - && ((src_format & 0xff) != 8) ) { + && ((src_format & 0xff) == 16) && ((dst_format & 0xff) == 16)) { cvt->filters[cvt->filter_index++] = SDL_ConvertEndian; } From 75df00ebdf6919934afd147f06dd9c02091ffbf2 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 16 Sep 2006 09:15:11 +0000 Subject: [PATCH 018/241] Only saved non preserved registers --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402087 --- src/audio/mint/SDL_mintaudio_it.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/audio/mint/SDL_mintaudio_it.S b/src/audio/mint/SDL_mintaudio_it.S index e9eab5922..acc7b5d89 100644 --- a/src/audio/mint/SDL_mintaudio_it.S +++ b/src/audio/mint/SDL_mintaudio_it.S @@ -137,7 +137,7 @@ _SDL_MintAudio_Dma8Interrupt: /* Swap buffers */ eorw #1,_SDL_MintAudio_numbuf - moveml d0-d7/a0-a6,sp@- + moveml d0-d1/a0-a1,sp@- /* Callback */ jsr _SDL_MintAudio_Callback @@ -169,7 +169,7 @@ _SDL_MintAudio_Dma8Interrupt: rorl #8,d1 moveb d1,a0@(0x0f) - moveml sp@+,d0-d7/a0-a6 + moveml sp@+,d0-d1/a0-a1 clrw _SDL_MintAudio_mutex SDL_MintAudio_Dma8End: From 336e30592d784ed3d49670de52fa4e6fa2715428 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 16 Sep 2006 10:38:09 +0000 Subject: [PATCH 019/241] Add function to check FPU presence --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402088 --- src/audio/mint/SDL_mintaudio.c | 22 ++++++++++++++++++++++ src/audio/mint/SDL_mintaudio.h | 2 ++ src/audio/mint/SDL_mintaudio_dma8.c | 2 ++ src/audio/mint/SDL_mintaudio_gsxb.c | 2 ++ src/audio/mint/SDL_mintaudio_mcsn.c | 2 ++ src/audio/mint/SDL_mintaudio_stfa.c | 2 ++ src/audio/mint/SDL_mintaudio_xbios.c | 2 ++ 7 files changed, 34 insertions(+) diff --git a/src/audio/mint/SDL_mintaudio.c b/src/audio/mint/SDL_mintaudio.c index b98bb3242..afdec649a 100644 --- a/src/audio/mint/SDL_mintaudio.c +++ b/src/audio/mint/SDL_mintaudio.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "SDL_audio.h" #include "SDL_mintaudio.h" @@ -46,6 +47,7 @@ volatile unsigned short SDL_MintAudio_numbuf; /* Buffer to play */ volatile unsigned short SDL_MintAudio_mutex; volatile unsigned long SDL_MintAudio_clocktics; cookie_stfa_t *SDL_MintAudio_stfa; +unsigned short SDL_MintAudio_hasfpu; /* MiNT thread variables */ SDL_bool SDL_MintAudio_mint_present; @@ -139,6 +141,26 @@ int SDL_MintAudio_SearchFrequency(_THIS, int desired_freq) return MINTAUDIO_freqcount-1; } +/* Check if FPU is present */ +void SDL_MintAudio_CheckFpu(void) +{ + unsigned long cookie_fpu; + + SDL_MintAudio_hasfpu = 0; + if (Getcookie(C__FPU, &cookie_fpu) != C_FOUND) { + return; + } + switch ((cookie_fpu>>16)&0xfffe) { + case 2: + case 4: + case 6: + case 8: + case 16: + SDL_MintAudio_hasfpu = 1; + break; + } +} + /* The thread function, used under MiNT with xbios */ int SDL_MintAudio_Thread(long param) { diff --git a/src/audio/mint/SDL_mintaudio.h b/src/audio/mint/SDL_mintaudio.h index 970169c17..9a0258007 100644 --- a/src/audio/mint/SDL_mintaudio.h +++ b/src/audio/mint/SDL_mintaudio.h @@ -123,6 +123,7 @@ extern volatile unsigned short SDL_MintAudio_numbuf; /* Buffer to play */ extern volatile unsigned short SDL_MintAudio_mutex; extern cookie_stfa_t *SDL_MintAudio_stfa; extern volatile unsigned long SDL_MintAudio_clocktics; +extern unsigned short SDL_MintAudio_hasfpu; /* To preserve fpu registers if needed */ /* MiNT thread variables */ extern SDL_bool SDL_MintAudio_mint_present; @@ -135,6 +136,7 @@ void SDL_MintAudio_Callback(void); void SDL_MintAudio_AddFrequency(_THIS, Uint32 frequency, Uint32 clock, Uint32 prediv, int gpio_bits); int SDL_MintAudio_SearchFrequency(_THIS, int desired_freq); +void SDL_MintAudio_CheckFpu(void); /* MiNT thread functions */ int SDL_MintAudio_Thread(long param); diff --git a/src/audio/mint/SDL_mintaudio_dma8.c b/src/audio/mint/SDL_mintaudio_dma8.c index b5e97039a..d4c43cfcf 100644 --- a/src/audio/mint/SDL_mintaudio_dma8.c +++ b/src/audio/mint/SDL_mintaudio_dma8.c @@ -352,6 +352,8 @@ static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); + SDL_MintAudio_CheckFpu(); + /* Setup audio hardware */ Mint_InitAudio(this, spec); diff --git a/src/audio/mint/SDL_mintaudio_gsxb.c b/src/audio/mint/SDL_mintaudio_gsxb.c index 4bac88d25..41f78c999 100644 --- a/src/audio/mint/SDL_mintaudio_gsxb.c +++ b/src/audio/mint/SDL_mintaudio_gsxb.c @@ -406,6 +406,8 @@ static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); + SDL_MintAudio_CheckFpu(); + /* Setup audio hardware */ Mint_InitAudio(this, spec); diff --git a/src/audio/mint/SDL_mintaudio_mcsn.c b/src/audio/mint/SDL_mintaudio_mcsn.c index cbaa6be5d..a464184e3 100644 --- a/src/audio/mint/SDL_mintaudio_mcsn.c +++ b/src/audio/mint/SDL_mintaudio_mcsn.c @@ -395,6 +395,8 @@ static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); + SDL_MintAudio_CheckFpu(); + /* Setup audio hardware */ Mint_InitAudio(this, spec); diff --git a/src/audio/mint/SDL_mintaudio_stfa.c b/src/audio/mint/SDL_mintaudio_stfa.c index 80c76f7e0..4ad1fdd36 100644 --- a/src/audio/mint/SDL_mintaudio_stfa.c +++ b/src/audio/mint/SDL_mintaudio_stfa.c @@ -314,6 +314,8 @@ static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); + SDL_MintAudio_CheckFpu(); + /* Setup audio hardware */ Mint_InitAudio(this, spec); diff --git a/src/audio/mint/SDL_mintaudio_xbios.c b/src/audio/mint/SDL_mintaudio_xbios.c index 09ff639f0..4a1af3f39 100644 --- a/src/audio/mint/SDL_mintaudio_xbios.c +++ b/src/audio/mint/SDL_mintaudio_xbios.c @@ -486,6 +486,8 @@ static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); + SDL_MintAudio_CheckFpu(); + /* Setup audio hardware */ Mint_InitAudio(this, spec); From f31a930c9830104fe407458f34b1a403d376a101 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 16 Sep 2006 11:50:34 +0000 Subject: [PATCH 020/241] Save/restore fpu registers if needed --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402089 --- src/audio/mint/SDL_mintaudio_it.S | 53 +++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/src/audio/mint/SDL_mintaudio_it.S b/src/audio/mint/SDL_mintaudio_it.S index acc7b5d89..4e93763a4 100644 --- a/src/audio/mint/SDL_mintaudio_it.S +++ b/src/audio/mint/SDL_mintaudio_it.S @@ -40,6 +40,7 @@ .globl _SDL_MintAudio_numbuf .globl _SDL_MintAudio_audiosize .globl _SDL_MintAudio_clocktics + .globl _SDL_MintAudio_hasfpu .globl _SDL_MintAudio_stfa @@ -77,7 +78,7 @@ _SDL_MintAudio_XbiosInterrupt: /* Check if we are not already running */ tstw _SDL_MintAudio_mutex - bnes SDL_MintAudio_XbiosEnd + bne SDL_MintAudio_XbiosEnd notw _SDL_MintAudio_mutex /* Swap buffers */ @@ -85,9 +86,25 @@ _SDL_MintAudio_XbiosInterrupt: moveml d0-d7/a0-a6,sp@- + /* Save FPU if needed */ + tstw _SDL_MintAudio_hasfpu + beqs SDL_MintAudio_Xbios_nofpu1 + fsave sp@- + fmoveml fpcr/fpsr/fpiar,sp@- + fmovemx fp0-fp7,sp@- +SDL_MintAudio_Xbios_nofpu1: + /* Callback */ jsr _SDL_MintAudio_Callback + /* Restore FPU if needed */ + tstw _SDL_MintAudio_hasfpu + beqs SDL_MintAudio_Xbios_nofpu2 + fmovemx sp@+,fp0-fp7 + fmoveml sp@+,fpcr/fpsr/fpiar + frestore sp@+ +SDL_MintAudio_Xbios_nofpu2: + /* Reserve space for registers */ subl #savamt,savptr @@ -131,7 +148,7 @@ _SDL_MintAudio_Dma8Interrupt: /* Check if we are not already running */ tstw _SDL_MintAudio_mutex - bnes SDL_MintAudio_Dma8End + bne SDL_MintAudio_Dma8End notw _SDL_MintAudio_mutex /* Swap buffers */ @@ -139,9 +156,25 @@ _SDL_MintAudio_Dma8Interrupt: moveml d0-d1/a0-a1,sp@- + /* Save FPU if needed */ + tstw _SDL_MintAudio_hasfpu + beqs SDL_MintAudio_Dma8_nofpu1 + fsave sp@- + fmoveml fpcr/fpsr/fpiar,sp@- + fmovemx fp0-fp7,sp@- +SDL_MintAudio_Dma8_nofpu1: + /* Callback */ jsr _SDL_MintAudio_Callback + /* Restore FPU if needed */ + tstw _SDL_MintAudio_hasfpu + beqs SDL_MintAudio_Dma8_nofpu2 + fmovemx sp@+,fp0-fp7 + fmoveml sp@+,fpcr/fpsr/fpiar + frestore sp@+ +SDL_MintAudio_Dma8_nofpu2: + /* Set new buffer */ moveq #0,d0 @@ -195,9 +228,25 @@ _SDL_MintAudio_StfaInterrupt: moveml d0-d7/a0-a6,sp@- + /* Save FPU if needed */ + tstw _SDL_MintAudio_hasfpu + beqs SDL_MintAudio_Stfa_nofpu1 + fsave sp@- + fmoveml fpcr/fpsr/fpiar,sp@- + fmovemx fp0-fp7,sp@- +SDL_MintAudio_Stfa_nofpu1: + /* Callback */ jsr _SDL_MintAudio_Callback + /* Restore FPU if needed */ + tstw _SDL_MintAudio_hasfpu + beqs SDL_MintAudio_Stfa_nofpu2 + fmovemx sp@+,fp0-fp7 + fmoveml sp@+,fpcr/fpsr/fpiar + frestore sp@+ +SDL_MintAudio_Stfa_nofpu2: + /* Set new buffer */ moveq #0,d0 From 9cc61d56c876bfde65a8bb99555c1745733ad16b Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 16 Sep 2006 12:00:03 +0000 Subject: [PATCH 021/241] Forgot cpu boundaries --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402090 --- src/audio/mint/SDL_mintaudio_it.S | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/audio/mint/SDL_mintaudio_it.S b/src/audio/mint/SDL_mintaudio_it.S index 4e93763a4..c751a5912 100644 --- a/src/audio/mint/SDL_mintaudio_it.S +++ b/src/audio/mint/SDL_mintaudio_it.S @@ -89,9 +89,11 @@ _SDL_MintAudio_XbiosInterrupt: /* Save FPU if needed */ tstw _SDL_MintAudio_hasfpu beqs SDL_MintAudio_Xbios_nofpu1 + .chip 68060 fsave sp@- fmoveml fpcr/fpsr/fpiar,sp@- fmovemx fp0-fp7,sp@- + .chip 68000 SDL_MintAudio_Xbios_nofpu1: /* Callback */ @@ -100,9 +102,11 @@ SDL_MintAudio_Xbios_nofpu1: /* Restore FPU if needed */ tstw _SDL_MintAudio_hasfpu beqs SDL_MintAudio_Xbios_nofpu2 + .chip 68060 fmovemx sp@+,fp0-fp7 fmoveml sp@+,fpcr/fpsr/fpiar frestore sp@+ + .chip 68000 SDL_MintAudio_Xbios_nofpu2: /* Reserve space for registers */ @@ -159,9 +163,11 @@ _SDL_MintAudio_Dma8Interrupt: /* Save FPU if needed */ tstw _SDL_MintAudio_hasfpu beqs SDL_MintAudio_Dma8_nofpu1 + .chip 68060 fsave sp@- fmoveml fpcr/fpsr/fpiar,sp@- fmovemx fp0-fp7,sp@- + .chip 68000 SDL_MintAudio_Dma8_nofpu1: /* Callback */ @@ -170,9 +176,11 @@ SDL_MintAudio_Dma8_nofpu1: /* Restore FPU if needed */ tstw _SDL_MintAudio_hasfpu beqs SDL_MintAudio_Dma8_nofpu2 + .chip 68060 fmovemx sp@+,fp0-fp7 fmoveml sp@+,fpcr/fpsr/fpiar frestore sp@+ + .chip 68000 SDL_MintAudio_Dma8_nofpu2: /* Set new buffer */ @@ -231,9 +239,11 @@ _SDL_MintAudio_StfaInterrupt: /* Save FPU if needed */ tstw _SDL_MintAudio_hasfpu beqs SDL_MintAudio_Stfa_nofpu1 + .chip 68060 fsave sp@- fmoveml fpcr/fpsr/fpiar,sp@- fmovemx fp0-fp7,sp@- + .chip 68000 SDL_MintAudio_Stfa_nofpu1: /* Callback */ @@ -242,9 +252,11 @@ SDL_MintAudio_Stfa_nofpu1: /* Restore FPU if needed */ tstw _SDL_MintAudio_hasfpu beqs SDL_MintAudio_Stfa_nofpu2 + .chip 68060 fmovemx sp@+,fp0-fp7 fmoveml sp@+,fpcr/fpsr/fpiar frestore sp@+ + .chip 68000 SDL_MintAudio_Stfa_nofpu2: /* Set new buffer */ From a71237840f9524542c35759067d819ac6797017c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 23 Sep 2006 23:07:52 +0000 Subject: [PATCH 022/241] Fixed bug #294 Can't build SDL 1.2.11(and svn) for Pocket PC 2003 with Visual Studio 2005 Fix contributed by Dmitry Yakimov --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402102 --- src/video/windib/SDL_dibevents.c | 23 ++++++++++++++++++++++- src/video/windib/SDL_dibvideo.c | 5 +++++ test/testalpha.c | 5 +++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/video/windib/SDL_dibevents.c b/src/video/windib/SDL_dibevents.c index ce903c573..1d18f86f0 100644 --- a/src/video/windib/SDL_dibevents.c +++ b/src/video/windib/SDL_dibevents.c @@ -273,18 +273,35 @@ static HKL hLayoutUS = NULL; void DIB_InitOSKeymap(_THIS) { int i; - char current_layout[256]; +#ifndef _WIN32_WCE + char current_layout[KL_NAMELENGTH]; GetKeyboardLayoutName(current_layout); //printf("Initial Keyboard Layout Name: '%s'\n", current_layout); hLayoutUS = LoadKeyboardLayout("00000409", KLF_NOTELLSHELL); + if (!hLayoutUS) { //printf("Failed to load US keyboard layout. Using current.\n"); hLayoutUS = GetKeyboardLayout(0); } LoadKeyboardLayout(current_layout, KLF_ACTIVATE); +#else +#if _WIN32_WCE >=420 + TCHAR current_layout[KL_NAMELENGTH]; + GetKeyboardLayoutName(current_layout); + //printf("Initial Keyboard Layout Name: '%s'\n", current_layout); + + hLayoutUS = LoadKeyboardLayout(L"00000409", 0); + + if (!hLayoutUS) { + //printf("Failed to load US keyboard layout. Using current.\n"); + hLayoutUS = GetKeyboardLayout(0); + } + LoadKeyboardLayout(current_layout, 0); +#endif // _WIN32_WCE >=420 +#endif /* Map the VK keysyms */ for ( i=0; iw; bounds.bottom = SDL_windowY+video->h; +#ifndef _WIN32_WCE AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), (GetMenu(SDL_Window) != NULL), 0); +#else + // The bMenu parameter must be FALSE; menu bars are not supported + AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), 0, 0); +#endif width = bounds.right-bounds.left; height = bounds.bottom-bounds.top; if ( (flags & SDL_FULLSCREEN) ) { diff --git a/test/testalpha.c b/test/testalpha.c index 0bdb7725c..4af5c10fa 100644 --- a/test/testalpha.c +++ b/test/testalpha.c @@ -505,9 +505,14 @@ fprintf(stderr, "Slept %d ticks\n", (SDL_GetTicks()-ticks)); } break; case SDL_KEYDOWN: +#ifndef _WIN32_WCE if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; } +#else + // there is no ESC key at all + done = 1; +#endif break; case SDL_QUIT: done = 1; From 66bd610f04c0360d4327a61c9febe916d5262d25 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 23 Sep 2006 23:12:44 +0000 Subject: [PATCH 023/241] Fixed bug #304 WinCE - refactoring of hardware buttons handling Contributed by Dmitry Yakimov --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402103 --- src/video/wincommon/SDL_syswm.c | 35 ++------------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/src/video/wincommon/SDL_syswm.c b/src/video/wincommon/SDL_syswm.c index c5ea7a864..e1106ac84 100644 --- a/src/video/wincommon/SDL_syswm.c +++ b/src/video/wincommon/SDL_syswm.c @@ -41,25 +41,6 @@ /* The screen icon -- needs to be freed on SDL_VideoQuit() */ HICON screen_icn = NULL; -#ifdef _WIN32_WCE - -BOOL (WINAPI *CoreCatchInput)(int flag) = NULL; -int input_catched = 0; -HINSTANCE coredll = NULL; - -// the same API call that gx.dll does to catch the input -void LoadInputCatchFunc() -{ - coredll = SDL_LoadObject("coredll.dll"); - if( coredll ) - { - CoreCatchInput = (int (WINAPI *)(int)) GetProcAddress(coredll, (const unsigned short *) 1453); - } -} - -#endif - - /* Win32 icon mask semantics are different from those of SDL: SDL applies the mask to the icon and copies result to desktop. Win32 applies the mask to the desktop and XORs the icon on. @@ -263,13 +244,7 @@ SDL_GrabMode WIN_GrabInput(_THIS, SDL_GrabMode mode) SetCursorPos(pt.x,pt.y); } #ifdef _WIN32_WCE - if( input_catched ) - { - if( !CoreCatchInput ) LoadInputCatchFunc(); - - if( CoreCatchInput ) - CoreCatchInput(0); - } + AllKeys(0); #endif } else { ClipCursor(&SDL_bounds); @@ -284,13 +259,7 @@ SDL_GrabMode WIN_GrabInput(_THIS, SDL_GrabMode mode) SetCursorPos(pt.x, pt.y); } #ifdef _WIN32_WCE - if( !input_catched ) - { - if( !CoreCatchInput ) LoadInputCatchFunc(); - - if( CoreCatchInput ) - CoreCatchInput(1); - } + AllKeys(1); #endif } return(mode); From 0b9d71091ee4d2b5b8bd66631ad9c2e1aebf167c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 23 Sep 2006 23:15:34 +0000 Subject: [PATCH 024/241] --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402104 --- src/video/SDL_blit_A.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/SDL_blit_A.c b/src/video/SDL_blit_A.c index 71109a27a..923b1624a 100644 --- a/src/video/SDL_blit_A.c +++ b/src/video/SDL_blit_A.c @@ -1556,7 +1556,7 @@ static void BlitRGBtoRGBPixelAlpha(SDL_BlitInfo *info) #if GCC_ASMBLIT /* fast (as in MMX with prefetch) ARGB888->(A)RGB888 blending with pixel alpha */ -inline static void BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo *info) +static void BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo *info) { int width = info->d_width; int height = info->d_height; From 6a16eb68dcd358aa4960ed21b0020ca41d6ed3a7 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 24 Sep 2006 00:04:06 +0000 Subject: [PATCH 025/241] Fixed bug #276 PlanarPixmapInfoYUV420 is a big endian structure. Fix contributed by Jean-Charles BERTIN --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402106 --- src/video/quartz/SDL_QuartzYUV.m | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/video/quartz/SDL_QuartzYUV.m b/src/video/quartz/SDL_QuartzYUV.m index 96539d679..acb3d944a 100644 --- a/src/video/quartz/SDL_QuartzYUV.m +++ b/src/video/quartz/SDL_QuartzYUV.m @@ -274,6 +274,8 @@ SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height, return NULL; } + /* Fix: jc.bertin@free.fr + PlanarPixmapInfoYUV420 is a big-endian struct */ yuv_pixmap = (PlanarPixmapInfoYUV420*) SDL_malloc (sizeof(PlanarPixmapInfoYUV420) + (width * height * 2)); @@ -291,20 +293,20 @@ SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height, /* CHECK_ALIGN(pixels[0]); */ pitches[0] = width; - yuv_pixmap->componentInfoY.offset = offset; - yuv_pixmap->componentInfoY.rowBytes = width; + yuv_pixmap->componentInfoY.offset = EndianS32_NtoB(offset); + yuv_pixmap->componentInfoY.rowBytes = EndianU32_NtoB(width); offset += width * height; pixels[plane2] = (Uint8*)yuv_pixmap + offset; pitches[plane2] = width / 2; - yuv_pixmap->componentInfoCb.offset = offset; - yuv_pixmap->componentInfoCb.rowBytes = width / 2; + yuv_pixmap->componentInfoCb.offset = EndianS32_NtoB(offset); + yuv_pixmap->componentInfoCb.rowBytes = EndianU32_NtoB(width / 2); offset += (width * height / 4); pixels[plane3] = (Uint8*)yuv_pixmap + offset; pitches[plane3] = width / 2; - yuv_pixmap->componentInfoCr.offset = offset; - yuv_pixmap->componentInfoCr.rowBytes = width / 2; + yuv_pixmap->componentInfoCr.offset = EndianS32_NtoB(offset); + yuv_pixmap->componentInfoCr.rowBytes = EndianU32_NtoB(width / 2); overlay->pixels = pixels; overlay->pitches = pitches; From 8460b069f68eeebaf09cc172b8d1439ef8d2bc9a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 24 Sep 2006 00:08:28 +0000 Subject: [PATCH 026/241] Fixed bug #278 Added the GFX_Display to the wminfo structure, contributed by Eric --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402107 --- include/SDL_syswm.h | 6 +++++- src/video/x11/SDL_x11wm.c | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h index e7f35139a..010dd1bcc 100644 --- a/include/SDL_syswm.h +++ b/include/SDL_syswm.h @@ -86,7 +86,8 @@ typedef struct SDL_SysWMinfo { Display *display; /* The X11 display */ Window window; /* The X11 display window */ /* These locking functions should be called around - any X11 functions using the display variable. + any X11 functions using the display variable, + but not the gfxdisplay variable. They lock the event thread, so should not be called around event functions or from event filters. */ @@ -96,6 +97,9 @@ typedef struct SDL_SysWMinfo { /* Introduced in SDL 1.0.2 */ Window fswindow; /* The X11 fullscreen window */ Window wmwindow; /* The X11 managed input window */ + + /* Introduced in SDL 1.2.12 */ + Display *gfxdisplay; /* The X11 display to which rendering is done */ } x11; } info; } SDL_SysWMinfo; diff --git a/src/video/x11/SDL_x11wm.c b/src/video/x11/SDL_x11wm.c index a50215cd3..d82a7a1d6 100644 --- a/src/video/x11/SDL_x11wm.c +++ b/src/video/x11/SDL_x11wm.c @@ -398,6 +398,8 @@ static void unlock_display(void) XSync(SDL_Display, False); SDL_Unlock_EventThread(); } + +#include int X11_GetWMInfo(_THIS, SDL_SysWMinfo *info) { if ( info->version.major <= SDL_MAJOR_VERSION ) { @@ -410,6 +412,14 @@ int X11_GetWMInfo(_THIS, SDL_SysWMinfo *info) info->info.x11.fswindow = FSwindow; info->info.x11.wmwindow = WMwindow; } + + + if ( SDL_VERSIONNUM(info->version.major, + info->version.minor, + info->version.patch) >= 1212 ) { + info->info.x11.gfxdisplay = GFX_Display; + } + info->info.x11.lock_func = lock_display; info->info.x11.unlock_func = unlock_display; return(1); From dd8038b0e4bd466fd28896821ebcb6c298bdd83f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 24 Sep 2006 00:10:59 +0000 Subject: [PATCH 027/241] Bumped the version in subversion to 1.2.12 --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402108 --- VisualC.zip | Bin 42466 -> 42465 bytes configure.in | 6 +++--- include/SDL_version.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/VisualC.zip b/VisualC.zip index 030db1cdefd600b2b7be511ba3e099405fbd74ba..d4a5a2a4fdb3f5154d2830a9bbce6c48b2a47ca5 100644 GIT binary patch delta 1240 zcmYk6e^Aq99LM*4w&p+>AdJa3V(j=e@Radm3&ufveX1W>02WF%|j2VKZIojA-_i+wYSFlWy_KA(*27otxu(flTXIYWrHnePLZE@ zg-h#?2U8_CqGP7dN#C!U(e9kS7*;y!_|fU@)FIya;`$u~G1I-w>>ci$MUMuHGAoY_ zeomhg`i_w7lRV4lIm#q<)K+e`w}kqj?Zows{*fswik`Qd?$n$<@@a+3*ZZ z^YB``>aLC3Ce zmm2MEc zkFLb;`7B7)IY*aP=I6KLh`?GPjPJVcEz+EUY`CWZ| zUcSFw|Uv+!Ts5-DKv*-DAYh~!l}VbE}Jh_2ZL_gOU1um-`;B(~FYa)Hz8i=u~XdZ{$ z4jgWF2r&*gbc)Gx774y#F`=lFPad&qUzqIVkste5I17BbgqRxgyV9`*$nU~osw)B8 z3NGDwXf^~wv~Ez>Ekx{4t5iie!>`=}R2X5in?a!t0ELQ<@F*+#UG);^ReU6SVZ~@L z)>ffIc8?HcCR*)qj}U2JNGfAXKnr49)q*yGLd`=RDOPk%EkO5IrE{tixT{}= z7!8hiQft*Y)gFqaG^o<>ka>?4O=xzYguOOt2hF{X!0#2Hw(NB%2@?ZX`wINs%g5S* zt9=8RWDug|z-L+^)&}W1FYwUuF%zWg3Q$N9glHKsrITV#;H^(bXWj+2-W?kB0(85? zdTVbv4fHAxFsdo=OphaPg$=twe4hXnmD{W*4EOO6y9SmF4EVQCfC^Wov34WuF$l0> iXffnsS@4G;4b#Dn{w!oX1#$geaH-#iTGwXzx&8x?bqWgr delta 1180 zcmZ9MYfO`86vug<7HGBFGHw-Q6^7hGAR^FORvojN7FSZBfFpussd96;N=9fVG+r_= z2vSZdrO;w&JBPTi*$n4qhQ@KLwJ?t|467nUcCvlP|#h05Z9U=(1> zEBO9V|F%1MAIqpo<9ivF$|D1F%8S--C!X)#w25}S(EPfQ`dTK(eO-`mWzml_>b0t~ zrUKiNOGjdjNtw4=;h!ZbVaSRKXISS>=5@sV61_ir&nK?qX_MF0ZfWNNx;_voke8PC z`_3;T8{RCJ~s6!pDWh9@l>eRQYp z@{ei7xIoii6_Hs{HD3F0RXZS3ET7Df?F;F6fAFrD+U$MMCsgKEp8MEyC7N~NY~HQ* zioplT?L4*Xpwu%_tuj5hDO*^W9N^VA8-8BAwxGDJP-ib1Zk>8+dGW)_wR?gyQ6poY z`>LlVjg~#rW#4r5){gYiYW=M7eOd`Ubq<<`dN0MHcK+>p0PEtZg&Y^~2=;|{^<0XbU=H-^`DhJLQw}nLyeS3G zhk=J72u7OtC<<5xIT{6}Ar%M3K#JK54Dl>@X5izZcv7+O6G0{JPFj|^l$0wY) z)GWf+4-oEB^LEH;5#S6VA%}%-U~l1KGa>7ZNqAmF1ahMU>m>x9X3PT2Dj^0RC~=2`wm5VHlx->a zr!vBns%S9X#>IguQtp7mmNqQD@4+1i*&2fI)0zO0hK`dApigX diff --git a/configure.in b/configure.in index 79cac877f..778a929db 100644 --- a/configure.in +++ b/configure.in @@ -16,9 +16,9 @@ dnl Set various version strings - taken gratefully from the GTk sources # SDL_MAJOR_VERSION=1 SDL_MINOR_VERSION=2 -SDL_MICRO_VERSION=11 -SDL_INTERFACE_AGE=0 -SDL_BINARY_AGE=11 +SDL_MICRO_VERSION=12 +SDL_INTERFACE_AGE=1 +SDL_BINARY_AGE=12 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION AC_SUBST(SDL_MAJOR_VERSION) diff --git a/include/SDL_version.h b/include/SDL_version.h index 262aa7b5e..610ffe679 100644 --- a/include/SDL_version.h +++ b/include/SDL_version.h @@ -37,7 +37,7 @@ extern "C" { */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 11 +#define SDL_PATCHLEVEL 12 typedef struct SDL_version { Uint8 major; From 2f28b8c5d02b7d71a640694eb7c276dd8e77b88b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 24 Sep 2006 00:36:24 +0000 Subject: [PATCH 028/241] Fixed bug #270 SDL_SetCursor returns void, not void* --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402109 --- docs/html/sdlsetcursor.html | 4 ++-- docs/man3/SDL_SetCursor.3 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/html/sdlsetcursor.html b/docs/html/sdlsetcursor.html index e6480a9e1..9c5443e53 100644 --- a/docs/html/sdlsetcursor.html +++ b/docs/html/sdlsetcursor.html @@ -102,7 +102,7 @@ CLASS="FUNCSYNOPSISINFO" >void *void SDL_SetCursor \ No newline at end of file +> diff --git a/docs/man3/SDL_SetCursor.3 b/docs/man3/SDL_SetCursor.3 index 6711274ff..462c2cac3 100644 --- a/docs/man3/SDL_SetCursor.3 +++ b/docs/man3/SDL_SetCursor.3 @@ -5,7 +5,7 @@ SDL_SetCursor\- Set the currently active mouse cursor\&. .PP \fB#include "SDL\&.h" .sp -\fBvoid *\fBSDL_SetCursor\fP\fR(\fBSDL_Cursor *cursor\fR); +\fBvoid \fBSDL_SetCursor\fP\fR(\fBSDL_Cursor *cursor\fR); .SH "DESCRIPTION" .PP Sets the currently active cursor to the specified one\&. If the cursor is currently visible, the change will be immediately represented on the display\&. From 045a682ec0445eb4e10b3ce00c1edbb410ae58fa Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 24 Sep 2006 00:43:36 +0000 Subject: [PATCH 029/241] Fixed bug #321 Hi, if "configure" is given an explicit --libdir, the sdl-config still contains the default "${exec_prefix}/lib" for runtime linker path. That should be changed to $libdir, as this is where the library goes to... Regards, Juergen --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402111 --- configure.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.in b/configure.in index 778a929db..1983f66d9 100644 --- a/configure.in +++ b/configure.in @@ -2612,10 +2612,10 @@ SDLMAIN_OBJECTS=`echo $SDLMAIN_OBJECTS | sed 's,[[^ ]]*/\([[^ ]]*\)\.c,$(objects if test "x$enable_rpath" = "xyes"; then if test $ARCH = bsdi -o $ARCH = freebsd -o $ARCH = irix -o $ARCH = linux -o $ARCH = netbsd; then - SDL_RLD_FLAGS="-Wl,-rpath,\${exec_prefix}/lib" + SDL_RLD_FLAGS="-Wl,-rpath,\${libdir}" fi if test $ARCH = solaris; then - SDL_RLD_FLAGS="-R\${exec_prefix}/lib" + SDL_RLD_FLAGS="-R\${libdir}" fi else SDL_RLD_FLAGS="" @@ -2630,7 +2630,7 @@ case "$ARCH" in SDL_LIBS="$SDL_LIBS -Wl,-framework,Carbon" fi # Evil hack to allow static linking on Mac OS X - SDL_STATIC_LIBS="\${exec_prefix}/lib/libSDLmain.a \${exec_prefix}/lib/libSDL.a $EXTRA_LDFLAGS" + SDL_STATIC_LIBS="\${libdir}/libSDLmain.a \${libdir}/libSDL.a $EXTRA_LDFLAGS" ;; *) SDL_STATIC_LIBS="$SDL_LIBS" From e37cb653ba335bd4d031f08a95d619d9c96307e4 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 24 Sep 2006 00:55:00 +0000 Subject: [PATCH 030/241] Fixed bug #316 Looks like this is a long standing typo... is this code even used anymore? --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402113 --- src/audio/ums/SDL_umsaudio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/ums/SDL_umsaudio.c b/src/audio/ums/SDL_umsaudio.c index 90bcd9b5b..e873b5636 100644 --- a/src/audio/ums/SDL_umsaudio.c +++ b/src/audio/ums/SDL_umsaudio.c @@ -136,7 +136,7 @@ static SDL_AudioDevice *Audio_CreateDevice(int devindex) } AudioBootStrap UMS_bootstrap = { - UMS_DRIVER_NAME, "AUX UMS audio", + UMS_DRIVER_NAME, "AIX UMS audio", Audio_Available, Audio_CreateDevice }; From fd8b91f9828af741a68ed6fc35e47521602c9ed6 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 24 Sep 2006 01:27:40 +0000 Subject: [PATCH 031/241] Fixed bug #281 ------- Comment #2 From Christian Walther 2006-07-23 07:37 [reply] ------- Wow, that was an interesting bug to chase. It was a timing issue: it seems that for some reason, a certain time must pass between ShowMenuBar() being called in QZ_UnsetVideoMode() and the application quitting. Before rev. 1885, this delay was provided by the slow hand-coded fade. With the asynchronous Core Graphics fading introduced in rev. 1885, that delay was no longer present (most of the time) and the bug became apparent. Adding an SDL_Delay(100) somewhere between ShowMenuBar() and the end of QZ_VideoQuit() lowered the frequency of the bug appearing from "almost every time" to "very rarely" here. However, there is another solution: doing the ShowMenuBar() before releasing the captured display instead of afterwards. Apparently, no delay is necessary in that case, and it looks nicer to me anyway because it is the reverse order of the way things are set up in the beginning: capture display - set video mode - hide menu bar - ... - show menu bar - reset video mode - release captured display. So, this is what the attached patch does. In addition, I've taken the liberty of - removing some unused code that I forgot to remove in rev. 1885, - fixing two warnings about undeclared functions in SDL_QuartzVideo.m by including OpenGL.h (whose name is a bit misleading - it only declares CGL stuff, so there's no interference with SDL_opengl.h). --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402115 --- src/video/quartz/SDL_QuartzVideo.h | 2 +- src/video/quartz/SDL_QuartzVideo.m | 17 +---------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/video/quartz/SDL_QuartzVideo.h b/src/video/quartz/SDL_QuartzVideo.h index c7b68ec34..be3daef09 100644 --- a/src/video/quartz/SDL_QuartzVideo.h +++ b/src/video/quartz/SDL_QuartzVideo.h @@ -54,7 +54,7 @@ #include #include #include -#include /* For CGLContextObj */ +#include /* For CGL functions and types */ #include /* For powersave handling */ #include diff --git a/src/video/quartz/SDL_QuartzVideo.m b/src/video/quartz/SDL_QuartzVideo.m index 8d41169ce..bfac0930c 100644 --- a/src/video/quartz/SDL_QuartzVideo.m +++ b/src/video/quartz/SDL_QuartzVideo.m @@ -43,21 +43,6 @@ @end -/* - Structure for rez switch gamma fades - We can hide the monitor flicker by setting the gamma tables to 0 -*/ -#define QZ_GAMMA_TABLE_SIZE 256 - -typedef struct { - - CGGammaValue red[QZ_GAMMA_TABLE_SIZE]; - CGGammaValue green[QZ_GAMMA_TABLE_SIZE]; - CGGammaValue blue[QZ_GAMMA_TABLE_SIZE]; - -} SDL_QuartzGammaTable; - - /* Bootstrap functions */ static int QZ_Available (); static SDL_VideoDevice* QZ_CreateDevice (int device_index); @@ -385,10 +370,10 @@ static void QZ_UnsetVideoMode (_THIS, BOOL to_desktop) { CGLSetFullScreen (NULL); } if (to_desktop) { + ShowMenuBar (); /* Restore original screen resolution/bpp */ CGDisplaySwitchToMode (display_id, save_mode); CGReleaseAllDisplays (); - ShowMenuBar (); /* Reset the main screen's rectangle See comment in QZ_SetVideoFullscreen for why we do this From 29285b1030d7d71fe1af28db87551f7f3858e704 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 24 Sep 2006 15:31:42 +0000 Subject: [PATCH 032/241] Fixed bug #286 Date: Thu, 9 Feb 2006 17:06:51 +0300 From: "Oleg K [BeSman]" Subject: BeOS SDL patches Hello all. My name is Oleg K. [BeSman], Im a BeOS user from Russia.This mail contain a BeOs-specific patches to SDL (implementation of InputGrabbing and mouse_relative mode). See the source in attached file for details. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402116 --- src/video/bwindow/SDL_BView.h | 35 +-- src/video/bwindow/SDL_BWin.h | 311 +------------------------- src/video/bwindow/SDL_sysevents.cc | 336 +++++++++++++++++++++++++++++ src/video/bwindow/SDL_sysmouse.cc | 17 +- src/video/bwindow/SDL_sysmouse_c.h | 1 + src/video/bwindow/SDL_sysvideo.cc | 28 ++- src/video/bwindow/SDL_syswm.cc | 38 +++- src/video/bwindow/SDL_syswm_c.h | 1 + 8 files changed, 410 insertions(+), 357 deletions(-) diff --git a/src/video/bwindow/SDL_BView.h b/src/video/bwindow/SDL_BView.h index 6d2547e3d..f78d17216 100644 --- a/src/video/bwindow/SDL_BView.h +++ b/src/video/bwindow/SDL_BView.h @@ -37,22 +37,12 @@ public: BView(frame, "SDL View", B_FOLLOW_ALL_SIDES, (B_WILL_DRAW|B_FRAME_EVENTS)) { image = NULL; - xoff = yoff = 0; SetViewColor(0,0,0,0); SetHighColor(0,0,0,0); } virtual ~SDL_BView() { SetBitmap(NULL); } - /* Set drawing offsets for fullscreen mode */ - virtual void SetXYOffset(int x, int y) { - xoff = x; - yoff = y; - } - virtual void GetXYOffset(int &x, int &y) { - x = xoff; - y = yoff; - } /* The view changed size. If it means we're in fullscreen, we * draw a nice black box in the entire view to get black borders. */ @@ -62,14 +52,14 @@ public: bounds.right = width; bounds.bottom = height; /* Fill the entire view with black */ - FillRect(bounds, B_SOLID_HIGH); +// FillRect(bounds, B_SOLID_HIGH); /* And if there's an image, redraw it. */ if( image ) { bounds = image->Bounds(); Draw(bounds); } } - + /* Drawing portion of this complete breakfast. :) */ virtual void SetBitmap(BBitmap *bitmap) { if ( image ) { @@ -79,34 +69,17 @@ public: } virtual void Draw(BRect updateRect) { if ( image ) { - if(xoff || yoff) { - BRect dest; - dest.top = updateRect.top + yoff; - dest.left = updateRect.left + xoff; - dest.bottom = updateRect.bottom + yoff; - dest.right = updateRect.right + xoff; - DrawBitmap(image, updateRect, dest); - } else { - DrawBitmap(image, updateRect, updateRect); - } + DrawBitmap(image, updateRect, updateRect); } } virtual void DrawAsync(BRect updateRect) { - if(xoff || yoff) { - BRect dest; - dest.top = updateRect.top + yoff; - dest.left = updateRect.left + xoff; - dest.bottom = updateRect.bottom + yoff; - dest.right = updateRect.right + xoff;; - DrawBitmapAsync(image, updateRect, dest); - } else { + if ( image ) { DrawBitmapAsync(image, updateRect, updateRect); } } private: BBitmap *image; - int xoff, yoff; }; #endif /* _SDL_BView_h */ diff --git a/src/video/bwindow/SDL_BWin.h b/src/video/bwindow/SDL_BWin.h index a6d3ef8d9..ea1783690 100644 --- a/src/video/bwindow/SDL_BWin.h +++ b/src/video/bwindow/SDL_BWin.h @@ -40,6 +40,8 @@ extern "C" { #include "../../events/SDL_events_c.h" + +extern int mouse_relative; }; class SDL_BWin : public BDirectWindow @@ -47,9 +49,7 @@ class SDL_BWin : public BDirectWindow public: SDL_BWin(BRect bounds) : BDirectWindow(bounds, "Untitled", B_TITLED_WINDOW, 0) { - InitKeyboard(); last_buttons = 0; - the_view = NULL; #if SDL_VIDEO_OPENGL SDL_GLView = NULL; @@ -82,118 +82,6 @@ public: } } - virtual void InitKeyboard(void) { - for ( uint i=0; iSetBitmap(bitmap); } - virtual void SetXYOffset(int x, int y) { -#if SDL_VIDEO_OPENGL - if ( the_view == SDL_GLView ) { - return; - } -#endif - SDL_View->SetXYOffset(x, y); - } - virtual void GetXYOffset(int &x, int &y) { -#if SDL_VIDEO_OPENGL - if ( the_view == SDL_GLView ) { - x = 0; - y = 0; - return; - } -#endif - SDL_View->GetXYOffset(x, y); - } virtual bool BeginDraw(void) { return(Lock()); } @@ -367,179 +237,7 @@ public: return unicode; } - virtual void DispatchMessage(BMessage *msg, BHandler *target) { - switch (msg->what) { - case B_MOUSE_MOVED: - { - BPoint where; - int32 transit; - if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) { - if (transit == B_EXITED_VIEW) { - if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { - SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); - be_app->SetCursor(B_HAND_CURSOR); - } - } else { - int x, y; - if ( ! (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { - SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); - SDL_SetCursor(NULL); - } - GetXYOffset(x, y); - x = (int)where.x - x; - y = (int)where.y - y; - SDL_PrivateMouseMotion(0, 0, x, y); - } - } - break; - } - - case B_MOUSE_DOWN: - { - /* it looks like mouse down is send only for first clicked - button, each next is not send while last one is holded */ - int32 buttons; - int sdl_buttons = 0; - if (msg->FindInt32("buttons", &buttons) == B_OK) { - /* Add any mouse button events */ - if (buttons & B_PRIMARY_MOUSE_BUTTON) { - sdl_buttons |= SDL_BUTTON_LEFT; - } - if (buttons & B_SECONDARY_MOUSE_BUTTON) { - sdl_buttons |= SDL_BUTTON_RIGHT; - } - if (buttons & B_TERTIARY_MOUSE_BUTTON) { - sdl_buttons |= SDL_BUTTON_MIDDLE; - } - SDL_PrivateMouseButton(SDL_PRESSED, sdl_buttons, 0, 0); - - last_buttons = buttons; - } - break; - } - - case B_MOUSE_UP: - { - /* mouse up doesn't give which button was released, - only state of buttons (after release, so it's always = 0), - which is not what we need ;] - So we need to store button in mouse down, and restore - in mouse up :( - mouse up is (similarly to mouse down) send only for - first button down (ie. it's no send if we click another button - without releasing previous one first) - but that's probably - because of how drivers are written?, not BeOS itself. */ - int32 buttons; - int sdl_buttons = 0; - if (msg->FindInt32("buttons", &buttons) == B_OK) { - /* Add any mouse button events */ - if ((buttons ^ B_PRIMARY_MOUSE_BUTTON) & last_buttons) { - sdl_buttons |= SDL_BUTTON_LEFT; - } - if ((buttons ^ B_SECONDARY_MOUSE_BUTTON) & last_buttons) { - sdl_buttons |= SDL_BUTTON_RIGHT; - } - if ((buttons ^ B_TERTIARY_MOUSE_BUTTON) & last_buttons) { - sdl_buttons |= SDL_BUTTON_MIDDLE; - } - SDL_PrivateMouseButton(SDL_RELEASED, sdl_buttons, 0, 0); - - last_buttons = buttons; - } - break; - } - - case B_MOUSE_WHEEL_CHANGED: - { - float x, y; - x = y = 0; - if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) { - if (x < 0 || y < 0) { - SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0); - SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0); - } else if (x > 0 || y > 0) { - SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0); - SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0); - } - } - break; - } - - case B_KEY_DOWN: - case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */ - { - int32 key; - int32 modifiers; - int32 key_repeat; - /* Workaround for SDL message queue being filled too fast because of BeOS own key-repeat mechanism */ - if (msg->FindInt32("be:key_repeat", &key_repeat) == B_OK && key_repeat > 0) - break; - - if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) { - SDL_keysym keysym; - keysym.scancode = key; - if ((key > 0) && (key < 128)) { - keysym.sym = keymap[key]; - } else { - keysym.sym = SDLK_UNKNOWN; - } - /* FIX THIS? - it seems SDL_PrivateKeyboard() changes mod value - anyway, and doesn't care about what we setup here */ - keysym.mod = KMOD_NONE; - keysym.unicode = 0; - if (SDL_TranslateUNICODE) { - const char *bytes; - if (msg->FindString("bytes", &bytes) == B_OK) { - /* FIX THIS? - this cares only about first "letter", - so if someone maps some key to print - "BeOS rulez!" only "B" will be used. */ - keysym.unicode = Translate2Unicode(bytes); - } - } - SDL_PrivateKeyboard(SDL_PRESSED, &keysym); - } - break; - } - - case B_KEY_UP: - case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */ - { - int32 key; - int32 modifiers; - if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) { - SDL_keysym keysym; - keysym.scancode = key; - if ((key > 0) && (key < 128)) { - keysym.sym = keymap[key]; - } else { - keysym.sym = SDLK_UNKNOWN; - } - keysym.mod = KMOD_NONE; /* FIX THIS? */ - keysym.unicode = 0; - if (SDL_TranslateUNICODE) { - const char *bytes; - if (msg->FindString("bytes", &bytes) == B_OK) { - keysym.unicode = Translate2Unicode(bytes); - } - } - SDL_PrivateKeyboard(SDL_RELEASED, &keysym); - } - break; - } - - default: - /* move it after switch{} so it's always handled - that way we keep BeOS feautures like: - - CTRL+Q to close window (and other shortcuts) - - PrintScreen to make screenshot into /boot/home - - etc.. */ - //BDirectWindow::DispatchMessage(msg, target); - break; - } - BDirectWindow::DispatchMessage(msg, target); - } + virtual void DispatchMessage(BMessage *msg, BHandler *target); private: #if SDL_VIDEO_OPENGL @@ -547,12 +245,9 @@ private: #endif SDL_BView *SDL_View; BView *the_view; - bool shown; bool inhibit_resize; - int32 last_buttons; - SDLKey keymap[128]; }; #endif /* _SDL_BWin_h */ diff --git a/src/video/bwindow/SDL_sysevents.cc b/src/video/bwindow/SDL_sysevents.cc index dee2f97d2..2a084682b 100644 --- a/src/video/bwindow/SDL_sysevents.cc +++ b/src/video/bwindow/SDL_sysevents.cc @@ -29,6 +29,8 @@ #include "SDL_BWin.h" #include "SDL_lowvideo.h" +static SDLKey keymap[128]; +int mouse_relative = 0; extern "C" { #include "../../events/SDL_sysevents.h" @@ -41,6 +43,340 @@ void BE_PumpEvents(_THIS) void BE_InitOSKeymap(_THIS) { + for ( uint i=0; iwhat) { + case B_MOUSE_MOVED: + { + SDL_VideoDevice *view = current_video; + BPoint where; + int32 transit; + if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) { + +//BeSman: I need another method for cursor catching !!! +if(view->input_grab != SDL_GRAB_OFF) +{ + BPoint center; + center.x = (SDL_VideoSurface->w/2); + center.y = (SDL_VideoSurface->h/2); + BPoint delta = where - center; +if(delta.x > center.x) +SDL_WarpMouse((int)center.x*2,(int)where.y); + +if(delta.x < -center.x) +SDL_WarpMouse(0,(int)where.y); + +if(delta.y > center.y) +SDL_WarpMouse((int)where.x,(int)center.y*2); + +if(delta.y < -center.y) +SDL_WarpMouse((int)where.x,0); + + +if((delta.x-1 < -center.x)&&(delta.y-1 < -center.y)) +SDL_WarpMouse(1,1); + +if((delta.x-1 < -center.x)&&(delta.y+1 > center.y)) +SDL_WarpMouse(1,(int)center.y*2-1); + +if((delta.x+1 > center.x)&&(delta.y-1 < -center.y)) +SDL_WarpMouse((int)center.x*2-1,1); + +if((delta.x+1 > center.x)&&(delta.y+1 > center.y)) +SDL_WarpMouse((int)center.x*2-1,(int)center.y*2-1); + +} + if (transit == B_EXITED_VIEW) { + if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { + SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); + // be_app->SetCursor(B_HAND_CURSOR); + } + } else { + + int x, y; + if ( ! (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { + SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); + SDL_SetCursor(NULL); + } + x = (int)where.x; + y = (int)where.y; + + if ( mouse_relative ) { + BPoint center; + center.x = (SDL_VideoSurface->w/2); + center.y = (SDL_VideoSurface->h/2); + x -= (int)center.x; + y -= (int)center.y; + if ( x || y ) { + ConvertToScreen(¢er); + set_mouse_position((int)center.x, (int)center.y); + SDL_PrivateMouseMotion(0, 1, x, y); + } + } else { + SDL_PrivateMouseMotion(0, 0, x, y); + } + } + } + break; + } + + case B_MOUSE_DOWN: + { + /* it looks like mouse down is send only for first clicked + button, each next is not send while last one is holded */ + int32 buttons; + int sdl_buttons = 0; + if (msg->FindInt32("buttons", &buttons) == B_OK) { + /* Add any mouse button events */ + if (buttons & B_PRIMARY_MOUSE_BUTTON) { + sdl_buttons |= SDL_BUTTON_LEFT; + } + if (buttons & B_SECONDARY_MOUSE_BUTTON) { + sdl_buttons |= SDL_BUTTON_RIGHT; + } + if (buttons & B_TERTIARY_MOUSE_BUTTON) { + sdl_buttons |= SDL_BUTTON_MIDDLE; + } + SDL_PrivateMouseButton(SDL_PRESSED, sdl_buttons, 0, 0); + + last_buttons = buttons; + } + break; + } + + case B_MOUSE_UP: + { + /* mouse up doesn't give which button was released, + only state of buttons (after release, so it's always = 0), + which is not what we need ;] + So we need to store button in mouse down, and restore + in mouse up :( + mouse up is (similarly to mouse down) send only for + first button down (ie. it's no send if we click another button + without releasing previous one first) - but that's probably + because of how drivers are written?, not BeOS itself. */ + int32 buttons; + int sdl_buttons = 0; + if (msg->FindInt32("buttons", &buttons) == B_OK) { + /* Add any mouse button events */ + if ((buttons ^ B_PRIMARY_MOUSE_BUTTON) & last_buttons) { + sdl_buttons |= SDL_BUTTON_LEFT; + } + if ((buttons ^ B_SECONDARY_MOUSE_BUTTON) & last_buttons) { + sdl_buttons |= SDL_BUTTON_RIGHT; + } + if ((buttons ^ B_TERTIARY_MOUSE_BUTTON) & last_buttons) { + sdl_buttons |= SDL_BUTTON_MIDDLE; + } + SDL_PrivateMouseButton(SDL_RELEASED, sdl_buttons, 0, 0); + + last_buttons = buttons; + } + break; + } + + case B_MOUSE_WHEEL_CHANGED: + { + float x, y; + x = y = 0; + if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) { + if (x < 0 || y < 0) { + SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0); + SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0); + } else if (x > 0 || y > 0) { + SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0); + SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0); + } + } + break; + } + + case B_KEY_DOWN: + case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */ + { + int32 key; + int32 modifiers; + int32 key_repeat; + /* Workaround for SDL message queue being filled too fast because of BeOS own key-repeat mechanism */ + if (msg->FindInt32("be:key_repeat", &key_repeat) == B_OK && key_repeat > 0) + break; + + if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) { + SDL_keysym keysym; + keysym.scancode = key; + if (key < 128) { + keysym.sym = keymap[key]; + } else { + keysym.sym = SDLK_UNKNOWN; + } + /* FIX THIS? + it seems SDL_PrivateKeyboard() changes mod value + anyway, and doesn't care about what we setup here */ + keysym.mod = KMOD_NONE; + keysym.unicode = 0; + if (SDL_TranslateUNICODE) { + const char *bytes; + if (msg->FindString("bytes", &bytes) == B_OK) { + /* FIX THIS? + this cares only about first "letter", + so if someone maps some key to print + "BeOS rulez!" only "B" will be used. */ + keysym.unicode = Translate2Unicode(bytes); + } + } + SDL_PrivateKeyboard(SDL_PRESSED, &keysym); + } + break; + } + + case B_KEY_UP: + case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */ + { + int32 key; + int32 modifiers; + if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) { + SDL_keysym keysym; + keysym.scancode = key; + if (key < 128) { + keysym.sym = keymap[key]; + } else { + keysym.sym = SDLK_UNKNOWN; + } + keysym.mod = KMOD_NONE; /* FIX THIS? */ + keysym.unicode = 0; + if (SDL_TranslateUNICODE) { + const char *bytes; + if (msg->FindString("bytes", &bytes) == B_OK) { + keysym.unicode = Translate2Unicode(bytes); + } + } + SDL_PrivateKeyboard(SDL_RELEASED, &keysym); + } + break; + } + + default: + /* move it after switch{} so it's always handled + that way we keep BeOS feautures like: + - CTRL+Q to close window (and other shortcuts) + - PrintScreen to make screenshot into /boot/home + - etc.. */ + //BDirectWindow::DispatchMessage(msg, target); + break; + } + BDirectWindow::DispatchMessage(msg, target); +} diff --git a/src/video/bwindow/SDL_sysmouse.cc b/src/video/bwindow/SDL_sysmouse.cc index 34644f6de..5efaf3838 100644 --- a/src/video/bwindow/SDL_sysmouse.cc +++ b/src/video/bwindow/SDL_sysmouse.cc @@ -27,7 +27,7 @@ #include "SDL_BWin.h" extern "C" { - +#include "SDL_cursor_c.h" #include "SDL_sysmouse_c.h" /* Convert bits to padded bytes */ @@ -128,11 +128,26 @@ void BE_FreeWMCursor(_THIS, WMcursor *cursor) /* Implementation by Christian Bauer */ void BE_WarpWMCursor(_THIS, Uint16 x, Uint16 y) { + if (_this->screen && (_this->screen->flags & SDL_FULLSCREEN) ) { + SDL_PrivateMouseMotion(0, 0, x, y); + } else { BPoint pt(x, y); SDL_Win->Lock(); SDL_Win->ConvertToScreen(&pt); SDL_Win->Unlock(); set_mouse_position((int32)pt.x, (int32)pt.y); + } +} +/* Check to see if we need to enter or leave mouse relative mode */ +void BE_CheckMouseMode(_THIS) +{ + /* If the mouse is hidden and input is grabbed, we use relative mode */ + if ( !(SDL_cursorstate & CURSOR_VISIBLE) && + (_this->input_grab != SDL_GRAB_OFF) ) { + mouse_relative = 1; + } else { + mouse_relative = 0; + } } }; /* Extern C */ diff --git a/src/video/bwindow/SDL_sysmouse_c.h b/src/video/bwindow/SDL_sysmouse_c.h index e4ee25534..4f4844eef 100644 --- a/src/video/bwindow/SDL_sysmouse_c.h +++ b/src/video/bwindow/SDL_sysmouse_c.h @@ -29,4 +29,5 @@ extern WMcursor *BE_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); extern int BE_ShowWMCursor(_THIS, WMcursor *cursor); extern void BE_WarpWMCursor(_THIS, Uint16 x, Uint16 y); +extern void BE_CheckMouseMode(_THIS); diff --git a/src/video/bwindow/SDL_sysvideo.cc b/src/video/bwindow/SDL_sysvideo.cc index 18e305ad4..7ee02c3e0 100644 --- a/src/video/bwindow/SDL_sysvideo.cc +++ b/src/video/bwindow/SDL_sysvideo.cc @@ -135,7 +135,7 @@ static SDL_VideoDevice *BE_CreateDevice(int devindex) device->SetCaption = BE_SetWMCaption; device->SetIcon = NULL; device->IconifyWindow = BE_IconifyWindow; - device->GrabInput = NULL; + device->GrabInput = BE_GrabInput; device->GetWMInfo = BE_GetWMInfo; /* Cursor manager functions */ device->FreeWMCursor = BE_FreeWMCursor; @@ -143,7 +143,7 @@ static SDL_VideoDevice *BE_CreateDevice(int devindex) device->ShowWMCursor = BE_ShowWMCursor; device->WarpWMCursor = BE_WarpWMCursor; device->MoveWMCursor = NULL; - device->CheckMouseMode = NULL; + device->CheckMouseMode = BE_CheckMouseMode; /* Event manager functions */ device->InitOSKeymap = BE_InitOSKeymap; device->PumpEvents = BE_PumpEvents; @@ -365,8 +365,11 @@ static bool BE_FindClosestFSMode(_THIS, int width, int height, int bpp, if ( ! modes[i] || (modes[i]->w < width) || (modes[i]->h < width) ) { --i; /* We went too far */ } - width = modes[i]->w; - height = modes[i]->h; + +/* BeSman::We dont want to use a Desktop resolution */ +// width = modes[i]->w; +// height = modes[i]->h; + bscreen.GetModeList(&dmodes, &nmodes); for ( i = 0; i < nmodes; ++i ) { if ( (bpp == ColorSpaceToBitsPerPixel(dmodes[i].space)) && @@ -433,7 +436,7 @@ static int BE_SetFullScreen(_THIS, SDL_Surface *screen, int fullscreen) } if ( SDL_Win->Lock() ) { - int xoff, yoff; + int cx, cy; if ( SDL_Win->Shown() ) { needs_unlock = 1; SDL_Win->Hide(); @@ -449,19 +452,12 @@ static int BE_SetFullScreen(_THIS, SDL_Surface *screen, int fullscreen) /* Calculate offsets - used either to center window * (windowed mode) or to set drawing offsets (fullscreen mode) */ - xoff = (bounds.IntegerWidth() - width)/2; - yoff = (bounds.IntegerHeight() - height)/2; - if ( fullscreen ) { - /* Set offset for drawing */ - SDL_Win->SetXYOffset(xoff, yoff); - } else { - /* Center window and reset the drawing offset */ - SDL_Win->SetXYOffset(0, 0); - } + cx = (bounds.IntegerWidth() - width)/2; + cy = (bounds.IntegerHeight() - height)/2; + if ( ! needs_unlock || was_fullscreen ) { /* Center the window the first time */ - SDL_Win->MoveTo(xoff > 0 ? (float)xoff : 0.0f, - yoff > 0 ? (float)yoff : 0.0f); + SDL_Win->MoveTo(cx, cy); } SDL_Win->Show(); diff --git a/src/video/bwindow/SDL_syswm.cc b/src/video/bwindow/SDL_syswm.cc index 81bda1a81..1083caf0f 100644 --- a/src/video/bwindow/SDL_syswm.cc +++ b/src/video/bwindow/SDL_syswm.cc @@ -24,9 +24,9 @@ #include "SDL_BWin.h" extern "C" { - #include "SDL_syswm_c.h" #include "SDL_error.h" +#include "../SDL_cursor_c.h" void BE_SetWMCaption(_THIS, const char *title, const char *icon) { @@ -38,6 +38,42 @@ int BE_IconifyWindow(_THIS) SDL_Win->Minimize(true); } +SDL_GrabMode BE_GrabInput(_THIS, SDL_GrabMode mode) +{ + if ( mode == SDL_GRAB_OFF ) { +// be_app->ShowCursor(); + if ( !(SDL_cursorstate & CURSOR_VISIBLE) ) { + /* BeSman: Jan 2, 2006 + must be leaving relative mode, move mouse from + center of window to where it belongs ... */ + BPoint pt; + int x, y; + SDL_GetMouseState(&x,&y); + pt.x = x; + pt.y = y; + SDL_Win->Lock(); + SDL_Win->ConvertToScreen(&pt); + SDL_Win->Unlock(); + set_mouse_position((int)pt.x, (int)pt.y); + } + } else { +// be_app->HideCursor(); + if ( !(SDL_cursorstate & CURSOR_VISIBLE) ) { + /* BeSman: Jan 2, 2006 + must be entering relative mode, get ready by + moving mouse to center of window ... */ + BPoint pt; + pt.x = (SDL_VideoSurface->w/2); + pt.y = (SDL_VideoSurface->h/2); + SDL_Win->Lock(); + SDL_Win->ConvertToScreen(&pt); + SDL_Win->Unlock(); + set_mouse_position((int)pt.x, (int)pt.y); + } + } + return(mode); +} + int BE_GetWMInfo(_THIS, SDL_SysWMinfo *info) { if (info->version.major <= SDL_MAJOR_VERSION) diff --git a/src/video/bwindow/SDL_syswm_c.h b/src/video/bwindow/SDL_syswm_c.h index 44892a8f6..0d33c5e5f 100644 --- a/src/video/bwindow/SDL_syswm_c.h +++ b/src/video/bwindow/SDL_syswm_c.h @@ -29,3 +29,4 @@ extern void BE_SetWMCaption(_THIS, const char *title, const char *icon); extern int BE_IconifyWindow(_THIS); extern int BE_GetWMInfo(_THIS, SDL_SysWMinfo *info); +extern SDL_GrabMode BE_GrabInput(_THIS, SDL_GrabMode mode); \ No newline at end of file From 654f1950a393346682c68dcacf281e367a38fdef Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 24 Sep 2006 15:36:37 +0000 Subject: [PATCH 033/241] Fixed formatting --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402117 --- src/video/bwindow/SDL_sysmouse.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/video/bwindow/SDL_sysmouse.cc b/src/video/bwindow/SDL_sysmouse.cc index 5efaf3838..093814f03 100644 --- a/src/video/bwindow/SDL_sysmouse.cc +++ b/src/video/bwindow/SDL_sysmouse.cc @@ -27,7 +27,7 @@ #include "SDL_BWin.h" extern "C" { -#include "SDL_cursor_c.h" +#include "../SDL_cursor_c.h" #include "SDL_sysmouse_c.h" /* Convert bits to padded bytes */ @@ -128,16 +128,17 @@ void BE_FreeWMCursor(_THIS, WMcursor *cursor) /* Implementation by Christian Bauer */ void BE_WarpWMCursor(_THIS, Uint16 x, Uint16 y) { - if (_this->screen && (_this->screen->flags & SDL_FULLSCREEN) ) { + if (_this->screen && (_this->screen->flags & SDL_FULLSCREEN)) { SDL_PrivateMouseMotion(0, 0, x, y); } else { - BPoint pt(x, y); - SDL_Win->Lock(); - SDL_Win->ConvertToScreen(&pt); - SDL_Win->Unlock(); - set_mouse_position((int32)pt.x, (int32)pt.y); + BPoint pt(x, y); + SDL_Win->Lock(); + SDL_Win->ConvertToScreen(&pt); + SDL_Win->Unlock(); + set_mouse_position((int32)pt.x, (int32)pt.y); } } + /* Check to see if we need to enter or leave mouse relative mode */ void BE_CheckMouseMode(_THIS) { From 64fd559c0d1f7f01414d4a721f3651d99b114465 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 24 Sep 2006 15:45:37 +0000 Subject: [PATCH 034/241] Fixed bug #292 I might be on crack here. It looks like SDL_ConvertMono() in src/audio/SDL_audiocvt.c adds the left and right channels of a stereo stream together, and clamps the new mono channel if it would overflow. Shouldn't it be dividing by 2 to average the two sample points instead of clamping? Otherwise the mono sample point's volume doubles in the conversion. This would also make the conversion faster, as it replaces two branches per sample frame with a bitwise shift. --ryan. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402118 --- src/audio/SDL_audiocvt.c | 71 ++++++++++------------------------------ 1 file changed, 18 insertions(+), 53 deletions(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 24afd0f0a..68c99e1ae 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -44,11 +44,7 @@ void SDLCALL SDL_ConvertMono(SDL_AudioCVT *cvt, Uint16 format) dst = cvt->buf; for ( i=cvt->len_cvt/2; i; --i ) { sample = src[0] + src[1]; - if ( sample > 255 ) { - *dst = 255; - } else { - *dst = (Uint8)sample; - } + *dst = (Uint8)(sample / 2); src += 2; dst += 1; } @@ -62,14 +58,7 @@ void SDLCALL SDL_ConvertMono(SDL_AudioCVT *cvt, Uint16 format) dst = (Sint8 *)cvt->buf; for ( i=cvt->len_cvt/2; i; --i ) { sample = src[0] + src[1]; - if ( sample > 127 ) { - *dst = 127; - } else - if ( sample < -128 ) { - *dst = -128; - } else { - *dst = (Sint8)sample; - } + *dst = (Sint8)(sample / 2); src += 2; dst += 1; } @@ -85,14 +74,10 @@ void SDLCALL SDL_ConvertMono(SDL_AudioCVT *cvt, Uint16 format) for ( i=cvt->len_cvt/4; i; --i ) { sample = (Uint16)((src[0]<<8)|src[1])+ (Uint16)((src[2]<<8)|src[3]); - if ( sample > 65535 ) { - dst[0] = 0xFF; - dst[1] = 0xFF; - } else { - dst[1] = (sample&0xFF); - sample >>= 8; - dst[0] = (sample&0xFF); - } + sample /= 2; + dst[1] = (sample&0xFF); + sample >>= 8; + dst[0] = (sample&0xFF); src += 4; dst += 2; } @@ -100,14 +85,10 @@ void SDLCALL SDL_ConvertMono(SDL_AudioCVT *cvt, Uint16 format) for ( i=cvt->len_cvt/4; i; --i ) { sample = (Uint16)((src[1]<<8)|src[0])+ (Uint16)((src[3]<<8)|src[2]); - if ( sample > 65535 ) { - dst[0] = 0xFF; - dst[1] = 0xFF; - } else { - dst[0] = (sample&0xFF); - sample >>= 8; - dst[1] = (sample&0xFF); - } + sample /= 2; + dst[0] = (sample&0xFF); + sample >>= 8; + dst[1] = (sample&0xFF); src += 4; dst += 2; } @@ -124,18 +105,10 @@ void SDLCALL SDL_ConvertMono(SDL_AudioCVT *cvt, Uint16 format) for ( i=cvt->len_cvt/4; i; --i ) { sample = (Sint16)((src[0]<<8)|src[1])+ (Sint16)((src[2]<<8)|src[3]); - if ( sample > 32767 ) { - dst[0] = 0x7F; - dst[1] = 0xFF; - } else - if ( sample < -32768 ) { - dst[0] = 0x80; - dst[1] = 0x00; - } else { - dst[1] = (sample&0xFF); - sample >>= 8; - dst[0] = (sample&0xFF); - } + sample /= 2; + dst[1] = (sample&0xFF); + sample >>= 8; + dst[0] = (sample&0xFF); src += 4; dst += 2; } @@ -143,18 +116,10 @@ void SDLCALL SDL_ConvertMono(SDL_AudioCVT *cvt, Uint16 format) for ( i=cvt->len_cvt/4; i; --i ) { sample = (Sint16)((src[1]<<8)|src[0])+ (Sint16)((src[3]<<8)|src[2]); - if ( sample > 32767 ) { - dst[1] = 0x7F; - dst[0] = 0xFF; - } else - if ( sample < -32768 ) { - dst[1] = 0x80; - dst[0] = 0x00; - } else { - dst[0] = (sample&0xFF); - sample >>= 8; - dst[1] = (sample&0xFF); - } + sample /= 2; + dst[0] = (sample&0xFF); + sample >>= 8; + dst[1] = (sample&0xFF); src += 4; dst += 2; } From 4ab10dce94d9d485ad3ad8a6e29e8df857629ff3 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 1 Oct 2006 02:07:09 +0000 Subject: [PATCH 035/241] 1.2 backport: Replaced strncmp for SDL_AUDIODRIVER test with strcasecmp. Fixes Bugzilla #334. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402123 --- src/audio/SDL_audio.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 84a5e0742..bac4847ff 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -350,7 +350,7 @@ int SDL_AudioInit(const char *driver_name) This probably isn't the place to do this, but... Shh! :) */ for ( i=0; bootstrap[i]; ++i ) { - if ( SDL_strcmp(bootstrap[i]->name, "esd") == 0 ) { + if ( SDL_strcasecmp(bootstrap[i]->name, "esd") == 0 ) { #ifdef HAVE_PUTENV const char *esd_no_spawn; @@ -381,8 +381,7 @@ int SDL_AudioInit(const char *driver_name) } #endif for ( i=0; bootstrap[i]; ++i ) { - if (SDL_strncmp(bootstrap[i]->name, driver_name, - SDL_strlen(bootstrap[i]->name)) == 0) { + if (SDL_strcasecmp(bootstrap[i]->name, driver_name) == 0) { if ( bootstrap[i]->available() ) { audio=bootstrap[i]->create(idx); break; From b894bd1a3cbb96269b0c911189bea1bf57df8f1c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 1 Oct 2006 02:30:03 +0000 Subject: [PATCH 036/241] backport from 1.3 --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402125 --- src/video/SDL_video.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 322b2f0e0..db52d48dc 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -175,8 +175,7 @@ int SDL_VideoInit (const char *driver_name, Uint32 flags) } #endif for ( i=0; bootstrap[i]; ++i ) { - if ( SDL_strncmp(bootstrap[i]->name, driver_name, - SDL_strlen(bootstrap[i]->name)) == 0 ) { + if ( SDL_strcasecmp(bootstrap[i]->name, driver_name) == 0) { if ( bootstrap[i]->available() ) { video = bootstrap[i]->create(index); break; From 0a1cd99daf20e3bd3943182c649011528c4ab36b Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 21 Oct 2006 18:53:33 +0000 Subject: [PATCH 037/241] Also save/restore fpu register in vbl interrupt --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402198 --- src/timer/mint/SDL_systimer.c | 5 +++++ src/timer/mint/SDL_vbltimer.S | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/timer/mint/SDL_systimer.c b/src/timer/mint/SDL_systimer.c index 8963ca0b7..0a3e71a84 100644 --- a/src/timer/mint/SDL_systimer.c +++ b/src/timer/mint/SDL_systimer.c @@ -48,6 +48,9 @@ #include "SDL_vbltimer_s.h" +/* from audio/mint */ +void SDL_MintAudio_CheckFpu(void); + /* The first ticks value of the application */ static Uint32 start; static SDL_bool supervisor; @@ -119,6 +122,8 @@ int SDL_SYS_TimerInit(void) supervisor=SDL_FALSE; + SDL_MintAudio_CheckFpu(); + /* Install RunTimer in vbl vector */ oldpile=(void *)Super(0); timer_installed = !SDL_AtariVblInstall(RunTimer); diff --git a/src/timer/mint/SDL_vbltimer.S b/src/timer/mint/SDL_vbltimer.S index d9b4a1b9b..6dfd49970 100644 --- a/src/timer/mint/SDL_vbltimer.S +++ b/src/timer/mint/SDL_vbltimer.S @@ -33,6 +33,8 @@ .globl _SDL_AtariVblInstall .globl _SDL_AtariVblUninstall + .globl _SDL_MintAudio_hasfpu + /*--- Vector installer ---*/ _SDL_AtariVblInstall: @@ -113,8 +115,30 @@ _my_vbl: notw vbl_mutex moveml d0-d7/a0-a6,sp@- + + /* Save FPU if needed */ + tstw _SDL_MintAudio_hasfpu + beqs SDL_AtariVbl_nofpu1 + .chip 68060 + fsave sp@- + fmoveml fpcr/fpsr/fpiar,sp@- + fmovemx fp0-fp7,sp@- + .chip 68000 +SDL_AtariVbl_nofpu1: + movel my_vector,a0 jsr a0@ + + /* Restore FPU if needed */ + tstw _SDL_MintAudio_hasfpu + beqs SDL_AtariVbl_Xbios_nofpu2 + .chip 68060 + fmovemx sp@+,fp0-fp7 + fmoveml sp@+,fpcr/fpsr/fpiar + frestore sp@+ + .chip 68000 +SDL_AtariVbl_Xbios_nofpu2: + moveml sp@+,d0-d7/a0-a6 clrw vbl_mutex From fce92444414b041b24ffeb03cff0fce93a1f8e1a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 27 Oct 2006 20:18:24 +0000 Subject: [PATCH 038/241] Fix for buffer overflow in audio code, when feeding a device that needs resampling. Fixes Bugzilla #298. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402200 --- src/audio/SDL_audio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index bac4847ff..21f05b28e 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -590,7 +590,8 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) return(-1); } if ( audio->convert.needed ) { - audio->convert.len = desired->size; + audio->convert.len = (int) ( ((double) desired->size) / + audio->convert.len_ratio ); audio->convert.buf =(Uint8 *)SDL_AllocAudioMem( audio->convert.len*audio->convert.len_mult); if ( audio->convert.buf == NULL ) { From 239244f8678f658698c87b3710176d52da821da3 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 29 Oct 2006 02:46:42 +0000 Subject: [PATCH 039/241] Closing minor memory leak in XME code. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402209 --- src/video/Xext/XME/xme.c | 10 ++++++++++ src/video/Xext/extensions/xme.h | 4 ++++ src/video/x11/SDL_x11video.c | 4 ++++ 3 files changed, 18 insertions(+) diff --git a/src/video/Xext/XME/xme.c b/src/video/Xext/XME/xme.c index 0a7379642..a3674d53d 100644 --- a/src/video/Xext/XME/xme.c +++ b/src/video/Xext/XME/xme.c @@ -393,3 +393,13 @@ Bool XiGMiscFullScreen(Display *dpy, int screen, XID window, XID cmap) return (rep.success ? xTrue : xFalse); } + +/* SDL addition from Ryan: free memory used by xme. */ +void XiGMiscDestroy(void) +{ + if (xigmisc_info) { + XextDestroyExtension(xigmisc_info); + xigmisc_info = NULL; + } +} + diff --git a/src/video/Xext/extensions/xme.h b/src/video/Xext/extensions/xme.h index 41bb416ad..f550623c9 100644 --- a/src/video/Xext/extensions/xme.h +++ b/src/video/Xext/extensions/xme.h @@ -36,6 +36,10 @@ extern int XiGMiscQueryResolutions(Display *dpy, int screen, int view, XiGMiscResolutionInfo **presolutions); extern void XiGMiscChangeResolution(Display *dpy, int screen, int view, int width, int height, int refresh); + +/* SDL addition from Ryan: free memory used by xme. */ +extern void XiGMiscDestroy(void); + #endif /* _XME_H_INCLUDED */ diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 94778967a..af3884a1f 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -1408,5 +1408,9 @@ void X11_VideoQuit(_THIS) /* Direct screen access, no memory buffer */ this->screen->pixels = NULL; } + +#if SDL_VIDEO_DRIVER_X11_XME + XiGMiscDestroy(); +#endif } From 876d68b4c98e3534b82f36851512dc4acd5fbbf9 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 29 Oct 2006 03:37:24 +0000 Subject: [PATCH 040/241] joyGetPosEx() was using the wrong variable for specifying a device; this is corrected now. (thanks, Ondrej!) Fixes Bugzilla #267. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402210 --- src/joystick/win32/SDL_mmjoystick.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/joystick/win32/SDL_mmjoystick.c b/src/joystick/win32/SDL_mmjoystick.c index 2523bbec4..d54c82237 100644 --- a/src/joystick/win32/SDL_mmjoystick.c +++ b/src/joystick/win32/SDL_mmjoystick.c @@ -167,7 +167,7 @@ int SDL_SYS_JoystickInit(void) joyinfo.dwSize = sizeof(joyinfo); joyinfo.dwFlags = JOY_RETURNALL; - result = joyGetPosEx(SYS_JoystickID[i], &joyinfo); + result = joyGetPosEx(i, &joyinfo); if ( result == JOYERR_NOERROR ) { result = joyGetDevCaps(i, &joycaps, sizeof(joycaps)); if ( result == JOYERR_NOERROR ) { From ca282f044bfda565ecbf12f96291119c0cfe9905 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 29 Oct 2006 03:44:25 +0000 Subject: [PATCH 041/241] Added some newer binaries to svn:ignore. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402212 From 79b94d85d18620841b4208a8b60f564a036d5528 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 29 Oct 2006 03:58:27 +0000 Subject: [PATCH 042/241] Removed broken AmigaOS support. Fixes Bugzilla #337. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402213 --- BUGS | 12 - README | 2 +- README.AmigaOS | 54 +- include/SDL_config.h.default | 4 +- include/SDL_config.h.in | 3 - include/SDL_config_amiga.h | 80 -- include/SDL_platform.h | 4 - src/audio/SDL_audio.c | 72 -- src/audio/amigaos/SDL_ahiaudio.c | 340 ------ src/audio/amigaos/SDL_ahiaudio.h | 60 -- src/joystick/amigaos/SDL_sysjoystick.c | 233 ---- src/thread/SDL_thread_c.h | 2 - src/thread/amigaos/SDL_syssem.c | 148 --- src/thread/amigaos/SDL_systhread.c | 151 --- src/thread/amigaos/SDL_systhread_c.h | 61 -- src/thread/amigaos/SDL_thread.c | 278 ----- src/timer/amigaos/SDL_systimer.c | 267 ----- src/video/SDL_video.c | 3 - src/video/cybergfx/SDL_amigaevents.c | 535 --------- src/video/cybergfx/SDL_amigaevents_c.h | 29 - src/video/cybergfx/SDL_amigamouse.c | 77 -- src/video/cybergfx/SDL_amigamouse_c.h | 32 - src/video/cybergfx/SDL_cgxaccel.c | 262 ----- src/video/cybergfx/SDL_cgxgl.c | 212 ---- src/video/cybergfx/SDL_cgxgl_c.h | 51 - src/video/cybergfx/SDL_cgximage.c | 906 ---------------- src/video/cybergfx/SDL_cgximage_c.h | 36 - src/video/cybergfx/SDL_cgxmodes.c | 316 ------ src/video/cybergfx/SDL_cgxmodes_c.h | 45 - src/video/cybergfx/SDL_cgxvideo.c | 1375 ------------------------ src/video/cybergfx/SDL_cgxvideo.h | 172 --- src/video/cybergfx/SDL_cgxwm.c | 63 -- src/video/cybergfx/SDL_cgxwm_c.h | 33 - test/testplatform.c | 2 - 34 files changed, 10 insertions(+), 5910 deletions(-) delete mode 100644 include/SDL_config_amiga.h delete mode 100644 src/audio/amigaos/SDL_ahiaudio.c delete mode 100644 src/audio/amigaos/SDL_ahiaudio.h delete mode 100644 src/joystick/amigaos/SDL_sysjoystick.c delete mode 100644 src/thread/amigaos/SDL_syssem.c delete mode 100644 src/thread/amigaos/SDL_systhread.c delete mode 100644 src/thread/amigaos/SDL_systhread_c.h delete mode 100644 src/thread/amigaos/SDL_thread.c delete mode 100644 src/timer/amigaos/SDL_systimer.c delete mode 100644 src/video/cybergfx/SDL_amigaevents.c delete mode 100644 src/video/cybergfx/SDL_amigaevents_c.h delete mode 100644 src/video/cybergfx/SDL_amigamouse.c delete mode 100644 src/video/cybergfx/SDL_amigamouse_c.h delete mode 100644 src/video/cybergfx/SDL_cgxaccel.c delete mode 100644 src/video/cybergfx/SDL_cgxgl.c delete mode 100644 src/video/cybergfx/SDL_cgxgl_c.h delete mode 100644 src/video/cybergfx/SDL_cgximage.c delete mode 100644 src/video/cybergfx/SDL_cgximage_c.h delete mode 100644 src/video/cybergfx/SDL_cgxmodes.c delete mode 100644 src/video/cybergfx/SDL_cgxmodes_c.h delete mode 100644 src/video/cybergfx/SDL_cgxvideo.c delete mode 100644 src/video/cybergfx/SDL_cgxvideo.h delete mode 100644 src/video/cybergfx/SDL_cgxwm.c delete mode 100644 src/video/cybergfx/SDL_cgxwm_c.h diff --git a/BUGS b/BUGS index 5b709c19d..b42bef4d7 100644 --- a/BUGS +++ b/BUGS @@ -190,15 +190,3 @@ AIX: -= NOT YET SUPPORTED =- More information on this port is available at: http://www.kom.e-technik.tu-darmstadt.de/~griff/SDL/ -AmigaOS: -= NOT YET SUPPORTED =- - The OpenGL support isn't implemented yet. - - SDL_WM_GrabInput() is not implemented. - Does anyone know how to do this? SDL_WM_GrabInput() is designed - to prevent the user from switching input and mouse focus away from - the SDL application. - - Continuous relative mouse motion is not implemented. - - The AmigaOS port was done by Gabriele.Greco@galactica.it - diff --git a/README b/README index 17ea835c0..ef9a76825 100644 --- a/README +++ b/README @@ -14,7 +14,7 @@ and 2D framebuffer across multiple platforms. The current version supports Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX. -The code contains support for AmigaOS, Dreamcast, Atari, AIX, OSF/Tru64, +The code contains support for Dreamcast, Atari, AIX, OSF/Tru64, RISC OS, SymbianOS, and OS/2, but these are not officially supported. SDL is written in C, but works with C++ natively, and has bindings to diff --git a/README.AmigaOS b/README.AmigaOS index dffb850d0..e0d890640 100644 --- a/README.AmigaOS +++ b/README.AmigaOS @@ -1,50 +1,12 @@ -This is the porting of 1.2.0 version of SDL (the latest stable one) -to AmigaOS/68k. +The AmigaOS code has been removed from SDL, since it had been broken for a + long time and had a few bits of fairly invasive code #ifdef'd into the + SDL core. -All the bugs known of the past version have been corrected. And I've -added all the new SDL features. +However, there is an OS4 version of SDL here: + http://www.rcdrummond.net/amiga/index.html -This version of SDL needs Cybergraphx V3 (r69+) or CyberGraphX V4 -and AHI v3+. Probably it works also with P96 or CGXAga, but it's -untested. +And a MorphOS version here: + http://www.lehtoranta.net/powersdl/ -This version is available as linked library for SAS/C and GCC, only 68k this -time, a powerup (ppcemu compatible) and a morphos version will be ready quite -soon (i hope). +--ryan. -Implemented: - -- 8/16/24/32bit video modes, both fullscreen and windowed. -- Hardware surfaces. -- CGX blitting acceleration. -- CGX colorkey blitting acceleration. -- AHI audio (8/16 bit, with any audio format), always uses unit 0 for now. -- Thread support (maybe not 100% compatible with other implementations) -- Semaphores -- Window resizing and backdrop windows (NEW) -- Joystick/Joypad support. - -To do: - -- CDRom audio playing support -- OpenGL (A guy was working on it but I've lost his tracks :( ) - -The SAS/C library is distributed with debug info attached, to strip debug info -simply add STRIPDEBUG argument to the linker. - -NOTE: SDL includes debug output using kprintf, to disable it add to your -project a function like this: - -void kprintf(char *a,...) -{ -} - -Otherwise you can redirect the debug to a console window with sushi, sashimi or -similar tools (the default output is the internal serial port). - -For info, support, bugfix and other feel free to mail me: - -Gabriele Greco (gabriele.greco@aruba.it) - -You can find also a small SDL Amiga page at: -http://ggreco.interfree.it/sdl.html diff --git a/include/SDL_config.h.default b/include/SDL_config.h.default index 8970ec3d5..cc5ab6574 100644 --- a/include/SDL_config.h.default +++ b/include/SDL_config.h.default @@ -26,9 +26,7 @@ #include "SDL_platform.h" /* Add any platform that doesn't build using the configure system */ -#if defined(__AMIGA__) -#include "SDL_config_amiga.h" -#elif defined(__DREAMCAST__) +#if defined(__DREAMCAST__) #include "SDL_config_dreamcast.h" #elif defined(__MACOS__) #include "SDL_config_macos.h" diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index 6f89569c9..61afa6bec 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -195,7 +195,6 @@ /* Enable various input drivers */ #undef SDL_INPUT_TSLIB -#undef SDL_JOYSTICK_AMIGA #undef SDL_JOYSTICK_BEOS #undef SDL_JOYSTICK_DC #undef SDL_JOYSTICK_DUMMY @@ -221,7 +220,6 @@ #undef SDL_LOADSO_WIN32 /* Enable various threading systems */ -#undef SDL_THREAD_AMIGA #undef SDL_THREAD_BEOS #undef SDL_THREAD_DC #undef SDL_THREAD_EPOC @@ -234,7 +232,6 @@ #undef SDL_THREAD_WIN32 /* Enable various timer systems */ -#undef SDL_TIMER_AMIGA #undef SDL_TIMER_BEOS #undef SDL_TIMER_DC #undef SDL_TIMER_DUMMY diff --git a/include/SDL_config_amiga.h b/include/SDL_config_amiga.h deleted file mode 100644 index 23e086192..000000000 --- a/include/SDL_config_amiga.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ - -#ifndef _SDL_config_amiga_h -#define _SDL_config_amiga_h - -#include "SDL_platform.h" - -/* This is a set of defines to configure the SDL features */ - -#define SDL_HAS_64BIT_TYPE 1 - -/* Useful headers */ -#define HAVE_SYS_TYPES_H 1 -#define HAVE_STDIO_H 1 -#define STDC_HEADERS 1 -#define HAVE_STRING_H 1 -#define HAVE_INTTYPES_H 1 -#define HAVE_SIGNAL_H 1 - -/* C library functions */ -#define HAVE_MALLOC 1 -#define HAVE_CALLOC 1 -#define HAVE_REALLOC 1 -#define HAVE_FREE 1 -#define HAVE_ALLOCA 1 -#define HAVE_GETENV 1 -#define HAVE_PUTENV 1 -#define HAVE_MEMSET 1 -#define HAVE_MEMCPY 1 -#define HAVE_MEMMOVE 1 -#define HAVE_MEMCMP 1 - -/* Enable various audio drivers */ -#define SDL_AUDIO_DRIVER_AHI 1 -#define SDL_AUDIO_DRIVER_DISK 1 -#define SDL_AUDIO_DRIVER_DUMMY 1 - -/* Enable various cdrom drivers */ -#define SDL_CDROM_DUMMY 1 - -/* Enable various input drivers */ -#define SDL_JOYSTICK_AMIGA 1 - -/* Enable various shared object loading systems */ -#define SDL_LOADSO_DUMMY 1 - -/* Enable various threading systems */ -#define SDL_THREAD_AMIGA 1 - -/* Enable various timer systems */ -#define SDL_TIMER_AMIGA 1 - -/* Enable various video drivers */ -#define SDL_VIDEO_DRIVER_CYBERGRAPHICS 1 -#define SDL_VIDEO_DRIVER_DUMMY 1 - -/* Enable OpenGL support */ -#define SDL_VIDEO_OPENGL 1 - -#endif /* _SDL_config_amiga_h */ diff --git a/include/SDL_platform.h b/include/SDL_platform.h index 80274bc43..1bfee29ec 100644 --- a/include/SDL_platform.h +++ b/include/SDL_platform.h @@ -29,10 +29,6 @@ #undef __AIX__ #define __AIX__ 1 #endif -#if defined(AMIGA) || defined(__AMIGA) || defined(__amigados__) -#undef __AMIGA__ -#define __AMIGA__ 1 -#endif #if defined(__BEOS__) #undef __BEOS__ #define __BEOS__ 1 diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 21f05b28e..6aa0c7a25 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -82,9 +82,6 @@ static AudioBootStrap *bootstrap[] = { #if SDL_AUDIO_DRIVER_SNDMGR &SNDMGR_bootstrap, #endif -#if SDL_AUDIO_DRIVER_AHI - &AHI_bootstrap, -#endif #if SDL_AUDIO_DRIVER_MINT &MINTAUDIO_GSXB_bootstrap, &MINTAUDIO_MCSN_bootstrap, @@ -115,10 +112,6 @@ SDL_AudioDevice *current_audio = NULL; int SDL_AudioInit(const char *driver_name); void SDL_AudioQuit(void); -#if SDL_AUDIO_DRIVER_AHI -static int audio_configured = 0; -#endif - /* The general mixing thread function */ int SDLCALL SDL_RunAudio(void *audiop) { @@ -128,21 +121,6 @@ int SDLCALL SDL_RunAudio(void *audiop) void *udata; void (SDLCALL *fill)(void *userdata,Uint8 *stream, int len); int silence; -#if SDL_AUDIO_DRIVER_AHI - int started = 0; - -/* AmigaOS NEEDS that the audio driver is opened in the thread that uses it! */ - - D(bug("Task audio started audio struct:<%lx>...\n",audiop)); - - D(bug("Before Openaudio...")); - if(audio->OpenAudio(audio, &audio->spec)==-1) - { - D(bug("Open audio failed...\n")); - return(-1); - } - D(bug("OpenAudio...OK\n")); -#endif /* Perform any thread setup */ if ( audio->ThreadInit ) { @@ -154,14 +132,6 @@ int SDLCALL SDL_RunAudio(void *audiop) fill = audio->spec.callback; udata = audio->spec.userdata; -#if SDL_AUDIO_DRIVER_AHI - audio_configured = 1; - - D(bug("Audio configured... Checking for conversion\n")); - SDL_mutexP(audio->mixer_lock); - D(bug("Semaphore obtained...\n")); -#endif - if ( audio->convert.needed ) { if ( audio->convert.src_format == AUDIO_U8 ) { silence = 0x80; @@ -174,11 +144,6 @@ int SDLCALL SDL_RunAudio(void *audiop) stream_len = audio->spec.size; } -#if SDL_AUDIO_DRIVER_AHI - SDL_mutexV(audio->mixer_lock); - D(bug("Entering audio loop...\n")); -#endif - #ifdef __OS2__ /* Increase the priority of this thread to make sure that the audio will be continuous all the time! */ @@ -253,14 +218,6 @@ int SDLCALL SDL_RunAudio(void *audiop) audio->WaitDone(audio); } -#if SDL_AUDIO_DRIVER_AHI - D(bug("WaitAudio...Done\n")); - - audio->CloseAudio(audio); - - D(bug("CloseAudio..Done, subtask exiting...\n")); - audio_configured = 0; -#endif #ifdef __OS2__ #ifdef DEBUG_BUILD printf("[SDL_RunAudio] : Task exiting. (TID%d)\n", SDL_ThreadID()); @@ -532,33 +489,12 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) audio->enabled = 1; audio->paused = 1; -#if !SDL_AUDIO_DRIVER_AHI - -/* AmigaOS opens audio inside the main loop */ audio->opened = audio->OpenAudio(audio, &audio->spec)+1; if ( ! audio->opened ) { SDL_CloseAudio(); return(-1); } -#else - D(bug("Locking semaphore...")); - SDL_mutexP(audio->mixer_lock); - - - audio->thread = SDL_CreateThread(SDL_RunAudio, audio); - D(bug("Created thread...\n")); - - if ( audio->thread == NULL ) { - SDL_mutexV(audio->mixer_lock); - SDL_CloseAudio(); - SDL_SetError("Couldn't create audio thread"); - return(-1); - } - - while(!audio_configured) - SDL_Delay(100); -#endif /* If the audio driver changes the buffer size, accept it */ if ( audio->spec.samples != desired->samples ) { @@ -602,7 +538,6 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) } } -#if !SDL_AUDIO_DRIVER_AHI /* Start the audio thread if necessary */ switch (audio->opened) { case 1: @@ -624,11 +559,6 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) /* The audio is now playing */ break; } -#else - SDL_mutexV(audio->mixer_lock); - D(bug("SDL_OpenAudio USCITA...\n")); - -#endif return(0); } @@ -702,12 +632,10 @@ void SDL_AudioQuit(void) SDL_FreeAudioMem(audio->convert.buf); } -#if !SDL_AUDIO_DRIVER_AHI if ( audio->opened ) { audio->CloseAudio(audio); audio->opened = 0; } -#endif /* Free the driver data */ audio->free(audio); current_audio = NULL; diff --git a/src/audio/amigaos/SDL_ahiaudio.c b/src/audio/amigaos/SDL_ahiaudio.c deleted file mode 100644 index f2efe1c2f..000000000 --- a/src/audio/amigaos/SDL_ahiaudio.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* Allow access to a raw mixing buffer (for AmigaOS) */ - -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "SDL_ahiaudio.h" - -/* Audio driver functions */ -static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec); -static void AHI_WaitAudio(_THIS); -static void AHI_PlayAudio(_THIS); -static Uint8 *AHI_GetAudioBuf(_THIS); -static void AHI_CloseAudio(_THIS); - -#ifndef __SASC - #define mymalloc(x) AllocVec(x,MEMF_PUBLIC) - #define myfree FreeVec -#else - #define mymalloc malloc - #define myfree free -#endif - -/* Audio driver bootstrap functions */ - -static int Audio_Available(void) -{ - int ok=0; - struct MsgPort *p; - struct AHIRequest *req; - - if(p=CreateMsgPort()) - { - if(req=(struct AHIRequest *)CreateIORequest(p,sizeof(struct AHIRequest))) - { - req->ahir_Version=4; - - if(!OpenDevice(AHINAME,0,(struct IORequest *)req,NULL)) - { - D(bug("AHI available.\n")); - ok=1; - CloseDevice((struct IORequest *)req); - } - DeleteIORequest((struct IORequest *)req); - } - DeleteMsgPort(p); - } - - D(if(!ok) bug("AHI not available\n")); - return ok; -} - -static void Audio_DeleteDevice(SDL_AudioDevice *device) -{ - SDL_free(device->hidden); - SDL_free(device); -} - -static SDL_AudioDevice *Audio_CreateDevice(int devindex) -{ - SDL_AudioDevice *this; - -#ifndef NO_AMIGADEBUG - D(bug("AHI created...\n")); -#endif - - /* Initialize all variables that we clean on shutdown */ - this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); - if ( this ) { - SDL_memset(this, 0, (sizeof *this)); - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - } - if ( (this == NULL) || (this->hidden == NULL) ) { - SDL_OutOfMemory(); - if ( this ) { - SDL_free(this); - } - return(0); - } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); - - /* Set the function pointers */ - this->OpenAudio = AHI_OpenAudio; - this->WaitAudio = AHI_WaitAudio; - this->PlayAudio = AHI_PlayAudio; - this->GetAudioBuf = AHI_GetAudioBuf; - this->CloseAudio = AHI_CloseAudio; - - this->free = Audio_DeleteDevice; - - return this; -} - -AudioBootStrap AHI_bootstrap = { - "AHI", Audio_Available, Audio_CreateDevice -}; - - -void static AHI_WaitAudio(_THIS) -{ - if(!CheckIO((struct IORequest *)audio_req[current_buffer])) - { - WaitIO((struct IORequest *)audio_req[current_buffer]); -// AbortIO((struct IORequest *)audio_req[current_buffer]); - } -} - -static void AHI_PlayAudio(_THIS) -{ - if(playing>1) - WaitIO((struct IORequest *)audio_req[current_buffer]); - - /* Write the audio data out */ - audio_req[current_buffer] -> ahir_Std. io_Message.mn_Node.ln_Pri = 60; - audio_req[current_buffer] -> ahir_Std. io_Data = mixbuf[current_buffer]; - audio_req[current_buffer] -> ahir_Std. io_Length = this->hidden->size; - audio_req[current_buffer] -> ahir_Std. io_Offset = 0; - audio_req[current_buffer] -> ahir_Std . io_Command = CMD_WRITE; - audio_req[current_buffer] -> ahir_Frequency = this->hidden->freq; - audio_req[current_buffer] -> ahir_Volume = 0x10000; - audio_req[current_buffer] -> ahir_Type = this->hidden->type; - audio_req[current_buffer] -> ahir_Position = 0x8000; - audio_req[current_buffer] -> ahir_Link = (playing>0 ? audio_req[current_buffer^1] : NULL); - - SendIO((struct IORequest *)audio_req[current_buffer]); - current_buffer^=1; - - playing++; -} - -static Uint8 *AHI_GetAudioBuf(_THIS) -{ - return(mixbuf[current_buffer]); -} - -static void AHI_CloseAudio(_THIS) -{ - D(bug("Closing audio...\n")); - - playing=0; - - if(audio_req[0]) - { - if(audio_req[1]) - { - D(bug("Break req[1]...\n")); - - AbortIO((struct IORequest *)audio_req[1]); - WaitIO((struct IORequest *)audio_req[1]); - } - - D(bug("Break req[0]...\n")); - - AbortIO((struct IORequest *)audio_req[0]); - WaitIO((struct IORequest *)audio_req[0]); - - if(audio_req[1]) - { - D(bug("Break AGAIN req[1]...\n")); - AbortIO((struct IORequest *)audio_req[1]); - WaitIO((struct IORequest *)audio_req[1]); - } -// Double abort to be sure to break the dbuffering process. - - SDL_Delay(200); - - D(bug("Reqs breaked, closing device...\n")); - CloseDevice((struct IORequest *)audio_req[0]); - D(bug("Device closed, freeing memory...\n")); - myfree(audio_req[1]); - D(bug("Memory freed, deleting IOReq...\n")); - DeleteIORequest((struct IORequest *)audio_req[0]); - audio_req[0]=audio_req[1]=NULL; - } - - D(bug("Freeing mixbuf[0]...\n")); - if ( mixbuf[0] != NULL ) { - myfree(mixbuf[0]); -// SDL_FreeAudioMem(mixbuf[0]); - mixbuf[0] = NULL; - } - - D(bug("Freeing mixbuf[1]...\n")); - if ( mixbuf[1] != NULL ) { - myfree(mixbuf[1]); -// SDL_FreeAudioMem(mixbuf[1]); - mixbuf[1] = NULL; - } - - D(bug("Freeing audio_port...\n")); - - if ( audio_port != NULL ) { - DeleteMsgPort(audio_port); - audio_port = NULL; - } - D(bug("...done!\n")); -} - -static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec) -{ - Uint16 test_format = SDL_FirstAudioFormat(spec->format); - int valid_datatype = 1; - - D(bug("AHI opening...\n")); - - /* Determine the audio parameters from the AudioSpec */ - while ((!valid_datatype) && (test_format)) { - valid_datatype = 1; - switch (test_format) { - case AUDIO_S8: - D(bug("AUDIO_S8...\n")); - spec->format = AUDIO_S8; - this->hidden->bytespersample = 1; - if (spec->channels < 2) - this->hidden->type = AHIST_M8S; - else - this->hidden->type = AHIST_S8S; - break; - - case AUDIO_S16MSB: - D(bug("AUDIO_S16MSB...\n")); - spec->format = AUDIO_S16MSB; - this->hidden->bytespersample = 2; - if (spec->channels < 2) - this->hidden->type = AHIST_M16S; - else - this->hidden->type = AHIST_S16S; - break; - - default: - valid_datatype = 0; - test_format = SDL_NextAudioFormat(); - break; - } - } - - if (!valid_datatype) { /* shouldn't happen, but just in case... */ - SDL_SetError("Unsupported audio format"); - return (-1); - } - - if (spec->channels > 2) { - spec->channels = 2; /* will convert at higher level. */ - } - - D(bug("Before CalculateAudioSpec\n")); - /* Update the fragment size as size in bytes */ - SDL_CalculateAudioSpec(spec); - - D(bug("Before CreateMsgPort\n")); - - if(!(audio_port=CreateMsgPort())) - { - SDL_SetError("Unable to create a MsgPort"); - return -1; - } - - D(bug("Before CreateIORequest\n")); - - if(!(audio_req[0]=(struct AHIRequest *)CreateIORequest(audio_port,sizeof(struct AHIRequest)))) - { - SDL_SetError("Unable to create an AHIRequest"); - DeleteMsgPort(audio_port); - return -1; - } - - audio_req[0]->ahir_Version = 4; - - if(OpenDevice(AHINAME,0,(struct IORequest *)audio_req[0],NULL)) - { - SDL_SetError("Unable to open AHI device!\n"); - DeleteIORequest((struct IORequest *)audio_req[0]); - DeleteMsgPort(audio_port); - return -1; - } - - D(bug("AFTER opendevice\n")); - - /* Set output frequency and size */ - this->hidden->freq = spec->freq; - this->hidden->size = spec->size; - - D(bug("Before buffer allocation\n")); - - /* Allocate mixing buffer */ - mixbuf[0] = (Uint8 *)mymalloc(spec->size); - mixbuf[1] = (Uint8 *)mymalloc(spec->size); - - D(bug("Before audio_req allocation\n")); - - if(!(audio_req[1]=mymalloc(sizeof(struct AHIRequest)))) - { - SDL_OutOfMemory(); - return(-1); - } - - D(bug("Before audio_req memcpy\n")); - - SDL_memcpy(audio_req[1],audio_req[0],sizeof(struct AHIRequest)); - - if ( mixbuf[0] == NULL || mixbuf[1] == NULL ) { - SDL_OutOfMemory(); - return(-1); - } - - D(bug("Before mixbuf memset\n")); - - SDL_memset(mixbuf[0], spec->silence, spec->size); - SDL_memset(mixbuf[1], spec->silence, spec->size); - - current_buffer=0; - playing=0; - - D(bug("AHI opened: freq:%ld mixbuf:%lx/%lx buflen:%ld bits:%ld channels:%ld\n",spec->freq,mixbuf[0],mixbuf[1],spec->size,this->hidden->bytespersample*8,spec->channels)); - - /* We're ready to rock and roll. :-) */ - return(0); -} diff --git a/src/audio/amigaos/SDL_ahiaudio.h b/src/audio/amigaos/SDL_ahiaudio.h deleted file mode 100644 index b9ef339c6..000000000 --- a/src/audio/amigaos/SDL_ahiaudio.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifndef _SDL_ahiaudio_h -#define _SDL_ahiaudio_h - -#include -#include -#ifdef __SASC -#include -#else -#include -#endif - -#include -#include "mydebug.h" - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData { - /* The handle for the audio device */ - struct AHIRequest *audio_req[2]; - struct MsgPort *audio_port; - Sint32 freq,type,bytespersample,size; - Uint8 *mixbuf[2]; /* The app mixing buffer */ - int current_buffer; - Uint32 playing; -}; - -/* Old variable names */ -#define audio_port (this->hidden->audio_port) -#define audio_req (this->hidden->audio_req) -#define mixbuf (this->hidden->mixbuf) -#define current_buffer (this->hidden->current_buffer) -#define playing (this->hidden->playing) - -#endif /* _SDL_ahiaudio_h */ diff --git a/src/joystick/amigaos/SDL_sysjoystick.c b/src/joystick/amigaos/SDL_sysjoystick.c deleted file mode 100644 index 35e4ebe41..000000000 --- a/src/joystick/amigaos/SDL_sysjoystick.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_JOYSTICK_AMIGA - -/* This is the system specific header for the SDL joystick API */ - -#include -#if defined(__SASC) || defined(STORMC4_WOS) -#include -#include -#include -#else -#include -#include -#include -#endif -#include "mydebug.h" - -extern struct ExecBase *SysBase; -extern struct GfxBase *GfxBase; - -#include "SDL_joystick.h" -#include "../SDL_sysjoystick.h" -#include "../SDL_joystick_c.h" - -/* Function to scan the system for joysticks. - * This function should set SDL_numjoysticks to the number of available - * joysticks. Joystick 0 should be the system default joystick. - * It should return 0, or -1 on an unrecoverable fatal error. - */ - - -/* Amiga specific datas */ -struct Library *LowLevelBase=NULL; - -ULONG joybut[]= -{ - JPF_BUTTON_RED, - JPF_BUTTON_BLUE, - JPF_BUTTON_PLAY, - JPF_BUTTON_YELLOW, - JPF_BUTTON_GREEN, - JPF_BUTTON_FORWARD, - JPF_BUTTON_REVERSE, -}; - -struct joystick_hwdata -{ - ULONG joystate; -}; - -int SDL_SYS_JoystickInit(void) -{ - if(!LowLevelBase) - { - if(LowLevelBase=OpenLibrary("lowlevel.library",37)) - return 2; - } - else - return 2; - - D(bug("%ld joysticks available.\n",SDL_numjoysticks)); - - return 0; -} - -/* Function to get the device-dependent name of a joystick */ -const char *SDL_SYS_JoystickName(int index) -{ - if(index<2&&LowLevelBase) - { - switch(index) - { - case 0: - return "Port 1 Amiga Joystick/Joypad"; - case 1: - return "Port 2 Amiga Joystick/Joypad"; - } - } - - SDL_SetError("No joystick available with that index"); - return(NULL); -} - -/* Function to open a joystick for use. - The joystick to open is specified by the index field of the joystick. - This should fill the nbuttons and naxes fields of the joystick structure. - It returns 0, or -1 if there is an error. - */ - -int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) -{ - ULONG temp,i; - D(bug("Opening joystick %ld\n",joystick->index)); - - if(!(joystick->hwdata=SDL_malloc(sizeof(struct joystick_hwdata)))) - return -1; - -/* This loop is to check if the controller is a joypad */ - - for(i=0;i<20;i++) - { - temp=ReadJoyPort(joystick->index^1); // fix to invert amiga joyports - WaitTOF(); - } - - if((temp&JP_TYPE_MASK)==JP_TYPE_GAMECTLR) - joystick->nbuttons=7; - else - joystick->nbuttons=3; - - joystick->nhats=0; - joystick->nballs=0; - joystick->naxes=2; - joystick->hwdata->joystate=0L; - - return 0; -} - -/* Function to update the state of a joystick - called as a device poll. - * This function shouldn't update the joystick structure directly, - * but instead should call SDL_PrivateJoystick*() to deliver events - * and update joystick device state. - */ -void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) -{ - ULONG data; - int i; - - if(joystick->index<2) - { - data=ReadJoyPort(joystick->index); - - if(data&JP_DIRECTION_MASK) - { - if(data&JPF_JOY_DOWN) - { - if(!(joystick->hwdata->joystate&JPF_JOY_DOWN)) - SDL_PrivateJoystickAxis(joystick,0,127); - } - else if(data&JPF_JOY_UP) - { - if(!(joystick->hwdata->joystate&JPF_JOY_UP)) - SDL_PrivateJoystickAxis(joystick,0,-127); - } - else if(joystick->hwdata->joystate&(JPF_JOY_UP|JPF_JOY_DOWN)) - SDL_PrivateJoystickAxis(joystick,0,0); - - if(data&JPF_JOY_LEFT) - { - if(!(joystick->hwdata->joystate&JPF_JOY_LEFT)) - SDL_PrivateJoystickAxis(joystick,1,-127); - } - else if(data&JPF_JOY_RIGHT) - { - if(!(joystick->hwdata->joystate&JPF_JOY_RIGHT)) - SDL_PrivateJoystickAxis(joystick,1,127); - } - else if(joystick->hwdata->joystate&(JPF_JOY_LEFT|JPF_JOY_RIGHT)) - SDL_PrivateJoystickAxis(joystick,1,0); - } - else if(joystick->hwdata->joystate&(JPF_JOY_LEFT|JPF_JOY_RIGHT)) - { - SDL_PrivateJoystickAxis(joystick,1,0); - } - else if(joystick->hwdata->joystate&(JPF_JOY_UP|JPF_JOY_DOWN)) - { - SDL_PrivateJoystickAxis(joystick,0,0); - } - - for(i=0;inbuttons;i++) - { - if( (data&joybut[i]) ) - { - if(i==1) - data&=(~(joybut[2])); - - if(!(joystick->hwdata->joystate&joybut[i])) - SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED); - } - else if(joystick->hwdata->joystate&joybut[i]) - SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED); - } - - joystick->hwdata->joystate=data; - } - - return; -} - -/* Function to close a joystick after use */ -void SDL_SYS_JoystickClose(SDL_Joystick *joystick) -{ - if(joystick->hwdata) - SDL_free(joystick->hwdata); - return; -} - -/* Function to perform any system-specific joystick related cleanup */ - -void SDL_SYS_JoystickQuit(void) -{ - if(LowLevelBase) - { - CloseLibrary(LowLevelBase); - LowLevelBase=NULL; - SDL_numjoysticks=0; - } - return; -} - -#endif /* SDL_JOYSTICK_AMIGA */ diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h index 13501db6d..6f83bea46 100644 --- a/src/thread/SDL_thread_c.h +++ b/src/thread/SDL_thread_c.h @@ -27,8 +27,6 @@ /* Need the definitions of SYS_ThreadHandle */ #if SDL_THREADS_DISABLED #include "generic/SDL_systhread_c.h" -#elif SDL_THREAD_AMIGA -#include "amigaos/SDL_systhread_c.h" #elif SDL_THREAD_BEOS #include "beos/SDL_systhread_c.h" #elif SDL_THREAD_DC diff --git a/src/thread/amigaos/SDL_syssem.c b/src/thread/amigaos/SDL_syssem.c deleted file mode 100644 index a31a2133b..000000000 --- a/src/thread/amigaos/SDL_syssem.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* An implementation of semaphores using mutexes and condition variables */ - -#include "SDL_thread.h" -#include "SDL_systhread_c.h" - - -struct SDL_semaphore -{ - struct SignalSemaphore Sem; -}; - -#undef D - -#define D(x) - -SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) -{ - SDL_sem *sem; - - sem = (SDL_sem *)SDL_malloc(sizeof(*sem)); - - if ( ! sem ) { - SDL_OutOfMemory(); - return(0); - } - - D(bug("Creating semaphore %lx...\n",sem)); - - SDL_memset(sem,0,sizeof(*sem)); - - InitSemaphore(&sem->Sem); - - return(sem); -} - -void SDL_DestroySemaphore(SDL_sem *sem) -{ - D(bug("Destroying semaphore %lx...\n",sem)); - - if ( sem ) { -// Condizioni per liberare i task in attesa? - SDL_free(sem); - } -} - -int SDL_SemTryWait(SDL_sem *sem) -{ - if ( ! sem ) { - SDL_SetError("Passed a NULL semaphore"); - return -1; - } - - D(bug("TryWait semaphore...%lx\n",sem)); - - ObtainSemaphore(&sem->Sem); -// ReleaseSemaphore(&sem->Sem); - - return 1; -} - -int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) -{ - int retval; - - - if ( ! sem ) { - SDL_SetError("Passed a NULL semaphore"); - return -1; - } - - D(bug("WaitTimeout (%ld) semaphore...%lx\n",timeout,sem)); - - /* A timeout of 0 is an easy case */ - if ( timeout == 0 ) { - ObtainSemaphore(&sem->Sem); - return 1; - } - if(!(retval=AttemptSemaphore(&sem->Sem))) - { - SDL_Delay(timeout); - retval=AttemptSemaphore(&sem->Sem); - } - - if(retval==TRUE) - { -// ReleaseSemaphore(&sem->Sem); - retval=1; - } - - return retval; -} - -int SDL_SemWait(SDL_sem *sem) -{ - ObtainSemaphore(&sem->Sem); - return 0; -} - -Uint32 SDL_SemValue(SDL_sem *sem) -{ - Uint32 value; - - value = 0; - if ( sem ) { - #ifdef STORMC4_WOS - value = sem->Sem.ssppc_SS.ss_NestCount; - #else - value = sem->Sem.ss_NestCount; - #endif - } - return value; -} - -int SDL_SemPost(SDL_sem *sem) -{ - if ( ! sem ) { - SDL_SetError("Passed a NULL semaphore"); - return -1; - } - D(bug("SemPost semaphore...%lx\n",sem)); - - ReleaseSemaphore(&sem->Sem); - return 0; -} - diff --git a/src/thread/amigaos/SDL_systhread.c b/src/thread/amigaos/SDL_systhread.c deleted file mode 100644 index c6b42e776..000000000 --- a/src/thread/amigaos/SDL_systhread.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* BeOS thread management routines for SDL */ - -#include "SDL_mutex.h" -#include "SDL_thread.h" -#include "../SDL_thread_c.h" -#include "../SDL_systhread.h" -#include "mydebug.h" - -typedef struct { - int (*func)(void *); - void *data; - SDL_Thread *info; - struct Task *wait; -} thread_args; - -#ifndef MORPHOS - -#if defined(__SASC) && !defined(__PPC__) -__saveds __asm Uint32 RunThread(register __a0 char *args ) -#elif defined(__PPC__) -Uint32 RunThread(char *args) -#else -Uint32 __saveds RunThread(char *args __asm("a0") ) -#endif -{ - #ifdef STORMC4_WOS - thread_args *data=(thread_args *)args; - #else - thread_args *data=(thread_args *)atol(args); - #endif - - struct Task *Father; - - D(bug("Received data: %lx\n",data)); - Father=data->wait; - - SDL_RunThread(data); - - Signal(Father,SIGBREAKF_CTRL_F); - D(bug("Thread with data %lx ended\n",data)); - return(0); -} - -#else - -#include - -Uint32 RunTheThread(void) -{ - thread_args *data=(thread_args *)atol((char *)REG_A0); - struct Task *Father; - - D(bug("Received data: %lx\n",data)); - Father=data->wait; - - SDL_RunThread(data); - - Signal(Father,SIGBREAKF_CTRL_F); - D(bug("Thread with data %lx ended\n",data)); - return(0); -} - -struct EmulLibEntry RunThreadStruct= -{ - TRAP_LIB, - 0, - (ULONG)RunTheThread -}; - -void *RunThread=&RunThreadStruct; -#endif - - -int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) -{ - /* Create the thread and go! */ - char buffer[20]; - - D(bug("Sending %lx to the new thread...\n",args)); - - if(args) - SDL_snprintf(buffer, SDL_arraysize(buffer),"%ld",args); - - #ifdef STORMC4_WOS - thread->handle=CreateTaskPPCTags(TASKATTR_CODE, RunThread, - TASKATTR_NAME, "SDL subtask", - TASKATTR_STACKSIZE, 100000, - (args ? TASKATTR_R3 : TAG_IGNORE), args, - TASKATTR_INHERITR2, TRUE, - TAG_DONE); - #else - thread->handle=(struct Task *)CreateNewProcTags(NP_Output,Output(), - NP_Name,(ULONG)"SDL subtask", - NP_CloseOutput, FALSE, - NP_StackSize,20000, - NP_Entry,(ULONG)RunThread, - args ? NP_Arguments : TAG_IGNORE,(ULONG)buffer, - TAG_DONE); - #endif - - if(!thread->handle) - { - SDL_SetError("Not enough resources to create thread"); - return(-1); - } - - return(0); -} - -void SDL_SYS_SetupThread(void) -{ -} - -Uint32 SDL_ThreadID(void) -{ - return((Uint32)FindTask(NULL)); -} - -void SDL_SYS_WaitThread(SDL_Thread *thread) -{ - SetSignal(0L,SIGBREAKF_CTRL_F|SIGBREAKF_CTRL_C); - Wait(SIGBREAKF_CTRL_F|SIGBREAKF_CTRL_C); -} - -void SDL_SYS_KillThread(SDL_Thread *thread) -{ - Signal((struct Task *)thread->handle,SIGBREAKF_CTRL_C); -} diff --git a/src/thread/amigaos/SDL_systhread_c.h b/src/thread/amigaos/SDL_systhread_c.h deleted file mode 100644 index 53ba3c8c6..000000000 --- a/src/thread/amigaos/SDL_systhread_c.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#include -#include -#include -#if defined (__SASC) || defined(STORMC4_WOS) -#include -#include -#else -#include -#include -#endif - -#include "mydebug.h" - -extern struct ExecBase *SysBase; -extern struct DosLibrary *DOSBase; - -#ifdef STORMC4_WOS -#include - -/* use powerpc.library functions instead og exec */ -#define SYS_ThreadHandle struct TaskPPC * -#define Signal SignalPPC -#define Wait WaitPPC -#define Task TaskPPC -#define FindTask FindTaskPPC -#define SetSignal SetSignalPPC - -#define InitSemaphore InitSemaphorePPC -#define ObtainSemaphore ObtainSemaphorePPC -#define AttemptSemaphore AttemptSemaphorePPC -#define ReleaseSemaphore ReleaseSemaphorePPC -#define SignalSemaphore SignalSemaphorePPC - -#else - -#define SYS_ThreadHandle struct Task * -#endif /*STORMC4_WOS*/ - diff --git a/src/thread/amigaos/SDL_thread.c b/src/thread/amigaos/SDL_thread.c deleted file mode 100644 index 7698f49f3..000000000 --- a/src/thread/amigaos/SDL_thread.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* System independent thread management routines for SDL */ - -#include "SDL_mutex.h" -#include "SDL_thread.h" -#include "../SDL_thread_c.h" -#include "../SDL_systhread.h" - -#define ARRAY_CHUNKSIZE 32 -/* The array of threads currently active in the application - (except the main thread) - The manipulation of an array here is safer than using a linked list. -*/ -static int SDL_maxthreads = 0; -static int SDL_numthreads = 0; -static SDL_Thread **SDL_Threads = NULL; -static struct SignalSemaphore thread_lock; -int thread_lock_created = 0; - -int SDL_ThreadsInit(void) -{ - InitSemaphore(&thread_lock); - thread_lock_created=1; - return 0; -} - -/* This should never be called... - If this is called by SDL_Quit(), we don't know whether or not we should - clean up threads here. If any threads are still running after this call, - they will no longer have access to any per-thread data. - */ -void SDL_ThreadsQuit() -{ - thread_lock_created=0; -} - -/* Routines for manipulating the thread list */ -static void SDL_AddThread(SDL_Thread *thread) -{ - SDL_Thread **threads; - - /* WARNING: - If the very first threads are created simultaneously, then - there could be a race condition causing memory corruption. - In practice, this isn't a problem because by definition there - is only one thread running the first time this is called. - */ - if ( !thread_lock_created ) { - if ( SDL_ThreadsInit() < 0 ) { - return; - } - } - ObtainSemaphore(&thread_lock); - - /* Expand the list of threads, if necessary */ -#ifdef DEBUG_THREADS - printf("Adding thread (%d already - %d max)\n", - SDL_numthreads, SDL_maxthreads); -#endif - if ( SDL_numthreads == SDL_maxthreads ) { - threads=(SDL_Thread **)SDL_malloc((SDL_maxthreads+ARRAY_CHUNKSIZE)* - (sizeof *threads)); - if ( threads == NULL ) { - SDL_OutOfMemory(); - goto done; - } - SDL_memcpy(threads, SDL_Threads, SDL_numthreads*(sizeof *threads)); - SDL_maxthreads += ARRAY_CHUNKSIZE; - if ( SDL_Threads ) { - SDL_free(SDL_Threads); - } - SDL_Threads = threads; - } - SDL_Threads[SDL_numthreads++] = thread; -done: - ReleaseSemaphore(&thread_lock); -} - -static void SDL_DelThread(SDL_Thread *thread) -{ - int i; - - if ( thread_lock_created ) { - ObtainSemaphore(&thread_lock); - for ( i=0; ithreadid ) { - errbuf = &SDL_Threads[i]->errbuf; - break; - } - } - ReleaseSemaphore(&thread_lock); - } - return(errbuf); -} - - -/* Arguments and callback to setup and run the user thread function */ -typedef struct { - int (*func)(void *); - void *data; - SDL_Thread *info; - struct Task *wait; -} thread_args; - -void SDL_RunThread(void *data) -{ - thread_args *args; - int (*userfunc)(void *); - void *userdata; - int *statusloc; - - /* Perform any system-dependent setup - - this function cannot fail, and cannot use SDL_SetError() - */ - SDL_SYS_SetupThread(); - - /* Get the thread id */ - args = (thread_args *)data; - args->info->threadid = SDL_ThreadID(); - - /* Figure out what function to run */ - userfunc = args->func; - userdata = args->data; - statusloc = &args->info->status; - - /* Wake up the parent thread */ - Signal(args->wait,SIGBREAKF_CTRL_E); - - /* Run the function */ - *statusloc = userfunc(userdata); -} - -SDL_Thread *SDL_CreateThread(int (*fn)(void *), void *data) -{ - SDL_Thread *thread; - thread_args *args; - int ret; - - /* Allocate memory for the thread info structure */ - thread = (SDL_Thread *)SDL_malloc(sizeof(*thread)); - if ( thread == NULL ) { - SDL_OutOfMemory(); - return(NULL); - } - SDL_memset(thread, 0, (sizeof *thread)); - thread->status = -1; - - /* Set up the arguments for the thread */ - args = (thread_args *)SDL_malloc(sizeof(*args)); - if ( args == NULL ) { - SDL_OutOfMemory(); - SDL_free(thread); - return(NULL); - } - args->func = fn; - args->data = data; - args->info = thread; - args->wait = FindTask(NULL); - if ( args->wait == NULL ) { - SDL_free(thread); - SDL_free(args); - SDL_OutOfMemory(); - return(NULL); - } - - /* Add the thread to the list of available threads */ - SDL_AddThread(thread); - - D(bug("Starting thread...\n")); - - /* Create the thread and go! */ - ret = SDL_SYS_CreateThread(thread, args); - if ( ret >= 0 ) { - D(bug("Waiting for thread CTRL_E...\n")); - /* Wait for the thread function to use arguments */ - Wait(SIGBREAKF_CTRL_E); - D(bug(" Arrived.")); - } else { - /* Oops, failed. Gotta free everything */ - SDL_DelThread(thread); - SDL_free(thread); - thread = NULL; - } - SDL_free(args); - - /* Everything is running now */ - return(thread); -} - -void SDL_WaitThread(SDL_Thread *thread, int *status) -{ - if ( thread ) { - SDL_SYS_WaitThread(thread); - if ( status ) { - *status = thread->status; - } - SDL_DelThread(thread); - SDL_free(thread); - } -} - -Uint32 SDL_GetThreadID(SDL_Thread *thread) -{ - Uint32 id; - - if ( thread ) { - id = thread->threadid; - } else { - id = SDL_ThreadID(); - } - return(id); -} - -void SDL_KillThread(SDL_Thread *thread) -{ - if ( thread ) { - SDL_SYS_KillThread(thread); - SDL_WaitThread(thread, NULL); - } -} - diff --git a/src/timer/amigaos/SDL_systimer.c b/src/timer/amigaos/SDL_systimer.c deleted file mode 100644 index a213b6142..000000000 --- a/src/timer/amigaos/SDL_systimer.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_TIMER_AMIGA - -#include -#include -#include -#include -#include -#include -#include -#ifdef __SASC -#include -#include -#include -#include -#include -#elif defined(STORMC4_WOS) -#include -#include -#include -#else -#include -#include -#include -#endif -#include "mydebug.h" - -extern struct DosLibrary *DOSBase; -extern struct ExecBase *SysBase; -static struct GfxBase *GfxBase; - -#include "SDL_timer.h" -#include "../SDL_timer_c.h" - -/* The first ticks value of the application */ - -#if !defined(__PPC__) || defined(STORMC4_WOS) || defined(MORPHOS) -static clock_t start; - -void SDL_StartTicks(void) -{ - /* Set first ticks value */ - start=clock(); -} - -Uint32 SDL_GetTicks (void) -{ - clock_t ticks; - - ticks=clock()-start; - -#ifdef __SASC -// CLOCKS_PER_SEC == 1000 ! - - return(ticks); -#else -// CLOCKS_PER_SEC != 1000 ! - - return ticks*(1000/CLOCKS_PER_SEC); -#endif -} - -void SDL_Delay (Uint32 ms) -{ -// Do a busy wait if time is less than 50ms - - if(ms<50) - { - clock_t to_wait=clock(); - -#ifndef __SASC - ms*=(CLOCKS_PER_SEC/1000); -#endif - to_wait+=ms; - - while(clock()>=10; - start[1]|=((result[0]&0x3ff)<<22); - start[0]>>=10; -} - -Uint32 SDL_GetTicks (void) -{ - ULONG result[2]; - PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result); - -// PPCAsr64p(result,10); -// Non va, la emulo: - - result[1]>>=10; - result[1]|=((result[0]&0x3ff)<<22); - -// Non mi interessa piu' result[0] - - return result[1]*1000/MY_CLOCKS_PER_SEC; -} - -void SDL_Delay (Uint32 ms) -{ -// Do a busy wait if time is less than 50ms - - if(ms<50) - { - ULONG to_wait[2],actual[2]; - PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result); - actual[1]=0; - to_wait[1]+=ms*1000/MY_CLOCKS_PER_SEC; - - while(actual[1]>=10; - result[1]|=((result[0]&0x3ff)<<22); - result[0]>>=10; - - D(bug("Shiftato TPS: %lu - %lu\n",result[0],result[1])); - MY_CLOCKS_PER_SEC=result[1]; - - PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result); - - D(bug("Current ticks: %lu - %lu\n",result[0],result[1])); - result[1]>>=10; - result[1]|=((result[0]&0x3ff)<<22); - result[0]>>=10; -// PPCAsr64p(result,10); - D(bug("Shiftato: %lu - %lu\n",result[0],result[1])); - } - else - { - D(bug("Errore nell'inizializzazione del timer!\n")); - } -} - -#endif - -#include "SDL_thread.h" - -/* Data to handle a single periodic alarm */ -static int timer_alive = 0; -static SDL_Thread *timer_thread = NULL; - -static int RunTimer(void *unused) -{ - D(bug("SYSTimer: Entering RunTimer loop...")); - - if(GfxBase==NULL) - GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37); - - while ( timer_alive ) { - if ( SDL_timer_running ) { - SDL_ThreadedTimerCheck(); - } - if(GfxBase) - WaitTOF(); // Check the timer every fifth of seconds. Was SDL_Delay(1)->BusyWait! - else - Delay(1); - } - D(bug("SYSTimer: EXITING RunTimer loop...")); - return(0); -} - -/* This is only called if the event thread is not running */ -int SDL_SYS_TimerInit(void) -{ - D(bug("Creating thread for the timer (NOITIMER)...\n")); - - timer_alive = 1; - timer_thread = SDL_CreateThread(RunTimer, NULL); - if ( timer_thread == NULL ) - { - D(bug("Creazione del thread fallita...\n")); - - return(-1); - } - return(SDL_SetTimerThreaded(1)); -} - -void SDL_SYS_TimerQuit(void) -{ - timer_alive = 0; - if ( timer_thread ) { - SDL_WaitThread(timer_thread, NULL); - timer_thread = NULL; - } -} - -int SDL_SYS_StartTimer(void) -{ - SDL_SetError("Internal logic error: AmigaOS uses threaded timer"); - return(-1); -} - -void SDL_SYS_StopTimer(void) -{ - return; -} - -#endif /* SDL_TIMER_AMIGA */ diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index db52d48dc..3329b85ac 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -90,9 +90,6 @@ static VideoBootStrap *bootstrap[] = { #if SDL_VIDEO_DRIVER_DRAWSPROCKET &DSp_bootstrap, #endif -#if SDL_VIDEO_DRIVER_CYBERGRAPHICS - &CGX_bootstrap, -#endif #if SDL_VIDEO_DRIVER_PHOTON &ph_bootstrap, #endif diff --git a/src/video/cybergfx/SDL_amigaevents.c b/src/video/cybergfx/SDL_amigaevents.c deleted file mode 100644 index 333d0fa38..000000000 --- a/src/video/cybergfx/SDL_amigaevents.c +++ /dev/null @@ -1,535 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* Handle the event stream, converting Amiga events into SDL events */ -#include "SDL.h" - -#include "SDL_syswm.h" -#include "../SDL_sysvideo.h" -#include "../../events/SDL_sysevents.h" -#include "../../events/SDL_events_c.h" -#include "SDL_cgxvideo.h" -#include "SDL_cgxmodes_c.h" -#include "SDL_cgximage_c.h" -#include "SDL_cgxwm_c.h" -#include "SDL_amigaevents_c.h" - - -/* The translation tables from an Amiga keysym to a SDL keysym */ -static SDLKey MISC_keymap[256]; -SDL_keysym *amiga_TranslateKey(int code, SDL_keysym *keysym); -struct IOStdReq *ConReq=NULL; -struct MsgPort *ConPort=NULL; - -/* Note: The X server buffers and accumulates mouse motion events, so - the motion event generated by the warp may not appear exactly as we - expect it to. We work around this (and improve performance) by only - warping the pointer when it reaches the edge, and then wait for it. -*/ -#define MOUSE_FUDGE_FACTOR 8 - -#if 0 - -static inline int amiga_WarpedMotion(_THIS, struct IntuiMessage *m) -{ - int w, h, i; - int deltax, deltay; - int posted; - - w = SDL_VideoSurface->w; - h = SDL_VideoSurface->h; - deltax = xevent->xmotion.x - mouse_last.x; - deltay = xevent->xmotion.y - mouse_last.y; -#ifdef DEBUG_MOTION - printf("Warped mouse motion: %d,%d\n", deltax, deltay); -#endif - mouse_last.x = xevent->xmotion.x; - mouse_last.y = xevent->xmotion.y; - posted = SDL_PrivateMouseMotion(0, 1, deltax, deltay); - - if ( (xevent->xmotion.x < MOUSE_FUDGE_FACTOR) || - (xevent->xmotion.x > (w-MOUSE_FUDGE_FACTOR)) || - (xevent->xmotion.y < MOUSE_FUDGE_FACTOR) || - (xevent->xmotion.y > (h-MOUSE_FUDGE_FACTOR)) ) { - /* Get the events that have accumulated */ - while ( XCheckTypedEvent(SDL_Display, MotionNotify, xevent) ) { - deltax = xevent->xmotion.x - mouse_last.x; - deltay = xevent->xmotion.y - mouse_last.y; -#ifdef DEBUG_MOTION - printf("Extra mouse motion: %d,%d\n", deltax, deltay); -#endif - mouse_last.x = xevent->xmotion.x; - mouse_last.y = xevent->xmotion.y; - posted += SDL_PrivateMouseMotion(0, 1, deltax, deltay); - } - mouse_last.x = w/2; - mouse_last.y = h/2; - XWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0, - mouse_last.x, mouse_last.y); - for ( i=0; i<10; ++i ) { - XMaskEvent(SDL_Display, PointerMotionMask, xevent); - if ( (xevent->xmotion.x > - (mouse_last.x-MOUSE_FUDGE_FACTOR)) && - (xevent->xmotion.x < - (mouse_last.x+MOUSE_FUDGE_FACTOR)) && - (xevent->xmotion.y > - (mouse_last.y-MOUSE_FUDGE_FACTOR)) && - (xevent->xmotion.y < - (mouse_last.y+MOUSE_FUDGE_FACTOR)) ) { - break; - } -#ifdef DEBUG_XEVENTS - printf("Lost mouse motion: %d,%d\n", xevent->xmotion.x, xevent->xmotion.y); -#endif - } -#ifdef DEBUG_XEVENTS - if ( i == 10 ) { - printf("Warning: didn't detect mouse warp motion\n"); - } -#endif - } - return(posted); -} - -#endif - -static int amiga_GetButton(int code) -{ - switch(code) - { - case IECODE_MBUTTON: - return SDL_BUTTON_MIDDLE; - case IECODE_RBUTTON: - return SDL_BUTTON_RIGHT; - default: - return SDL_BUTTON_LEFT; - } -} - -static int amiga_DispatchEvent(_THIS,struct IntuiMessage *msg) -{ - int class=msg->Class,code=msg->Code; - int posted; - - posted = 0; - switch (class) { - /* Gaining mouse coverage? */ - case IDCMP_ACTIVEWINDOW: - posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); - break; - - /* Losing mouse coverage? */ - case IDCMP_INACTIVEWINDOW: - posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); - break; -#if 0 - /* Gaining input focus? */ - case IDCMP_ACTIVEWINDOW: - posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); - - /* Queue entry into fullscreen mode */ - switch_waiting = 0x01 | SDL_FULLSCREEN; - switch_time = SDL_GetTicks() + 1500; - break; - - /* Losing input focus? */ - case IDCMP_INACTIVEWINDOW: - posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS); - - /* Queue leaving fullscreen mode */ - switch_waiting = 0x01; - switch_time = SDL_GetTicks() + 200; - break; -#endif - /* Mouse motion? */ - case IDCMP_MOUSEMOVE: - if ( SDL_VideoSurface ) { - posted = SDL_PrivateMouseMotion(0, 0, - msg->MouseX-SDL_Window->BorderLeft, - msg->MouseY-SDL_Window->BorderTop); - } - break; - - /* Mouse button press? */ - case IDCMP_MOUSEBUTTONS: - - if(!(code&IECODE_UP_PREFIX)) - { - posted = SDL_PrivateMouseButton(SDL_PRESSED, - amiga_GetButton(code), 0, 0); - } - /* Mouse button release? */ - else - { - code&=~IECODE_UP_PREFIX; - posted = SDL_PrivateMouseButton(SDL_RELEASED, - amiga_GetButton(code), 0, 0); - } - break; - - case IDCMP_RAWKEY: - - /* Key press? */ - - if( !(code&IECODE_UP_PREFIX) ) - { - SDL_keysym keysym; - posted = SDL_PrivateKeyboard(SDL_PRESSED, - amiga_TranslateKey(code, &keysym)); - } - else - { - /* Key release? */ - - SDL_keysym keysym; - code&=~IECODE_UP_PREFIX; - - /* Check to see if this is a repeated key */ -/* if ( ! X11_KeyRepeat(SDL_Display, &xevent) ) */ - - posted = SDL_PrivateKeyboard(SDL_RELEASED, - amiga_TranslateKey(code, &keysym)); - } - break; - /* Have we been iconified? */ -#if 0 - case UnmapNotify: { -#ifdef DEBUG_XEVENTS -printf("UnmapNotify!\n"); -#endif - posted=SDL_PrivateAppActive(0, SDL_APPACTIVE|SDL_APPINPUTFOCUS); - } - break; - - /* Have we been restored? */ - - case MapNotify: { -#ifdef DEBUG_XEVENTS -printf("MapNotify!\n"); -#endif - - posted = SDL_PrivateAppActive(1, SDL_APPACTIVE); - - if ( SDL_VideoSurface && - (SDL_VideoSurface->flags & SDL_FULLSCREEN) ) - { - CGX_EnterFullScreen(this); - } else { - X11_GrabInputNoLock(this, this->input_grab); - } - if ( SDL_VideoSurface ) { - CGX_RefreshDisplay(this); - } - } - break; - case Expose: - if ( SDL_VideoSurface && (xevent.xexpose.count == 0) ) { - CGX_RefreshDisplay(this); - } - break; -#endif - - /* Have we been resized? */ - case IDCMP_NEWSIZE: - SDL_PrivateResize(SDL_Window->Width-SDL_Window->BorderLeft-SDL_Window->BorderRight, - SDL_Window->Height-SDL_Window->BorderTop-SDL_Window->BorderBottom); - - break; - - /* Have we been requested to quit? */ - case IDCMP_CLOSEWINDOW: - posted = SDL_PrivateQuit(); - break; - - /* Do we need to refresh ourselves? */ - - default: { - /* Only post the event if we're watching for it */ - if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) { - SDL_SysWMmsg wmmsg; - - SDL_VERSION(&wmmsg.version); -#if 0 - wmmsg.subsystem = SDL_SYSWM_CGX; - wmmsg.event.xevent = xevent; -#endif - posted = SDL_PrivateSysWMEvent(&wmmsg); - } - } - break; - } - ReplyMsg((struct Message *)msg); - - - return(posted); -} - -void amiga_PumpEvents(_THIS) -{ - int pending; - struct IntuiMessage *m; - - /* Keep processing pending events */ - pending = 0; - while ( m=(struct IntuiMessage *)GetMsg(SDL_Window->UserPort) ) { - amiga_DispatchEvent(this,m); - ++pending; - } -} - -void amiga_InitKeymap(void) -{ - int i; - - /* Map the miscellaneous keys */ - for ( i=0; iscancode = code; - keysym->sym = MISC_keymap[code]; - -#ifdef DEBUG_KEYS - fprintf(stderr, "Translating key 0x%.4x (%d)\n", xsym, xkey->keycode); -#endif - /* Get the translated SDL virtual keysym */ - if ( keysym->sym==SDLK_UNKNOWN ) - { - #ifdef STORMC4_WOS - if(!KeymapBase) - #else - if(!ConsoleDevice) - #endif - { - #ifdef STORMC4_WOS - KeymapBase=OpenLibrary("keymap.library", 0L); - #else - if(ConPort=CreateMsgPort()) - { - if(ConReq=CreateIORequest(ConPort,sizeof(struct IOStdReq))) - { - if(!OpenDevice("console.device",-1,(struct IORequest *)ConReq,0)) - ConsoleDevice=(struct Library *)ConReq->io_Device; - else - { - DeleteIORequest(ConReq); - ConReq=NULL; - } - } - else - { - DeleteMsgPort(ConPort); - ConPort=NULL; - } - } - #endif - } - - #ifdef STORMC4_WOS - if(KeymapBase) - #else - if(ConsoleDevice) - #endif - { - struct InputEvent event; - long actual; - char buffer[5]; - - event.ie_Qualifier=0; - event.ie_Class=IECLASS_RAWKEY; - event.ie_SubClass=0L; - event.ie_Code=code; - event.ie_X=event.ie_Y=0; - event.ie_EventAddress=NULL; - event.ie_NextEvent=NULL; - event.ie_Prev1DownCode=event.ie_Prev1DownQual=event.ie_Prev2DownCode=event.ie_Prev2DownQual=0; - - #ifdef STORMC4_WOS - if( (actual=MapRawKey(&event,buffer,5,NULL))>=0) - #else - if( (actual=RawKeyConvert(&event,buffer,5,NULL))>=0) - #endif - { - if(actual>1) - { - D(bug("Warning (%ld) character conversion!\n",actual)); - } - else if(actual==1) - { - keysym->sym=*buffer; - D(bug("Converted rawcode %ld to <%lc>\n",code,*buffer)); -// Bufferizzo x le successive chiamate! - MISC_keymap[code]=*buffer; - } - } - } - - } - keysym->mod = KMOD_NONE; - - /* If UNICODE is on, get the UNICODE value for the key */ - keysym->unicode = 0; - if ( SDL_TranslateUNICODE ) { -#if 0 - static XComposeStatus state; - /* Until we handle the IM protocol, use XLookupString() */ - unsigned char keybuf[32]; - if ( XLookupString(xkey, (char *)keybuf, sizeof(keybuf), - NULL, &state) ) { - keysym->unicode = keybuf[0]; - } -#endif - } - return(keysym); -} - -void amiga_InitOSKeymap(_THIS) -{ - amiga_InitKeymap(); -} diff --git a/src/video/cybergfx/SDL_amigaevents_c.h b/src/video/cybergfx/SDL_amigaevents_c.h deleted file mode 100644 index 11b86b5e5..000000000 --- a/src/video/cybergfx/SDL_amigaevents_c.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#include "SDL_cgxvideo.h" - -/* Functions to be exported */ -extern void amiga_InitOSKeymap(_THIS); -extern void amiga_PumpEvents(_THIS); - diff --git a/src/video/cybergfx/SDL_amigamouse.c b/src/video/cybergfx/SDL_amigamouse.c deleted file mode 100644 index 64940a82d..000000000 --- a/src/video/cybergfx/SDL_amigamouse.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#include "SDL_mouse.h" -#include "../../events/SDL_events_c.h" -#include "../SDL_cursor_c.h" -#include "SDL_amigamouse_c.h" - - -/* The implementation dependent data for the window manager cursor */ - -typedef void * WMCursor; - -void amiga_FreeWMCursor(_THIS, WMcursor *cursor) -{ -} - -WMcursor *amiga_CreateWMCursor(_THIS, - Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) -{ - return (WMcursor *)1; // Amiga has an Hardware cursor, so it's ok to return something unuseful but true -} - -int amiga_ShowWMCursor(_THIS, WMcursor *cursor) -{ - /* Don't do anything if the display is gone */ - if ( SDL_Display == NULL) { - return(0); - } - - /* Set the Amiga prefs cursor cursor, or blank if cursor is NULL */ - - if ( SDL_Window ) { - SDL_Lock_EventThread(); - if ( cursor == NULL ) { - if ( SDL_BlankCursor != NULL ) { -// Hide cursor HERE - SetPointer(SDL_Window,(UWORD *)SDL_BlankCursor,1,1,0,0); - } - } else { -// Show cursor - ClearPointer(SDL_Window); - } - SDL_Unlock_EventThread(); - } - return(1); -} - -void amiga_WarpWMCursor(_THIS, Uint16 x, Uint16 y) -{ -/* FIXME: Not implemented */ -} - -/* Check to see if we need to enter or leave mouse relative mode */ -void amiga_CheckMouseMode(_THIS) -{ -} diff --git a/src/video/cybergfx/SDL_amigamouse_c.h b/src/video/cybergfx/SDL_amigamouse_c.h deleted file mode 100644 index aad19b627..000000000 --- a/src/video/cybergfx/SDL_amigamouse_c.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#include "SDL_cgxvideo.h" - -/* Functions to be exported */ -extern void amiga_FreeWMCursor(_THIS, WMcursor *cursor); -extern WMcursor *amiga_CreateWMCursor(_THIS, - Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); -extern int amiga_ShowWMCursor(_THIS, WMcursor *cursor); -extern void amiga_WarpWMCursor(_THIS, Uint16 x, Uint16 y); -extern void amiga_CheckMouseMode(_THIS); diff --git a/src/video/cybergfx/SDL_cgxaccel.c b/src/video/cybergfx/SDL_cgxaccel.c deleted file mode 100644 index 24605e355..000000000 --- a/src/video/cybergfx/SDL_cgxaccel.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#include "SDL_endian.h" -#include "SDL_video.h" -#include "../SDL_sysvideo.h" -#include "../SDL_blit.h" -#include "SDL_cgxvideo.h" - -static int CGX_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, - SDL_Surface *dst, SDL_Rect *dstrect); - -// These are needed to avoid register troubles with gcc -O2! - -#if defined(__SASC) || defined(__PPC__) || defined(MORPHOS) -#define BMKBRP(a,b,c,d,e,f,g,h,i,j) BltMaskBitMapRastPort(a,b,c,d,e,f,g,h,i,j) -#define BBRP(a,b,c,d,e,f,g,h,i) BltBitMapRastPort(a,b,c,d,e,f,g,h,i) -#define BBB(a,b,c,d,e,f,g,h,i,j,k) BltBitMap(a,b,c,d,e,f,g,h,i,j,k) -#else -void BMKBRP(struct BitMap *a,WORD b, WORD c,struct RastPort *d,WORD e,WORD f,WORD g,WORD h,UBYTE i,APTR j) -{BltMaskBitMapRastPort(a,b,c,d,e,f,g,h,i,j);} - -void BBRP(struct BitMap *a,WORD b, WORD c,struct RastPort *d,WORD e,WORD f,WORD g,WORD h,UBYTE i) -{BltBitMapRastPort(a,b,c,d,e,f,g,h,i);} - -void BBB(struct BitMap *a,WORD b, WORD c,struct BitMap *d,WORD e,WORD f,WORD g,WORD h,UBYTE i,UBYTE j,UWORD *k) -{BltBitMap(a,b,c,d,e,f,g,h,i,j,k);} -#endif - -int CGX_SetHWColorKey(_THIS,SDL_Surface *surface, Uint32 key) -{ - if(surface->hwdata) - { - if(surface->hwdata->mask) - SDL_free(surface->hwdata->mask); - - if(surface->hwdata->mask=SDL_malloc(RASSIZE(surface->w,surface->h))) - { - Uint32 pitch,ok=0; - APTR lock; - - SDL_memset(surface->hwdata->mask,255,RASSIZE(surface->w,surface->h)); - - D(bug("Building colorkey mask: color: %ld, size: %ld x %ld, %ld bytes...Bpp:%ld\n",key,surface->w,surface->h,RASSIZE(surface->w,surface->h),surface->format->BytesPerPixel)); - - if(lock=LockBitMapTags(surface->hwdata->bmap,LBMI_BASEADDRESS,(ULONG)&surface->pixels, - LBMI_BYTESPERROW,(ULONG)&pitch,TAG_DONE)) - { - switch(surface->format->BytesPerPixel) - { - case 1: - { - unsigned char k=key; - register int i,j,t; - register unsigned char *dest=surface->hwdata->mask,*map=surface->pixels; - - pitch-=surface->w; - - for(i=0;ih;i++) - { - for(t=128,j=0;jw;j++) - { - if(*map==k) - *dest&=~t; - - t>>=1; - - if(t==0) - { - dest++; - t=128; - } - map++; - } - map+=pitch; - } - } - break; - case 2: - { - Uint16 k=key,*mapw; - register int i,j,t; - register unsigned char *dest=surface->hwdata->mask,*map=surface->pixels; - - for(i=surface->h;i;--i) - { - mapw=(Uint16 *)map; - - for(t=128,j=surface->w;j;--j) - { - if(*mapw==k) - *dest&=~t; - - t>>=1; - - if(t==0) - { - dest++; - t=128; - } - mapw++; - } - map+=pitch; - } - } - break; - case 4: - { - Uint32 *mapl; - register int i,j,t; - register unsigned char *dest=surface->hwdata->mask,*map=surface->pixels; - - for(i=surface->h;i;--i) - { - mapl=(Uint32 *)map; - - for(t=128,j=surface->w;j;--j) - { - if(*mapl==key) - *dest&=~t; - - t>>=1; - - if(t==0) - { - dest++; - t=128; - } - mapl++; - } - map+=pitch; - } - - } - break; - default: - D(bug("Pixel mode non supported for color key...")); - SDL_free(surface->hwdata->mask); - surface->hwdata->mask=NULL; - ok=-1; - } - UnLockBitMap(lock); - D(bug("...Colorkey built!\n")); - return ok; - } - } - } - D(bug("HW colorkey not supported for this depth\n")); - - return -1; -} - -int CGX_CheckHWBlit(_THIS,SDL_Surface *src,SDL_Surface *dst) -{ -// Doesn't support yet alpha blitting - - if(src->hwdata&& !(src->flags & (SDL_SRCALPHA))) - { - D(bug("CheckHW blit... OK!\n")); - - if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { - if ( CGX_SetHWColorKey(this, src, src->format->colorkey) < 0 ) { - src->flags &= ~SDL_HWACCEL; - return -1; - } - } - - src->flags|=SDL_HWACCEL; - src->map->hw_blit = CGX_HWAccelBlit; - return 1; - } - else - src->flags &= ~SDL_HWACCEL; - - D(bug("CheckHW blit... NO!\n")); - - return 0; -} - -static int temprp_init=0; -static struct RastPort temprp; - -static int CGX_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, - SDL_Surface *dst, SDL_Rect *dstrect) -{ - struct SDL_VideoDevice *this=src->hwdata->videodata; - -// D(bug("Accel blit!\n")); - - if(src->flags&SDL_SRCCOLORKEY && src->hwdata->mask) - { - if(dst==SDL_VideoSurface) - { - BMKBRP(src->hwdata->bmap,srcrect->x,srcrect->y, - SDL_RastPort,dstrect->x+SDL_Window->BorderLeft,dstrect->y+SDL_Window->BorderTop, - srcrect->w,srcrect->h,0xc0,src->hwdata->mask); - } - else if(dst->hwdata) - { - if(!temprp_init) - { - InitRastPort(&temprp); - temprp_init=1; - } - temprp.BitMap=(struct BitMap *)dst->hwdata->bmap; - - BMKBRP(src->hwdata->bmap,srcrect->x,srcrect->y, - &temprp,dstrect->x,dstrect->y, - srcrect->w,srcrect->h,0xc0,src->hwdata->mask); - - } - } - else if(dst==SDL_VideoSurface) - { - BBRP(src->hwdata->bmap,srcrect->x,srcrect->y,SDL_RastPort,dstrect->x+SDL_Window->BorderLeft,dstrect->y+SDL_Window->BorderTop,srcrect->w,srcrect->h,0xc0); - } - else if(dst->hwdata) - BBB(src->hwdata->bmap,srcrect->x,srcrect->y,dst->hwdata->bmap,dstrect->x,dstrect->y,srcrect->w,srcrect->h,0xc0,0xff,NULL); - - return 0; -} - -int CGX_FillHWRect(_THIS,SDL_Surface *dst,SDL_Rect *dstrect,Uint32 color) -{ - if(dst==SDL_VideoSurface) - { - FillPixelArray(SDL_RastPort,dstrect->x+SDL_Window->BorderLeft,dstrect->y+SDL_Window->BorderTop,dstrect->w,dstrect->h,color); - } - else if(dst->hwdata) - { - if(!temprp_init) - { - InitRastPort(&temprp); - temprp_init=1; - } - - temprp.BitMap=(struct BitMap *)dst->hwdata->bmap; - - FillPixelArray(&temprp,dstrect->x,dstrect->y,dstrect->w,dstrect->h,color); - } - return 0; -} diff --git a/src/video/cybergfx/SDL_cgxgl.c b/src/video/cybergfx/SDL_cgxgl.c deleted file mode 100644 index e19614b9d..000000000 --- a/src/video/cybergfx/SDL_cgxgl.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* StormMesa implementation of SDL OpenGL support */ - -#include "SDL_cgxgl_c.h" -#include "SDL_cgxvideo.h" - -#if SDL_VIDEO_OPENGL -AmigaMesaContext glcont=NULL; -#endif - -/* Init OpenGL */ -int CGX_GL_Init(_THIS) -{ -#if SDL_VIDEO_OPENGL - int i = 0; - struct TagItem attributes [ 14 ]; /* 14 should be more than enough :) */ - struct Window *win = (struct Window *)SDL_Window; - - // default config. Always used... - attributes[i].ti_Tag = AMA_Window; attributes[i++].ti_Data = (unsigned long)win; - attributes[i].ti_Tag = AMA_Left; attributes[i++].ti_Data = 0; - attributes[i].ti_Tag = AMA_Bottom; attributes[i++].ti_Data = 0; - attributes[i].ti_Tag = AMA_Width; attributes[i++].ti_Data = win->Width-win->BorderLeft-win->BorderRight; - attributes[i].ti_Tag = AMA_Height; attributes[i++].ti_Data = win->Height-win->BorderBottom-win->BorderTop; - attributes[i].ti_Tag = AMA_DirectRender; attributes[i++].ti_Data = GL_TRUE; - - // double buffer ? - attributes[i].ti_Tag = AMA_DoubleBuf; - if ( this->gl_config.double_buffer ) { - attributes[i++].ti_Data = GL_TRUE; - } - else { - attributes[i++].ti_Data = GL_FALSE; - } - // RGB(A) Mode ? - attributes[i].ti_Tag = AMA_RGBMode; - if ( this->gl_config.red_size != 0 && - this->gl_config.blue_size != 0 && - this->gl_config.green_size != 0 ) { - attributes[i++].ti_Data = GL_TRUE; - } - else { - attributes[i++].ti_Data = GL_FALSE; - } - // no depth buffer ? - if ( this->gl_config.depth_size == 0 ) { - attributes[i].ti_Tag = AMA_NoDepth; - attributes[i++].ti_Data = GL_TRUE; - } - // no stencil buffer ? - if ( this->gl_config.stencil_size == 0 ) { - attributes[i].ti_Tag = AMA_NoStencil; - attributes[i++].ti_Data = GL_TRUE; - } - // no accum buffer ? - if ( this->gl_config.accum_red_size != 0 && - this->gl_config.accum_blue_size != 0 && - this->gl_config.accum_green_size != 0 ) { - attributes[i].ti_Tag = AMA_NoAccum; - attributes[i++].ti_Data = GL_TRUE; - } - // done... - attributes[i].ti_Tag = TAG_DONE; - - glcont = AmigaMesaCreateContext(attributes); - if ( glcont == NULL ) { - SDL_SetError("Couldn't create OpenGL context"); - return(-1); - } - this->gl_data->gl_active = 1; - this->gl_config.driver_loaded = 1; - - return(0); -#else - SDL_SetError("OpenGL support not configured"); - return(-1); -#endif -} - -/* Quit OpenGL */ -void CGX_GL_Quit(_THIS) -{ -#if SDL_VIDEO_OPENGL - if ( glcont != NULL ) { - AmigaMesaDestroyContext(glcont); - glcont = NULL; - this->gl_data->gl_active = 0; - this->gl_config.driver_loaded = 0; - } -#endif -} - -/* Attach context to another window */ -int CGX_GL_Update(_THIS) -{ -#if SDL_VIDEO_OPENGL - struct TagItem tags[2]; - struct Window *win = (struct Window*)SDL_Window; - if(glcont == NULL) { - return -1; //should never happen - } - tags[0].ti_Tag = AMA_Window; - tags[0].ti_Data = (unsigned long)win; - tags[1].ti_Tag = TAG_DONE; - AmigaMesaSetRast(glcont, tags); - - return 0; -#else - SDL_SetError("OpenGL support not configured"); - return -1; -#endif -} - -#if SDL_VIDEO_OPENGL - -/* Make the current context active */ -int CGX_GL_MakeCurrent(_THIS) -{ - if(glcont == NULL) - return -1; - - AmigaMesaMakeCurrent(glcont, glcont->buffer); - return 0; -} - -void CGX_GL_SwapBuffers(_THIS) -{ - AmigaMesaSwapBuffers(glcont); -} - -int CGX_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) { - GLenum mesa_attrib; - - switch(attrib) { - case SDL_GL_RED_SIZE: - mesa_attrib = GL_RED_BITS; - break; - case SDL_GL_GREEN_SIZE: - mesa_attrib = GL_GREEN_BITS; - break; - case SDL_GL_BLUE_SIZE: - mesa_attrib = GL_BLUE_BITS; - break; - case SDL_GL_ALPHA_SIZE: - mesa_attrib = GL_ALPHA_BITS; - break; - case SDL_GL_DOUBLEBUFFER: - mesa_attrib = GL_DOUBLEBUFFER; - break; - case SDL_GL_DEPTH_SIZE: - mesa_attrib = GL_DEPTH_BITS; - break; - case SDL_GL_STENCIL_SIZE: - mesa_attrib = GL_STENCIL_BITS; - break; - case SDL_GL_ACCUM_RED_SIZE: - mesa_attrib = GL_ACCUM_RED_BITS; - break; - case SDL_GL_ACCUM_GREEN_SIZE: - mesa_attrib = GL_ACCUM_GREEN_BITS; - break; - case SDL_GL_ACCUM_BLUE_SIZE: - mesa_attrib = GL_ACCUM_BLUE_BITS; - break; - case SDL_GL_ACCUM_ALPHA_SIZE: - mesa_attrib = GL_ACCUM_ALPHA_BITS; - break; - default : - return -1; - } - - AmigaMesaGetConfig(glcont->visual, mesa_attrib, value); - return 0; -} - -void *CGX_GL_GetProcAddress(_THIS, const char *proc) { - void *func = NULL; - func = AmiGetGLProc(proc); - return func; -} - -int CGX_GL_LoadLibrary(_THIS, const char *path) { - /* Library is always open */ - this->gl_config.driver_loaded = 1; - - return 0; -} - -#endif /* SDL_VIDEO_OPENGL */ - diff --git a/src/video/cybergfx/SDL_cgxgl_c.h b/src/video/cybergfx/SDL_cgxgl_c.h deleted file mode 100644 index 4c04f59a5..000000000 --- a/src/video/cybergfx/SDL_cgxgl_c.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* StormMesa implementation of SDL OpenGL support */ - -#include "../SDL_sysvideo.h" - -#define _THIS SDL_VideoDevice *_this - -#if SDL_VIDEO_OPENGL -#include -extern void *AmiGetGLProc(const char *proc); -#endif /* SDL_VIDEO_OPENGL */ - -struct SDL_PrivateGLData { - int gl_active; -}; - -/* OpenGL functions */ -extern int CGX_GL_Init(_THIS); -extern void CGX_GL_Quit(_THIS); -extern int CGX_GL_Update(_THIS); -#if SDL_VIDEO_OPENGL -extern int CGX_GL_MakeCurrent(_THIS); -extern int CGX_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value); -extern void CGX_GL_SwapBuffers(_THIS); -extern void *CGX_GL_GetProcAddress(_THIS, const char *proc); -extern int CGX_GL_LoadLibrary(_THIS, const char *path); -#endif - -#undef _THIS diff --git a/src/video/cybergfx/SDL_cgximage.c b/src/video/cybergfx/SDL_cgximage.c deleted file mode 100644 index 3e8938efe..000000000 --- a/src/video/cybergfx/SDL_cgximage.c +++ /dev/null @@ -1,906 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#include "SDL_endian.h" -#include "SDL_cgximage_c.h" - -#ifdef HAVE_KSTAT -#include -#endif - -#ifdef USE_CGX_WRITELUTPIXEL -#if defined(__SASC) || defined(__PPC__) - #define WLUT WriteLUTPixelArray -#else -void WLUT(APTR a,UWORD b,UWORD c,UWORD d,struct RastPort *e,APTR f,UWORD g,UWORD h,UWORD i,UWORD l,UBYTE m) -{ WriteLUTPixelArray(a,b,c,d,e,f,g,h,i,l,m); } -#endif - -#endif - -/* Various screen update functions available */ -static void CGX_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); -static void CGX_FakeUpdate(_THIS, int numrects, SDL_Rect *rects); - -BOOL SafeDisp=TRUE,SafeChange=TRUE; -struct MsgPort *safeport=NULL,*dispport=NULL; -ULONG safe_sigbit,disp_sigbit; -int use_picasso96=1; - -int CGX_SetupImage(_THIS, SDL_Surface *screen) -{ - SDL_Ximage=NULL; - - if(screen->flags&SDL_HWSURFACE) { - ULONG pitch; - - if(!screen->hwdata) { - if(!(screen->hwdata=SDL_malloc(sizeof(struct private_hwdata)))) - return -1; - - D(bug("Creating system accel struct\n")); - } - screen->hwdata->lock=NULL; - screen->hwdata->allocated=0; - screen->hwdata->mask=NULL; - screen->hwdata->bmap=SDL_RastPort->BitMap; - screen->hwdata->videodata=this; - - if(!(screen->hwdata->lock=LockBitMapTags(screen->hwdata->bmap, - LBMI_BASEADDRESS,(ULONG)&screen->pixels, - LBMI_BYTESPERROW,(ULONG)&pitch,TAG_DONE))) { - SDL_free(screen->hwdata); - screen->hwdata=NULL; - return -1; - } - else { - UnLockBitMap(screen->hwdata->lock); - screen->hwdata->lock=NULL; - } - - screen->pitch=pitch; - - this->UpdateRects = CGX_FakeUpdate; - - D(bug("Accel video image configured (%lx, pitch %ld).\n",screen->pixels,screen->pitch)); - return 0; - } - - screen->pixels = SDL_malloc(screen->h*screen->pitch); - - if ( screen->pixels == NULL ) { - SDL_OutOfMemory(); - return(-1); - } - - SDL_Ximage=screen->pixels; - - if ( SDL_Ximage == NULL ) { - SDL_SetError("Couldn't create XImage"); - return(-1); - } - - this->UpdateRects = CGX_NormalUpdate; - - return(0); -} - -void CGX_DestroyImage(_THIS, SDL_Surface *screen) -{ - if ( SDL_Ximage ) { - SDL_free(SDL_Ximage); - SDL_Ximage = NULL; - } - if ( screen ) { - screen->pixels = NULL; - - if(screen->hwdata) { - SDL_free(screen->hwdata); - screen->hwdata=NULL; - } - } -} - -/* This is a hack to see whether this system has more than 1 CPU */ -static int num_CPU(void) -{ - return 1; -} - -int CGX_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags) -{ - int retval; - - D(bug("Calling ResizeImage()\n")); - - CGX_DestroyImage(this, screen); - - if ( flags & SDL_OPENGL ) { /* No image when using GL */ - retval = 0; - } else { - retval = CGX_SetupImage(this, screen); - /* We support asynchronous blitting on the display */ - if ( flags & SDL_ASYNCBLIT ) { - if ( num_CPU() > 1 ) { - screen->flags |= SDL_ASYNCBLIT; - } - } - } - return(retval); -} - -int CGX_AllocHWSurface(_THIS, SDL_Surface *surface) -{ - D(bug("Alloc HW surface...%ld x %ld x %ld!\n",surface->w,surface->h,this->hidden->depth)); - - if(surface==SDL_VideoSurface) - { - D(bug("Allocation skipped, it's system one!\n")); - return 0; - } - - if(!surface->hwdata) - { - if(!(surface->hwdata=SDL_malloc(sizeof(struct private_hwdata)))) - return -1; - } - - surface->hwdata->mask=NULL; - surface->hwdata->lock=NULL; - surface->hwdata->videodata=this; - surface->hwdata->allocated=0; - - if(surface->hwdata->bmap=AllocBitMap(surface->w,surface->h,this->hidden->depth,BMF_MINPLANES,SDL_Display->RastPort.BitMap)) - { - surface->hwdata->allocated=1; - surface->flags|=SDL_HWSURFACE; - D(bug("...OK\n")); - return 0; - } - else - { - SDL_free(surface->hwdata); - surface->hwdata=NULL; - } - - return(-1); -} -void CGX_FreeHWSurface(_THIS, SDL_Surface *surface) -{ - if(surface && surface!=SDL_VideoSurface && surface->hwdata) - { - D(bug("Free hw surface.\n")); - - if(surface->hwdata->mask) - SDL_free(surface->hwdata->mask); - - if(surface->hwdata->bmap&&surface->hwdata->allocated) - FreeBitMap(surface->hwdata->bmap); - - SDL_free(surface->hwdata); - surface->hwdata=NULL; - surface->pixels=NULL; - D(bug("end of free hw surface\n")); - } - return; -} - -int CGX_LockHWSurface(_THIS, SDL_Surface *surface) -{ - if (surface->hwdata) - { -// D(bug("Locking a bitmap...\n")); - if(!surface->hwdata->lock) - { - Uint32 pitch; - - if(!(surface->hwdata->lock=LockBitMapTags(surface->hwdata->bmap, - LBMI_BASEADDRESS,(ULONG)&surface->pixels, - LBMI_BYTESPERROW,(ULONG)&pitch,TAG_DONE))) - return -1; - -// surface->pitch e' a 16bit! - - surface->pitch=pitch; - - if(!currently_fullscreen&&surface==SDL_VideoSurface) - surface->pixels=((char *)surface->pixels)+(surface->pitch*(SDL_Window->BorderTop+SDL_Window->TopEdge)+ - surface->format->BytesPerPixel*(SDL_Window->BorderLeft+SDL_Window->LeftEdge)); - } - D(else bug("Already locked!!!\n")); - } - return(0); -} - -void CGX_UnlockHWSurface(_THIS, SDL_Surface *surface) -{ - if(surface->hwdata && surface->hwdata->lock) - { - UnLockBitMap(surface->hwdata->lock); - surface->hwdata->lock=NULL; -// surface->pixels=NULL; - } -} - -int CGX_FlipHWSurface(_THIS, SDL_Surface *surface) -{ - static int current=0; - - if(this->hidden->dbuffer) - { - if(!SafeChange) - { - Wait(disp_sigbit); -// Non faccio nulla, vuoto solo la porta - while(GetMsg(dispport)!=NULL) - ; - SafeChange=TRUE; - } - - if(ChangeScreenBuffer(SDL_Display,this->hidden->SB[current^1])) - { - surface->hwdata->bmap=SDL_RastPort->BitMap=this->hidden->SB[current]->sb_BitMap; - SafeChange=FALSE; - SafeDisp=FALSE; - current^=1; - } - - if(!SafeDisp) - { - Wait(safe_sigbit); - while(GetMsg(safeport)!=NULL) - ; - SafeDisp=TRUE; - } - - } - return(0); -} - -/* Byte-swap the pixels in the display image */ -static void CGX_SwapAllPixels(SDL_Surface *screen) -{ - int x, y; - - switch (screen->format->BytesPerPixel) { - case 2: { - Uint16 *spot; - for ( y=0; yh; ++y ) { - spot = (Uint16 *) ((Uint8 *)screen->pixels + - y * screen->pitch); - for ( x=0; xw; ++x, ++spot ) { - *spot = SDL_Swap16(*spot); - } - } - } - break; - - case 4: { - Uint32 *spot; - for ( y=0; yh; ++y ) { - spot = (Uint32 *) ((Uint8 *)screen->pixels + - y * screen->pitch); - for ( x=0; xw; ++x, ++spot ) { - *spot = SDL_Swap32(*spot); - } - } - } - break; - - default: - /* should never get here */ - break; - } -} -static void CGX_SwapPixels(SDL_Surface *screen, int numrects, SDL_Rect *rects) -{ - int i; - int x, minx, maxx; - int y, miny, maxy; - - switch (screen->format->BytesPerPixel) { - case 2: { - Uint16 *spot; - for ( i=0; ipixels + - y * screen->pitch + minx * 2); - for ( x=minx; xpixels + - y * screen->pitch + minx * 4); - for ( x=minx; xhidden->same_format && !use_picasso96) - { - format=RECTFMT_RAW; - } - else switch(this->screen->format->BytesPerPixel) - { - case 4: - format=RECTFMT_RGBA; - break; - case 3: - format=RECTFMT_RGB; - break; - case 2: - customroutine=1; - break; - case 1: -// D(bug("soft depth: 8 hardbpp: %ld\n",this->hidden->depth)); - if(this->hidden->depth>8) - { -#ifndef USE_CGX_WRITELUTPIXEL - if(this->hidden->depth>32) - customroutine=4; - else if(this->hidden->depth>16) - { - bpp=this->hidden->BytesPerPixel; // That one is the only one that needs bpp - customroutine=2; // The slow one! - } - else - customroutine=3; -#else - - customroutine=2; -#endif - -// format=RECTFMT_LUT8; Vecchia funzione x usare la WritePixelArray. - } - else - customroutine=1; - break; - default: - D(bug("Unable to blit this surface!\n")); - return; - } - - /* Check for endian-swapped X server, swap if necessary (VERY slow!) */ - if ( swap_pixels && - ((this->screen->format->BytesPerPixel%2) == 0) ) { - D(bug("Software Swapping! SLOOOW!\n")); - CGX_SwapPixels(this->screen, numrects, rects); - for ( i=0; iscreen->pixels,rects[i].x, rects[i].y,this->screen->pitch, - SDL_RastPort,SDL_Window->BorderLeft+rects[i].x,SDL_Window->BorderTop+rects[i].y, - rects[i].w,rects[i].h,format); - } - CGX_SwapPixels(this->screen, numrects, rects); - } - else if (customroutine==2) - { -#ifdef USE_CGX_WRITELUTPIXEL - for ( i=0; iscreen->pixels,rects[i].x, rects[i].y,this->screen->pitch, - SDL_RastPort,SDL_XPixels,SDL_Window->BorderLeft+rects[i].x,SDL_Window->BorderTop+rects[i].y, - rects[i].w,rects[i].h,CTABFMT_XRGB8); - } -#else - unsigned char *bm_address; - Uint32 destpitch; - APTR handle; - - if(handle=LockBitMapTags(SDL_RastPort->BitMap,LBMI_BASEADDRESS,&bm_address, - LBMI_BYTESPERROW,&destpitch,TAG_DONE)) - { - int srcwidth; - unsigned char *destbase; - register int j,k,t; - register unsigned char *mask,*dst; - register unsigned char *src,*dest; - -// Aggiungo il bordo della finestra se sono fullscreen. - if(currently_fullscreen) - destbase=bm_address; - else - destbase=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->hidden->BytesPerPixel; - - for ( i=0; ihidden->BytesPerPixel; - dest+=(rects[i].y*destpitch); - src=((char *)(this->screen->pixels))+rects[i].x; - src+=(rects[i].y*this->screen->pitch); - - for(j=rects[i].h;j;--j) - { - dst=dest; -// SLOW routine, used for 8->24 bit mapping - for(k=0;kscreen->pitch; - dest+=destpitch; - } - } - UnLockBitMap(handle); - } - } - else if (customroutine==3) - { - unsigned char *bm_address; - Uint32 destpitch; - APTR handle; - - if(handle=LockBitMapTags(SDL_RastPort->BitMap,LBMI_BASEADDRESS,&bm_address, - LBMI_BYTESPERROW,&destpitch,TAG_DONE)) - { - int srcwidth; - unsigned char *destbase; - register int j,k; - register unsigned char *src,*dest; - register Uint16 *destl,*srcl; - - if(currently_fullscreen) - destbase=bm_address; - else - destbase=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->hidden->BytesPerPixel; - - for ( i=0; ihidden->BytesPerPixel; - dest+=(rects[i].y*destpitch); - src=((char *)(this->screen->pixels))+rects[i].x; - src+=(rects[i].y*this->screen->pitch); - -// This is the fast, well not too slow, remapping code for 16bit displays - - for(j=rects[i].h;j;--j) - { - destl=(Uint16 *)dest; - - for(k=0;kscreen->pitch; - dest+=destpitch; - } - } - UnLockBitMap(handle); - } - } - else if (customroutine==4) - { - unsigned char *bm_address; - Uint32 destpitch; - APTR handle; - - if(handle=LockBitMapTags(SDL_RastPort->BitMap,LBMI_BASEADDRESS,&bm_address, - LBMI_BYTESPERROW,&destpitch,TAG_DONE)) - { - int srcwidth; - unsigned char *destbase; - register int j,k; - register unsigned char *src,*dest; - register Uint32 *destl,*srcl; - - if(currently_fullscreen) - destbase=bm_address; - else - destbase=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->hidden->BytesPerPixel; - - for ( i=0; ihidden->BytesPerPixel; - dest+=(rects[i].y*destpitch); - src=((char *)(this->screen->pixels))+rects[i].x; - src+=(rects[i].y*this->screen->pitch); - -// This is the fast, well not too slow, remapping code for 32bit displays - - for(j=rects[i].h;j;--j) - { - destl=(Uint32 *)dest; - - for(k=0;kscreen->pitch; - dest+=destpitch; - } - } - UnLockBitMap(handle); - } -#endif - } - else if(customroutine) - { - unsigned char *bm_address; - Uint32 destpitch; - APTR handle; - -// D(bug("Using customroutine!\n")); - - if(handle=LockBitMapTags(SDL_RastPort->BitMap,LBMI_BASEADDRESS,(ULONG)&bm_address, - LBMI_BYTESPERROW,(ULONG)&destpitch,TAG_DONE)) - { - unsigned char *destbase; - register int j,srcwidth; - register unsigned char *src,*dest; - -// Aggiungo il bordo della finestra se sono fullscreen. - if(currently_fullscreen) - destbase=bm_address; - else - destbase=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->screen->format->BytesPerPixel; - - for ( i=0; iscreen->format->BytesPerPixel; - dest+=(rects[i].y*destpitch); - src=((char *)(this->screen->pixels))+rects[i].x*this->screen->format->BytesPerPixel; - src+=(rects[i].y*this->screen->pitch); - - srcwidth*=this->screen->format->BytesPerPixel; - -// D(bug("Rects: %ld,%ld %ld,%ld Src:%lx Dest:%lx\n",rects[i].x,rects[i].y,rects[i].w,rects[i].h,src,dest)); - - for(j=rects[i].h;j;--j) - { - SDL_memcpy(dest,src,srcwidth); - src+=this->screen->pitch; - dest+=destpitch; - } - } - UnLockBitMap(handle); -// D(bug("Rectblit addr: %lx pitch: %ld rects:%ld srcptr: %lx srcpitch: %ld\n",bm_address,destpitch,numrects,this->screen->pixels,this->screen->pitch)); - } - } - else - { - for ( i=0; iscreen->pixels,rects[i].x, rects[i].y,this->screen->pitch, - SDL_RastPort,SDL_Window->BorderLeft+rects[i].x,SDL_Window->BorderTop+rects[i].y, - rects[i].w,rects[i].h,format); - } - } -} - -void CGX_RefreshDisplay(_THIS) -{ - int format,customroutine=0; -#ifndef USE_CGX_WRITELUTPIXEL - int bpp; -#endif - /* Don't refresh a display that doesn't have an image (like GL) */ - if ( ! SDL_Ximage ) { - return; - } - - if(this->hidden->same_format && !use_picasso96) - { - format=RECTFMT_RAW; - } - else switch(this->screen->format->BytesPerPixel) - { - case 4: - format=RECTFMT_RGBA; - break; - case 3: - format=RECTFMT_RGB; - break; - case 2: - customroutine=1; - break; - case 1: -// D(bug("soft depth: 8 hardbpp: %ld\n",this->hidden->depth)); - if(this->hidden->depth>8) - { -#ifndef USE_CGX_WRITELUTPIXEL - if(this->hidden->depth>32) - customroutine=4; - else if(this->hidden->depth>16) - { - bpp=this->hidden->BytesPerPixel; // That one is the only one that needs bpp - customroutine=2; // The slow one! - } - else - customroutine=3; -#else - - customroutine=2; -#endif -// format=RECTFMT_LUT8; - } - else - customroutine=1; - break; - - } - - /* Check for endian-swapped X server, swap if necessary */ - if ( swap_pixels && - ((this->screen->format->BytesPerPixel%2) == 0) ) { - CGX_SwapAllPixels(this->screen); - USE_WPA(this->screen->pixels,0,0,this->screen->pitch, - SDL_RastPort,SDL_Window->BorderLeft,SDL_Window->BorderTop, - this->screen->w,this->screen->h,format); - CGX_SwapAllPixels(this->screen); - } - else if (customroutine==2) - { -#ifdef USE_CGX_WRITELUTPIXEL - WLUT(this->screen->pixels,0,0,this->screen->pitch, - SDL_RastPort,SDL_XPixels,SDL_Window->BorderLeft,SDL_Window->BorderTop, - this->screen->w,this->screen->h,CTABFMT_XRGB8); -#else - unsigned char *bm_address; - Uint32 destpitch; - APTR handle; - - if(handle=LockBitMapTags(SDL_RastPort->BitMap,LBMI_BASEADDRESS,(ULONG)&bm_address, - LBMI_BYTESPERROW,(ULONG)&destpitch,TAG_DONE)) - { - register int j,k,t; - register unsigned char *mask,*dst; - register unsigned char *src,*dest; - -// Aggiungo il bordo della finestra se sono fullscreen. - if(!currently_fullscreen) - dest=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->hidden->BytesPerPixel; - else - dest=bm_address; - - src=this->screen->pixels; - - for(j=this->screen->h;j;--j) - { - dst=dest; -// SLOW routine, used for 8->24 bit mapping - for(k=0;kscreen->w;k++) - { - mask=(unsigned char *)(&SDL_XPixels[src[k]]); - for(t=0;tscreen->pitch; - dest+=destpitch; - } - UnLockBitMap(handle); - } - } - else if (customroutine==3) - { - unsigned char *bm_address; - Uint32 destpitch; - APTR handle; - - if(handle=LockBitMapTags(SDL_RastPort->BitMap,LBMI_BASEADDRESS,(ULONG)&bm_address, - LBMI_BYTESPERROW,(ULONG)&destpitch,TAG_DONE)) - { - register int j,k; - register unsigned char *src,*dest; - register Uint16 *destl,*srcl; - - if(!currently_fullscreen) - dest=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->hidden->BytesPerPixel; - else - dest=bm_address; - - src=this->screen->pixels; - -// This is the fast, well not too slow, remapping code for 16bit displays - - for(j=this->screen->h;j;--j) - { - destl=(Uint16 *)dest; - - for(k=0;kscreen->w;k++) - { - srcl=(Uint16 *)&SDL_XPixels[src[k]]; - *destl=*srcl; - destl++; - } - src+=this->screen->pitch; - dest+=destpitch; - } - UnLockBitMap(handle); - } - } - else if (customroutine==4) - { - unsigned char *bm_address; - Uint32 destpitch; - APTR handle; - - if(handle=LockBitMapTags(SDL_RastPort->BitMap,LBMI_BASEADDRESS,(ULONG)&bm_address, - LBMI_BYTESPERROW,(ULONG)&destpitch,TAG_DONE)) - { - register int j,k; - register unsigned char *src,*dest; - register Uint32 *destl,*srcl; - - if(!currently_fullscreen) - dest=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->hidden->BytesPerPixel; - else - dest=bm_address; - - src=this->screen->pixels; - -// This is the fast, well not too slow, remapping code for 32bit displays - - for(j=this->screen->h;j;--j) - { - destl=(Uint32 *)dest; - - for(k=0;kscreen->w;k++) - { - srcl=(Uint32 *)&SDL_XPixels[src[k]]; - *destl=*srcl; - destl++; - } - src+=this->screen->pitch; - dest+=destpitch; - } - UnLockBitMap(handle); - } -#endif - } - else if(customroutine) - { - unsigned char *bm_address; - Uint32 destpitch; - APTR handle; - - if(handle=LockBitMapTags(SDL_RastPort->BitMap, - LBMI_BASEADDRESS,(ULONG)&bm_address, - LBMI_BYTESPERROW,(ULONG)&destpitch,TAG_DONE)) - { - register int j; - register unsigned char *src,*dest; - - if(!currently_fullscreen) - dest=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->screen->format->BytesPerPixel; - else - dest=bm_address; - - src=this->screen->pixels; - -// D(bug("addr: %lx pitch: %ld src:%lx srcpitch: %ld\n",dest,destpitch,this->screen->pixels,this->screen->pitch)); - - if(this->screen->pitch==destpitch) - { - SDL_memcpy(dest,src,this->screen->pitch*this->screen->h); - } - else - { - for(j=this->screen->h;j;--j) - { - SDL_memcpy(dest,src,this->screen->pitch); - src+=this->screen->pitch; - dest+=destpitch; - } - } - - UnLockBitMap(handle); - } - } - else - { - USE_WPA(this->screen->pixels,0,0,this->screen->pitch, - SDL_RastPort,SDL_Window->BorderLeft,SDL_Window->BorderTop, - this->screen->w,this->screen->h,format); - } - -} diff --git a/src/video/cybergfx/SDL_cgximage_c.h b/src/video/cybergfx/SDL_cgximage_c.h deleted file mode 100644 index 30dc7a413..000000000 --- a/src/video/cybergfx/SDL_cgximage_c.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#include "SDL_cgxvideo.h" - -extern int CGX_SetupImage(_THIS, SDL_Surface *screen); -extern void CGX_DestroyImage(_THIS, SDL_Surface *screen); -extern int CGX_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags); - -extern int CGX_AllocHWSurface(_THIS, SDL_Surface *surface); -extern void CGX_FreeHWSurface(_THIS, SDL_Surface *surface); -extern int CGX_LockHWSurface(_THIS, SDL_Surface *surface); -extern void CGX_UnlockHWSurface(_THIS, SDL_Surface *surface); -extern int CGX_FlipHWSurface(_THIS, SDL_Surface *surface); - -extern void CGX_RefreshDisplay(_THIS); diff --git a/src/video/cybergfx/SDL_cgxmodes.c b/src/video/cybergfx/SDL_cgxmodes.c deleted file mode 100644 index fdf7dbd29..000000000 --- a/src/video/cybergfx/SDL_cgxmodes.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* Utilities for getting and setting the X display mode */ - -#include "SDL_timer.h" -#include "SDL_events.h" -#include "../../events/SDL_events_c.h" -#include "SDL_cgxvideo.h" -#include "SDL_cgxwm_c.h" -#include "SDL_cgxmodes_c.h" - -#define CGX_DEBUG - -static void set_best_resolution(_THIS, int width, int height) -{ - Uint32 idok; - int depth=8; - - if(SDL_Display) - depth=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH); - - idok=BestCModeIDTags(CYBRBIDTG_NominalWidth,width, - CYBRBIDTG_NominalHeight,height, - CYBRBIDTG_Depth,depth, - TAG_DONE); - - if(idok!=INVALID_ID) - { - if(SDL_Display) - { - if(currently_fullscreen) - CloseScreen(SDL_Display); - else - UnlockPubScreen(NULL,SDL_Display); - } - SDL_Display=GFX_Display=OpenScreenTags(NULL,SA_Width,width,SA_Height,height, - SA_Depth,depth,SA_DisplayID,idok, - SA_ShowTitle,FALSE, - TAG_DONE); - } -} - -static void get_real_resolution(_THIS, int* w, int* h) -{ - *w = /*SDL_Display->Width*/ SDL_Window->Width-SDL_Window->BorderLeft-SDL_Window->BorderRight; - *h = /*SDL_Display->Height*/ SDL_Window->Height-SDL_Window->BorderBottom-SDL_Window->BorderTop; -} - -static void move_cursor_to(_THIS, int x, int y) -{ -/* XWarpPointer(SDL_Display, None, SDL_Root, 0, 0, 0, 0, x, y); */ - -/* DA FARE! */ -} - -static void add_visual(_THIS, int depth, int class) -{ - Uint32 tID; - - tID=BestCModeIDTags(CYBRBIDTG_Depth,depth, - CYBRBIDTG_NominalWidth,640, - CYBRBIDTG_NominalHeight,480, - TAG_DONE); - - if(tID!=INVALID_ID) - { - int n = this->hidden->nvisuals; - - this->hidden->visuals[n].depth = depth; - this->hidden->visuals[n].visual = tID; - this->hidden->visuals[n].bpp = GetCyberIDAttr(CYBRIDATTR_BPPIX,tID); - this->hidden->nvisuals++; - } -} - -#define TrueColor 1 -#define PseudoColor 2 - -int CGX_GetVideoModes(_THIS) -{ - int i; - ULONG nextid; - int nmodes=0; - - SDL_modelist=NULL; - - nextid=NextDisplayInfo(INVALID_ID); - - while(nextid!=INVALID_ID) - { - if(IsCyberModeID(nextid)) - { - DisplayInfoHandle h; - - if(h=FindDisplayInfo(nextid)) - { - struct DimensionInfo info; - - if(GetDisplayInfoData(h,(char *)&info,sizeof(struct DimensionInfo),DTAG_DIMS,NULL)) - { - int ok=0; - - for(i=0;iw == (info.Nominal.MaxX+1) && - SDL_modelist[i]->h == (info.Nominal.MaxY+1) ) - ok=1; - } - - if(!ok) - { - nmodes++; - - SDL_modelist = (SDL_Rect **)SDL_realloc(SDL_modelist,(nmodes+1)*sizeof(SDL_Rect *)); - SDL_modelist[nmodes]=NULL; - - if ( SDL_modelist ) - { - SDL_modelist[nmodes-1] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); - - if ( SDL_modelist[nmodes-1] == NULL ) - break; - - SDL_modelist[nmodes-1]->x = 0; - SDL_modelist[nmodes-1]->y = 0; - SDL_modelist[nmodes-1]->w = info.Nominal.MaxX+1; - SDL_modelist[nmodes-1]->h = info.Nominal.MaxY+1; - } - } - } - } - } - nextid=NextDisplayInfo(nextid); - } - - - this->hidden->nvisuals = 0; - /* Search for the visuals in deepest-first order, so that the first - will be the richest one */ - add_visual(this, 32, TrueColor); - add_visual(this, 24, TrueColor); - add_visual(this, 16, TrueColor); - add_visual(this, 15, TrueColor); - add_visual(this, 8, PseudoColor); - - if(this->hidden->nvisuals == 0) { - SDL_SetError("Found no sufficiently capable CGX visuals"); - return -1; - } - - if ( SDL_modelist == NULL ) { - SDL_modelist = (SDL_Rect **)SDL_malloc((1+1)*sizeof(SDL_Rect *)); - i = 0; - if ( SDL_modelist ) { - SDL_modelist[i] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); - if ( SDL_modelist[i] ) { - SDL_modelist[i]->x = 0; - SDL_modelist[i]->y = 0; - SDL_modelist[i]->w = SDL_Display->Width; - SDL_modelist[i]->h = SDL_Display->Height; - ++i; - } - SDL_modelist[i] = NULL; - } - } - - D( if ( SDL_modelist ) { - bug("CGX video mode list: (%ld)\n",nmodes); - for ( i=0; SDL_modelist[i]; ++i ) { - bug( "\t%ld x %ld\n", - SDL_modelist[i]->w, SDL_modelist[i]->h); - } - } - ); - - D( { bug("CGX visuals list: (%ld)\n",this->hidden->nvisuals); - - for(i=0;ihidden->nvisuals;i++) - bug("\t%lx - depth: %ld bpp: %ld\n",this->hidden->visuals[i].visual,this->hidden->visuals[i].depth,this->hidden->visuals[i].bpp); - } - ); - return 0; -} - -int CGX_SupportedVisual(_THIS, SDL_PixelFormat *format) -{ - int i; - for(i = 0; i < this->hidden->nvisuals; i++) - { - if(this->hidden->visuals[i].depth == format->BitsPerPixel) // Era bpp - return 1; - } - return 0; -} - -SDL_Rect **CGX_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) -{ - if ( CGX_SupportedVisual(this, format) ) { - if ( flags & SDL_FULLSCREEN ) { - return(SDL_modelist); - } else { - return((SDL_Rect **)-1); - } - } else { - return((SDL_Rect **)0); - } -} - -void CGX_FreeVideoModes(_THIS) -{ - int i; - - if ( SDL_modelist ) { - for ( i=0; SDL_modelist[i]; ++i ) { - SDL_free(SDL_modelist[i]); - } - SDL_free(SDL_modelist); - SDL_modelist = NULL; - } -} - -int CGX_ResizeFullScreen(_THIS) -{ - int x, y; - int real_w, real_h; - - if ( currently_fullscreen ) { -/* Per ora non faccio nulla qui */ - } - return(1); -} - -void _QueueEnterFullScreen(_THIS) -{ -} - -int CGX_EnterFullScreen(_THIS) -{ - int okay; - Uint32 saved_flags; - - okay = 1; - saved_flags = this->screen->flags; - - if ( ! currently_fullscreen ) - { - int real_w, real_h; - - /* Map the fullscreen window to blank the screen */ - get_real_resolution(this, &real_w, &real_h); - - CGX_DestroyWindow(this,this->screen); - set_best_resolution(this, real_w,real_h); - - currently_fullscreen = 1; - this->screen->flags = saved_flags; - - CGX_CreateWindow(this,this->screen,real_w,real_h,GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH),this->screen->flags); - - /* Set the new resolution */ - okay = CGX_ResizeFullScreen(this); - if ( ! okay ) { - CGX_LeaveFullScreen(this); - } - /* Set the colormap */ -/* - if ( SDL_XColorMap ) { - XInstallColormap(SDL_Display, SDL_XColorMap); - } -*/ - } -// CGX_GrabInputNoLock(this, this->input_grab | SDL_GRAB_FULLSCREEN); - return(okay); -} - -int CGX_LeaveFullScreen(_THIS) -{ - if ( currently_fullscreen ) { - int width,height; - if ( SDL_Window ) { - CloseWindow(SDL_Window); - SDL_Window=NULL; - } - CloseScreen(SDL_Display); - - GFX_Display=SDL_Display=LockPubScreen(NULL); - - currently_fullscreen = 0; - - CGX_CreateWindow(this,this->screen,this->screen->w,this->screen->h,GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH),this->screen->flags); - CGX_ResizeImage(this,this->screen,0L); - } - - return(0); -} diff --git a/src/video/cybergfx/SDL_cgxmodes_c.h b/src/video/cybergfx/SDL_cgxmodes_c.h deleted file mode 100644 index 6c6f4856e..000000000 --- a/src/video/cybergfx/SDL_cgxmodes_c.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* Utilities for getting and setting the X display mode */ - -#include "SDL_cgxvideo.h" - -/* Define this if you want to grab the keyboard in fullscreen mode. - If you do not define this, SDL will return from SDL_SetVideoMode() - immediately, but will not actually go fullscreen until the window - manager is idle. -*/ -#define GRAB_FULLSCREEN - -extern int CGX_GetVideoModes(_THIS); -extern SDL_Rect **CGX_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); -extern void CGX_FreeVideoModes(_THIS); -extern int CGX_ResizeFullScreen(_THIS); -/* -extern void CGX_WaitMapped(_THIS, Window win); -extern void CGX_WaitUnmapped(_THIS, Window win); -extern void CGX_QueueEnterFullScreen(_THIS); -*/ -extern int CGX_EnterFullScreen(_THIS); -extern int CGX_LeaveFullScreen(_THIS); diff --git a/src/video/cybergfx/SDL_cgxvideo.c b/src/video/cybergfx/SDL_cgxvideo.c deleted file mode 100644 index e3067464d..000000000 --- a/src/video/cybergfx/SDL_cgxvideo.c +++ /dev/null @@ -1,1375 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - * CGX based SDL video driver implementation by Gabriele Greco - * gabriele.greco@aruba.it - */ - -#include "SDL_endian.h" -#include "SDL_timer.h" -#include "SDL_thread.h" -#include "SDL_video.h" -#include "SDL_mouse.h" -#include "../SDL_sysvideo.h" -#include "../SDL_pixels_c.h" -#include "../../events/SDL_events_c.h" -#include "SDL_cgxgl_c.h" -#include "SDL_cgxvideo.h" -#include "SDL_cgxwm_c.h" -#include "SDL_amigamouse_c.h" -#include "SDL_amigaevents_c.h" -#include "SDL_cgxmodes_c.h" -#include "SDL_cgximage_c.h" - -/* Initialization/Query functions */ -static int CGX_VideoInit(_THIS, SDL_PixelFormat *vformat); -static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); -static int CGX_ToggleFullScreen(_THIS, int on); -static void CGX_UpdateMouse(_THIS); -static int CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); -static void CGX_VideoQuit(_THIS); - -/* CGX driver bootstrap functions */ - -struct Library *CyberGfxBase=NULL; -struct IntuitionBase *IntuitionBase=NULL; -struct GfxBase *GfxBase=NULL; - -int CGX_SetGamma(_THIS, float red, float green, float blue) -{ - SDL_SetError("Gamma correction not supported"); - return -1; -} - -int CGX_GetGamma(_THIS, float red, float green, float blue) -{ - SDL_SetError("Gamma correction not supported"); - return -1; -} - -int CGX_SetGammaRamp(_THIS, Uint16 *ramp) -{ -#if 0 - Int i, ncolors; - XColor xcmap[256]; - - /* See if actually setting the gamma is supported */ - if ( SDL_Visual->class != DirectColor ) { - SDL_SetError("Gamma correction not supported on this visual"); - return(-1); - } - - /* Calculate the appropriate palette for the given gamma ramp */ - ncolors = SDL_Visual->map_entries; - for ( i=0; iscreen->format, c, c, c); - xcmap[i].red = ramp[0*256+c]; - xcmap[i].green = ramp[1*256+c]; - xcmap[i].blue = ramp[2*256+c]; - xcmap[i].flags = (DoRed|DoGreen|DoBlue); - } - XStoreColors(GFX_Display, SDL_XColorMap, xcmap, ncolors); - XSync(GFX_Display, False); - - return(0); - -#else - SDL_SetError("Gamma correction not supported on this visual"); - return(-1); - -#endif -} - -static void DestroyScreen(_THIS) -{ - if(currently_fullscreen) - { - if(this->hidden->dbuffer) - { - extern struct MsgPort *safeport,*dispport; - - this->hidden->dbuffer=0; - - if(safeport) - { - while(GetMsg(safeport)!=NULL); - DeleteMsgPort(safeport); - } - if(dispport) - { - while(GetMsg(dispport)!=NULL); - DeleteMsgPort(dispport); - } - - this->hidden->SB[0]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=this->hidden->SB[0]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=NULL; - this->hidden->SB[1]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=this->hidden->SB[1]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=NULL; - - if(this->hidden->SB[1]) - FreeScreenBuffer(SDL_Display,this->hidden->SB[1]); - if(this->hidden->SB[0]) - FreeScreenBuffer(SDL_Display,this->hidden->SB[0]); - - - this->hidden->SB[0]=this->hidden->SB[1]=NULL; - - if(SDL_RastPort && SDL_RastPort != &SDL_Display->RastPort) - SDL_free(SDL_RastPort); - - SDL_RastPort=NULL; - } - CloseScreen(GFX_Display); - currently_fullscreen=0; - } - else if(GFX_Display) - UnlockPubScreen(NULL,GFX_Display); - - GFX_Display = NULL; -} - -static int CGX_Available(void) -{ - struct Library *l; - - l = OpenLibrary("cybergraphics.library",0L); - - if ( l != NULL ) { - D(bug("CGX video device AVAILABLE\n")); - CloseLibrary(l); - } - D(else bug("**CGX video device UNAVAILABLE\n")); - - return(l != NULL); -} - -static void CGX_DeleteDevice(SDL_VideoDevice *device) -{ - if ( device ) { - if ( device->hidden ) { - SDL_free(device->hidden); - } - if ( device->gl_data ) { - SDL_free(device->gl_data); - } - SDL_free(device); - } -} - -static SDL_VideoDevice *CGX_CreateDevice(int devindex) -{ - SDL_VideoDevice *device; - - /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); - if ( device ) { - SDL_memset(device, 0, (sizeof *device)); - device->hidden = (struct SDL_PrivateVideoData *) - SDL_malloc((sizeof *device->hidden)); - device->gl_data = (struct SDL_PrivateGLData *) - SDL_malloc((sizeof *device->gl_data)); - } - if ( (device == NULL) || (device->hidden == NULL) || - (device->gl_data == NULL) ) { - D(bug("Unable to create video device!\n")); - SDL_OutOfMemory(); - CGX_DeleteDevice(device); - return(0); - } - SDL_memset(device->hidden, 0, sizeof(*device->hidden)); - SDL_memset(device->gl_data, 0, sizeof(*device->gl_data)); - - /* Set the driver flags */ - device->handles_any_size = 1; - - /* Set the function pointers */ - device->VideoInit = CGX_VideoInit; - device->ListModes = CGX_ListModes; - device->SetVideoMode = CGX_SetVideoMode; - device->ToggleFullScreen = CGX_ToggleFullScreen; - device->UpdateMouse = CGX_UpdateMouse; - device->SetColors = CGX_SetColors; - device->UpdateRects = NULL; - device->VideoQuit = CGX_VideoQuit; - device->AllocHWSurface = CGX_AllocHWSurface; - device->CheckHWBlit = CGX_CheckHWBlit; - device->FillHWRect = CGX_FillHWRect; - device->SetHWColorKey = CGX_SetHWColorKey; - device->SetHWAlpha = NULL; - device->LockHWSurface = CGX_LockHWSurface; - device->UnlockHWSurface = CGX_UnlockHWSurface; - device->FlipHWSurface = CGX_FlipHWSurface; - device->FreeHWSurface = CGX_FreeHWSurface; - device->SetGamma = CGX_SetGamma; - device->GetGamma = CGX_GetGamma; - device->SetGammaRamp = CGX_SetGammaRamp; - device->GetGammaRamp = NULL; -#if SDL_VIDEO_OPENGL - device->GL_LoadLibrary = CGX_GL_LoadLibrary; - device->GL_GetProcAddress = CGX_GL_GetProcAddress; - device->GL_GetAttribute = CGX_GL_GetAttribute; - device->GL_MakeCurrent = CGX_GL_MakeCurrent; - device->GL_SwapBuffers = CGX_GL_SwapBuffers; -#endif - device->SetIcon = CGX_SetIcon; - device->SetCaption = CGX_SetCaption; - device->IconifyWindow = NULL; /* CGX_IconifyWindow; */ - device->GrabInput = NULL /* CGX_GrabInput*/; - device->GetWMInfo = CGX_GetWMInfo; - device->FreeWMCursor = amiga_FreeWMCursor; - device->CreateWMCursor = amiga_CreateWMCursor; - device->ShowWMCursor = amiga_ShowWMCursor; - device->WarpWMCursor = amiga_WarpWMCursor; - device->CheckMouseMode = amiga_CheckMouseMode; - device->InitOSKeymap = amiga_InitOSKeymap; - device->PumpEvents = amiga_PumpEvents; - - device->free = CGX_DeleteDevice; - - return device; -} - -VideoBootStrap CGX_bootstrap = { - "CGX", "AmigaOS CyberGraphics", CGX_Available, CGX_CreateDevice -}; - -Uint32 MakeBitMask(_THIS,int type,int format,int *bpp) -{ - D(if(type==0)bug("REAL pixel format: ")); - - if(this->hidden->depth==*bpp) - { - - switch(format) - { - case PIXFMT_LUT8: - D(if(type==0)bug("LUT8\n")); - return 0; - case PIXFMT_BGR15: - case PIXFMT_RGB15PC: - switch(type) - { - case 0: - D(bug("RGB15PC/BGR15\n")); - return 31; - case 1: - return 992; - case 2: - return 31744; - } - case PIXFMT_RGB15: - case PIXFMT_BGR15PC: - switch(type) - { - case 0: - D(bug("RGB15/BGR15PC\n")); - return 31744; - case 1: - return 992; - case 2: - return 31; - } - case PIXFMT_BGR16PC: - case PIXFMT_RGB16: - switch(type) - { - case 0: - D(bug("RGB16PC\n")); - return 63488; - case 1: - return 2016; - case 2: - return 31; - } - case PIXFMT_BGR16: - case PIXFMT_RGB16PC: - switch(type) - { - case 0: - D(bug("RGB16PC/BGR16\n")); - return 31; - case 1: - return 2016; - case 2: - return 63488; - } - - case PIXFMT_RGB24: - switch(type) - { - case 0: - D(bug("RGB24/BGR24\n")); - return 0xff0000; - case 1: - return 0xff00; - case 2: - return 0xff; - } - case PIXFMT_BGR24: - switch(type) - { - case 0: - D(bug("BGR24\n")); - return 0xff; - case 1: - return 0xff00; - case 2: - return 0xff0000; - } - case PIXFMT_ARGB32: - switch(type) - { - case 0: - D(bug("ARGB32\n")); - return 0xff0000; - case 1: - return 0xff00; - case 2: - return 0xff; - } - case PIXFMT_BGRA32: - switch(type) - { - case 0: - D(bug("BGRA32\n")); - return 0xff00; - case 1: - return 0xff0000; - case 2: - return 0xff000000; - } - case PIXFMT_RGBA32: - switch(type) - { - case 0: - D(bug("RGBA32\n")); - return 0xff000000; - case 1: - return 0xff0000; - case 2: - return 0xff00; - } - default: - D(bug("Unknown pixel format! Default to 24bit\n")); - return (Uint32) (255<<(type*8)); - } - } - else - { - D(if(type==0)bug("DIFFERENT from screen.\nAllocated screen format: ")); - - switch(*bpp) - { - case 32: - D(if(type==0) bug("RGBA32\n")); - switch(type) - { - case 0: - return 0xff000000; - case 1: - return 0xff0000; - case 2: - return 0xff00; - } - break; - case 24: -use_truecolor: - switch(type) - { - case 0: - D(bug("RGB24\n")); - return 0xff0000; - case 1: - return 0xff00; - case 2: - return 0xff; - } - case 16: - case 15: - D(if(type==0) bug("Not supported, switching to 24bit!\n")); - *bpp=24; - goto use_truecolor; - break; - default: - D(if(type==0)bug("This is a chunky display\n")); -// For chunky display mask is always 0; - return 0; - } - } - return 0; -} - -static int CGX_VideoInit(_THIS, SDL_PixelFormat *vformat) -{ - int i; - struct Library *RTGBase; - - D(bug("VideoInit... Opening libraries\n")); - - if(!IntuitionBase) { - if( !(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",39L))) { - SDL_SetError("Couldn't open intuition V39+"); - return -1; - } - } - - if(!GfxBase) { - if( !(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",39L))) { - SDL_SetError("Couldn't open graphics V39+"); - return -1; - } - } - - if(!CyberGfxBase) { - if( !(CyberGfxBase=OpenLibrary("cybergraphics.library",40L))) { - SDL_SetError("Couldn't open cybergraphics."); - return(-1); - } - } - - if(RTGBase=OpenLibrary("libs:picasso96/rtg.library",0L)) { - extern int use_picasso96; - - CloseLibrary(RTGBase); - use_picasso96=1; - } - - D(bug("Library intialized, locking screen...\n")); - - SDL_Display = LockPubScreen(NULL); - - if ( SDL_Display == NULL ) { - D(bug("Cannot lock display...\n")); - SDL_SetError("Couldn't lock the display"); - return(-1); - } - this->info.current_w = SDL_Display->Width; - this->info.current_h = SDL_Display->Height; - - D(bug("Checking if we are using a CGX native display...\n")); - - if(!IsCyberModeID(GetVPModeID(&SDL_Display->ViewPort))) - { - Uint32 okid=BestCModeIDTags(CYBRBIDTG_NominalWidth,SDL_Display->Width, - CYBRBIDTG_NominalHeight,SDL_Display->Height, - CYBRBIDTG_Depth,8, - TAG_DONE); - - D(bug("Default visual is not CGX native!\n")); - - UnlockPubScreen(NULL,SDL_Display); - - GFX_Display=NULL; - - if(okid!=INVALID_ID) - { - GFX_Display=OpenScreenTags(NULL, - SA_Width,SDL_Display->Width, - SA_Height,SDL_Display->Height, - SA_Depth,8,SA_Quiet,TRUE, - SA_ShowTitle,FALSE, - SA_DisplayID,okid, - TAG_DONE); - } - - if(!GFX_Display) - { - SDL_SetError("Unable to open a suited CGX display"); - return -1; - } - else SDL_Display=GFX_Display; - - } - else GFX_Display = SDL_Display; - - - /* See whether or not we need to swap pixels */ - - swap_pixels = 0; - -// Non e' detto che sia cosi' pero', alcune schede potrebbero gestire i modi in modo differente - - if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { - swap_pixels = 1; - } - - D(bug("Before GetVideoModes....\n")); - - /* Get the available video modes */ - if(CGX_GetVideoModes(this) < 0) - return -1; - - /* Determine the default screen depth: - Use the default visual (or at least one with the same depth) */ - - for(i = 0; i < this->hidden->nvisuals; i++) - if(this->hidden->visuals[i].depth == GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH)) - break; - if(i == this->hidden->nvisuals) { - /* default visual was useless, take the deepest one instead */ - i = 0; - } - SDL_Visual = this->hidden->visuals[i].visual; - -// SDL_XColorMap = SDL_DisplayColormap; - - this->hidden->depth = this->hidden->visuals[i].depth; - D(bug("Init: Setting screen depth to: %ld\n",this->hidden->depth)); - vformat->BitsPerPixel = this->hidden->visuals[i].depth; /* this->hidden->visuals[i].bpp; */ - - { - int form; - APTR handle; - struct DisplayInfo info; - - if(!(handle=FindDisplayInfo(this->hidden->visuals[i].visual))) - { - D(bug("Unable to get visual info...\n")); - return -1; - } - - if(!GetDisplayInfoData(handle,(char *)&info,sizeof(struct DisplayInfo),DTAG_DISP,NULL)) { - D(bug("Unable to get visual info data...\n")); - return -1; - } - - form=GetCyberIDAttr(CYBRIDATTR_PIXFMT,SDL_Visual); - -// In this case I use makebitmask in a way that I'm sure I'll get PIXFMT pixel mask - - if ( vformat->BitsPerPixel > 8 ) - { - vformat->Rmask = MakeBitMask(this,0,form,&this->hidden->depth); - vformat->Gmask = MakeBitMask(this,1,form,&this->hidden->depth); - vformat->Bmask = MakeBitMask(this,2,form,&this->hidden->depth); - } - } - - /* See if we have been passed a window to use */ -/* SDL_windowid = SDL_getenv("SDL_WINDOWID"); */ - SDL_windowid=NULL; - - /* Create the blank cursor */ - SDL_BlankCursor = AllocMem(16,MEMF_CHIP|MEMF_CLEAR); - - /* Fill in some window manager capabilities */ - this->info.wm_available = 1; - this->info.blit_hw = 1; - this->info.blit_hw_CC = 1; - this->info.blit_sw = 1; - this->info.blit_fill = 1; - this->info.video_mem=2000000; // Not always true but almost any Amiga card has this memory! - - this->hidden->same_format=0; - SDL_RastPort=&SDL_Display->RastPort; - /* We're done! */ - D(bug("End of CGX_VideoInit\n")); - - return(0); -} - -void CGX_DestroyWindow(_THIS, SDL_Surface *screen) -{ - D(bug("Destroy Window...\n")); - - if ( ! SDL_windowid ) { - /* Hide the managed window */ - int was_fullscreen=0; - - /* Clean up OpenGL */ - if ( screen ) { - screen->flags &= ~(SDL_OPENGL|SDL_OPENGLBLIT); - } - - if ( screen && (screen->flags & SDL_FULLSCREEN) ) { - was_fullscreen=1; - screen->flags &= ~SDL_FULLSCREEN; -// CGX_LeaveFullScreen(this); tolto x crash - } - - /* Destroy the output window */ - if ( SDL_Window ) { - CloseWindow(SDL_Window); - SDL_Window=NULL; - } - - /* Free the colormap entries */ - if ( SDL_XPixels ) { - int numcolors; - unsigned long pixel; - - if(this->screen->format&&this->hidden->depth==8&&!was_fullscreen) - { - numcolors = 1<screen->format->BitsPerPixel; - - if(numcolors>256) - numcolors=256; - - if(!was_fullscreen&&this->hidden->depth==8) - { - for ( pixel=0; pixel=0) - ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]); - } - } - } - SDL_free(SDL_XPixels); - SDL_XPixels = NULL; - } - } -} - -static void CGX_SetSizeHints(_THIS, int w, int h, Uint32 flags) -{ - if ( flags & SDL_RESIZABLE ) { - WindowLimits(SDL_Window, 32, 32,4096,4096); - } else { - WindowLimits(SDL_Window, w,h,w,h); - } - if ( flags & SDL_FULLSCREEN ) { - flags&=~SDL_RESIZABLE; - } else if ( SDL_getenv("SDL_VIDEO_CENTERED") ) { - int display_w, display_h; - - display_w = SDL_Display->Width; - display_h = SDL_Display->Height; - ChangeWindowBox(SDL_Window,(display_w - w - SDL_Window->BorderLeft-SDL_Window->BorderRight)/2, - (display_h - h - SDL_Window->BorderTop-SDL_Window->BorderBottom)/2, - w+SDL_Window->BorderLeft+SDL_Window->BorderRight, - h+SDL_Window->BorderTop+SDL_Window->BorderBottom); - } -} - -int CGX_CreateWindow(_THIS, SDL_Surface *screen, - int w, int h, int bpp, Uint32 flags) -{ -#if 0 - int i, depth; - Uint32 vis; -#endif - D(bug("CGX_CreateWindow\n")); - - /* If a window is already present, destroy it and start fresh */ - if ( SDL_Window ) { - CGX_DestroyWindow(this, screen); - } - - /* See if we have been given a window id */ - if ( SDL_windowid ) { - SDL_Window = (struct Window *)atol(SDL_windowid); - } else { - SDL_Window = 0; - } - - /* find out which visual we are going to use */ -#if 0 -/* questo l'ho spostato nell'apertura dello schermo, in quanto su Amiga le finestre - hanno il pixel mode degli schermi. - */ - /*if ( flags & SDL_OPENGL ) { - SDL_SetError("OpenGL not supported by the Amiga SDL!"); - return -1; - } - else {*/ - for ( i = 0; i < this->hidden->nvisuals; i++ ) { - if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */ - break; - } - if ( i == this->hidden->nvisuals ) { - SDL_SetError("No matching visual for requested depth"); - return -1; /* should never happen */ - } - vis = this->hidden->visuals[i].visual; - depth = this->hidden->visuals[i].depth; -// } - SDL_Visual = vis; - this->hidden->depth = depth; - D(bug("Setting screen depth to: %ld\n",this->hidden->depth)); -#endif - - /* Allocate the new pixel format for this video mode */ - { - Uint32 form; - APTR handle; - struct DisplayInfo info; - - if(!(handle=FindDisplayInfo(SDL_Visual))) - return -1; - - if(!GetDisplayInfoData(handle,(char *)&info,sizeof(struct DisplayInfo),DTAG_DISP,NULL)) - return -1; - - form=GetCyberIDAttr(CYBRIDATTR_PIXFMT,SDL_Visual); - - if(flags&SDL_HWSURFACE) - { - if(bpp!=this->hidden->depth) - { - bpp=this->hidden->depth; - D(bug("Accel forces bpp to be equal (%ld)\n",bpp)); - } - } - - D(bug("BEFORE screen allocation: bpp:%ld (real:%ld)\n",bpp,this->hidden->depth)); - -/* With this call if needed I'll revert the wanted bpp to a bpp best suited for the display, actually occurs - only with requested format 15/16bit and display format != 15/16bit - */ - - if ( ! SDL_ReallocFormat(screen, bpp, - MakeBitMask(this,0,form,&bpp), MakeBitMask(this,1,form,&bpp), MakeBitMask(this,2,form,&bpp), 0) ) - return -1; - - D(bug("AFTER screen allocation: bpp:%ld (real:%ld)\n",bpp,this->hidden->depth)); - - } - - /* Create the appropriate colormap */ -/* - if ( SDL_XColorMap != SDL_DisplayColormap ) { - XFreeColormap(SDL_Display, SDL_XColorMap); - } -*/ - if ( GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_PIXFMT)==PIXFMT_LUT8 || bpp==8 ) { - int ncolors,i; - D(bug("XPixels palette allocation...\n")); - - /* Allocate the pixel flags */ - - if(bpp==8) - ncolors=256; - else - ncolors = 1 << screen->format->BitsPerPixel; - - SDL_XPixels = (Sint32 *)SDL_malloc(ncolors * sizeof(Sint32)); - - if(SDL_XPixels == NULL) { - SDL_OutOfMemory(); - return -1; - } - - - for(i=0;iflags |= SDL_HWPALETTE; - } - - /* resize the (possibly new) window manager window */ - - /* Create (or use) the X11 display window */ - - if ( !SDL_windowid ) { - if( flags & SDL_FULLSCREEN ) - { - SDL_Window = OpenWindowTags(NULL,WA_Width,w,WA_Height,h, - WA_Flags,WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_BORDERLESS|WFLG_BACKDROP|WFLG_REPORTMOUSE, - WA_IDCMP,IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE, - WA_CustomScreen,(ULONG)SDL_Display, - TAG_DONE); - - D(bug("Opening backdrop window %ldx%ld on display %lx!\n",w,h,SDL_Display)); - } - else - { - /* Create GimmeZeroZero window when OpenGL is used */ - unsigned long gzz = FALSE; - if( flags & SDL_OPENGL ) { - gzz = TRUE; - } - - SDL_Window = OpenWindowTags(NULL,WA_InnerWidth,w,WA_InnerHeight,h, - WA_Flags,WFLG_REPORTMOUSE|WFLG_ACTIVATE|WFLG_RMBTRAP | ((flags&SDL_NOFRAME) ? 0 : (WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_DRAGBAR | ((flags&SDL_RESIZABLE) ? WFLG_SIZEGADGET|WFLG_SIZEBBOTTOM : 0))), - WA_IDCMP,IDCMP_RAWKEY|IDCMP_CLOSEWINDOW|IDCMP_MOUSEBUTTONS|IDCMP_NEWSIZE|IDCMP_MOUSEMOVE, - WA_PubScreen,(ULONG)SDL_Display, - WA_GimmeZeroZero, gzz, - TAG_DONE); - D(bug("Opening WB window of size: %ldx%ld!\n",w,h)); - } - - if(!SDL_Window) - return -1; - } - - this->hidden->BytesPerPixel=GetCyberMapAttr(SDL_Window->RPort->BitMap,CYBRMATTR_BPPIX); - - if(screen->flags & SDL_DOUBLEBUF) - { - if(SDL_RastPort=SDL_malloc(sizeof(struct RastPort))) - { - InitRastPort(SDL_RastPort); - SDL_RastPort->BitMap=this->hidden->SB[1]->sb_BitMap; - } - else - return -1; - } - else SDL_RastPort=SDL_Window->RPort; - - if(flags&SDL_HWSURFACE) - screen->flags|=SDL_HWSURFACE; - - if( !SDL_windowid ) { - CGX_SetSizeHints(this, w, h, flags); - } - - /* Set our colormaps when not setting a GL mode */ -/* - if ( ! (flags & SDL_OPENGL) ) { - XSetWindowColormap(SDL_Display, SDL_Window, SDL_XColorMap); - } -*/ - - /* Map them both and go fullscreen, if requested */ - if ( ! SDL_windowid ) { - if ( flags & SDL_FULLSCREEN ) { - screen->flags |= SDL_FULLSCREEN; - currently_fullscreen=1; -// CGX_EnterFullScreen(this); Ci siamo gia'! - } else { - screen->flags &= ~SDL_FULLSCREEN; - } - } - screen->w = w; - screen->h = h; - screen->pitch = SDL_CalculatePitch(screen); - CGX_ResizeImage(this, screen, flags); - - /* Make OpenGL Context if needed*/ - if(flags & SDL_OPENGL) { - if(this->gl_data->gl_active == 0) { - if(CGX_GL_Init(this) < 0) - return -1; - else - screen->flags |= SDL_OPENGL; - } - else { - if(CGX_GL_Update(this) < 0) - return -1; - else - screen->flags |= SDL_OPENGL; - } - } -} - -int CGX_ResizeWindow(_THIS, - SDL_Surface *screen, int w, int h, Uint32 flags) -{ - D(bug("CGX_ResizeWindow\n")); - - if ( ! SDL_windowid ) { - /* Resize the window manager window */ - CGX_SetSizeHints(this, w, h, flags); - - ChangeWindowBox(SDL_Window,SDL_Window->LeftEdge,SDL_Window->TopEdge, w+SDL_Window->BorderLeft+SDL_Window->BorderRight, - h+SDL_Window->BorderTop+SDL_Window->BorderBottom); - - screen->w = w; - screen->h = h; - screen->pitch = SDL_CalculatePitch(screen); - CGX_ResizeImage(this, screen, flags); - } - return(0); -} - -static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current, - int width, int height, int bpp, Uint32 flags) -{ - Uint32 saved_flags; - int needcreate=0; - - D(bug("CGX_SetVideoMode current:%lx\n",current)); - - /* Lock the event thread, in multi-threading environments */ - SDL_Lock_EventThread(); - -// Check if the window needs to be closed or can be resized - - if( (flags&SDL_FULLSCREEN) || (current && current->flags&SDL_FULLSCREEN && !(flags&SDL_FULLSCREEN))) - needcreate=1; - -// Check if we need to close an already existing videomode... - - if(current && current->flags&SDL_FULLSCREEN && !(flags&SDL_FULLSCREEN)) { - unsigned long i; - D(bug("Destroying image, window & screen!\n")); - - CGX_DestroyImage(this,current); - CGX_DestroyWindow(this,current); - DestroyScreen(this); - GFX_Display=SDL_Display=LockPubScreen(NULL); - - bpp=this->hidden->depth=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH); - - for ( i = 0; i < this->hidden->nvisuals; i++ ) { - if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */ - break; - } - if ( i == this->hidden->nvisuals ) { - SDL_SetError("No matching visual for requested depth"); - return NULL; /* should never happen */ - } - SDL_Visual = this->hidden->visuals[i].visual; - - D(bug("Setting screen depth to: %ld\n",this->hidden->depth)); - - } - /* Check the combination of flags we were passed */ - if ( flags & SDL_FULLSCREEN ) { - int i; - - /* Clear fullscreen flag if not supported */ - if ( SDL_windowid ) { - flags &= ~SDL_FULLSCREEN; - } - else if(current && current->flags&SDL_FULLSCREEN ) { - if(current->w!=width || - current->h!=height || - (this->hidden && this->hidden->depth!=bpp)) - { - D(bug("Deleting previous window...\n")); - CGX_DestroyImage(this,current); - CGX_DestroyWindow(this,current); - DestroyScreen(this); - goto buildnewscreen; - } - } - else -buildnewscreen: - { - Uint32 okid=BestCModeIDTags(CYBRBIDTG_NominalWidth,width, - CYBRBIDTG_NominalHeight,height, - CYBRBIDTG_Depth,bpp, - TAG_DONE); - - GFX_Display=NULL; - - D(bug("Opening screen...\n")); - - if(okid!=INVALID_ID) - GFX_Display=OpenScreenTags(NULL, - SA_Width,width, - SA_Height,height, - SA_Quiet,TRUE,SA_ShowTitle,FALSE, - SA_Depth,bpp, - SA_DisplayID,okid, - TAG_DONE); - - if(!GFX_Display) { - GFX_Display=SDL_Display; - flags &= ~SDL_FULLSCREEN; - flags &= ~SDL_DOUBLEBUF; - } - else { - UnlockPubScreen(NULL,SDL_Display); - SDL_Display=GFX_Display; - - D(bug("Screen opened.\n")); - - if(flags&SDL_DOUBLEBUF) { - int ok=0; - D(bug("Start of DBuffering allocations...\n")); - - if(this->hidden->SB[0]=AllocScreenBuffer(SDL_Display,NULL,SB_SCREEN_BITMAP)) { - - if(this->hidden->SB[1]=AllocScreenBuffer(SDL_Display,NULL,0L)) { - extern struct MsgPort *safeport,*dispport; - - safeport=CreateMsgPort(); - dispport=CreateMsgPort(); - - if(!safeport || !dispport) { - if(safeport) { - DeleteMsgPort(safeport); - safeport=NULL; - } - if(dispport) { - DeleteMsgPort(dispport); - dispport=NULL; - } - FreeScreenBuffer(SDL_Display,this->hidden->SB[0]); - FreeScreenBuffer(SDL_Display,this->hidden->SB[1]); - } - else { - extern ULONG safe_sigbit,disp_sigbit; - int i; - - safe_sigbit=1L<< safeport->mp_SigBit; - disp_sigbit=1L<< dispport->mp_SigBit; - - for(i=0;i<2;i++) { - this->hidden->SB[i]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=safeport; - this->hidden->SB[i]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=dispport; - } - - ok=1; - D(bug("Dbuffering enabled!\n")); - this->hidden->dbuffer=1; - current->flags|=SDL_DOUBLEBUF; - } - } - else { - FreeScreenBuffer(SDL_Display,this->hidden->SB[1]); - this->hidden->SB[0]=NULL; - } - } - - if(!ok) - flags&=~SDL_DOUBLEBUF; - } - } - - if(GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH)==bpp) - this->hidden->same_format=1; - } - - bpp=this->hidden->depth=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH); - D(bug("Setting screen depth to: %ld\n",this->hidden->depth)); - - for ( i = 0; i < this->hidden->nvisuals; i++ ) - if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */ - break; - - if ( i == this->hidden->nvisuals ) { - SDL_SetError("No matching visual for requested depth"); - return NULL; /* should never happen */ - } - SDL_Visual = this->hidden->visuals[i].visual; - - } - - /* Set up the X11 window */ - saved_flags = current->flags; - - if (SDL_Window && (saved_flags&SDL_OPENGL) == (flags&SDL_OPENGL) - && bpp == current->format->BitsPerPixel && !needcreate) { - if (CGX_ResizeWindow(this, current, width, height, flags) < 0) { - current = NULL; - goto done; - } - } else { - if (CGX_CreateWindow(this,current,width,height,bpp,flags) < 0) { - current = NULL; - goto done; - } - } - -#if 0 - /* Set up the new mode framebuffer */ - if ( ((current->w != width) || (current->h != height)) || - ((saved_flags&SDL_OPENGL) != (flags&SDL_OPENGL)) ) { - current->w = width; - current->h = height; - current->pitch = SDL_CalculatePitch(current); - CGX_ResizeImage(this, current, flags); - } -#endif - - current->flags |= (flags&SDL_RESIZABLE); // Resizable only if the user asked it - - done: - /* Release the event thread */ - SDL_Unlock_EventThread(); - - /* We're done! */ - return(current); -} - -static int CGX_ToggleFullScreen(_THIS, int on) -{ - Uint32 event_thread; - - /* Don't switch if we don't own the window */ - if ( SDL_windowid ) { - return(0); - } - - /* Don't lock if we are the event thread */ - event_thread = SDL_EventThreadID(); - if ( event_thread && (SDL_ThreadID() == event_thread) ) { - event_thread = 0; - } - if ( event_thread ) { - SDL_Lock_EventThread(); - } - if ( on ) { - this->screen->flags |= SDL_FULLSCREEN; - CGX_EnterFullScreen(this); - } else { - this->screen->flags &= ~SDL_FULLSCREEN; - CGX_LeaveFullScreen(this); - } - - CGX_RefreshDisplay(this); - if ( event_thread ) { - SDL_Unlock_EventThread(); - } - - SDL_ResetKeyboard(); - - return(1); -} - -static void SetSingleColor(Uint32 fmt, unsigned char r, unsigned char g, unsigned char b, unsigned char *c) -{ - switch(fmt) - { - case PIXFMT_BGR15: - case PIXFMT_RGB15PC: - { - Uint16 *t=(Uint16 *)c; - *t=(r>>3) | ((g>>3)<<5) | ((b>>3)<<10) ; - } - break; - case PIXFMT_RGB15: - case PIXFMT_BGR15PC: - { - Uint16 *t=(Uint16 *)c; - *t=(b>>3) | ((g>>3)<<5) | ((r>>3)<<10) ; - } - break; - case PIXFMT_BGR16PC: - case PIXFMT_RGB16: - { - Uint16 *t=(Uint16 *)c; - *t=(b>>3) | ((g>>2)<<5) | ((r>>3)<<11) ; - } - break; - case PIXFMT_BGR16: - case PIXFMT_RGB16PC: - { - Uint16 *t=(Uint16 *)c; - *t=(r>>3) | ((g>>2)<<5) | ((b>>3)<<11) ; - } - break; - case PIXFMT_RGB24: - c[0]=r; - c[1]=g; - c[2]=b; - c[3]=0; - break; - case PIXFMT_BGR24: - c[0]=b; - c[1]=g; - c[2]=r; - c[3]=0; - break; - case PIXFMT_ARGB32: - c[0]=0; - c[1]=r; - c[2]=g; - c[3]=b; - break; - case PIXFMT_BGRA32: - c[0]=b; - c[1]=g; - c[2]=r; - c[3]=0; - break; - case PIXFMT_RGBA32: - c[0]=r; - c[1]=g; - c[2]=b; - c[3]=0; - break; - - default: - D(bug("Error, SetSingleColor with PIXFMT %ld!\n",fmt)); - } -} - -/* Update the current mouse state and position */ -static void CGX_UpdateMouse(_THIS) -{ - /* Lock the event thread, in multi-threading environments */ - SDL_Lock_EventThread(); - - if(currently_fullscreen) - { - SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); - SDL_PrivateMouseMotion(0, 0, SDL_Display->MouseX, SDL_Display->MouseY); - } - else - { - if( SDL_Display->MouseX>=(SDL_Window->LeftEdge+SDL_Window->BorderLeft) && SDL_Display->MouseX<(SDL_Window->LeftEdge+SDL_Window->Width-SDL_Window->BorderRight) && - SDL_Display->MouseY>=(SDL_Window->TopEdge+SDL_Window->BorderLeft) && SDL_Display->MouseY<(SDL_Window->TopEdge+SDL_Window->Height-SDL_Window->BorderBottom) - ) - { - SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); - SDL_PrivateMouseMotion(0, 0, SDL_Display->MouseX-SDL_Window->LeftEdge-SDL_Window->BorderLeft, - SDL_Display->MouseY-SDL_Window->TopEdge-SDL_Window->BorderTop); - } - else - { - SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); - } - } - SDL_Unlock_EventThread(); -} - -static int CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) -{ - int i; - - /* Check to make sure we have a colormap allocated */ - - /* It's easy if we have a hidden colormap */ - if ( (this->screen->flags & SDL_HWPALETTE) && currently_fullscreen ) - { - ULONG xcmap[256*3+2]; - - xcmap[0]=(ncolors<<16); - xcmap[0]+=firstcolor; - -// D(bug("Setting %ld colors on an HWPALETTE screen\n",ncolors)); - - for ( i=0; iViewPort,xcmap); - } else { -// XPixels are not needed on 8bit screen with hwpalette - unsigned long pixel; - - if ( SDL_XPixels == NULL ) { - D(bug("SetColors without colormap!")); - return(0); - } - - if(this->hidden->depth==8) - { -// In this case I have to unalloc and realloc the full palette - D(bug("Obtaining %ld colors on the screen\n",ncolors)); - - /* Free existing allocated colors */ - for ( pixel=0; pixelscreen->format->palette->ncolors; ++pixel ) { - if(SDL_XPixels[pixel]>=0) - ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]); - } - - /* Try to allocate all the colors */ - for ( i=0; iscreen->format->palette->ncolors; ++i ) { - SDL_XPixels[i]=ObtainBestPenA(GFX_Display->ViewPort.ColorMap,colors[i].r<<24,colors[i].g<<24,colors[i].b<<24,NULL); - } - } - else - { -#ifndef USE_CGX_WRITELUTPIXEL - Uint32 fmt; - D(bug("Preparing a conversion pixel table...\n")); - - fmt=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_PIXFMT); - - for(i=0;igl_data->gl_active == 1) { - CGX_GL_Quit(this); - } - /* Start shutting down the windows */ - D(bug("Destroying image...\n")); - CGX_DestroyImage(this, this->screen); - D(bug("Destroying window...\n")); - CGX_DestroyWindow(this, this->screen); -// Otherwise SDL_VideoQuit will try to free it! - SDL_VideoSurface=NULL; - - CGX_FreeVideoModes(this); - - /* Free that blank cursor */ - if ( SDL_BlankCursor != NULL ) { - FreeMem(SDL_BlankCursor,16); - SDL_BlankCursor = NULL; - } - - /* Close the X11 graphics connection */ - this->hidden->same_format=0; - - D(bug("Destroying screen...\n")); - - if ( GFX_Display != NULL ) - DestroyScreen(this); - - /* Close the X11 display connection */ - SDL_Display = NULL; - - /* Unload GL library after X11 shuts down */ - } - - D(bug("Closing libraries...\n")); - - if( CyberGfxBase) { - CloseLibrary(CyberGfxBase); - CyberGfxBase=NULL; - } - - if (IntuitionBase) { - CloseLibrary((struct Library *)IntuitionBase); - IntuitionBase=NULL; - } - if (GfxBase) { - CloseLibrary((struct Library *)GfxBase); - GfxBase=NULL; - } - - if ( this->screen && (this->screen->flags & SDL_HWSURFACE) ) { - /* Direct screen access, no memory buffer */ - this->screen->pixels = NULL; - } - D(bug("End of CGX_VideoQuit.\n")); - -} - diff --git a/src/video/cybergfx/SDL_cgxvideo.h b/src/video/cybergfx/SDL_cgxvideo.h deleted file mode 100644 index 9ef76ea55..000000000 --- a/src/video/cybergfx/SDL_cgxvideo.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifndef _SDL_cgxvideo_h -#define _SDL_cgxvideo_h - - -#include -#include -#include -#include -#include -#if defined(__SASC) || defined(STORMC4_WOS) -#include -#include -#include -#include -#include -#else -#include -#include -#include -#include -#include -#endif - -#include "SDL_mouse.h" -#include "../SDL_sysvideo.h" -#include "mydebug.h" - -#define USE_CGX_WRITELUTPIXEL - -/* Hidden "this" pointer for the video functions */ -#define _THIS SDL_VideoDevice *this - -/* Private display data */ -struct SDL_PrivateVideoData { - struct Screen *Public_Display; /* Used for events and window management */ - struct Screen *GFX_Display; /* Used for graphics and colormap stuff */ - Uint32 SDL_VisualUnused; /* The visual used by our window */ - struct Window *SDL_Window; /* Shared by both displays (no X security?) */ - unsigned char *BlankCursor; /* The invisible cursor */ - - char *SDL_windowid; /* Flag: true if we have been passed a window */ - - /* The variables used for displaying graphics */ - Uint8 *Ximage; /* The X image for our window */ - int swap_pixels; /* Flag: true if display is swapped endian */ - - /* Support for internal mouse warping */ - struct { - int x; - int y; - } mouse_last; - struct { - int numerator; - int denominator; - int threshold; - } mouse_accel; - int mouse_relative; - - /* The current list of available video modes */ - SDL_Rect **modelist; - - /* available visuals of interest to us, sorted deepest first */ - struct { - Uint32 visual; - int depth; /* number of significant bits/pixel */ - int bpp; /* pixel quantum in bits */ - } visuals[5]; /* at most entries for 8, 15, 16, 24 */ - int nvisuals; - - Uint32 vis; /* current visual in use */ - int depth; /* current visual depth (not bpp) */ - int BytesPerPixel; - int currently_fullscreen,same_format,dbuffer; - - /* Automatic mode switching support (entering/leaving fullscreen) */ - Uint32 switch_waiting; - Uint32 switch_time; - - /* Prevent too many XSync() calls */ - int blit_queued; - - /* Colormap handling */ - LONG Pens; - Sint32 *XPixels; /* A list of pixels that have been allocated, the size depends on the screen format */ - struct ScreenBuffer *SB[2]; - struct RastPort *RP; - short *iconcolors; /* List of colors used by the icon */ -}; - -/* Old variable names */ -#define local_X11 (this->hidden->local_X11) -#define SDL_Display (this->hidden->Public_Display) -#define GFX_Display (this->hidden->GFX_Display) -#define SDL_Screen DefaultScreen(this->hidden->Public_Display) - -#define SDL_Visual (this->hidden->vis) - -#define SDL_Root RootWindow(SDL_Display, SDL_Screen) -#define WMwindow (this->hidden->WMwindow) -#define FSwindow (this->hidden->FSwindow) -#define SDL_Window (this->hidden->SDL_Window) -#define WM_DELETE_WINDOW (this->hidden->WM_DELETE_WINDOW) -#define SDL_BlankCursor (this->hidden->BlankCursor) -#define SDL_windowid (this->hidden->SDL_windowid) -#define SDL_Ximage (this->hidden->Ximage) -#define SDL_GC (this->hidden->gc) -#define swap_pixels (this->hidden->swap_pixels) -#define mouse_last (this->hidden->mouse_last) -#define mouse_accel (this->hidden->mouse_accel) -#define mouse_relative (this->hidden->mouse_relative) -#define SDL_modelist (this->hidden->modelist) -#define SDL_RastPort (this->hidden->RP) -#define saved_mode (this->hidden->saved_mode) -#define saved_view (this->hidden->saved_view) -#define currently_fullscreen (this->hidden->currently_fullscreen) -#define blit_queued (this->hidden->blit_queued) -#define SDL_DisplayColormap (this->hidden->GFX_Display->ViewPort.ColorMap) -#define SDL_XPixels (this->hidden->XPixels) -#define SDL_iconcolors (this->hidden->iconcolors) - -/* Used to get the X cursor from a window-manager specific cursor */ -// extern Cursor SDL_GetWMXCursor(WMcursor *cursor); - -extern int CGX_CreateWindow(_THIS, SDL_Surface *screen, - int w, int h, int bpp, Uint32 flags); -extern int CGX_ResizeWindow(_THIS, - SDL_Surface *screen, int w, int h, Uint32 flags); - -extern void CGX_DestroyWindow(_THIS, SDL_Surface *screen); - -extern struct Library *CyberGfxBase; -extern struct IntuitionBase *IntuitionBase; -extern struct GfxBase *GfxBase; -extern struct ExecBase *SysBase; -extern struct DosLibrary *DOSBase; - -struct private_hwdata -{ - struct BitMap *bmap; - APTR lock; - struct SDL_VideoDevice *videodata; - APTR mask; - int allocated; -}; - -int CGX_CheckHWBlit(_THIS,SDL_Surface *src,SDL_Surface *dst); -int CGX_FillHWRect(_THIS,SDL_Surface *dst,SDL_Rect *dstrect,Uint32 color); -int CGX_SetHWColorKey(_THIS,SDL_Surface *surface, Uint32 key); -#endif /* _SDL_x11video_h */ diff --git a/src/video/cybergfx/SDL_cgxwm.c b/src/video/cybergfx/SDL_cgxwm.c deleted file mode 100644 index 47a7d6002..000000000 --- a/src/video/cybergfx/SDL_cgxwm.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#include "SDL_version.h" -#include "SDL_timer.h" -#include "SDL_video.h" -#include "SDL_syswm.h" -#include "../../events/SDL_events_c.h" -#include "../SDL_pixels_c.h" -#include "SDL_cgxmodes_c.h" -#include "SDL_cgxwm_c.h" - -/* This is necessary for working properly with Enlightenment, etc. */ -#define USE_ICON_WINDOW - -void CGX_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask) -{ -/* Not yet implemented */ -} - -void CGX_SetCaption(_THIS, const char *title, const char *icon) -{ - if(SDL_Window) - SetWindowTitles(SDL_Window,(char *)title,NULL); -} - -/* Iconify the window */ -int CGX_IconifyWindow(_THIS) -{ -/* Not yet implemented */ - return 0; -} - -int CGX_GetWMInfo(_THIS, SDL_SysWMinfo *info) -{ - if ( info->version.major <= SDL_MAJOR_VERSION ) { - return(1); - } else { - SDL_SetError("Application not compiled with SDL %d.%d\n", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); - return(-1); - } -} diff --git a/src/video/cybergfx/SDL_cgxwm_c.h b/src/video/cybergfx/SDL_cgxwm_c.h deleted file mode 100644 index 35d1a616e..000000000 --- a/src/video/cybergfx/SDL_cgxwm_c.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#include "SDL_cgxvideo.h" - -/* Functions to be exported */ -extern void CGX_SetCaption(_THIS, const char *title, const char *icon); -extern void CGX_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask); -extern int CGX_IconifyWindow(_THIS); -extern SDL_GrabMode CGX_GrabInputNoLock(_THIS, SDL_GrabMode mode); -extern SDL_GrabMode CGX_GrabInput(_THIS, SDL_GrabMode mode); -extern int CGX_GetWMInfo(_THIS, SDL_SysWMinfo *info); - diff --git a/test/testplatform.c b/test/testplatform.c index 5b8388ed2..a68f42b02 100644 --- a/test/testplatform.c +++ b/test/testplatform.c @@ -154,8 +154,6 @@ int main(int argc, char *argv[]) printf("This system is running %s\n", #if __AIX__ "AIX" -#elif __AMIGA__ - "AmigaOS" #elif __BEOS__ "BeOS" #elif __BSDI__ From 74852e1d64ac6370815a35600bee2c3e059078a4 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 29 Oct 2006 04:08:50 +0000 Subject: [PATCH 043/241] A few more AmigaOS things. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402214 --- include/SDL_config.h.in | 2 -- src/audio/SDL_sysaudio.h | 3 --- src/video/SDL_sysvideo.h | 3 --- 3 files changed, 8 deletions(-) diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index 61afa6bec..89252e46d 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -149,7 +149,6 @@ #undef SDL_VIDEO_DISABLED /* Enable various audio drivers */ -#undef SDL_AUDIO_DRIVER_AHI #undef SDL_AUDIO_DRIVER_ALSA #undef SDL_AUDIO_DRIVER_ALSA_DYNAMIC #undef SDL_AUDIO_DRIVER_ARTS @@ -247,7 +246,6 @@ /* Enable various video drivers */ #undef SDL_VIDEO_DRIVER_AALIB #undef SDL_VIDEO_DRIVER_BWINDOW -#undef SDL_VIDEO_DRIVER_CYBERGRAPHICS #undef SDL_VIDEO_DRIVER_DC #undef SDL_VIDEO_DRIVER_DDRAW #undef SDL_VIDEO_DRIVER_DGA diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index 13e2dd516..2945448f2 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -146,9 +146,6 @@ extern AudioBootStrap COREAUDIO_bootstrap; #if SDL_AUDIO_DRIVER_SNDMGR extern AudioBootStrap SNDMGR_bootstrap; #endif -#if SDL_AUDIO_DRIVER_AHI -extern AudioBootStrap AHI_bootstrap; -#endif #if SDL_AUDIO_DRIVER_MINT extern AudioBootStrap MINTAUDIO_GSXB_bootstrap; extern AudioBootStrap MINTAUDIO_MCSN_bootstrap; diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index e1568a7db..80a579c35 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -374,9 +374,6 @@ extern VideoBootStrap TOOLBOX_bootstrap; #if SDL_VIDEO_DRIVER_DRAWSPROCKET extern VideoBootStrap DSp_bootstrap; #endif -#if SDL_VIDEO_DRIVER_CYBERGRAPHICS -extern VideoBootStrap CGX_bootstrap; -#endif #if SDL_VIDEO_DRIVER_PHOTON extern VideoBootStrap ph_bootstrap; #endif From eb72e866d7fcca0ac086de97054576023cef880b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 3 Nov 2006 21:52:54 +0000 Subject: [PATCH 044/241] Merged r2896:2897 from trunk (use dummy joystick if subsystem enabled and no platform-specific driver exists). Fixes Bugzilla #356 (and maybe Bugzilla #350). --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402220 --- configure.in | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/configure.in b/configure.in index 1983f66d9..893a8b961 100644 --- a/configure.in +++ b/configure.in @@ -2564,11 +2564,12 @@ case "$host" in esac # Verify that we have all the platform specific files we need -if test x$have_joystick != xyes; then - if test x$enable_joystick = xyes; then - AC_DEFINE(SDL_JOYSTICK_DISABLED) - fi + +if test x$enable_joystick = xyes; then + if test x$have_joystick != xyes; then + # Wants joystick subsystem, but doesn't have a platform-specific backend... SOURCES="$SOURCES $srcdir/src/joystick/dummy/*.c" + fi fi if test x$have_cdrom != xyes; then if test x$enable_cdrom = xyes; then From 23fc5d0035bacd12c39d28a3fb02f11fa77c4acd Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 7 Nov 2006 14:06:25 +0000 Subject: [PATCH 045/241] Chopped out some code to match changes in revision #2793 to fix build...but I think this just breaks fullscreen YUV rendering. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402221 --- src/video/bwindow/SDL_sysyuv.cc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/video/bwindow/SDL_sysyuv.cc b/src/video/bwindow/SDL_sysyuv.cc index 557a120ed..64213af70 100644 --- a/src/video/bwindow/SDL_sysyuv.cc +++ b/src/video/bwindow/SDL_sysyuv.cc @@ -274,13 +274,7 @@ int BE_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* src, SDL_Rect *d return 0; } BView * bview = overlay->hwdata->bview; - if (SDL_Win->IsFullScreen()) { - int left,top; - SDL_Win->GetXYOffset(left,top); - bview->MoveTo(left+dst->x,top+dst->y); - } else { - bview->MoveTo(dst->x,dst->y); - } + bview->MoveTo(dst->x,dst->y); bview->ResizeTo(dst->w,dst->h); bview->Flush(); if (overlay->hwdata->first_display) { From 92643bac520ebe9c06e3070d04c917da1dfbac56 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 7 Nov 2006 14:31:25 +0000 Subject: [PATCH 046/241] Added a test program for loadso subsystem. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402222 --- test/Makefile.in | 5 +++- test/testloadso.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 test/testloadso.c diff --git a/test/Makefile.in b/test/Makefile.in index f589aaa4e..7d5bb8b73 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -7,7 +7,7 @@ EXE = @EXE@ CFLAGS = @CFLAGS@ LIBS = @LIBS@ -TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) threadwin$(EXE) torturethread$(EXE) +TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) all: $(TARGETS) @@ -104,6 +104,9 @@ threadwin$(EXE): $(srcdir)/threadwin.c torturethread$(EXE): $(srcdir)/torturethread.c $(CC) -o $@ $? $(CFLAGS) $(LIBS) +testloadso$(EXE): $(srcdir)/testloadso.c + $(CC) -o $@ $? $(CFLAGS) $(LIBS) + clean: rm -f $(TARGETS) diff --git a/test/testloadso.c b/test/testloadso.c new file mode 100644 index 000000000..5b94a37b6 --- /dev/null +++ b/test/testloadso.c @@ -0,0 +1,70 @@ + +/* Test program to test dynamic loading with the loadso subsystem. +*/ + +#include +#include + +#include "SDL.h" + +typedef int (*fntype)(const char *); + +int main(int argc, char *argv[]) +{ + int retval = 0; + int hello = 0; + const char *libname = NULL; + const char *symname = NULL; + void *lib = NULL; + fntype fn = NULL; + + if (argc != 3) { + fprintf(stderr, "USAGE: %s \n"); + fprintf(stderr, " %s --hello \n"); + return 1; + } + + /* Initialize SDL */ + if ( SDL_Init(0) < 0 ) { + fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); + return 2; + } + + if (strcmp(argv[1], "--hello") == 0) { + hello = 1; + libname = argv[2]; + symname = "puts"; + } else { + libname = argv[1]; + symname = argv[2]; + } + + lib = SDL_LoadObject(libname); + if (lib == NULL) { + fprintf(stderr, "SDL_LoadObject('%s') failed: %s\n", + libname, SDL_GetError()); + retval = 3; + } else { + fn = (fntype) SDL_LoadFunction(lib, symname); + if (fn == NULL) { + fprintf(stderr, "SDL_LoadFunction('%s') failed: %s\n", + symname, SDL_GetError()); + retval = 4; + } else { + printf("Found %s in %s at %p\n", symname, libname); + if (hello) { + printf("Calling function...\n"); + fflush(stdout); + fn(" HELLO, WORLD!\n"); + printf("...apparently, we survived. :)\n"); + printf("Unloading library...\n"); + fflush(stdout); + } + } + SDL_UnloadObject(lib); + } + SDL_Quit(); + return(0); +} + + From c3143b8b9ce2c45c4c1bcbc7e17b211250cd4ad1 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 7 Nov 2006 15:00:43 +0000 Subject: [PATCH 047/241] Man, who let this moron near printf()?! :) --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402224 --- test/testloadso.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/testloadso.c b/test/testloadso.c index 5b94a37b6..39c14c69f 100644 --- a/test/testloadso.c +++ b/test/testloadso.c @@ -19,8 +19,9 @@ int main(int argc, char *argv[]) fntype fn = NULL; if (argc != 3) { - fprintf(stderr, "USAGE: %s \n"); - fprintf(stderr, " %s --hello \n"); + const char *app = argv[0]; + fprintf(stderr, "USAGE: %s \n", app); + fprintf(stderr, " %s --hello \n", app); return 1; } @@ -51,7 +52,7 @@ int main(int argc, char *argv[]) symname, SDL_GetError()); retval = 4; } else { - printf("Found %s in %s at %p\n", symname, libname); + printf("Found %s in %s at %p\n", symname, libname, fn); if (hello) { printf("Calling function...\n"); fflush(stdout); From 72c5d1e8abcf453201cd482a4e43dd573eae179f Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 7 Nov 2006 15:17:31 +0000 Subject: [PATCH 048/241] BeOS loadso code now reports failure correctly from SDL_LoadObject(), and uses the system to provide text for SDL_SetError(). --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402226 --- src/loadso/beos/SDL_sysloadso.c | 62 +++++++++++++++------------------ 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/src/loadso/beos/SDL_sysloadso.c b/src/loadso/beos/SDL_sysloadso.c index cf14c0b32..ba06d933e 100644 --- a/src/loadso/beos/SDL_sysloadso.c +++ b/src/loadso/beos/SDL_sysloadso.c @@ -31,46 +31,42 @@ #include "SDL_loadso.h" -void *SDL_LoadObject(const char *sofile) +void * +SDL_LoadObject(const char *sofile) { - void *handle = NULL; - const char *loaderror = "Unknown error"; - image_id library_id = load_add_on(sofile); - if ( library_id == B_ERROR ) { - loaderror = "BeOS error"; - } else { - handle = (void *)(library_id); - } - - if ( handle == NULL ) { - SDL_SetError("Failed loading %s: %s", sofile, loaderror); - } - return(handle); + void *handle = NULL; + image_id library_id = load_add_on(sofile); + if (library_id < 0) { + SDL_SetError(strerror((int) library_id)); + } else { + handle = (void *) (library_id); + } + return (handle); } -void *SDL_LoadFunction(void *handle, const char *name) +void * +SDL_LoadFunction(void *handle, const char *name) { - void *symbol = NULL; - const char *loaderror = "Unknown error"; - image_id library_id = (image_id)handle; - if ( get_image_symbol(library_id, - name, B_SYMBOL_TYPE_TEXT, &symbol) != B_NO_ERROR ) { - loaderror = "Symbol not found"; - } - - if ( symbol == NULL ) { - SDL_SetError("Failed loading %s: %s", name, loaderror); - } - return(symbol); + void *sym = NULL; + image_id library_id = (image_id) handle; + status_t rc = get_image_symbol(library_id, name, B_SYMBOL_TYPE_TEXT, &sym); + if (rc != B_NO_ERROR) { + SDL_SetError(strerror(rc)); + } + return (sym); } -void SDL_UnloadObject(void *handle) +void +SDL_UnloadObject(void *handle) { - image_id library_id; - if ( handle != NULL ) { - library_id = (image_id)handle; - unload_add_on(library_id); - } + image_id library_id; + if (handle != NULL) { + library_id = (image_id) handle; + unload_add_on(library_id); + } } #endif /* SDL_LOADSO_BEOS */ + +/* vi: set ts=4 sw=4 expandtab: */ + From 6bde13418708250b52ccbca8a66d2ab61e4f56e5 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 12 Nov 2006 21:23:57 +0000 Subject: [PATCH 049/241] Block fruity channel values in dspaudio, or the fragment size won't be a power of 2. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402229 --- src/audio/dsp/SDL_dspaudio.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/audio/dsp/SDL_dspaudio.c b/src/audio/dsp/SDL_dspaudio.c index 183cdd170..95617e3b0 100644 --- a/src/audio/dsp/SDL_dspaudio.c +++ b/src/audio/dsp/SDL_dspaudio.c @@ -168,6 +168,15 @@ static int DSP_OpenAudio(_THIS, SDL_AudioSpec *spec) int frag_spec; Uint16 test_format; + /* Make sure fragment size stays a power of 2, or OSS fails. */ + /* I don't know which of these are actually legal values, though... */ + if (spec->channels > 8) + spec->channels = 8; + else if (spec->channels > 4) + spec->channels = 4; + else if (spec->channels > 2) + spec->channels = 2; + /* Open the audio device */ audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); if ( audio_fd < 0 ) { From 8061a35dcfb99df974ad6edcc3267a566a6e706a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 13 Nov 2006 03:58:22 +0000 Subject: [PATCH 050/241] X11 backend: tell app that mouse focus has been obtained when grabbing the input. This allows us to enable DGA mode, even when the system cursor was outside of the window when the grab was initiated. Fixes Bugzilla #299, which has a more detailed explanation of the issue. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402231 --- src/video/x11/SDL_x11wm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/x11/SDL_x11wm.c b/src/video/x11/SDL_x11wm.c index d82a7a1d6..ba78aac9d 100644 --- a/src/video/x11/SDL_x11wm.c +++ b/src/video/x11/SDL_x11wm.c @@ -369,6 +369,8 @@ SDL_GrabMode X11_GrabInputNoLock(_THIS, SDL_GrabMode mode) /* Make sure we register input focus */ SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); + /* Since we grabbed the pointer, we have mouse focus, too. */ + SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); } XSync(SDL_Display, False); From ae2275c2b426727ab62a5ef2682cdaabbc26bab4 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 19 Nov 2006 14:07:32 +0000 Subject: [PATCH 051/241] Check video driver mouse cursor pointers before using them --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402234 --- src/video/SDL_cursor.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/video/SDL_cursor.c b/src/video/SDL_cursor.c index 723040e0b..c1f86032b 100644 --- a/src/video/SDL_cursor.c +++ b/src/video/SDL_cursor.c @@ -188,7 +188,7 @@ void SDL_SetCursor (SDL_Cursor *cursor) it needs to hide the old cursor before (possibly) showing the new one. (But don't erase NULL cursor) */ - if ( SDL_cursor ) { + if ( SDL_cursor && video->ShowWMCursor ) { video->ShowWMCursor(this, NULL); } } @@ -198,8 +198,11 @@ void SDL_SetCursor (SDL_Cursor *cursor) /* Draw the new mouse cursor */ if ( SDL_cursor && (SDL_cursorstate&CURSOR_VISIBLE) ) { /* Use window manager cursor if possible */ - if ( SDL_cursor->wm_cursor && - video->ShowWMCursor(this, SDL_cursor->wm_cursor) ) { + int show_wm_cursor = 0; + if ( SDL_cursor->wm_cursor && video->ShowWMCursor ) { + show_wm_cursor = video->ShowWMCursor(this, SDL_cursor->wm_cursor); + } + if ( show_wm_cursor ) { SDL_cursorstate &= ~CURSOR_USINGSW; } else { SDL_cursorstate |= CURSOR_USINGSW; @@ -219,7 +222,9 @@ void SDL_SetCursor (SDL_Cursor *cursor) SDL_EraseCursor(SDL_VideoSurface); } else { if ( video ) { - video->ShowWMCursor(this, NULL); + if ( video->ShowWMCursor ) { + video->ShowWMCursor(this, NULL); + } } } } @@ -248,7 +253,9 @@ void SDL_FreeCursor (SDL_Cursor *cursor) SDL_free(cursor->save[0]); } if ( video && cursor->wm_cursor ) { - video->FreeWMCursor(this, cursor->wm_cursor); + if ( video->FreeWMCursor ) { + video->FreeWMCursor(this, cursor->wm_cursor); + } } SDL_free(cursor); } From 8ab5a93d38717e2f7bf7f8505695330d3de00e8d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 21 Nov 2006 20:49:35 +0000 Subject: [PATCH 052/241] Added sdl.pc to svn:ignore. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402235 From 7a80023487f7497cd4e98b94444628500c719a74 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 21 Nov 2006 23:17:00 +0000 Subject: [PATCH 053/241] From: Gabriel Gambetta To: SDL Mailing List Date: Fri, 17 Nov 2006 00:39:29 -0200 Subject: [SDL] Alpha blending bug - fixed? It turns out mm5 never got the correct value. This failed : [...] "movd %1, %%mm5\n\t" : : "m" (amask), "m" (sf->Ashift) ); mm5 got 0xFF000018 instead of 0x00000018. However I did this : Uint32 ashift = sf->Ashift; [...] "movd %1, %%mm5\n\t" : : "m" (amask), "m" (ashift) ); and everything worked fine. The only thing I could find out was that ashift is 32-bit aligned but sf->Ashift isn't: printf("ashift %8X [%d]\n", &ashift, (int)(&ashift) % 4); printf("sf->Ashift %8X [%d]\n", &sf->Ashift, (int)(&sf->Ashift) % 4); ashift at BFF0E0C4 [0] sf->Ashift at 08AFB9CD [1] Could this be the problem? If it is, the fix is extremely trivial. Should I submit a patch? --Gabriel --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402236 --- src/video/SDL_blit_A.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/video/SDL_blit_A.c b/src/video/SDL_blit_A.c index 923b1624a..c33211eef 100644 --- a/src/video/SDL_blit_A.c +++ b/src/video/SDL_blit_A.c @@ -1566,6 +1566,7 @@ static void BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo *info) int dstskip = info->d_skip >> 2; SDL_PixelFormat* sf = info->src; Uint32 amask = sf->Amask; + Uint32 ashift = sf->Ashift; __asm__ ( /* make mm6 all zeros. */ @@ -1587,7 +1588,7 @@ static void BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo *info) /* get alpha channel shift */ "movd %1, %%mm5\n\t" /* Ashift -> mm5 */ - : /* nothing */ : "m" (sf->Amask), "m" (sf->Ashift) ); + : /* nothing */ : "m" (amask), "m" (ashift) ); while(height--) { From 880be03a0d8e58df063251fd4070b3389df6d7c8 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 29 Nov 2006 10:30:05 +0000 Subject: [PATCH 054/241] Wrapped some macro params in parentheses for alloca wrappers. Thansk, Suzuki Masahiro. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402240 --- include/SDL_stdinc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index 62535629f..4fd95163c 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -181,10 +181,10 @@ extern DECLSPEC void SDLCALL SDL_free(void *mem); # endif #endif #ifdef HAVE_ALLOCA -#define SDL_stack_alloc(type, count) (type*)alloca(sizeof(type)*count) +#define SDL_stack_alloc(type, count) (type*)alloca(sizeof(type)*(count)) #define SDL_stack_free(data) #else -#define SDL_stack_alloc(type, count) (type*)SDL_malloc(sizeof(type)*count) +#define SDL_stack_alloc(type, count) (type*)SDL_malloc(sizeof(type)*(count)) #define SDL_stack_free(data) SDL_free(data) #endif From cafb1ab2062cfa2d065770c7cf627ebbcdfe25d3 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 1 Dec 2006 20:26:06 +0000 Subject: [PATCH 055/241] Merge r2921:2922 from SDL trunk to 1.2 branch: mingw alloca.h workaround. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402244 --- configure.in | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 893a8b961..aefd09ad7 100644 --- a/configure.in +++ b/configure.in @@ -124,7 +124,14 @@ if test x$enable_libc = xyes; then fi dnl Checks for library functions. - AC_FUNC_ALLOCA + case "$host" in + *-*-cygwin* | *-*-mingw32*) + ;; + *) + AC_FUNC_ALLOCA + ;; + esac + AC_FUNC_MEMCMP if test x$ac_cv_func_memcmp_working = xyes; then AC_DEFINE(HAVE_MEMCMP) From 55d74eb418e62f177339671382014085cf3b0bd0 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 11 Dec 2006 19:51:19 +0000 Subject: [PATCH 056/241] Fix of HBITMAP leak in GAPI driver by Dmitry Yakimov. Fixes Bugzilla #371. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402247 --- src/video/gapi/SDL_gapivideo.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/video/gapi/SDL_gapivideo.c b/src/video/gapi/SDL_gapivideo.c index 93648f983..0dfce50cb 100644 --- a/src/video/gapi/SDL_gapivideo.c +++ b/src/video/gapi/SDL_gapivideo.c @@ -1178,7 +1178,7 @@ static void GAPI_WinPAINT(_THIS, HDC hdc) // draw current offscreen buffer on hdc int bpp = 16; // we always use either 8 or 16 bpp internally - + HGDIOBJ prevObject; unsigned short *bitmapData; HBITMAP hb; HDC srcDC; @@ -1216,10 +1216,11 @@ static void GAPI_WinPAINT(_THIS, HDC hdc) // FIXME: prevent misalignment, but I've never seen non aligned width of screen memcpy(bitmapData, this->hidden->buffer, pHeader->biSizeImage); srcDC = CreateCompatibleDC(hdc); - SelectObject(srcDC, hb); + prevObject = SelectObject(srcDC, hb); BitBlt(hdc, 0, 0, this->hidden->w, this->hidden->h, srcDC, 0, 0, SRCCOPY); + SelectObject(srcDC, prevObject); DeleteObject(hb); DeleteDC(srcDC); } From 4f0435f4d239321cd300d7998463aefba426918e Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 4 Jan 2007 19:52:12 +0000 Subject: [PATCH 057/241] Alpha sort the test list, add missing ones, remove removed ones --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402248 --- test/README | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/test/README b/test/README index c42fe3e8a..9cf5659c7 100644 --- a/test/README +++ b/test/README @@ -1,28 +1,35 @@ These are test programs for the SDL library: - testver Check the version and dynamic loading and endianness - testtypes Check to see if the data types are the correct size - testhread Hacked up test of multi-threading - testlock Hacked up test of multi-threading and locking - testerror Tests multi-threaded error handling - testsem Tests SDL's semaphore implementation - testtimer Test the timer facilities - loopwave Audio test -- loop playing a WAV file - testcdrom Sample audio CD control program - testkeys List the available keyboard keys - testvidinfo Show the pixel format of the display and perfom the benchmark checkkeys Watch the key events to check the keyboard - testwin Display a BMP image at various depths graywin Display a gray gradient and center mouse on spacebar - testsprite Example of fast sprite movement on the screen - testbitmap Test displaying 1-bit bitmaps + loopwave Audio test -- loop playing a WAV file testalpha Display an alpha faded icon -- paint with mouse - testwm Test window manager -- title, icon, events - threadwin Test multi-threaded event handling + testbitmap Test displaying 1-bit bitmaps + testblitspeed Tests performance of SDL's blitters and converters. + testcdrom Sample audio CD control program + testcursor Tests custom mouse cursor + testdyngl Tests dynamically loading OpenGL library + testerror Tests multi-threaded error handling + testfile Tests RWops layer + testgamma Tests video device gamma ramp testgl A very simple example of using OpenGL with SDL + testhread Hacked up test of multi-threading + testiconv Tests international string conversion testjoystick List joysticks and watch joystick events + testkeys List the available keyboard keys + testloadso Tests the loadable library layer + testlock Hacked up test of multi-threading and locking testoverlay Tests the software/hardware overlay functionality. testoverlay2 Tests the overlay flickering/scaling during playback. - testblitspeed Tests performance of SDL's blitters and converters. - + testpalette Tests palette color cycling + testplatform Tests types, endianness and cpu capabilities + testsem Tests SDL's semaphore implementation + testsprite Example of fast sprite movement on the screen + testtimer Test the timer facilities + testver Check the version and dynamic loading and endianness + testvidinfo Show the pixel format of the display and perfom the benchmark + testwin Display a BMP image at various depths + testwm Test window manager -- title, icon, events + threadwin Test multi-threaded event handling + torturethread Simple test for thread creation/destruction From 574cd41a99b37e815ce2b213a5757fb79cdfab87 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 11 Jan 2007 20:33:13 +0000 Subject: [PATCH 058/241] Disable TurboVeille screensaver if present --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402250 --- src/video/xbios/SDL_xbios.c | 11 +++++ src/video/xbios/SDL_xbios_tveille.c | 52 +++++++++++++++++++++ src/video/xbios/SDL_xbios_tveille.h | 70 +++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 src/video/xbios/SDL_xbios_tveille.c create mode 100644 src/video/xbios/SDL_xbios_tveille.h diff --git a/src/video/xbios/SDL_xbios.c b/src/video/xbios/SDL_xbios.c index a3b80dd2e..9cbb4a8ac 100644 --- a/src/video/xbios/SDL_xbios.c +++ b/src/video/xbios/SDL_xbios.c @@ -49,6 +49,7 @@ #include "SDL_xbios_blowup.h" #include "SDL_xbios_centscreen.h" #include "SDL_xbios_sb3.h" +#include "SDL_xbios_tveille.h" #define XBIOS_VID_DRIVER_NAME "xbios" @@ -464,6 +465,11 @@ static int XBIOS_VideoInit(_THIS, SDL_PixelFormat *vformat) SDL_AtariGL_InitPointers(this); #endif + /* Disable screensavers */ + if (SDL_XBIOS_TveillePresent(this)) { + SDL_XBIOS_TveilleDisable(this); + } + /* We're done! */ return(0); } @@ -928,6 +934,11 @@ static void XBIOS_VideoQuit(_THIS) } this->screen->pixels = NULL; + + /* Restore screensavers */ + if (SDL_XBIOS_TveillePresent(this)) { + SDL_XBIOS_TveilleRestore(this); + } } #if SDL_VIDEO_OPENGL diff --git a/src/video/xbios/SDL_xbios_tveille.c b/src/video/xbios/SDL_xbios_tveille.c new file mode 100644 index 000000000..461ad390a --- /dev/null +++ b/src/video/xbios/SDL_xbios_tveille.c @@ -0,0 +1,52 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2004 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* + Turbo veille screensaver + + Patrice Mandin +*/ + +#include + +#include "SDL_xbios.h" +#include "SDL_xbios_tveille.h" + +static tveille_t *cookie_veil; +static int status; + +int SDL_XBIOS_TveillePresent(_THIS) +{ + return (Getcookie(C_VeiL, (unsigned long *)&cookie_veil) == C_FOUND); +} + +void SDL_XBIOS_TveilleDisable(_THIS) +{ + status = cookie_veil->enabled; + cookie_veil->enabled = 0xff; +} + +void SDL_XBIOS_TveilleRestore(_THIS) +{ + cookie_veil->enabled = status; +} diff --git a/src/video/xbios/SDL_xbios_tveille.h b/src/video/xbios/SDL_xbios_tveille.h new file mode 100644 index 000000000..6ae9005f7 --- /dev/null +++ b/src/video/xbios/SDL_xbios_tveille.h @@ -0,0 +1,70 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2004 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* + Turbo veille screensaver + + Patrice Mandin +*/ + +#ifndef _SDL_xbios_tveille_h +#define _SDL_xbios_tveille_h + +#include "SDL_xbios.h" + +/*--- Defines ---*/ + +#ifndef C_VeiL +#define C_VeiL 0x5665694CL +#endif + +/*--- Structures ---*/ + +typedef struct { + unsigned long version; + void (*prg_ptr)(); + void (*kbd_ptr)(); + void (*vbl_ptr)(); + unsigned long vbl_count; + void (*oldkbd_ptr)(); + unsigned long off_count; + unsigned long prg_size; + unsigned long dummy1[4]; + unsigned char dummy2; + unsigned char status; + unsigned short freq; + unsigned short dummy3; + unsigned char clear_first; + unsigned char enabled; /* 0=enabled, 0xff=disabled */ + unsigned char serial_redir; + unsigned char dummy4; + void (*oldserial_ptr)(); +} __attribute__((packed)) tveille_t; + +/*--- Functions prototypes ---*/ + +int SDL_XBIOS_TveillePresent(_THIS); +void SDL_XBIOS_TveilleDisable(_THIS); +void SDL_XBIOS_TveilleEnable(_THIS); + +#endif /* _SDL_xbios_tveille_h */ From 776d4072e8db3e7b1e9d7db15706a94f154f1cfa Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 14 Jan 2007 14:24:36 +0000 Subject: [PATCH 059/241] Add error message if not using SDL_LoadObject --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402251 --- src/video/x11/SDL_x11gl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/video/x11/SDL_x11gl.c b/src/video/x11/SDL_x11gl.c index 43334c10f..1d767e17f 100644 --- a/src/video/x11/SDL_x11gl.c +++ b/src/video/x11/SDL_x11gl.c @@ -479,7 +479,11 @@ int X11_GL_LoadLibrary(_THIS, const char* path) handle = GL_LoadObject(path); if ( handle == NULL ) { +#if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN) + SDL_SetError("Failed loading %s", path); +#else /* SDL_LoadObject() will call SDL_SetError() for us. */ +#endif return -1; } From ac32d0c5f92b215a37846d9f3a1aa92b82aa7ce6 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 23 Jan 2007 04:47:11 +0000 Subject: [PATCH 060/241] Updated svn repository --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402252 --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index d7acd2547..9b1112bfd 100644 --- a/Makefile.in +++ b/Makefile.in @@ -169,7 +169,7 @@ rpm: $(distfile) # Create a SVN snapshot that people can run update on snapshot: - svn co svn://libsdl.org/branches/SDL-1.2 + svn co http://svn.libsdl.org/branches/SDL-1.2 (cd SDL-1.2 && ./autogen.sh && rm -rf autom4te.cache) cp SDL-1.2/include/SDL_config.h.default SDL-1.2/include/SDL_config.h tar zcf $(HOME)/SDL-1.2.tar.gz SDL-1.2 From 320270a127c2f5832126030da065826d2df31dc3 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 3 Feb 2007 08:11:45 +0000 Subject: [PATCH 061/241] Moved otherwise-unused underscore-prepending code in dlopen backend into an #ifdef. Fixes Bugzilla #354. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402254 --- src/loadso/dlopen/SDL_sysloadso.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/loadso/dlopen/SDL_sysloadso.c b/src/loadso/dlopen/SDL_sysloadso.c index ebd595500..05e4529ee 100644 --- a/src/loadso/dlopen/SDL_sysloadso.c +++ b/src/loadso/dlopen/SDL_sysloadso.c @@ -45,12 +45,19 @@ void *SDL_LoadFunction(void *handle, const char *name) { void *symbol = dlsym(handle, name); if ( symbol == NULL ) { + +#ifdef DLOPEN_NEED_UNDERSCORE + /* append an underscore for platforms that need that. */ size_t len = 1+SDL_strlen(name)+1; char *_name = SDL_stack_alloc(char, len); _name[0] = '_'; SDL_strlcpy(&_name[1], name, len); - symbol = dlsym(handle, name); + symbol = dlsym(handle, _name); SDL_stack_free(_name); +#else + symbol = dlsym(handle, name); +#endif + if ( symbol == NULL ) { SDL_SetError("Failed loading %s: %s", name, (const char *)dlerror()); } From a258df05a05a4418e36cca52ee912765fd2012fc Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 3 Feb 2007 08:17:12 +0000 Subject: [PATCH 062/241] Actually, this is dumb, just simplify this for now. (But what if this finds the wrong symbol? We really should make this a ./configure test and only do one dlsym or the other depending on the platform...) Reference Bugzilla #354. --ryan. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402255 --- src/loadso/dlopen/SDL_sysloadso.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/loadso/dlopen/SDL_sysloadso.c b/src/loadso/dlopen/SDL_sysloadso.c index 05e4529ee..550acad3e 100644 --- a/src/loadso/dlopen/SDL_sysloadso.c +++ b/src/loadso/dlopen/SDL_sysloadso.c @@ -45,8 +45,6 @@ void *SDL_LoadFunction(void *handle, const char *name) { void *symbol = dlsym(handle, name); if ( symbol == NULL ) { - -#ifdef DLOPEN_NEED_UNDERSCORE /* append an underscore for platforms that need that. */ size_t len = 1+SDL_strlen(name)+1; char *_name = SDL_stack_alloc(char, len); @@ -54,10 +52,6 @@ void *SDL_LoadFunction(void *handle, const char *name) SDL_strlcpy(&_name[1], name, len); symbol = dlsym(handle, _name); SDL_stack_free(_name); -#else - symbol = dlsym(handle, name); -#endif - if ( symbol == NULL ) { SDL_SetError("Failed loading %s: %s", name, (const char *)dlerror()); } From 8bc3ad08b26bdf45dee9ce569b44a1c57d310b8a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 5 Feb 2007 06:44:51 +0000 Subject: [PATCH 063/241] Patched to compile on BeOS and old, old GCC releases. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402257 --- include/SDL_endian.h | 8 +++++--- src/video/SDL_blit.c | 10 +++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/include/SDL_endian.h b/include/SDL_endian.h index 6257a649d..8f8db4cca 100644 --- a/include/SDL_endian.h +++ b/include/SDL_endian.h @@ -56,7 +56,7 @@ extern "C" { header should only be included in files that actually use them. */ #if defined(__GNUC__) && defined(__i386__) && \ - !(__GNUC__ == 2 && __GNUC_MINOR__ == 95 /* broken gcc version */) + !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) static __inline__ Uint16 SDL_Swap16(Uint16 x) { __asm__("xchgb %b0,%h0" : "=q" (x) : "0" (x)); @@ -88,7 +88,8 @@ static __inline__ Uint16 SDL_Swap16(Uint16 x) { } #endif -#if defined(__GNUC__) && defined(__i386__) +#if defined(__GNUC__) && defined(__i386__) && \ + !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) static __inline__ Uint32 SDL_Swap32(Uint32 x) { __asm__("bswap %0" : "=r" (x) : "0" (x)); @@ -123,7 +124,8 @@ static __inline__ Uint32 SDL_Swap32(Uint32 x) { #endif #ifdef SDL_HAS_64BIT_TYPE -#if defined(__GNUC__) && defined(__i386__) +#if defined(__GNUC__) && defined(__i386__) && \ + !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) static __inline__ Uint64 SDL_Swap64(Uint64 x) { union { diff --git a/src/video/SDL_blit.c b/src/video/SDL_blit.c index d3fb7783e..fee473891 100644 --- a/src/video/SDL_blit.c +++ b/src/video/SDL_blit.c @@ -29,6 +29,9 @@ #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && SDL_ASSEMBLY_ROUTINES #define MMX_ASMBLIT +#if (__GNUC__ > 2) /* SSE instructions aren't in GCC 2. */ +#define SSE_ASMBLIT +#endif #endif #if defined(MMX_ASMBLIT) @@ -122,6 +125,7 @@ static __inline__ void SDL_memcpyMMX(Uint8 *to, const Uint8 *from, int len) SDL_memcpy(to, from, len&7); } +#ifdef SSE_ASMBLIT static __inline__ void SDL_memcpySSE(Uint8 *to, const Uint8 *from, int len) { int i; @@ -146,6 +150,7 @@ static __inline__ void SDL_memcpySSE(Uint8 *to, const Uint8 *from, int len) SDL_memcpy(to, from, len&7); } #endif +#endif static void SDL_BlitCopy(SDL_BlitInfo *info) { @@ -159,7 +164,8 @@ static void SDL_BlitCopy(SDL_BlitInfo *info) dst = info->d_pixels; srcskip = w+info->s_skip; dstskip = w+info->d_skip; -#ifdef MMX_ASMBLIT + +#ifdef SSE_ASMBLIT if(SDL_HasSSE()) { while ( h-- ) { @@ -172,6 +178,8 @@ static void SDL_BlitCopy(SDL_BlitInfo *info) ::); } else +#endif +#ifdef MMX_ASMBLIT if(SDL_HasMMX()) { while ( h-- ) { From 275142c73de41d8411f9e4f27807e0ea4da3c04a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 12 Feb 2007 10:52:10 +0000 Subject: [PATCH 064/241] Handle source data alignment correctly in Blit32to32SurfaceAlphaAltivec(). Fixes Bugzilla #279. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402259 --- src/video/SDL_blit_A.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/SDL_blit_A.c b/src/video/SDL_blit_A.c index c33211eef..5b10ab397 100644 --- a/src/video/SDL_blit_A.c +++ b/src/video/SDL_blit_A.c @@ -1287,7 +1287,7 @@ static void Blit32to32SurfaceAlphaAltivec(SDL_BlitInfo *info) ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width); if (width > 0) { int extrawidth = (width % 4); - vector unsigned char valigner = vec_lvsl(0, srcp); + vector unsigned char valigner = VEC_ALIGNER(srcp); vector unsigned char vs = (vector unsigned char)vec_ld(0, srcp); width -= extrawidth; while (width) { From 9a1cd1510c2e429f388a3e50dd6c46ccb67bfb13 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 12 Feb 2007 11:45:18 +0000 Subject: [PATCH 065/241] Digital Mars has stdint.h, so use the header on Windows with that compiler. Fixes Bugzilla #376. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402261 --- include/SDL_config_win32.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL_config_win32.h b/include/SDL_config_win32.h index 23e4868c2..8d32b13cd 100644 --- a/include/SDL_config_win32.h +++ b/include/SDL_config_win32.h @@ -27,7 +27,7 @@ /* This is a set of defines to configure the SDL features */ -#ifdef __GNUC__ +#if defined(__GNUC__) || defined(__DMC__) #define HAVE_STDINT_H 1 #elif defined(_MSC_VER) typedef signed __int8 int8_t; From ebb3fc747833a02001b7c24e0774b7e3d43a3413 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 13 Feb 2007 09:20:37 +0000 Subject: [PATCH 066/241] Free all the created cursors in test/testcursor.c. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402263 --- test/testcursor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/testcursor.c b/test/testcursor.c index 863b83941..010e0a630 100644 --- a/test/testcursor.c +++ b/test/testcursor.c @@ -209,6 +209,7 @@ int main(int argc, char *argv[]) SDL_FreeCursor(cursor[0]); SDL_FreeCursor(cursor[1]); + SDL_FreeCursor(cursor[2]); SDL_Quit(); return(0); From 64941faf12087d8ffd21e8a6dfb3ebce12bf612d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 13 Feb 2007 09:58:04 +0000 Subject: [PATCH 067/241] Corrected wrong SDK path in build-scripts/fatbuild.sh. Fixes Bugzilla #377. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402265 --- build-scripts/fatbuild.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-scripts/fatbuild.sh b/build-scripts/fatbuild.sh index 3fd40cfb2..d5da20788 100755 --- a/build-scripts/fatbuild.sh +++ b/build-scripts/fatbuild.sh @@ -48,7 +48,7 @@ CPPFLAGS_X86="-DMAC_OS_X_VERSION_MIN_REQUIRED=1040 \ # Intel linker flags LFLAGS_X86="-arch i386 -mmacosx-version-min=10.4 \ --L/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/gcc/i686-apple-darwin8/4.0.0 \ +-L/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/gcc/i686-apple-darwin8/4.0.1 \ -Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk" # From b360c13391a59b2a450cd04e549162625324b493 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 14 Feb 2007 10:23:23 +0000 Subject: [PATCH 068/241] Quartz code should use F13, F14, and F15 keys instead of PrintScreen, ScrollLock, and Pause, since that's what's on the standard Apple keyboards (minus the laptops, which have neither set). Ideally we'll find a better way to distinguish this...the keys being replaced would be correct on a USB keyboard for Windows. Sigh. Fixes Bugzilla #301. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402267 --- src/video/quartz/SDL_QuartzEvents.m | 7 +++++++ src/video/quartz/SDL_QuartzKeys.h | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/src/video/quartz/SDL_QuartzEvents.m b/src/video/quartz/SDL_QuartzEvents.m index b18598c66..496e4f092 100644 --- a/src/video/quartz/SDL_QuartzEvents.m +++ b/src/video/quartz/SDL_QuartzEvents.m @@ -87,9 +87,14 @@ void QZ_InitOSKeymap (_THIS) { keymap[QZ_F10] = SDLK_F10; keymap[QZ_F11] = SDLK_F11; keymap[QZ_F12] = SDLK_F12; + keymap[QZ_F13] = SDLK_F13; + keymap[QZ_F14] = SDLK_F14; + keymap[QZ_F15] = SDLK_F15; +/* keymap[QZ_PRINT] = SDLK_PRINT; keymap[QZ_SCROLLOCK] = SDLK_SCROLLOCK; keymap[QZ_PAUSE] = SDLK_PAUSE; +*/ keymap[QZ_POWER] = SDLK_POWER; keymap[QZ_BACKQUOTE] = SDLK_BACKQUOTE; keymap[QZ_1] = SDLK_1; @@ -270,6 +275,7 @@ static void QZ_DoKey (_THIS, int state, NSEvent *event) { if (numChars == 0) { key.scancode = [ event keyCode ]; +printf("numChars == 0, scancode == %d\n", (int) key.scancode); key.sym = keymap [ key.scancode ]; key.unicode = 0; key.mod = KMOD_NONE; @@ -279,6 +285,7 @@ static void QZ_DoKey (_THIS, int state, NSEvent *event) { else if (numChars == 1) { key.scancode = [ event keyCode ]; +printf("numChars == 1, scancode == %d\n", (int) key.scancode); key.sym = keymap [ key.scancode ]; key.unicode = [ chars characterAtIndex:0 ]; key.mod = KMOD_NONE; diff --git a/src/video/quartz/SDL_QuartzKeys.h b/src/video/quartz/SDL_QuartzKeys.h index 19389126d..8b1c13bef 100644 --- a/src/video/quartz/SDL_QuartzKeys.h +++ b/src/video/quartz/SDL_QuartzKeys.h @@ -36,9 +36,14 @@ #define QZ_F10 0x6D #define QZ_F11 0x67 #define QZ_F12 0x6F +#define QZ_F13 0x69 +#define QZ_F14 0x6B +#define QZ_F15 0x71 +/* #define QZ_PRINT 0x69 #define QZ_SCROLLOCK 0x6B #define QZ_PAUSE 0x71 +*/ #define QZ_POWER 0x7F #define QZ_BACKQUOTE 0x32 #define QZ_1 0x12 From 0855a63e16ddcf02bf6d10ea353449744ef97d1e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 14 Feb 2007 10:40:24 +0000 Subject: [PATCH 069/241] Removed the contents of the BUGS file, as most (all?) of the issues were either long-since fixed or something that will never get fixed. The file now points people to Bugzilla and the mailing list. Fixes Bugzilla #352. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402269 --- BUGS | 190 +++-------------------------------------------------------- 1 file changed, 8 insertions(+), 182 deletions(-) diff --git a/BUGS b/BUGS index b42bef4d7..218bf3d15 100644 --- a/BUGS +++ b/BUGS @@ -1,192 +1,18 @@ -All: - Audio rate conversion is only implemented by multiplying or dividing - by a power of two. This is a side-effect of the requirement that the - raw audio buffer size be a power of two, and can hopefully be fixed. - This means 8 KHz audio converted to 22 KHz ends up being 16 KHz. :-/ +Bugs are now managed in the SDL bug tracker, here: - When the implementation is writing directly to video memory the mouse - cursor doesn't work properly. Applications which do this should use - their own mouse cursor and call SDL_ShowCursor(0) to hide the system - cursor. + http://bugzilla.libsdl.org/ -Linux: - Wide UNICODE character input (Kanji, etc.) is not yet supported. - It requires handling of keyboard mapping events and using the XIM - input translation extension. I will implement it as requested. - Latin-1 keyboard input works fine. - (UPDATE 04/06/2004: this bug is now fixed) +You may report bugs there, and search to see if a given issue has already + been reported, discussed, and maybe even fixed. - The keyboard modifiers are not set to the correct state on startup. - The AAlib, GGI, and SVGAlib video drivers are not heavily tested. -Win32: - The MCI driver can't tell if the CD-ROM drive is paused or stopped. +You may also find help at the SDL mailing list. Subscription information: - The SDL_INIT_EVENTTHREAD flag is not supported on Win32 - (Idea: create a separate DirectInput polling thread) - The main purpose of this flag is for smooth cursor motion in - fullscreen environments. + http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org - Wide UNICODE character input (Kanji, etc.) is not yet supported. - This requires the ToUnicode() API which is only implemented on - Windows NT/2000, not on Windows 95/98. - Latin-1 keyboard input works fine. +Bug reports are welcome here, but we really appreciate if you use Bugzilla, as + bugs discussed on the mailing list may be forgotten or missed. - Joysticks are only supported under the Win32 MultiMedia API, - DirectInput support is not yet implemented. - -BeOS: - BePPC is not supported, apparently not even by Be Inc. - - SDL_WM_GrabInput() is not implemented. - Does anyone know how to do this? SDL_WM_GrabInput() is designed - to prevent the user from switching input and mouse focus away from - the SDL application. - - Continuous relative mouse motion is not implemented. - - Wide UNICODE character input (Kanji, etc.) has not been tested. - Latin-1 keyboard input works fine. - -MacOS: - Palette handling isn't implemented in windowed mode yet. - - Audio hasn't been extensively tested, in particular the locking - isn't implemented and mixer routines may not call malloc() or free() - because they are called at interrupt time. - - SDL_WM_GrabInput() is not implemented. - Does anyone know how to do this? SDL_WM_GrabInput() is designed - to prevent the user from switching input and mouse focus away from - the SDL application. - - Continuous relative mouse motion is not implemented. - - SDL_AddTimer() and SDL_RemoveTimer() haven't been implemented yet. - - Not all of the keys are properly recognized on the keyboard. - -Mac OS X: - Depth switching for windowed mode isn't implemented yet. - - Palette handling isn't implemented in windowed mode yet. - - Command-line arguments dialog is not implemented yet. - - Fullscreen drawing has some artifacts. - - Fullscreen OpenGL for the software renderer is broken. - - Some OpenGL parameters are not accounted for, for example color bits customization. - - Continuous mouse motion perhaps is not as smooth as it should be. - - SDL_WM_GrabInput() is implemented, but it "freezes" the hardware - cursor in the center of the window/screen. Also, mouse moved events - are not generated, and the keyboard cannot be grabbed. - - Mac OS X seems to have a broken pthread_cancel() implementation. - Actually, it just only has one cancellation point defined. - http://lists.apple.com/archives/darwin-development/2004/Jun/24/killingapthread.001.txt - -FreeBSD: - pthread_cancel() isn't supported by FreeBSD 3.X, so threads don't - work on versions of FreeBSD earlier than 4.0. - - The CD-ROM handling doesn't work completely. - - Wide UNICODE character input (Kanji, etc.) is not yet supported. - It requires handling of keyboard mapping events and using the XIM - input translation extension. I will implement it as requested. - Latin-1 keyboard input works fine. - (UPDATE 04/06/2004: this bug is now fixed but needs testing) - - The keyboard modifiers are not set to the correct state on startup. - -Solaris: - The joystick functions are not implemented yet. - - Wide UNICODE character input (Kanji, etc.) is not yet supported. - It requires handling of keyboard mapping events and using the XIM - input translation extension. I will implement it as requested. - Latin-1 keyboard input works fine. - (UPDATE 04/06/2004: this bug is now fixed but needs testing) - - The keyboard modifiers are not set to the correct state on startup. - -IRIX: - The CD-ROM handling doesn't work completely. - - The joystick functions are not implemented yet. - - Wide UNICODE character input (Kanji, etc.) is not yet supported. - It requires handling of keyboard mapping events and using the XIM - input translation extension. I will implement it as requested. - Latin-1 keyboard input works fine. - (UPDATE 04/06/2004: this bug is now fixed but needs testing) - - The keyboard modifiers are not set to the correct state on startup. - -EPOC: - Only Crystal version of Epoc/SymbianOS is currently supported. - - SDL is implemented in static library only. SDL uses static/global - variables and that is not allowed in EPOC dll libraries. - - Sound is not yet supported. - - Joystick, OpenGL and cdrom is not supported (think about cdrom in a cell phone:-). - - No console output screen. Printing to stdout do not have any effect. - -QNX: - Fullscreen switch doesn't work (disabled for now). - - -OpenBSD: -= NOT YET SUPPORTED =- - This is reported to work, but I haven't verified this. - - Wide UNICODE character input (Kanji, etc.) is not yet supported. - It requires handling of keyboard mapping events and using the XIM - input translation extension. I will implement it as requested. - Latin-1 keyboard input works fine. - (UPDATE 04/06/2004: this bug is now fixed but needs testing) - - The keyboard modifiers are not set to the correct state on startup. - -OSF/Tru64: -= NOT YET SUPPORTED =- - The audio functions are not implemented yet. - - Joysticks and CD-ROM functions are not implemented yet. - - Wide UNICODE character input (Kanji, etc.) is not yet supported. - It requires handling of keyboard mapping events and using the XIM - input translation extension. I will implement it as requested. - Latin-1 keyboard input works fine. - (UPDATE 04/06/2004: this bug is now fixed but needs testing) - - The keyboard modifiers are not set to the correct state on startup. - -AIX: -= NOT YET SUPPORTED =- - This port has only been tested with AIX 4.3.3 - - The OpenGL support doesn't work yet. - - The joystick subsystem isn't implemented yet. - - Endian detection doesn't work yet - needs a unique CPP symbol. - - Wide UNICODE character input (Kanji, etc.) is not yet supported. - It requires handling of keyboard mapping events and using the XIM - input translation extension. I will implement it as requested. - Latin-1 keyboard input works fine. - (UPDATE 04/06/2004: this bug is now fixed but needs testing) - - The keyboard modifiers are not set to the correct state on startup. - - The AIX port was done by Carsten.Griwodz@KOM.tu-darmstadt.de - More information on this port is available at: - http://www.kom.e-technik.tu-darmstadt.de/~griff/SDL/ From cb20c837f46dabe2f25b108326d1094540839eee Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 15 Feb 2007 11:06:22 +0000 Subject: [PATCH 070/241] Force chars to unsigned chars in SDL_string.c, so platforms that expect these to not be negative, when not EOF, work. Fixes Bugzilla #338. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402271 --- src/stdlib/SDL_string.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index 02a93a5d9..8c44e6d69 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -45,7 +45,7 @@ static size_t SDL_ScanLong(const char *text, int radix, long *valuep) } for ( ; ; ) { int v; - if ( SDL_isdigit(*text) ) { + if ( SDL_isdigit((unsigned char) *text) ) { v = *text - '0'; } else if ( radix == 16 && SDL_isupperhex(*text) ) { v = 10 + (*text - 'A'); @@ -80,7 +80,7 @@ static size_t SDL_ScanUnsignedLong(const char *text, int radix, unsigned long *v } for ( ; ; ) { int v; - if ( SDL_isdigit(*text) ) { + if ( SDL_isdigit((unsigned char) *text) ) { v = *text - '0'; } else if ( radix == 16 && SDL_isupperhex(*text) ) { v = 10 + (*text - 'A'); @@ -111,7 +111,7 @@ static size_t SDL_ScanUintPtrT(const char *text, int radix, uintptr_t *valuep) } for ( ; ; ) { int v; - if ( SDL_isdigit(*text) ) { + if ( SDL_isdigit((unsigned char) *text) ) { v = *text - '0'; } else if ( radix == 16 && SDL_isupperhex(*text) ) { v = 10 + (*text - 'A'); @@ -148,7 +148,7 @@ static size_t SDL_ScanLongLong(const char *text, int radix, Sint64 *valuep) } for ( ; ; ) { int v; - if ( SDL_isdigit(*text) ) { + if ( SDL_isdigit((unsigned char) *text) ) { v = *text - '0'; } else if ( radix == 16 && SDL_isupperhex(*text) ) { v = 10 + (*text - 'A'); @@ -183,7 +183,7 @@ static size_t SDL_ScanUnsignedLongLong(const char *text, int radix, Uint64 *valu } for ( ; ; ) { int v; - if ( SDL_isdigit(*text) ) { + if ( SDL_isdigit((unsigned char) *text) ) { v = *text - '0'; } else if ( radix == 16 && SDL_isupperhex(*text) ) { v = 10 + (*text - 'A'); @@ -221,7 +221,7 @@ static size_t SDL_ScanFloat(const char *text, double *valuep) if ( *text == '.' ) { int mult = 10; ++text; - while ( SDL_isdigit(*text) ) { + while ( SDL_isdigit((unsigned char) *text) ) { lvalue = *text - '0'; value += (double)lvalue / mult; mult *= 10; @@ -383,7 +383,7 @@ char *SDL_strupr(char *string) { char *bufp = string; while ( *bufp ) { - *bufp = SDL_toupper(*bufp); + *bufp = SDL_toupper((unsigned char) *bufp); ++bufp; } return string; @@ -395,7 +395,7 @@ char *SDL_strlwr(char *string) { char *bufp = string; while ( *bufp ) { - *bufp = SDL_tolower(*bufp); + *bufp = SDL_tolower((unsigned char) *bufp); ++bufp; } return string; @@ -699,8 +699,8 @@ int SDL_strcasecmp(const char *str1, const char *str2) char a = 0; char b = 0; while ( *str1 && *str2 ) { - a = SDL_tolower(*str1); - b = SDL_tolower(*str2); + a = SDL_tolower((unsigned char) *str1); + b = SDL_tolower((unsigned char) *str2); if ( a != b ) break; ++str1; @@ -716,8 +716,8 @@ int SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen) char a = 0; char b = 0; while ( *str1 && *str2 && maxlen ) { - a = SDL_tolower(*str1); - b = SDL_tolower(*str2); + a = SDL_tolower((unsigned char) *str1); + b = SDL_tolower((unsigned char) *str2); if ( a != b ) break; ++str1; @@ -737,7 +737,7 @@ int SDL_sscanf(const char *text, const char *fmt, ...) va_start(ap, fmt); while ( *fmt ) { if ( *fmt == ' ' ) { - while ( SDL_isspace(*text) ) { + while ( SDL_isspace((unsigned char) *text) ) { ++text; } ++fmt; @@ -788,7 +788,7 @@ int SDL_sscanf(const char *text, const char *fmt, ...) continue; } - while ( SDL_isspace(*text) ) { + while ( SDL_isspace((unsigned char) *text) ) { ++text; } @@ -821,7 +821,7 @@ int SDL_sscanf(const char *text, const char *fmt, ...) ++index; } if ( text[index] == '0' ) { - if ( SDL_tolower(text[index+1]) == 'x' ) { + if ( SDL_tolower((unsigned char) text[index+1]) == 'x' ) { radix = 16; } else { radix = 8; @@ -950,7 +950,7 @@ int SDL_sscanf(const char *text, const char *fmt, ...) break; case 's': if ( suppress ) { - while ( !SDL_isspace(*text) ) { + while ( !SDL_isspace((unsigned char) *text) ) { ++text; if ( count ) { if ( --count == 0 ) { @@ -960,7 +960,7 @@ int SDL_sscanf(const char *text, const char *fmt, ...) } } else { char *valuep = va_arg(ap, char*); - while ( !SDL_isspace(*text) ) { + while ( !SDL_isspace((unsigned char) *text) ) { *valuep++ = *text++; if ( count ) { if ( --count == 0 ) { From 8b407756dc9d0ca8ecb81b79a8c4485e4496c6f6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 15 Feb 2007 23:50:45 +0000 Subject: [PATCH 071/241] Patched fbcon to compile on newer Linux kernels that don't #define PAGE_SIZE, since a memory page's size may vary on various architectures and kernel configurations. Will use getpagesize() if it exists, the PAGE_SIZE #define from older kernels if that doesn't, and #error out if that's not there either...but it's probably 4096 in that case. We may revisit this. Fixes Bugzilla #392. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402273 --- configure.in | 1 + include/SDL_config.h.in | 1 + src/video/fbcon/SDL_fbvideo.c | 16 +++++++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index aefd09ad7..c2a2ff325 100644 --- a/configure.in +++ b/configure.in @@ -1125,6 +1125,7 @@ AC_HELP_STRING([--enable-video-fbcon], [use framebuffer console video driver [[d ]) AC_MSG_RESULT($video_fbcon) if test x$video_fbcon = xyes; then + AC_CHECK_FUNCS(getpagesize) AC_DEFINE(SDL_VIDEO_DRIVER_FBCON) SOURCES="$SOURCES $srcdir/src/video/fbcon/*.c" have_video=yes diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index 89252e46d..afd6eb73f 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -130,6 +130,7 @@ #undef HAVE_NANOSLEEP #undef HAVE_CLOCK_GETTIME #undef HAVE_DLVSYM +#undef HAVE_GETPAGESIZE #else /* We may need some replacement for stdarg.h here */ diff --git a/src/video/fbcon/SDL_fbvideo.c b/src/video/fbcon/SDL_fbvideo.c index 2d97bcbeb..baf6aeb24 100644 --- a/src/video/fbcon/SDL_fbvideo.c +++ b/src/video/fbcon/SDL_fbvideo.c @@ -149,6 +149,19 @@ static void FB_SavePalette(_THIS, struct fb_fix_screeninfo *finfo, struct fb_var_screeninfo *vinfo); static void FB_RestorePalette(_THIS); +static int SDL_getpagesize(void) +{ +#ifdef HAVE_GETPAGESIZE + return getpagesize(); +#elif defined(PAGE_SIZE) + return PAGE_SIZE; +#else +#error Can not determine system page size. + return 4096; /* this is what it USED to be in Linux... */ +#endif +} + + /* Small wrapper for mmap() so we can play nicely with no-mmu hosts * (non-mmu hosts disallow the MAP_SHARED flag) */ @@ -466,6 +479,7 @@ static void FB_SortModes(_THIS) static int FB_VideoInit(_THIS, SDL_PixelFormat *vformat) { + const int pagesize = SDL_getpagesize(); struct fb_fix_screeninfo finfo; struct fb_var_screeninfo vinfo; int i, j; @@ -547,7 +561,7 @@ static int FB_VideoInit(_THIS, SDL_PixelFormat *vformat) /* Memory map the device, compensating for buggy PPC mmap() */ mapped_offset = (((long)finfo.smem_start) - - (((long)finfo.smem_start)&~(PAGE_SIZE-1))); + (((long)finfo.smem_start)&~(pagesize-1))); mapped_memlen = finfo.smem_len+mapped_offset; mapped_mem = do_mmap(NULL, mapped_memlen, PROT_READ|PROT_WRITE, MAP_SHARED, console_fd, 0); From d969c7e22198be4261a047384520cac3c84be3f6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 16 Feb 2007 03:50:42 +0000 Subject: [PATCH 072/241] Minor const correctness patch to SDL_iconv. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402275 --- include/SDL_stdinc.h | 5 ++--- src/stdlib/SDL_iconv.c | 7 ++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index 4fd95163c..660b06a53 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -561,17 +561,16 @@ extern DECLSPEC int SDLCALL SDL_vsnprintf(char *text, size_t maxlen, const char #define SDL_iconv_t iconv_t #define SDL_iconv_open iconv_open #define SDL_iconv_close iconv_close -extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); #else typedef struct _SDL_iconv_t *SDL_iconv_t; extern DECLSPEC SDL_iconv_t SDLCALL SDL_iconv_open(const char *tocode, const char *fromcode); extern DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd); -extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); #endif +extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); /* This function converts a string between encodings in one pass, returning a string that must be freed with SDL_free() or NULL on error. */ -extern DECLSPEC char * SDLCALL SDL_iconv_string(const char *tocode, const char *fromcode, char *inbuf, size_t inbytesleft); +extern DECLSPEC char * SDLCALL SDL_iconv_string(const char *tocode, const char *fromcode, const char *inbuf, size_t inbytesleft); #define SDL_iconv_utf8_ascii(S) SDL_iconv_string("ASCII", "UTF-8", S, SDL_strlen(S)+1) #define SDL_iconv_utf8_latin1(S) SDL_iconv_string("LATIN1", "UTF-8", S, SDL_strlen(S)+1) #define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2", "UTF-8", S, SDL_strlen(S)+1) diff --git a/src/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c index 1a94e0f3b..caa3eb1e5 100644 --- a/src/stdlib/SDL_iconv.c +++ b/src/stdlib/SDL_iconv.c @@ -149,11 +149,12 @@ SDL_iconv_t SDL_iconv_open(const char *tocode, const char *fromcode) } size_t SDL_iconv(SDL_iconv_t cd, - char **inbuf, size_t *inbytesleft, + const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { /* For simplicity, we'll convert everything to and from UCS-4 */ - char *src, *dst; + const char *src; + char *dst; size_t srclen, dstlen; Uint32 ch = 0; size_t total; @@ -755,7 +756,7 @@ int SDL_iconv_close(SDL_iconv_t cd) #endif /* !HAVE_ICONV */ -char *SDL_iconv_string(const char *tocode, const char *fromcode, char *inbuf, size_t inbytesleft) +char *SDL_iconv_string(const char *tocode, const char *fromcode, const char *inbuf, size_t inbytesleft) { SDL_iconv_t cd; char *string; From 372defa7ba9812f318e5d1ce379b521fc66238d7 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 16 Feb 2007 04:56:17 +0000 Subject: [PATCH 073/241] SDL_SetWindowCaption() on Windows: try to use the unicode SetWindowText() if it exists in user32.dll, and fallback to converting to the current codepage (instead of latin1) if not. Fixes Bugzilla #365. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402276 --- src/video/wincommon/SDL_syswm.c | 34 +++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/video/wincommon/SDL_syswm.c b/src/video/wincommon/SDL_syswm.c index e1106ac84..8bd2c1880 100644 --- a/src/video/wincommon/SDL_syswm.c +++ b/src/video/wincommon/SDL_syswm.c @@ -207,6 +207,8 @@ void WIN_SetWMIcon(_THIS, SDL_Surface *icon, Uint8 *mask) #endif /* DISABLE_ICON_SUPPORT */ } +typedef BOOL (WINAPI *PtrSetWindowTextW)(HWND hWnd, LPCWSTR lpString); + void WIN_SetWMCaption(_THIS, const char *title, const char *icon) { #ifdef _WIN32_WCE @@ -215,8 +217,36 @@ void WIN_SetWMCaption(_THIS, const char *title, const char *icon) SetWindowText(SDL_Window, lpszW); SDL_free(lpszW); #else - char *lpsz = SDL_iconv_utf8_latin1((char *)title); - SetWindowText(SDL_Window, lpsz); + /* + * Try loading SetWindowTextW from kernel32.dll first, and if it exists, + * pass the UCS-2 string to it. If it doesn't, use + * WideCharToMultiByte(CP_ACP) and hope that the codepage can support the + * string data in question. This lets us keep binary compatibility with + * Win95/98/ME but still use saner Unicode on NT-based Windows. + */ + static int tried_loading = 0; + static PtrSetWindowTextW swtw = NULL; + Uint16 *lpsz = SDL_iconv_utf8_ucs2(title); + if (!tried_loading) { + HMODULE dll = LoadLibrary("user32.dll"); + if (dll != NULL) { + swtw = (PtrSetWindowTextW) GetProcAddress(dll, "SetWindowTextW"); + if (swtw == NULL) { + FreeLibrary(dll); + } + } + tried_loading = 1; + } + + if (swtw != NULL) { + swtw(SDL_Window, lpsz); + } else { + size_t len = WideCharToMultiByte(CP_ACP, 0, lpsz, -1, NULL, 0, NULL, NULL); + char *cvt = SDL_malloc(len + 1); + WideCharToMultiByte(CP_ACP, 0, lpsz, -1, cvt, len, NULL, NULL); + SetWindowText(SDL_Window, cvt); + SDL_free(cvt); + } SDL_free(lpsz); #endif } From b3c3a9ad4737019bab45592ea592a33df654c1ac Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 20 Feb 2007 21:05:12 +0000 Subject: [PATCH 074/241] Need to set DLSCL_ADMINISTRATIVE coop level in directfb driver, or YUV overlay creation will fail in newer DirectFB versions. Fixes Bugzilla #394. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402277 --- src/video/directfb/SDL_DirectFB_yuv.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/video/directfb/SDL_DirectFB_yuv.c b/src/video/directfb/SDL_DirectFB_yuv.c index 583b8274e..ad0910e98 100644 --- a/src/video/directfb/SDL_DirectFB_yuv.c +++ b/src/video/directfb/SDL_DirectFB_yuv.c @@ -118,6 +118,15 @@ static DFBResult CreateYUVSurface(_THIS, struct private_yuvhwdata *hwdata, break; } + /* Need to set coop level or newer DirectFB versions will fail here. */ + ret = layer->SetCooperativeLevel (layer, DLSCL_ADMINISTRATIVE); + if (ret) + { + SetDirectFBError("IDirectFBDisplayLayer::SetCooperativeLevel() failed", ret); + layer->Release (layer); + return ret; + } + ret = layer->SetConfiguration (layer, &conf); if (ret) { From 27002e9323113f91f4b8eddf8d1c9ec917910792 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 20 Feb 2007 22:57:28 +0000 Subject: [PATCH 075/241] Merged r2987:2988 from trunk/SDL: buggy Sidewinder ID added to linux joysticks. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402280 --- src/joystick/linux/SDL_sysjoystick.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c index 37cf4efe0..d90bae6ff 100644 --- a/src/joystick/linux/SDL_sysjoystick.c +++ b/src/joystick/linux/SDL_sysjoystick.c @@ -50,6 +50,7 @@ static struct { { "SideWinder Precision Pro", 4, 1, 0 }, { "SideWinder 3D Pro", 4, 1, 0 }, { "Microsoft SideWinder 3D Pro", 4, 1, 0 }, + { "Microsoft SideWinder Precision Pro", 4, 1, 0 }, { "Microsoft SideWinder Dual Strike USB version 1.0", 2, 1, 0 }, { "WingMan Interceptor", 3, 3, 0 }, { "WingMan Extreme Digital 3D", 4, 1, 0 }, From 214b58fbad2a93dfe8a09cefdc251e873d64d8a3 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 23 Feb 2007 00:37:07 +0000 Subject: [PATCH 076/241] Removed some debug printf() calls I accidentally added to Subversion. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402281 --- src/video/quartz/SDL_QuartzEvents.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/video/quartz/SDL_QuartzEvents.m b/src/video/quartz/SDL_QuartzEvents.m index 496e4f092..328ee882a 100644 --- a/src/video/quartz/SDL_QuartzEvents.m +++ b/src/video/quartz/SDL_QuartzEvents.m @@ -275,7 +275,6 @@ static void QZ_DoKey (_THIS, int state, NSEvent *event) { if (numChars == 0) { key.scancode = [ event keyCode ]; -printf("numChars == 0, scancode == %d\n", (int) key.scancode); key.sym = keymap [ key.scancode ]; key.unicode = 0; key.mod = KMOD_NONE; @@ -285,7 +284,6 @@ printf("numChars == 0, scancode == %d\n", (int) key.scancode); else if (numChars == 1) { key.scancode = [ event keyCode ]; -printf("numChars == 1, scancode == %d\n", (int) key.scancode); key.sym = keymap [ key.scancode ]; key.unicode = [ chars characterAtIndex:0 ]; key.mod = KMOD_NONE; From 9e136b5ec7e82eaf768a506752ce016bd85bfc0c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 14 Mar 2007 01:09:24 +0000 Subject: [PATCH 077/241] Linux fbcon: don't include asm/page.h if we know getpagesize() exists, since we don't need it, and doing so will hit #error lines on some CPU archs. Thanks to Mike Frysinger for the heads up. Fixes Bugzilla #414. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402282 --- src/video/fbcon/SDL_fbvideo.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/video/fbcon/SDL_fbvideo.c b/src/video/fbcon/SDL_fbvideo.c index baf6aeb24..d58d39957 100644 --- a/src/video/fbcon/SDL_fbvideo.c +++ b/src/video/fbcon/SDL_fbvideo.c @@ -29,7 +29,11 @@ #include #include #include + +#ifndef HAVE_GETPAGESIZE #include /* For definition of PAGE_SIZE */ +#endif + #include #include "SDL_video.h" From 87f0994d7a1ba70a787957b8763da192d012dd5f Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 18 Mar 2007 22:37:10 +0000 Subject: [PATCH 078/241] Mac OS X joystick support: don't ignore kHIDUsage_GD_MultiAxisController devices, since they are probably joysticks, or joystick-like things. See 3Dconnexion's SpaceNavigator for an example of such a device: http://www.3dconnexion.com/products/3a1d.php Thanks to Laurence Passmore for the fix. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402284 --- src/joystick/darwin/SDL_sysjoystick.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/joystick/darwin/SDL_sysjoystick.c b/src/joystick/darwin/SDL_sysjoystick.c index 022c992d4..8a152e8b0 100644 --- a/src/joystick/darwin/SDL_sysjoystick.c +++ b/src/joystick/darwin/SDL_sysjoystick.c @@ -652,7 +652,8 @@ int SDL_SYS_JoystickInit(void) /* Filter device list to non-keyboard/mouse stuff */ if ( (device->usagePage != kHIDPage_GenericDesktop) || ((device->usage != kHIDUsage_GD_Joystick && - device->usage != kHIDUsage_GD_GamePad)) ) { + device->usage != kHIDUsage_GD_GamePad && + device->usage != kHIDUsage_GD_MultiAxisController)) ) { /* release memory for the device */ HIDDisposeDevice (&device); From db2fe20ace82d7cb2e8927d5fe916a4c210e45b9 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 27 Mar 2007 00:37:51 +0000 Subject: [PATCH 079/241] From: Laurence Passmore Date: Mon, 26 Mar 2007 23:22:45 +0100 To: "A list for developers using the SDL library. \(includes SDL-announce\)" Subject: [SDL] SDL_config_macosx.h: MAC_OS_X_VERSION_MIN_REQUIRED Hi, I just compiled my SDL application on Mac OS X with -Wundef and it threw a number of errors. Of note was: SDL_config_macosx.h: 34 warning: "MAC_OS_X_VERSION_MIN_REQUIRED" is not defined Line 34 is: #if ( (MAC_OS_X_VERSION_MIN_REQUIRED >= 1030) || (!defined (__POWERPC__)) ) Now according to this mailing on the Apple developer lists: http://lists.apple.com/archives/Xcode-users/2005/May/msg00602.html that particular #define was removed from the gcc compiler defaults and AvailabilityMacros.h (/usr/include/AvailabilityMacros.h) should be pulled in directly instead. Would someone closer to the Mac OS X version of SDL be willing to make that change please? Thanks. Laurence Passmore Homeworld SDL @ www.homeworldsdl.org --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402286 --- include/SDL_config_macosx.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/SDL_config_macosx.h b/include/SDL_config_macosx.h index 8f04930d5..15b0025cd 100644 --- a/include/SDL_config_macosx.h +++ b/include/SDL_config_macosx.h @@ -25,6 +25,9 @@ #include "SDL_platform.h" +/* This gets us MAC_OS_X_VERSION_MIN_REQUIRED... */ +#include + /* This is a set of defines to configure the SDL features */ #define SDL_HAS_64BIT_TYPE 1 From 357970bfe2f2006d3a936dd9ae236d7aa2a16409 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 28 Mar 2007 00:36:35 +0000 Subject: [PATCH 080/241] Fixed Mac OS X config header when compiling with -Wundef. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402288 --- include/SDL_config_macosx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL_config_macosx.h b/include/SDL_config_macosx.h index 15b0025cd..481c22edc 100644 --- a/include/SDL_config_macosx.h +++ b/include/SDL_config_macosx.h @@ -117,7 +117,7 @@ /* Enable various video drivers */ #define SDL_VIDEO_DRIVER_DUMMY 1 -#if TARGET_API_MAC_CARBON +#if ((defined TARGET_API_MAC_CARBON) && (TARGET_API_MAC_CARBON)) #define SDL_VIDEO_DRIVER_TOOLBOX 1 #else #define SDL_VIDEO_DRIVER_QUARTZ 1 From 98838b4428c37b4b8495bd3bfb60e4f108f77014 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 30 Mar 2007 06:26:28 +0000 Subject: [PATCH 081/241] Patched to compile on Visual Studio. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402290 --- test/testfile.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/testfile.c b/test/testfile.c index 3e902ee0d..ecebb7d49 100644 --- a/test/testfile.c +++ b/test/testfile.c @@ -2,7 +2,10 @@ /* sanity tests on SDL_rwops.c (usefull for alternative implementations of stdio rwops) */ #include + +#ifndef _MSC_VER #include +#endif #include "SDL.h" #include "SDL_endian.h" From c6a106ad29d414478ef478371916fa7df24f5f90 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 30 Mar 2007 20:09:55 +0000 Subject: [PATCH 082/241] Adjusted to handle different constness in older versions of iconv. Fixes Bugzilla #419. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402292 --- include/SDL_stdinc.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index 660b06a53..7e0346334 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -561,12 +561,13 @@ extern DECLSPEC int SDLCALL SDL_vsnprintf(char *text, size_t maxlen, const char #define SDL_iconv_t iconv_t #define SDL_iconv_open iconv_open #define SDL_iconv_close iconv_close +extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); #else typedef struct _SDL_iconv_t *SDL_iconv_t; extern DECLSPEC SDL_iconv_t SDLCALL SDL_iconv_open(const char *tocode, const char *fromcode); extern DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd); -#endif extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); +#endif /* This function converts a string between encodings in one pass, returning a string that must be freed with SDL_free() or NULL on error. */ From 749c11c06bdd00ee7aebfefb908589c11b08dcde Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 1 Apr 2007 03:27:45 +0000 Subject: [PATCH 083/241] Date: Sat, 31 Mar 2007 16:39:52 +0200 From: Bert Wesarg To: sdl@lists.libsdl.org Subject: [SDL] [PATCH] sdl-config.in needs ${libdir} Hello, after the patch for Bug #321, sdl-config.in needs the libdir variable. and there is a hardcoded 'lib' in SDL.spec.in too. Bert Wesarg --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402293 --- SDL.spec.in | 2 +- sdl-config.in | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/SDL.spec.in b/SDL.spec.in index 329d5998b..dbda11210 100644 --- a/SDL.spec.in +++ b/SDL.spec.in @@ -54,7 +54,7 @@ make install prefix=$RPM_BUILD_ROOT%{prefix} \ includedir=$RPM_BUILD_ROOT%{_includedir} \ datadir=$RPM_BUILD_ROOT%{_datadir} \ mandir=$RPM_BUILD_ROOT%{_mandir} -ln -s libSDL-1.2.so.0 $RPM_BUILD_ROOT%{prefix}/lib/libSDL-1.1.so.0 +ln -s libSDL-1.2.so.0 $RPM_BUILD_ROOT%{_libdir}/libSDL-1.1.so.0 %else %makeinstall %endif diff --git a/sdl-config.in b/sdl-config.in index ef278fd6c..e0fcc0ced 100644 --- a/sdl-config.in +++ b/sdl-config.in @@ -3,6 +3,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ exec_prefix_set=no +libdir=@libdir@ @ENABLE_STATIC_FALSE@usage="\ @ENABLE_STATIC_FALSE@Usage: sdl-config [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--cflags] [--libs]" From 31327331d96cd19cae33bc564570547dfbbdb802 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 4 Apr 2007 09:15:39 +0000 Subject: [PATCH 084/241] Fixed buggy SDL_VIDEO_X11_MOUSEACCEL behaviour...correctly free buffer, and only call XChangePointerControl() if we have valid arguments. Fixes Bugzilla #417. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402295 --- src/video/x11/SDL_x11mouse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/x11/SDL_x11mouse.c b/src/video/x11/SDL_x11mouse.c index c5c30a781..221032b82 100644 --- a/src/video/x11/SDL_x11mouse.c +++ b/src/video/x11/SDL_x11mouse.c @@ -216,11 +216,11 @@ static void SetMouseAccel(_THIS, const char *accel_param) mouse_param = NULL; } } - if ( mouse_param_buf ) { + if ( i == 3 ) { XChangePointerControl(SDL_Display, True, True, accel_value[0], accel_value[1], accel_value[2]); - SDL_free(mouse_param_buf); } + SDL_stack_free(mouse_param_buf); } /* Check to see if we need to enter or leave mouse relative mode */ From 3a156ea6be21583c0ef6ea47f089ef2a0bb62e68 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 4 Apr 2007 09:32:29 +0000 Subject: [PATCH 085/241] BlitRGBtoRGBPixelAlphaMMX() is putting the wrong value into a register. Thanks to Alex Volkov for following up on this. Fixes Bugzilla #390. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402296 --- src/video/SDL_blit_A.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/video/SDL_blit_A.c b/src/video/SDL_blit_A.c index 5b10ab397..9319d1e3c 100644 --- a/src/video/SDL_blit_A.c +++ b/src/video/SDL_blit_A.c @@ -369,7 +369,9 @@ static void BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo *info) packsswb_r2r(mm6, mm3); /* 0000FFFF -> mm3 */ pxor_r2r(mm0, mm3); /* 0000F000 -> mm3 (~channel mask) */ /* get alpha channel shift */ - movd_m2r(sf->Ashift, mm5); /* Ashift -> mm5 */ + __asm__ __volatile__ ( + "movd %0, %%mm5" + : : "rm" ((Uint32) sf->Ashift) ); /* Ashift -> mm5 */ while(height--) { DUFFS_LOOP4({ @@ -1566,7 +1568,6 @@ static void BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo *info) int dstskip = info->d_skip >> 2; SDL_PixelFormat* sf = info->src; Uint32 amask = sf->Amask; - Uint32 ashift = sf->Ashift; __asm__ ( /* make mm6 all zeros. */ @@ -1588,7 +1589,7 @@ static void BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo *info) /* get alpha channel shift */ "movd %1, %%mm5\n\t" /* Ashift -> mm5 */ - : /* nothing */ : "m" (amask), "m" (ashift) ); + : /* nothing */ : "rm" (amask), "rm" ((Uint32) sf->Ashift) ); while(height--) { From 3ce0d260d0656cdb900acad91ead055a42050532 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 4 Apr 2007 09:40:40 +0000 Subject: [PATCH 086/241] Const correctness patch for SDL_MapRGB and SDL_MapRGBA. Fixes Bugzilla #421. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402298 --- include/SDL_video.h | 8 +++++--- src/video/SDL_pixels.c | 8 ++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/SDL_video.h b/include/SDL_video.h index 720022e36..f6baccee7 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -447,13 +447,15 @@ extern DECLSPEC int SDLCALL SDL_SetPalette(SDL_Surface *surface, int flags, * Maps an RGB triple to an opaque pixel value for a given pixel format */ extern DECLSPEC Uint32 SDLCALL SDL_MapRGB - (SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b); +(const SDL_PixelFormat * const format, + const Uint8 r, const Uint8 g, const Uint8 b); /* * Maps an RGBA quadruple to a pixel value for a given pixel format */ -extern DECLSPEC Uint32 SDLCALL SDL_MapRGBA(SDL_PixelFormat *format, - Uint8 r, Uint8 g, Uint8 b, Uint8 a); +extern DECLSPEC Uint32 SDLCALL SDL_MapRGBA +(const SDL_PixelFormat * const format, + const Uint8 r, const Uint8 g, const Uint8 b, const Uint8 a); /* * Maps a pixel value into the RGB components for a given pixel format diff --git a/src/video/SDL_pixels.c b/src/video/SDL_pixels.c index 9b8a1257e..33c16e6cc 100644 --- a/src/video/SDL_pixels.c +++ b/src/video/SDL_pixels.c @@ -337,7 +337,9 @@ Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b) } /* Find the opaque pixel value corresponding to an RGB triple */ -Uint32 SDL_MapRGB(SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b) +Uint32 SDL_MapRGB +(const SDL_PixelFormat * const format, + const Uint8 r, const Uint8 g, const Uint8 b) { if ( format->palette == NULL ) { return (r >> format->Rloss) << format->Rshift @@ -350,7 +352,9 @@ Uint32 SDL_MapRGB(SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b) } /* Find the pixel value corresponding to an RGBA quadruple */ -Uint32 SDL_MapRGBA(SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +Uint32 SDL_MapRGBA +(const SDL_PixelFormat * const format, + const Uint8 r, const Uint8 g, const Uint8 b, const Uint8 a) { if ( format->palette == NULL ) { return (r >> format->Rloss) << format->Rshift From a198a2d80f27da8f7f370fc59377c80db46d0587 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 4 Apr 2007 10:28:14 +0000 Subject: [PATCH 087/241] Don't compile the joystick code if --disable-joystick is specified at ./configure time, and define SDL_JOYSTICK_DUMMY if the subsystem is wanted but there aren't any drivers available for the platform. Fixes Bugzilla #403. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402300 --- configure.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index c2a2ff325..4ac580c40 100644 --- a/configure.in +++ b/configure.in @@ -196,7 +196,6 @@ SOURCES="$SOURCES $srcdir/src/cdrom/*.c" SOURCES="$SOURCES $srcdir/src/cpuinfo/*.c" SOURCES="$SOURCES $srcdir/src/events/*.c" SOURCES="$SOURCES $srcdir/src/file/*.c" -SOURCES="$SOURCES $srcdir/src/joystick/*.c" SOURCES="$SOURCES $srcdir/src/stdlib/*.c" SOURCES="$SOURCES $srcdir/src/thread/*.c" SOURCES="$SOURCES $srcdir/src/timer/*.c" @@ -215,6 +214,8 @@ AC_HELP_STRING([--enable-video], [Enable the video subsystem [[default=yes]]]), , enable_video=yes) if test x$enable_video != xyes; then AC_DEFINE(SDL_VIDEO_DISABLED) +else + SOURCES="$SOURCES $srcdir/src/joystick/*.c" fi AC_ARG_ENABLE(events, AC_HELP_STRING([--enable-events], [Enable the events subsystem [[default=yes]]]), @@ -2576,6 +2577,7 @@ esac if test x$enable_joystick = xyes; then if test x$have_joystick != xyes; then # Wants joystick subsystem, but doesn't have a platform-specific backend... + AC_DEFINE(SDL_JOYSTICK_DUMMY) SOURCES="$SOURCES $srcdir/src/joystick/dummy/*.c" fi fi From 2dc670fd22231d34ee45d5fccd989f655258046a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 4 Apr 2007 10:30:07 +0000 Subject: [PATCH 088/241] Crap, put this patch in the wrong place. THIS fixes Bugzilla #403. :/ --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402301 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 4ac580c40..49a290233 100644 --- a/configure.in +++ b/configure.in @@ -214,8 +214,6 @@ AC_HELP_STRING([--enable-video], [Enable the video subsystem [[default=yes]]]), , enable_video=yes) if test x$enable_video != xyes; then AC_DEFINE(SDL_VIDEO_DISABLED) -else - SOURCES="$SOURCES $srcdir/src/joystick/*.c" fi AC_ARG_ENABLE(events, AC_HELP_STRING([--enable-events], [Enable the events subsystem [[default=yes]]]), @@ -228,6 +226,8 @@ AC_HELP_STRING([--enable-joystick], [Enable the joystick subsystem [[default=yes , enable_joystick=yes) if test x$enable_joystick != xyes; then AC_DEFINE(SDL_JOYSTICK_DISABLED) +else + SOURCES="$SOURCES $srcdir/src/joystick/*.c" fi AC_ARG_ENABLE(cdrom, AC_HELP_STRING([--enable-cdrom], [Enable the cdrom subsystem [[default=yes]]]), From b120a012d27b4df789c8fc45fa5b2a6928312d1e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 4 Apr 2007 10:34:42 +0000 Subject: [PATCH 089/241] There are several subsystems that need IOKit linked in on Mac OS X, so handle cases where one or more of them are disabled. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402302 --- configure.in | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 49a290233..1d456a143 100644 --- a/configure.in +++ b/configure.in @@ -2462,8 +2462,8 @@ case "$host" in if test x$enable_joystick = xyes; then AC_DEFINE(SDL_JOYSTICK_IOKIT) SOURCES="$SOURCES $srcdir/src/joystick/darwin/*.c" - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,IOKit" have_joystick=yes + need_iokit_framework=yes fi # Set up files for the cdrom library if test x$enable_cdrom = xyes; then @@ -2483,6 +2483,7 @@ case "$host" in SDL_LIBS="-lSDLmain $SDL_LIBS" if test x$enable_video_cocoa = xyes; then EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Cocoa" + need_iokit_framework=yes fi if test x$enable_video_carbon = xyes -o x$enable_video_cocoa = xyes; then # The Cocoa backend still needs Carbon, and the YUV code QuickTime @@ -2493,6 +2494,10 @@ case "$host" in if test x$enable_audio = xyes -o x$enable_cdrom = xyes; then EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit" fi + # Some subsystems reference IOKit... + if test x$need_iokit_framework = xyes; then + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,IOKit" + fi ;; *-*-mint*) ARCH=mint From 0ea790c9ae9319b40d27c68aedc4baa0c8bb3154 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 6 Apr 2007 20:30:41 +0000 Subject: [PATCH 090/241] Let app set SDL_VIDEO_ALLOW_SCREENSAVER environment variable to override SDL's attempt to disable screen savers. Works for Quartz (Mac OS X) and X11. Need a formal API for this in 1.3, still. Fixes Bugzilla #415. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402305 --- src/video/quartz/SDL_QuartzEvents.m | 12 +++++++----- src/video/quartz/SDL_QuartzVideo.h | 2 ++ src/video/quartz/SDL_QuartzVideo.m | 5 +++++ src/video/x11/SDL_x11events.c | 14 ++++++++++++-- src/video/x11/SDL_x11events_c.h | 4 ++-- src/video/x11/SDL_x11video.c | 9 +++++++-- src/video/x11/SDL_x11video.h | 2 ++ 7 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/video/quartz/SDL_QuartzEvents.m b/src/video/quartz/SDL_QuartzEvents.m index 328ee882a..3c0267e15 100644 --- a/src/video/quartz/SDL_QuartzEvents.m +++ b/src/video/quartz/SDL_QuartzEvents.m @@ -734,11 +734,13 @@ void QZ_PumpEvents (_THIS) return; /* don't do anything if there's no screen surface. */ /* Update activity every five seconds to prevent screensaver. --ryan. */ - nowTicks = SDL_GetTicks(); - if ((nowTicks - screensaverTicks) > 5000) - { - UpdateSystemActivity(UsrActivity); - screensaverTicks = nowTicks; + if (!allow_screensaver) { + nowTicks = SDL_GetTicks(); + if ((nowTicks - screensaverTicks) > 5000) + { + UpdateSystemActivity(UsrActivity); + screensaverTicks = nowTicks; + } } pool = [ [ NSAutoreleasePool alloc ] init ]; diff --git a/src/video/quartz/SDL_QuartzVideo.h b/src/video/quartz/SDL_QuartzVideo.h index be3daef09..50aa38432 100644 --- a/src/video/quartz/SDL_QuartzVideo.h +++ b/src/video/quartz/SDL_QuartzVideo.h @@ -80,6 +80,7 @@ /* Main driver structure to store required state information */ typedef struct SDL_PrivateVideoData { + BOOL allow_screensaver; /* 0 == disable screensaver */ CGDirectDisplayID display; /* 0 == main display (only support single display) */ CFDictionaryRef mode; /* current mode of the display */ CFDictionaryRef save_mode; /* original mode of the display */ @@ -127,6 +128,7 @@ typedef struct SDL_PrivateVideoData { #define display_id (this->hidden->display) #define mode (this->hidden->mode) #define save_mode (this->hidden->save_mode) +#define allow_screensaver (this->hidden->allow_screensaver) #define mode_list (this->hidden->mode_list) #define palette (this->hidden->palette) #define gl_context (this->hidden->gl_context) diff --git a/src/video/quartz/SDL_QuartzVideo.m b/src/video/quartz/SDL_QuartzVideo.m index bfac0930c..9a1759fbe 100644 --- a/src/video/quartz/SDL_QuartzVideo.m +++ b/src/video/quartz/SDL_QuartzVideo.m @@ -169,12 +169,17 @@ static void QZ_DeleteDevice (SDL_VideoDevice *device) { static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format) { + const char *env = NULL; + /* Initialize the video settings; this data persists between mode switches */ display_id = kCGDirectMainDisplay; save_mode = CGDisplayCurrentMode (display_id); mode_list = CGDisplayAvailableModes (display_id); palette = CGPaletteCreateDefaultColorPalette (); + env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER"); + allow_screensaver = ( env && SDL_atoi(env) ) ? YES : NO; + /* Gather some information that is useful to know about the display */ CFNumberGetValue (CFDictionaryGetValue (save_mode, kCGDisplayBitsPerPixel), kCFNumberSInt32Type, &device_bpp); diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 47d6b2ceb..f32279e44 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -1136,9 +1136,14 @@ void X11_SaveScreenSaver(Display *display, int *saved_timeout, BOOL *dpms) #endif /* SDL_VIDEO_DRIVER_X11_DPMS */ } -void X11_DisableScreenSaver(Display *display) +void X11_DisableScreenSaver(_THIS, Display *display) { int timeout, interval, prefer_blank, allow_exp; + + if (this->hidden->allow_screensaver) { + return; + } + XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp); timeout = 0; XSetScreenSaver(display, timeout, interval, prefer_blank, allow_exp); @@ -1153,9 +1158,14 @@ void X11_DisableScreenSaver(Display *display) #endif /* SDL_VIDEO_DRIVER_X11_DPMS */ } -void X11_RestoreScreenSaver(Display *display, int saved_timeout, BOOL dpms) +void X11_RestoreScreenSaver(_THIS, Display *display, int saved_timeout, BOOL dpms) { int timeout, interval, prefer_blank, allow_exp; + + if (this->hidden->allow_screensaver) { + return; + } + XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp); timeout = saved_timeout; XSetScreenSaver(display, timeout, interval, prefer_blank, allow_exp); diff --git a/src/video/x11/SDL_x11events_c.h b/src/video/x11/SDL_x11events_c.h index 567adb46d..18a17089f 100644 --- a/src/video/x11/SDL_x11events_c.h +++ b/src/video/x11/SDL_x11events_c.h @@ -29,5 +29,5 @@ extern void X11_PumpEvents(_THIS); extern void X11_SetKeyboardState(Display *display, const char *key_vec); extern void X11_SaveScreenSaver(Display *display, int *saved_timeout, BOOL *dpms); -extern void X11_DisableScreenSaver(Display *display); -extern void X11_RestoreScreenSaver(Display *display, int saved_timeout, BOOL dpms); +extern void X11_DisableScreenSaver(_THIS, Display *display); +extern void X11_RestoreScreenSaver(_THIS, Display *display, int saved_timeout, BOOL dpms); diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index af3884a1f..28cf61007 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -441,6 +441,7 @@ static void create_aux_windows(_THIS) static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat) { + const char *env = NULL; char *display; int i; @@ -546,7 +547,7 @@ static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat) /* Save DPMS and screensaver settings */ X11_SaveScreenSaver(SDL_Display, &screensaver_timeout, &dpms_enabled); - X11_DisableScreenSaver(SDL_Display); + X11_DisableScreenSaver(this, SDL_Display); /* See if we have been passed a window to use */ SDL_windowid = SDL_getenv("SDL_WINDOWID"); @@ -562,6 +563,10 @@ static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat) /* Fill in some window manager capabilities */ this->info.wm_available = 1; + /* Allow environment override of screensaver disable. */ + env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER"); + this->hidden->allow_screensaver = ( (env && SDL_atoi(env)) ? 1 : 0 ); + /* We're done! */ XFlush(SDL_Display); return(0); @@ -1375,7 +1380,7 @@ void X11_VideoQuit(_THIS) } /* Restore DPMS and screensaver settings */ - X11_RestoreScreenSaver(SDL_Display, screensaver_timeout, dpms_enabled); + X11_RestoreScreenSaver(this, SDL_Display, screensaver_timeout, dpms_enabled); /* Free that blank cursor */ if ( SDL_BlankCursor != NULL ) { diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index 788ee5c23..920942efd 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -139,6 +139,8 @@ struct SDL_PrivateVideoData { int use_xme; int currently_fullscreen; + int allow_screensaver; + /* Automatic mode switching support (entering/leaving fullscreen) */ Uint32 switch_waiting; Uint32 switch_time; From b17574196bf556c6a4d65c6b427f226095e63055 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 17 Apr 2007 08:28:19 +0000 Subject: [PATCH 091/241] Let Windows OpenGL users use SDL_GL_SWAP_CONTROL even if WGL_ARB_pixel_format isn't available...this looks like it got tucked into here with the other attributes, which are wrapped in a pixel_format availability check. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402306 --- src/video/wincommon/SDL_wingl.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/video/wincommon/SDL_wingl.c b/src/video/wincommon/SDL_wingl.c index 05933421c..c3ce470d8 100644 --- a/src/video/wincommon/SDL_wingl.c +++ b/src/video/wincommon/SDL_wingl.c @@ -403,11 +403,19 @@ int WIN_GL_MakeCurrent(_THIS) return(retval); } -/* Get attribute data from glX. */ +/* Get attribute data from wgl. */ int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) { int retval; - + + if (attrib == SDL_GL_SWAP_CONTROL) { + if ( this->gl_data->wglGetSwapIntervalEXT ) { + *value = this->gl_data->wglGetSwapIntervalEXT(); + return 0; + } + return -1; + } + if ( this->gl_data->WGL_ARB_pixel_format ) { int wgl_attrib; @@ -466,15 +474,6 @@ int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) *value = SDL_TRUE; } return 0; - break; - case SDL_GL_SWAP_CONTROL: - if ( this->gl_data->wglGetSwapIntervalEXT ) { - *value = this->gl_data->wglGetSwapIntervalEXT(); - return 0; - } else { - return -1; - } - break; default: return(-1); } From d070d0ddfd20e60cb2ff350b74159a4be353d8fd Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 17 Apr 2007 09:09:48 +0000 Subject: [PATCH 092/241] Removing .gdbinit from test directory. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402307 --- test/.gdbinit | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 test/.gdbinit diff --git a/test/.gdbinit b/test/.gdbinit deleted file mode 100644 index 63ebf2cbf..000000000 --- a/test/.gdbinit +++ /dev/null @@ -1,3 +0,0 @@ -handle SIGUSR1 pass noprint -handle SIGUSR2 pass noprint -break main From a144a3d025ae3134d4de4b464c7f952d8eefe2b6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 13 May 2007 23:12:46 +0000 Subject: [PATCH 093/241] Committed PulseAudio driver. Thanks, Stephan! --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402310 --- configure.in | 58 +++++ include/SDL_config.h.in | 2 + src/audio/SDL_audio.c | 3 + src/audio/SDL_sysaudio.h | 3 + src/audio/pulse/SDL_pulseaudio.c | 377 +++++++++++++++++++++++++++++++ src/audio/pulse/SDL_pulseaudio.h | 53 +++++ 6 files changed, 496 insertions(+) create mode 100644 src/audio/pulse/SDL_pulseaudio.c create mode 100644 src/audio/pulse/SDL_pulseaudio.h diff --git a/configure.in b/configure.in index 1d456a143..b865ea7bc 100644 --- a/configure.in +++ b/configure.in @@ -459,6 +459,63 @@ AC_HELP_STRING([--enable-esd-shared], [dynamically load ESD audio support [[defa fi } +dnl Find PulseAudio +CheckPulseAudio() +{ + AC_ARG_ENABLE(pulseaudio, +AC_HELP_STRING([--enable-pulseaudio], [use PulseAudio [[default=yes]]]), + , enable_pulse=yes) + if test x$enable_audio = xyes -a x$enable_pulse = xyes; then + audio_pulse=no + + PULSE_REQUIRED_VERSION=0.9 + + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + AC_MSG_CHECKING(for PulseAudio $PULSE_REQUIRED_VERSION support) + if test x$PKG_CONFIG != xno; then + if $PKG_CONFIG --atleast-pkgconfig-version 0.7 && $PKG_CONFIG --atleast-version $PULSE_REQUIRED_VERSION libpulse-simple; then + PULSE_CFLAGS=`$PKG_CONFIG --cflags libpulse-simple` + PULSE_LIBS=`$PKG_CONFIG --libs libpulse-simple` + audio_pulse=yes + fi + fi + AC_MSG_RESULT($audio_pulse) + + if test x$audio_pulse = xyes; then + AC_ARG_ENABLE(pulseaudio-shared, +AC_HELP_STRING([--enable-pulseaudio-shared], [dynamically load PulseAudio support [[default=yes]]]), + , enable_pulse_shared=yes) + if test "x`echo $PULSE_LIBS | grep -- -L`" = "x"; then + if test "x`ls /lib/libpulse-simple.so.* 2> /dev/null`" != "x"; then + PULSE_LIBS="-L/lib $PULSE_LIBS" + elif test "x`ls /usr/lib/libpulse-simple.so.* 2> /dev/null`" != "x"; then + PULSE_LIBS="-L/usr/lib $PULSE_LIBS" + elif test "x`ls /usr/local/lib/libpulse-simple.so.* 2> /dev/null`" != "x"; then + PULSE_LIBS="-L/usr/local/lib $PULSE_LIBS" + fi + fi + pulse_lib_spec=`echo $PULSE_LIBS | sed 's/.*-L\([[^ ]]*\).*/\1\/libpulse-simple.so.*/'` + pulse_lib=`ls -- $pulse_lib_spec | sed 's/.*\/\(.*\)/\1/; q'` + echo "-- $pulse_lib_spec -> $pulse_lib" + + AC_DEFINE(SDL_AUDIO_DRIVER_PULSE) + SOURCES="$SOURCES $srcdir/src/audio/pulse/*.c" + EXTRA_CFLAGS="$EXTRA_CFLAGS $PULSE_CFLAGS" + if test x$have_loadso != xyes && \ + test x$enable_pulse_shared = xyes; then + AC_MSG_WARN([You must have SDL_LoadObject() support for dynamic PulseAudio loading]) + fi + if test x$have_loadso = xyes && \ + test x$enable_pulse_shared = xyes && test x$pulse_lib != x; then + AC_DEFINE_UNQUOTED(SDL_AUDIO_DRIVER_PULSE_DYNAMIC, "$pulse_lib") + else + EXTRA_LDFLAGS="$EXTRA_LDFLAGS $PULSE_LIBS" + fi + have_audio=yes + fi + fi +} + CheckARTSC() { AC_ARG_ENABLE(arts, @@ -2150,6 +2207,7 @@ case "$host" in CheckALSA CheckARTSC CheckESD + CheckPulseAudio CheckNAS CheckX11 CheckNANOX diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index afd6eb73f..c2a76950d 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -163,6 +163,8 @@ #undef SDL_AUDIO_DRIVER_DUMMY #undef SDL_AUDIO_DRIVER_DMEDIA #undef SDL_AUDIO_DRIVER_DSOUND +#undef SDL_AUDIO_DRIVER_PULSE +#undef SDL_AUDIO_DRIVER_PULSE_DYNAMIC #undef SDL_AUDIO_DRIVER_ESD #undef SDL_AUDIO_DRIVER_ESD_DYNAMIC #undef SDL_AUDIO_DRIVER_MINT diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 6aa0c7a25..91d6945ed 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -46,6 +46,9 @@ static AudioBootStrap *bootstrap[] = { #if SDL_AUDIO_DRIVER_ALSA &ALSA_bootstrap, #endif +#if SDL_AUDIO_DRIVER_PULSE + &PULSE_bootstrap, +#endif #if SDL_AUDIO_DRIVER_QNXNTO &QNXNTOAUDIO_bootstrap, #endif diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index 2945448f2..b73748aab 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -103,6 +103,9 @@ typedef struct AudioBootStrap { #if SDL_AUDIO_DRIVER_BSD extern AudioBootStrap BSD_AUDIO_bootstrap; #endif +#if SDL_AUDIO_DRIVER_PULSE +extern AudioBootStrap PULSE_bootstrap; +#endif #if SDL_AUDIO_DRIVER_OSS extern AudioBootStrap DSP_bootstrap; extern AudioBootStrap DMA_bootstrap; diff --git a/src/audio/pulse/SDL_pulseaudio.c b/src/audio/pulse/SDL_pulseaudio.c new file mode 100644 index 000000000..4eb1d8149 --- /dev/null +++ b/src/audio/pulse/SDL_pulseaudio.c @@ -0,0 +1,377 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2007 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Stéphan Kochen + stephan@kochen.nl + + Based on parts of the ALSA and ESounD output drivers. +*/ +#include "SDL_config.h" + +/* Allow access to an PulseAudio network stream mixing buffer */ + +#include +#include +#include +#include +#include + +#include "SDL_timer.h" +#include "SDL_audio.h" +#include "../SDL_audiomem.h" +#include "../SDL_audio_c.h" +#include "../SDL_audiodev_c.h" +#include "SDL_pulseaudio.h" + +#ifdef SDL_AUDIO_DRIVER_PULSE_DYNAMIC +#include "SDL_name.h" +#include "SDL_loadso.h" +#else +#define SDL_NAME(X) X +#endif + +/* The tag name used by the driver */ +#define PULSE_DRIVER_NAME "pulse" + +/* Audio driver functions */ +static int PULSE_OpenAudio(_THIS, SDL_AudioSpec *spec); +static void PULSE_WaitAudio(_THIS); +static void PULSE_PlayAudio(_THIS); +static Uint8 *PULSE_GetAudioBuf(_THIS); +static void PULSE_CloseAudio(_THIS); + +#ifdef SDL_AUDIO_DRIVER_PULSE_DYNAMIC + +static const char *pulse_library = SDL_AUDIO_DRIVER_PULSE_DYNAMIC; +static void *pulse_handle = NULL; +static int pulse_loaded = 0; + +static pa_simple* (*SDL_NAME(pa_simple_new))( + const char *server, + const char *name, + pa_stream_direction_t dir, + const char *dev, + const char *stream_name, + const pa_sample_spec *ss, + const pa_channel_map *map, + const pa_buffer_attr *attr, + int *error +); +static void (*SDL_NAME(pa_simple_free))(pa_simple *s); +static int (*SDL_NAME(pa_simple_drain))(pa_simple *s, int *error); +static int (*SDL_NAME(pa_simple_write))( + pa_simple *s, + const void *data, + size_t length, + int *error +); +static pa_channel_map* (*SDL_NAME(pa_channel_map_init_auto))( + pa_channel_map *m, + unsigned channels, + pa_channel_map_def_t def +); + + +static struct { + const char *name; + void **func; +} pulse_functions[] = { + { "pa_simple_new", + (void **)&SDL_NAME(pa_simple_new) }, + { "pa_simple_free", + (void **)&SDL_NAME(pa_simple_free) }, + { "pa_simple_drain", + (void **)&SDL_NAME(pa_simple_drain) }, + { "pa_simple_write", + (void **)&SDL_NAME(pa_simple_write) }, + { "pa_channel_map_init_auto", + (void **)&SDL_NAME(pa_channel_map_init_auto) }, +}; + +static void UnloadPulseLibrary() +{ + if ( pulse_loaded ) { + SDL_UnloadObject(pulse_handle); + pulse_handle = NULL; + pulse_loaded = 0; + } +} + +static int LoadPulseLibrary(void) +{ + int i, retval = -1; + + pulse_handle = SDL_LoadObject(pulse_library); + if ( pulse_handle ) { + pulse_loaded = 1; + retval = 0; + for ( i=0; ihidden); + SDL_free(device); + UnloadPulseLibrary(); +} + +static SDL_AudioDevice *Audio_CreateDevice(int devindex) +{ + SDL_AudioDevice *this; + + /* Initialize all variables that we clean on shutdown */ + LoadPulseLibrary(); + this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); + if ( this ) { + SDL_memset(this, 0, (sizeof *this)); + this->hidden = (struct SDL_PrivateAudioData *) + SDL_malloc((sizeof *this->hidden)); + } + if ( (this == NULL) || (this->hidden == NULL) ) { + SDL_OutOfMemory(); + if ( this ) { + SDL_free(this); + } + return(0); + } + SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + + /* Set the function pointers */ + this->OpenAudio = PULSE_OpenAudio; + this->WaitAudio = PULSE_WaitAudio; + this->PlayAudio = PULSE_PlayAudio; + this->GetAudioBuf = PULSE_GetAudioBuf; + this->CloseAudio = PULSE_CloseAudio; + + this->free = Audio_DeleteDevice; + + return this; +} + +AudioBootStrap PULSE_bootstrap = { + PULSE_DRIVER_NAME, "PulseAudio", + Audio_Available, Audio_CreateDevice +}; + +/* This function waits until it is possible to write a full sound buffer */ +static void PULSE_WaitAudio(_THIS) +{ + /* Check to see if the thread-parent process is still alive */ + { static int cnt = 0; + /* Note that this only works with thread implementations + that use a different process id for each thread. + */ + if (parent && (((++cnt)%10) == 0)) { /* Check every 10 loops */ + if ( kill(parent, 0) < 0 ) { + this->enabled = 0; + } + } + } +} + +static void PULSE_PlayAudio(_THIS) +{ + /* Write the audio data */ + if ( SDL_NAME(pa_simple_write)(stream, mixbuf, mixlen, NULL) != 0 ) + { + this->enabled = 0; + } +} + +static Uint8 *PULSE_GetAudioBuf(_THIS) +{ + return(mixbuf); +} + +static void PULSE_CloseAudio(_THIS) +{ + if ( mixbuf != NULL ) { + SDL_FreeAudioMem(mixbuf); + mixbuf = NULL; + } + if ( stream != NULL ) { + SDL_NAME(pa_simple_drain)(stream, NULL); + SDL_NAME(pa_simple_free)(stream); + stream = NULL; + } +} + +/* Try to get the name of the program */ +static char *get_progname(void) +{ + char *progname = NULL; +#ifdef __LINUX__ + FILE *fp; + static char temp[BUFSIZ]; + + SDL_snprintf(temp, SDL_arraysize(temp), "/proc/%d/cmdline", getpid()); + fp = fopen(temp, "r"); + if ( fp != NULL ) { + if ( fgets(temp, sizeof(temp)-1, fp) ) { + progname = SDL_strrchr(temp, '/'); + if ( progname == NULL ) { + progname = temp; + } else { + progname = progname+1; + } + } + fclose(fp); + } +#endif + return(progname); +} + +static int PULSE_OpenAudio(_THIS, SDL_AudioSpec *spec) +{ + Uint16 test_format; + pa_sample_spec paspec; + pa_buffer_attr paattr; + pa_channel_map pacmap; + + paspec.format = PA_SAMPLE_INVALID; + for ( test_format = SDL_FirstAudioFormat(spec->format); test_format; ) { + switch ( test_format ) { + case AUDIO_U8: + paspec.format = PA_SAMPLE_U8; + break; + case AUDIO_S16LSB: + paspec.format = PA_SAMPLE_S16LE; + break; + case AUDIO_S16MSB: + paspec.format = PA_SAMPLE_S16BE; + break; + } + if ( paspec.format != PA_SAMPLE_INVALID ) + break; + } + if (paspec.format == PA_SAMPLE_INVALID ) { + SDL_SetError("Couldn't find any suitable audio formats"); + return(-1); + } + spec->format = test_format; + + paspec.channels = spec->channels; + paspec.rate = spec->freq; + + /* Calculate the final parameters for this audio specification */ + SDL_CalculateAudioSpec(spec); + + /* Allocate mixing buffer */ + mixlen = spec->size; + mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen); + if ( mixbuf == NULL ) { + return(-1); + } + SDL_memset(mixbuf, spec->silence, spec->size); + + /* Reduced prebuffering compared to the defaults. */ + paattr.tlength = mixlen; + paattr.minreq = mixlen; + paattr.fragsize = mixlen; + paattr.prebuf = mixlen; + paattr.maxlength = mixlen * 4; + + /* The SDL ALSA output hints us that we use Windows' channel mapping */ + /* http://bugzilla.libsdl.org/show_bug.cgi?id=110 */ + SDL_NAME(pa_channel_map_init_auto)( + &pacmap, spec->channels, PA_CHANNEL_MAP_WAVEEX); + + /* Connect to the PulseAudio server */ + stream = SDL_NAME(pa_simple_new)( + SDL_getenv("PASERVER"), /* server */ + get_progname(), /* application name */ + PA_STREAM_PLAYBACK, /* playback mode */ + SDL_getenv("PADEVICE"), /* device on the server */ + "Simple DirectMedia Layer", /* stream description */ + &paspec, /* sample format spec */ + &pacmap, /* channel map */ + &paattr, /* buffering attributes */ + NULL /* error code */ + ); + if ( stream == NULL ) { + PULSE_CloseAudio(this); + SDL_SetError("Could not connect to PulseAudio"); + return(-1); + } + + /* Get the parent process id (we're the parent of the audio thread) */ + parent = getpid(); + + return(0); +} + diff --git a/src/audio/pulse/SDL_pulseaudio.h b/src/audio/pulse/SDL_pulseaudio.h new file mode 100644 index 000000000..e19189b6d --- /dev/null +++ b/src/audio/pulse/SDL_pulseaudio.h @@ -0,0 +1,53 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2007 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Stéphan Kochen + stephan@kochen.nl + + Based on parts of the ALSA and ESounD output drivers. +*/ +#include "SDL_config.h" + +#ifndef _SDL_pulseaudio_h +#define _SDL_pulseaudio_h + +#include "../SDL_sysaudio.h" + +/* Hidden "this" pointer for the video functions */ +#define _THIS SDL_AudioDevice *this + +struct SDL_PrivateAudioData { + /* The audio stream handle */ + pa_simple * stream; + + /* The parent process id, to detect when application quits */ + pid_t parent; + + /* Raw mixing buffer */ + Uint8 *mixbuf; + int mixlen; +}; + +/* Old variable names */ +#define stream (this->hidden->stream) +#define parent (this->hidden->parent) +#define mixbuf (this->hidden->mixbuf) +#define mixlen (this->hidden->mixlen) + +#endif /* _SDL_pulseaudio_h */ + From 4fbac0bf457b8f94cc2a36d93ef25e315257296e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 22 May 2007 22:15:54 +0000 Subject: [PATCH 094/241] Check correct glX extension name for swap_control, but it doesn't look like we ever actually look up the symbol...that's probably a bug. :/ --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402312 --- src/video/x11/SDL_x11gl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/x11/SDL_x11gl.c b/src/video/x11/SDL_x11gl.c index 1d767e17f..7e89d1707 100644 --- a/src/video/x11/SDL_x11gl.c +++ b/src/video/x11/SDL_x11gl.c @@ -269,7 +269,7 @@ int X11_GL_CreateContext(_THIS) } gl_active = 1; - if ( !glXExtensionSupported(this, "SGI_swap_control") ) { + if ( !glXExtensionSupported(this, "GLX_SGI_swap_control") ) { this->gl_data->glXSwapIntervalSGI = NULL; } if ( !glXExtensionSupported(this, "GLX_MESA_swap_control") ) { From 3e7810109abffe5c177e35e069442dabd8f8241a Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 26 May 2007 19:44:37 +0000 Subject: [PATCH 095/241] GEM has a window manager, of course --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402313 --- src/video/gem/SDL_gemvideo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/gem/SDL_gemvideo.c b/src/video/gem/SDL_gemvideo.c index eea9863d3..0e87d2946 100644 --- a/src/video/gem/SDL_gemvideo.c +++ b/src/video/gem/SDL_gemvideo.c @@ -467,6 +467,8 @@ int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat) SDL_AtariGL_InitPointers(this); #endif + video->info.wm_available = 1; + /* We're done! */ return(0); } From 536d584388e68e4a9e29b8e064c3d70603c6aa08 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 26 May 2007 20:09:56 +0000 Subject: [PATCH 096/241] Simply resize existing window --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402315 --- src/video/gem/SDL_gemvideo.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/video/gem/SDL_gemvideo.c b/src/video/gem/SDL_gemvideo.c index 0e87d2946..874eb95a0 100644 --- a/src/video/gem/SDL_gemvideo.c +++ b/src/video/gem/SDL_gemvideo.c @@ -778,17 +778,10 @@ SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current, /* Open the window */ wind_open(GEM_handle,x2,y2,w2,h2); } else { - /* Resize window if needed, to fit asked video mode */ - if (modeflags & SDL_RESIZABLE) { - wind_get (GEM_handle, WF_WORKXYWH, &x2,&y2,&w2,&h2); - if ((w2&15)!=0) { - w2=(w2|15)+1; - } - if ((w2!=width) || (h2!=height)) { - if (wind_calc(WC_BORDER, GEM_win_type, x2,y2,width,height, &x2,&y2,&w2,&h2)) { - wind_set (GEM_handle, WF_CURRXYWH, x2,y2,w2,h2); - } - } + /* Resize window to fit asked video mode */ + wind_get (GEM_handle, WF_WORKXYWH, &x2,&y2,&w2,&h2); + if (wind_calc(WC_BORDER, GEM_win_type, x2,y2,width,height, &x2,&y2,&w2,&h2)) { + wind_set (GEM_handle, WF_CURRXYWH, x2,y2,w2,h2); } } From d3b8d75c1bc0d7ff389b4536d81d92f8a7f5cfef Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 26 May 2007 20:12:58 +0000 Subject: [PATCH 097/241] Oops --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402317 --- src/video/gem/SDL_gemvideo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/gem/SDL_gemvideo.c b/src/video/gem/SDL_gemvideo.c index 874eb95a0..1cf58278c 100644 --- a/src/video/gem/SDL_gemvideo.c +++ b/src/video/gem/SDL_gemvideo.c @@ -467,7 +467,7 @@ int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat) SDL_AtariGL_InitPointers(this); #endif - video->info.wm_available = 1; + this->info.wm_available = 1; /* We're done! */ return(0); From 576d64cb8d67d036ad1126bce06186d981de4ecb Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 27 May 2007 08:53:48 +0000 Subject: [PATCH 098/241] Allow creation of window bigger than visible size --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402318 --- src/video/gem/SDL_gemvideo.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/video/gem/SDL_gemvideo.c b/src/video/gem/SDL_gemvideo.c index 1cf58278c..353e02779 100644 --- a/src/video/gem/SDL_gemvideo.c +++ b/src/video/gem/SDL_gemvideo.c @@ -621,30 +621,27 @@ static void GEM_UnlockScreen(_THIS) SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { - int maxwidth, maxheight; Uint32 modeflags, screensize; SDL_bool use_shadow1, use_shadow2; - /*--- Verify if asked mode can be used ---*/ - if (flags & SDL_FULLSCREEN) { - maxwidth=VDI_w; - maxheight=VDI_h; - } else { - /* Windowed mode */ - maxwidth=GEM_desk_w; - maxheight=GEM_desk_h; - } - /* width must be multiple of 16, for vro_cpyfm() and c2p_convert() */ if ((width & 15) != 0) { width = (width | 15) +1; } - if ((maxwidth < width) || (maxheight < height) || (VDI_bpp != bpp)) { - SDL_SetError("Couldn't find requested mode in list"); + /*--- Verify if asked mode can be used ---*/ + if (VDI_bpp != bpp) { + SDL_SetError("%d bpp mode not supported", bpp); return(NULL); } + if (flags & SDL_FULLSCREEN) { + if ((VDI_w < width) || (VDI_h < height)) { + SDL_SetError("%dx%d mode is too large", width, height); + return(NULL); + } + } + /*--- Allocate the new pixel format for the screen ---*/ if ( ! SDL_ReallocFormat(current, VDI_bpp, VDI_redmask, VDI_greenmask, VDI_bluemask, VDI_alphamask) ) { SDL_SetError("Couldn't allocate new pixel format for requested mode"); @@ -750,8 +747,16 @@ SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current, } /* Center window */ - x2 = GEM_desk_x+((GEM_desk_w-w2)>>1); - y2 = GEM_desk_y+((GEM_desk_h-h2)>>1); + x2 = (GEM_desk_w-w2)>>1; + y2 = (GEM_desk_h-h2)>>1; + if (x2<0) { + x2 = 0; + } + if (y2<0) { + y2 = 0; + } + x2 += GEM_desk_x; + y2 += GEM_desk_y; /* Destroy existing window */ if (GEM_handle >= 0) { From 27d3e5f271b221fb538a82c1ebf2a014185d6bb1 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 29 May 2007 12:01:07 +0000 Subject: [PATCH 099/241] Mac OS X joystick calibration code should start with device-specified bounds. Fixes Bugzilla #344. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402320 --- src/joystick/darwin/SDL_sysjoystick.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/joystick/darwin/SDL_sysjoystick.c b/src/joystick/darwin/SDL_sysjoystick.c index 8a152e8b0..8fd983ee2 100644 --- a/src/joystick/darwin/SDL_sysjoystick.c +++ b/src/joystick/darwin/SDL_sysjoystick.c @@ -241,12 +241,10 @@ static void HIDGetElementInfo (CFTypeRef refElement, recElement *pElement) pElement->cookie = (IOHIDElementCookie) number; refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementMinKey)); if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) - pElement->min = number; - pElement->maxReport = pElement->min; + pElement->minReport = pElement->min = number; refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementMaxKey)); if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) - pElement->max = number; - pElement->minReport = pElement->max; + pElement->maxReport = pElement->max = number; /* TODO: maybe should handle the following stuff somehow? From e883b665aff70e340a3ea8ad748756590eb340d4 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 3 Jun 2007 06:52:06 +0000 Subject: [PATCH 100/241] Use system memset/memcpy on Mac OS X, since Apple hand-tunes these for each processor they ship (and thus, it's likely to beat our code on PowerPC and Intel and whatever variants or new archs show up later). --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402323 --- include/SDL_stdinc.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index 7e0346334..53d1288f0 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -234,7 +234,10 @@ extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, extern DECLSPEC void * SDLCALL SDL_memset(void *dst, int c, size_t len); #endif -#if defined(__GNUC__) && defined(i386) +/* We can count on memset existing on Mac OS X and being well-tuned. */ +#if defined(__MACH__) && defined(__APPLE__) +#define SDL_memset4(dst, val, len) memset(dst, val, (len)*4) +#elif defined(__GNUC__) && defined(i386) #define SDL_memset4(dst, val, len) \ do { \ int u0, u1, u2; \ @@ -263,7 +266,10 @@ do { \ } while(0) #endif -#if defined(__GNUC__) && defined(i386) +/* We can count on memcpy existing on Mac OS X and being well-tuned. */ +#if defined(__MACH__) && defined(__APPLE__) +#define SDL_memcpy(dst, src, len) memcpy(dst, src, len) +#elif defined(__GNUC__) && defined(i386) #define SDL_memcpy(dst, src, len) \ do { \ int u0, u1, u2; \ @@ -292,7 +298,10 @@ extern DECLSPEC void * SDLCALL SDL_memcpy(void *dst, const void *src, size_t len #endif #endif -#if defined(__GNUC__) && defined(i386) +/* We can count on memcpy existing on Mac OS X and being well-tuned. */ +#if defined(__MACH__) && defined(__APPLE__) +#define SDL_memcpy4(dst, src, len) memcpy(dst, src, (len)*4) +#elif defined(__GNUC__) && defined(i386) #define SDL_memcpy4(dst, src, len) \ do { \ int ecx, edi, esi; \ From 24f42ead234be7a0582d0e5c6a996858224efc25 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 3 Jun 2007 06:52:58 +0000 Subject: [PATCH 101/241] Patched to compile on Mac OS X (not that you should necessarily be using this on Mac OS X, but still) ... --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402324 --- src/video/maccommon/SDL_macevents.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/video/maccommon/SDL_macevents.c b/src/video/maccommon/SDL_macevents.c index 0e4f813e2..4c5bce3f8 100644 --- a/src/video/maccommon/SDL_macevents.c +++ b/src/video/maccommon/SDL_macevents.c @@ -159,6 +159,8 @@ static int Mac_HandleEvents(_THIS, int wait4it) /* Check the current state of the keyboard */ if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) { KeyMap keys; + const Uint8 *keysptr = (Uint8 *) &keys; + const Uint8 *last_keysptr = (Uint8 *) &last_keys; /* Check for special non-event keys */ if ( event.modifiers != last_mods ) { @@ -214,8 +216,10 @@ static int Mac_HandleEvents(_THIS, int wait4it) is immediately followed by a keyup event. */ GetKeys(keys); - if ( (keys[0] != last_keys[0]) || (keys[1] != last_keys[1]) || - (keys[2] != last_keys[2]) || (keys[3] != last_keys[3]) ) { + if ( (keysptr[0] != last_keysptr[0]) || + (keysptr[1] != last_keysptr[1]) || + (keysptr[2] != last_keysptr[2]) || + (keysptr[3] != last_keysptr[3]) ) { SDL_keysym keysym; int old_bit, new_bit; @@ -730,7 +734,7 @@ static void Mac_DoAppleMenu(_THIS, long choice) #if !TARGET_API_MAC_CARBON /* Since we don't initialize QuickDraw, we need to get a pointer to qd */ -QDGlobals *theQD = NULL; +struct QDGlobals *theQD = NULL; #endif /* Exported to the macmain code */ From 10b93c9102411eeab72f4b7bf99581069cb572e9 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 3 Jun 2007 19:19:16 +0000 Subject: [PATCH 102/241] Minor tab fix in mac drawsprocket code. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402326 --- src/video/macdsp/SDL_dspvideo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/macdsp/SDL_dspvideo.c b/src/video/macdsp/SDL_dspvideo.c index a1150d777..060833fe6 100644 --- a/src/video/macdsp/SDL_dspvideo.c +++ b/src/video/macdsp/SDL_dspvideo.c @@ -1378,8 +1378,8 @@ void DSp_VideoQuit(_THIS) /* Free current video mode */ DSp_UnsetVideoMode(this, this->screen); - /* Free Palette and restore original */ - DSp_DestroyPalette (this); + /* Free Palette and restore original */ + DSp_DestroyPalette (this); /* Free list of video modes */ if ( SDL_modelist != NULL ) { @@ -1391,7 +1391,7 @@ void DSp_VideoQuit(_THIS) } /* Unload DrawSprocket */ - DSpShutdown (); + DSpShutdown (); } #if SDL_VIDEO_OPENGL From a0395a876cb6e9debeefd0159ba0d7352349beca Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 3 Jun 2007 19:21:07 +0000 Subject: [PATCH 103/241] Minor macrom comment cleanup. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402327 --- src/video/macrom/SDL_romvideo.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/video/macrom/SDL_romvideo.c b/src/video/macrom/SDL_romvideo.c index fbe65fd9a..3113b206d 100644 --- a/src/video/macrom/SDL_romvideo.c +++ b/src/video/macrom/SDL_romvideo.c @@ -163,7 +163,7 @@ static SDL_VideoDevice *ROM_CreateDevice(int devindex) device->GL_SwapBuffers = Mac_GL_SwapBuffers; device->GL_LoadLibrary = Mac_GL_LoadLibrary; device->GL_GetProcAddress = Mac_GL_GetProcAddress; -#endif // Have OpenGL +#endif /* Have OpenGL */ device->SetCaption = Mac_SetCaption; device->SetIcon = NULL; device->IconifyWindow = NULL; @@ -689,8 +689,11 @@ static int ROM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) (**cTab).ctTable[j].rgb.green = colors[i].g << 8 | colors[i].g; (**cTab).ctTable[j].rgb.blue = colors[i].b << 8 | colors[i].b; } -// if ( (this->screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) -{ + +#if 0 + if ( (this->screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) +#endif + { GDevice **odisplay; odisplay = GetGDevice(); SetGDevice(SDL_Display); From f1107d917985307ca1dd8d830c1bb952fc205ac6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 4 Jun 2007 11:06:48 +0000 Subject: [PATCH 104/241] Check if yasm supports a nasm-specific syntax we use (it doesn't in 0.5.0, which is still common in Linux distros, and does in 0.6.0). Disable it if we don't, attempting to fallback to using nasm. Thanks to Mike Frysinger for the patch. Fixes Bugzilla #393. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402328 --- configure.in | 62 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/configure.in b/configure.in index b865ea7bc..5d0e33ab7 100644 --- a/configure.in +++ b/configure.in @@ -662,38 +662,56 @@ CheckNASM() AC_HELP_STRING([--enable-nasm], [use nasm assembly blitters on x86 [[default=yes]]]), , enable_nasm=yes) if test x$enable_video = xyes -a x$enable_assembly = xyes -a x$enable_nasm = xyes; then + CompileNASM() + { + # Usage: CompileNASM + AC_MSG_CHECKING(to see if $NASM supports $1) + if $NASM $NASMFLAGS $1 -o $1.o >&AS_MESSAGE_LOG_FD 2>&1; then + CompileNASM_ret="yes" + else + CompileNASM_ret="no" + fi + rm -f $1 $1.o + AC_MSG_RESULT($CompileNASM_ret) + test "$CompileNASM_ret" = "yes" + } + + if test x"$NASMFLAGS" = x; then + case $ARCH in + win32) + NASMFLAGS="-f win32" + ;; + openbsd) + NASMFLAGS="-f aoutb" + ;; + macosx) + NASMFLAGS="-f macho" + ;; + *) + NASMFLAGS="-f elf" + ;; + esac + fi + AC_PATH_PROG(NASM, yasm) + echo "%ifidn __OUTPUT_FORMAT__,elf" > unquoted-sections + echo "section .note.GNU-stack noalloc noexec nowrite progbits" >> unquoted-sections + echo "%endif" >> unquoted-sections + CompileNASM unquoted-sections || NASM="" + if test "x$NASM" = x -o "x$NASM" = x'"$NASM"'; then + $as_unset ac_cv_path_NASM AC_PATH_PROG(NASM, nasm) fi if test "x$NASM" != x -a "x$NASM" != x'"$NASM"'; then AC_DEFINE(SDL_HERMES_BLITTERS) SOURCES="$SOURCES $srcdir/src/hermes/*.asm" - if test x"$NASMFLAGS" = x; then - case $ARCH in - win32) - NASMFLAGS="-f win32" - ;; - openbsd) - NASMFLAGS="-f aoutb" - ;; - macosx) - NASMFLAGS="-f macho" - ;; - *) - NASMFLAGS="-f elf" - ;; - esac - fi NASMFLAGS="$NASMFLAGS -i $srcdir/src/hermes/" dnl See if hidden visibility is supported - echo "GLOBAL _bar:function hidden" > nasm_vis.asm - echo "_bar:" >>nasm_vis.asm - if $NASM $NASMFLAGS nasm_vis.asm -o nasm_vis.o >&AS_MESSAGE_LOG_FD 2>&1; then - NASMFLAGS="$NASMFLAGS -DHIDDEN_VISIBILITY" - fi - rm -f nasm_vis.asm nasm_vis.o + echo "GLOBAL _bar:function hidden" > symbol-visibility + echo "_bar:" >> symbol-visibility + CompileNASM symbol-visibility && NASMFLAGS="$NASMFLAGS -DHIDDEN_VISIBILITY" AC_SUBST(NASM) AC_SUBST(NASMFLAGS) From 88ccf13d13802cff7a3207888c5e160d4fc2d292 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 4 Jun 2007 11:15:58 +0000 Subject: [PATCH 105/241] Patch to allow DirectFB target to report a correct screen size. Fixes Bugzilla #399. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402330 --- src/video/directfb/SDL_DirectFB_video.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/directfb/SDL_DirectFB_video.c b/src/video/directfb/SDL_DirectFB_video.c index 696b5c3b1..5b592c1cb 100644 --- a/src/video/directfb/SDL_DirectFB_video.c +++ b/src/video/directfb/SDL_DirectFB_video.c @@ -460,6 +460,8 @@ int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat) this->info.blit_hw_A = 1; this->info.blit_fill = 1; this->info.video_mem = caps.video_memory / 1024; + this->info.current_w = dlc.width; + this->info.current_h = dlc.height; HIDDEN->initialized = 1; HIDDEN->dfb = dfb; From 6b5b916b0d7da53d4de391d40a89d4dee85799ba Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 4 Jun 2007 11:22:23 +0000 Subject: [PATCH 106/241] Better handling of multiple queued Cocoa mouse events. Thanks to Christian Walther for the patch. Fixes Bugzilla #353. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402332 --- src/video/quartz/SDL_QuartzEvents.m | 33 ++++++++++------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/video/quartz/SDL_QuartzEvents.m b/src/video/quartz/SDL_QuartzEvents.m index 3c0267e15..1647570b5 100644 --- a/src/video/quartz/SDL_QuartzEvents.m +++ b/src/video/quartz/SDL_QuartzEvents.m @@ -722,7 +722,6 @@ void QZ_PumpEvents (_THIS) { static Uint32 screensaverTicks = 0; Uint32 nowTicks; - int firstMouseEvent; CGMouseDelta dx, dy; NSDate *distantPast; @@ -748,10 +747,7 @@ void QZ_PumpEvents (_THIS) winRect = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h); - /* send the first mouse event in absolute coordinates */ - firstMouseEvent = 1; - - /* accumulate any additional mouse moved events into one SDL mouse event */ + /* while grabbed, accumulate all mouse moved events into one SDL mouse event */ dx = 0; dy = 0; @@ -853,29 +849,22 @@ void QZ_PumpEvents (_THIS) dx += dx1; dy += dy1; } - else if (firstMouseEvent) { + else { /* - Get the first mouse event in a possible - sequence of mouse moved events. Since we - use absolute coordinates, this serves to - compensate any inaccuracy in deltas, and - provides the first known mouse position, - since everything after this uses deltas + Get the absolute mouse location. This is not the + mouse location after the currently processed event, + but the *current* mouse location, i.e. after all + pending events. This means that if there are + multiple mouse moved events in the queue, we make + multiple identical calls to SDL_PrivateMouseMotion(), + but that's no problem since the latter only + generates SDL events for nonzero movements. In my + experience on PBG4/10.4.8, this rarely happens anyway. */ NSPoint p; QZ_GetMouseLocation (this, &p); SDL_PrivateMouseMotion (0, 0, p.x, p.y); - firstMouseEvent = 0; - } - else { - - /* - Get the amount moved since the last drag or move event, - add it on for one big move event at the end. - */ - dx += [ event deltaX ]; - dy += [ event deltaY ]; } /* From 2d2ab89a1da10c29d4a5d7795f0d41df68e87012 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 4 Jun 2007 11:43:47 +0000 Subject: [PATCH 107/241] C fallback for SDL_revcpy() was off by one. Thanks to Emmanuel Jeandel for the catch. Fixes Bugzilla #424. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402333 --- src/stdlib/SDL_string.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index 8c44e6d69..0ab5af6bb 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -289,8 +289,8 @@ void *SDL_revcpy(void *dst, const void *src, size_t len) { char *srcp = (char *)src; char *dstp = (char *)dst; - srcp += len; - dstp += len; + srcp += len-1; + dstp += len-1; while ( len-- ) { *dstp-- = *srcp--; } From ebf84b70dd10891a200a6b69632b3c627a0f72ca Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 8 Jun 2007 21:44:40 +0000 Subject: [PATCH 108/241] Set supervisor as volatile as it is modified from an interrupt --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402335 --- src/timer/mint/SDL_systimer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/timer/mint/SDL_systimer.c b/src/timer/mint/SDL_systimer.c index 0a3e71a84..3d2228545 100644 --- a/src/timer/mint/SDL_systimer.c +++ b/src/timer/mint/SDL_systimer.c @@ -53,7 +53,7 @@ void SDL_MintAudio_CheckFpu(void); /* The first ticks value of the application */ static Uint32 start; -static SDL_bool supervisor; +static volatile SDL_bool supervisor; static int mint_present; /* can we use Syield() ? */ void SDL_StartTicks(void) From 32a44529339c9012b816715de4553b8f5eb5c881 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 9 Jun 2007 19:52:05 +0000 Subject: [PATCH 109/241] Avoid switch to supervisor mode in SDL_GetTicks, by updating system counter from vbl interrupt --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402337 --- src/timer/mint/SDL_systimer.c | 61 +++++++++++++-------------------- src/timer/mint/SDL_vbltimer.S | 7 ++++ src/timer/mint/SDL_vbltimer_s.h | 2 ++ 3 files changed, 32 insertions(+), 38 deletions(-) diff --git a/src/timer/mint/SDL_systimer.c b/src/timer/mint/SDL_systimer.c index 3d2228545..f9560c48d 100644 --- a/src/timer/mint/SDL_systimer.c +++ b/src/timer/mint/SDL_systimer.c @@ -53,18 +53,18 @@ void SDL_MintAudio_CheckFpu(void); /* The first ticks value of the application */ static Uint32 start; -static volatile SDL_bool supervisor; +static SDL_bool read_hz200_from_vbl = SDL_FALSE; static int mint_present; /* can we use Syield() ? */ void SDL_StartTicks(void) { - void *oldpile; + void *old_stack; unsigned long dummy; /* Set first ticks value */ - oldpile=(void *)Super(0); - start=*((volatile long *)_hz_200); - Super(oldpile); + old_stack = (void *)Super(0); + start = *((volatile long *)_hz_200); + Super(old_stack); start *= 5; /* One _hz_200 tic is 5ms */ @@ -73,21 +73,14 @@ void SDL_StartTicks(void) Uint32 SDL_GetTicks (void) { - Uint32 now; - void *oldpile=NULL; + Uint32 now = start; - /* Check if we are in supervisor mode - (this is the case when called from SDL_ThreadedTimerCheck, - which is called from RunTimer, running in the vbl vector) - */ - if (!supervisor) { - oldpile=(void *)Super(0); - } - - now=*((volatile long *)_hz_200); - - if (!supervisor) { - Super(oldpile); + if (read_hz200_from_vbl) { + now = SDL_Atari_hz200; + } else { + void *old_stack = (void *)Super(0); + now = *((volatile long *)_hz_200); + Super(old_stack); } return((now*5)-start); @@ -108,44 +101,36 @@ void SDL_Delay (Uint32 ms) /* Data to handle a single periodic alarm */ static SDL_bool timer_installed=SDL_FALSE; -static void RunTimer(void) -{ - supervisor=SDL_TRUE; - SDL_ThreadedTimerCheck(); - supervisor=SDL_FALSE; -} - /* This is only called if the event thread is not running */ int SDL_SYS_TimerInit(void) { - void *oldpile; - - supervisor=SDL_FALSE; + void *old_stack; SDL_MintAudio_CheckFpu(); /* Install RunTimer in vbl vector */ - oldpile=(void *)Super(0); - timer_installed = !SDL_AtariVblInstall(RunTimer); - Super(oldpile); + old_stack = (void *)Super(0); + timer_installed = !SDL_AtariVblInstall(SDL_ThreadedTimerCheck); + Super(old_stack); if (!timer_installed) { return(-1); } + + read_hz200_from_vbl = SDL_TRUE; return(SDL_SetTimerThreaded(0)); } void SDL_SYS_TimerQuit(void) { - void *oldpile; - + /* Uninstall RunTimer vbl vector */ if (timer_installed) { - /* Uninstall RunTimer vbl vector */ - oldpile=(void *)Super(0); - SDL_AtariVblUninstall(RunTimer); - Super(oldpile); + void *old_stack = (void *)Super(0); + SDL_AtariVblUninstall(SDL_ThreadedTimerCheck); + Super(old_stack); timer_installed = SDL_FALSE; } + read_hz200_from_vbl = SDL_FALSE; } int SDL_SYS_StartTimer(void) diff --git a/src/timer/mint/SDL_vbltimer.S b/src/timer/mint/SDL_vbltimer.S index 6dfd49970..f9c4be96d 100644 --- a/src/timer/mint/SDL_vbltimer.S +++ b/src/timer/mint/SDL_vbltimer.S @@ -27,6 +27,7 @@ */ #define _vbl_queue 0x456 +#define _hz_200 0x4ba .text @@ -42,6 +43,7 @@ _SDL_AtariVblInstall: lea _my_vbl,a0 clrw vbl_mutex + movel _hz_200.w, _SDL_Atari_hz200 /* Stop interrupts */ @@ -108,6 +110,9 @@ badvector: /*--- Our vbl ---*/ _my_vbl: + /* Update _hz_200 */ + movel _hz_200.w, _SDL_Atari_hz200 + /* Verify if this is not already running */ tstw vbl_mutex @@ -147,6 +152,8 @@ vbl_end: .data .even + .comm _SDL_Atari_hz200,4*1 + .even .comm vbl_mutex,2*1 .even .comm my_vector,4*1 diff --git a/src/timer/mint/SDL_vbltimer_s.h b/src/timer/mint/SDL_vbltimer_s.h index 6d1f4f5ce..f893ef58b 100644 --- a/src/timer/mint/SDL_vbltimer_s.h +++ b/src/timer/mint/SDL_vbltimer_s.h @@ -28,6 +28,8 @@ * Patrice Mandin */ +extern volatile long SDL_Atari_hz200; + /* Functions prototypes */ extern int SDL_AtariVblInstall(void *newvector); extern void SDL_AtariVblUninstall(void *newvector); From 935338957de7e3a14f3a3dfc4f66684db36b9e90 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 13 Jun 2007 04:13:21 +0000 Subject: [PATCH 110/241] Print keysym with key events. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402339 --- test/threadwin.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/threadwin.c b/test/threadwin.c index c7ea5c8a7..c704b30d1 100644 --- a/test/threadwin.c +++ b/test/threadwin.c @@ -179,8 +179,9 @@ int SDLCALL HandleKeyboard(void *unused) /* We want to toggle visibility on buttonpress */ case SDL_KEYDOWN: case SDL_KEYUP: - printf("Key '%c' has been %s\n", + printf("Key '%c' (keysym==%d) has been %s\n", events[i].key.keysym.unicode, + (int) events[i].key.keysym.sym, (events[i].key.state == SDL_PRESSED) ? "pressed" : "released"); From 7bcb6190152eaa3235764a4b4bb8c81827de4c99 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 13 Jun 2007 07:54:10 +0000 Subject: [PATCH 111/241] Date: Mon, 4 Jun 2007 06:17:59 +0000 (UTC) From: George Gensure Subject: [SDL] error removal patch for SDL_x11dyn.c I found that calling SDL_GetError when an error hasn't necessarily occurred is still reporting problems from loadso regarding dynamic functions in X11. I've added the following to my local copy to avoid revealing the 'many library lookup' approach adopted by x11dyn.c: --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402341 --- src/video/x11/SDL_x11dyn.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/video/x11/SDL_x11dyn.c b/src/video/x11/SDL_x11dyn.c index a327c6ec8..c8f29213e 100644 --- a/src/video/x11/SDL_x11dyn.c +++ b/src/video/x11/SDL_x11dyn.c @@ -73,6 +73,11 @@ static void X11_GetSym(const char *fnname, int *rc, void **fn) } } + if (*fn != NULL) + SDL_ClearError(); + else + SDL_SetError("Failed to load function %s from x11libs", fnname); + #if DEBUG_DYNAMIC_X11 if (*fn != NULL) printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname, *fn); From 3c92462fd1c84c640cb849c63f132e6b5b6c5510 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 13 Jun 2007 08:00:10 +0000 Subject: [PATCH 112/241] Actually, this is a better fix...clear the error state once if everything we need loaded; it's more efficient, and works even if the last unnecessary xrandr symbol failed to load. Otherwise, leave the original loadso error, so the end user can find out what symbol failed. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402342 --- src/video/x11/SDL_x11dyn.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/video/x11/SDL_x11dyn.c b/src/video/x11/SDL_x11dyn.c index c8f29213e..e7f235d2f 100644 --- a/src/video/x11/SDL_x11dyn.c +++ b/src/video/x11/SDL_x11dyn.c @@ -73,11 +73,6 @@ static void X11_GetSym(const char *fnname, int *rc, void **fn) } } - if (*fn != NULL) - SDL_ClearError(); - else - SDL_SetError("Failed to load function %s from x11libs", fnname); - #if DEBUG_DYNAMIC_X11 if (*fn != NULL) printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname, *fn); @@ -170,7 +165,9 @@ int SDL_X11_LoadSymbols(void) X11_GetSym("XCreateIC",&SDL_X11_HAVE_UTF8,(void **)&pXCreateIC); #endif - if (!SDL_X11_HAVE_BASEXLIB) { /* some required symbol didn't load. */ + if (SDL_X11_HAVE_BASEXLIB) { /* all required symbols loaded. */ + SDL_ClearError(); + } else { SDL_X11_UnloadSymbols(); /* in case something got loaded... */ rc = 0; } From 2af6c8e18c355cc52cc3638a28e502ae459c349d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 14 Jun 2007 14:09:25 +0000 Subject: [PATCH 113/241] Prevent arts audio target from crashing/hanging SDL if the audio hardware isn't available. Fixes Bugzilla #372. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402346 --- src/audio/arts/SDL_artsaudio.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/audio/arts/SDL_artsaudio.c b/src/audio/arts/SDL_artsaudio.c index 59949a52f..6581e97cb 100644 --- a/src/audio/arts/SDL_artsaudio.c +++ b/src/audio/arts/SDL_artsaudio.c @@ -60,6 +60,8 @@ static int (*SDL_NAME(arts_stream_set))(arts_stream_t s, arts_parameter_t param, static int (*SDL_NAME(arts_stream_get))(arts_stream_t s, arts_parameter_t param); static int (*SDL_NAME(arts_write))(arts_stream_t s, const void *buffer, int count); static void (*SDL_NAME(arts_close_stream))(arts_stream_t s); +static int (*SDL_NAME(arts_suspended))(void); +static const char *(*SDL_NAME(arts_error_text))(int errorcode); static struct { const char *name; @@ -72,6 +74,8 @@ static struct { { "arts_stream_get", (void **)&SDL_NAME(arts_stream_get) }, { "arts_write", (void **)&SDL_NAME(arts_write) }, { "arts_close_stream", (void **)&SDL_NAME(arts_close_stream) }, + { "arts_suspended", (void **)&SDL_NAME(arts_suspended) }, + { "arts_error_text", (void **)&SDL_NAME(arts_error_text) }, }; static void UnloadARTSLibrary() @@ -127,14 +131,14 @@ static int Audio_Available(void) return available; } if ( SDL_NAME(arts_init)() == 0 ) { -#define ARTS_CRASH_HACK /* Play a stream so aRts doesn't crash */ -#ifdef ARTS_CRASH_HACK - arts_stream_t stream2; - stream2=SDL_NAME(arts_play_stream)(44100, 16, 2, "SDL"); - SDL_NAME(arts_write)(stream2, "", 0); - SDL_NAME(arts_close_stream)(stream2); -#endif - available = 1; + if ( SDL_NAME(arts_suspended)() ) { + /* Play a stream so aRts doesn't crash */ + arts_stream_t stream2; + stream2=SDL_NAME(arts_play_stream)(44100, 16, 2, "SDL"); + SDL_NAME(arts_write)(stream2, "", 0); + SDL_NAME(arts_close_stream)(stream2); + available = 1; + } SDL_NAME(arts_free)(); } UnloadARTSLibrary(); @@ -255,6 +259,7 @@ static int ARTS_OpenAudio(_THIS, SDL_AudioSpec *spec) { int bits, frag_spec; Uint16 test_format, format; + int error_code; /* Reset the timer synchronization flag */ frame_ticks = 0.0; @@ -292,8 +297,13 @@ static int ARTS_OpenAudio(_THIS, SDL_AudioSpec *spec) } spec->format = test_format; - if ( SDL_NAME(arts_init)() != 0 ) { - SDL_SetError("Unable to initialize ARTS"); + error_code = SDL_NAME(arts_init)(); + if ( error_code != 0 ) { + SDL_SetError("Unable to initialize ARTS: %s", SDL_NAME(arts_error_text)(error_code)); + return(-1); + } + if ( ! SDL_NAME(arts_suspended)() ) { + SDL_SetError("ARTS can not open audio device"); return(-1); } stream = SDL_NAME(arts_play_stream)(spec->freq, bits, spec->channels, "SDL"); From 22b2aca10eded6fd5e1783d6124da204632fa7aa Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 15 Jun 2007 05:21:33 +0000 Subject: [PATCH 114/241] Updated docs with bug fixes in subversion. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402348 --- WhatsNew | 4 +++ docs.html | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/WhatsNew b/WhatsNew index 5f6cea345..8538e93ac 100644 --- a/WhatsNew +++ b/WhatsNew @@ -3,6 +3,10 @@ This is a list of API changes in SDL's version history. Version 1.0: +1.2.12: + Added SDL_VIDEO_ALLOW_SCREENSAVER to override SDL's disabling + of the screensaver on Mac OS X and X11. + 1.2.10: If SDL_OpenAudio() is passed zero for the desired format fields, the following environment variables will be used diff --git a/docs.html b/docs.html index 8b00610c8..160fe1754 100644 --- a/docs.html +++ b/docs.html @@ -14,6 +14,104 @@ The latest stable release may be found on the

API Documentation

+

SDL 1.2.12 Release Notes

+

+SDL 1.2.12 is a minor bug fix release. +

+ +

General Notes

+ +
+

+ Added support for the PulseAudio sound server: http://www.pulseaudio.org/ +

+

+ Added SDL_VIDEO_ALLOW_SCREENSAVER to override SDL's disabling of the screensaver on Mac OS X and X11. +

+

+ Fixed buffer overrun crash when resampling audio rates. +

+

+ Fixed audio bug where converting to mono was doubling the volume. +

+

+ Fixed off-by-one error in the C implementation of SDL_revcpy() +

+

+ Support for AmigaOS has been removed from the main SDL code. +

+
+ +

Unix Notes

+ +
+

+ The GFX_Display has been added to the X11 window information in SDL_syswm.h. +

+

+ Fixed PAGE_SIZE compile error in the fbcon video driver on newer Linux kernels. +

+

+ Fixed hang or crash at startup if aRts can't access the hardware. +

+

+ Fixed relative mouse mode when the cursor starts outside the X11 window. +

+

+ Fixed accidental free of stack memory in X11 mouse acceleration code. +

+

+ Closed minor memory leak in XME code. +

+
+ +

Windows Notes

+ +
+

+ Added support for UTF-8 window titles on Windows. +

+

+ Fixed joystick detection on Windows. +

+

+ Fixed HBITMAP leak in GAPI driver. +

+
+ +

Mac OS X Notes

+ +
+

+ Added support for multi-axis controllers like 3Dconnxion's SpaceNavigator on Mac OS X. +

+

+ Fixed YUV overlay crash inside Quicktime on Intel Mac OS X. +

+

+ Fixed blitting alignment in Altivec alpha blit functions. +

+

+ Keys F13, F14, and F15 are now usable on Apple keyboards under Mac OS X. +

+

+ Fixed joystick calibration code on Mac OS X. +

+

+ Fixed mouse jitter when multiple motion events are queued up in Mac OS X. +

+
+ +

BeOS Notes

+ +
+

+ Implemented mouse grabbing and mouse relative mode on BeOS. +

+
+ +[separator] +

SDL 1.2.11 Release Notes

SDL 1.2.11 is a minor bug fix release. From 2a55f0a351652b2d79865ef2c17b58d5c7eadebb Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 15 Jun 2007 05:41:22 +0000 Subject: [PATCH 115/241] Don't install the extra SDL config headers or SDL_copying.h Fixes Bugzilla #361. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402349 --- Makefile.in | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile.in b/Makefile.in index 9b1112bfd..6d18f3791 100644 --- a/Makefile.in +++ b/Makefile.in @@ -40,6 +40,8 @@ SDLMAIN_OBJECTS = @SDLMAIN_OBJECTS@ DIST = acinclude.m4 autogen.sh Borland.html Borland.zip BUGS build-scripts configure configure.in COPYING CREDITS CWprojects.sea.bin docs docs.html EpocBuildFiles.zip include INSTALL Makefile.dc Makefile.minimal Makefile.in MPWmake.sea.bin README* sdl-config.in sdl.m4 sdl.pc.in SDL.qpg.in SDL.spec SDL.spec.in src test TODO VisualCE.zip VisualC.html VisualC.zip Watcom-OS2.zip Watcom-Win32.zip WhatsNew Xcode.tar.gz +HDRS = SDL.h SDL_active.h SDL_audio.h SDL_byteorder.h SDL_cdrom.h SDL_cpuinfo.h SDL_endian.h SDL_error.h SDL_events.h SDL_getenv.h SDL_joystick.h SDL_keyboard.h SDL_keysym.h SDL_loadso.h SDL_main.h SDL_mouse.h SDL_mutex.h SDL_name.h SDL_opengl.h SDL_platform.h SDL_quit.h SDL_rwops.h SDL_stdinc.h SDL_syswm.h SDL_thread.h SDL_timer.h SDL_types.h SDL_version.h SDL_video.h begin_code.h close_code.h + LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_RELEASE = @LT_RELEASE@ @@ -84,9 +86,8 @@ install-bin: $(INSTALL) -m 755 sdl-config $(bindir)/sdl-config install-hdrs: $(SHELL) $(auxdir)/mkinstalldirs $(includedir)/SDL - for src in $(srcdir)/include/*.h; do \ - file=`echo $$src | sed -e 's|^.*/||'`; \ - $(INSTALL) -m 644 $$src $(includedir)/SDL/$$file; \ + for file in $(HDRS); do \ + $(INSTALL) -m 644 $(srcdir)/include/$$file $(includedir)/SDL/$$file; \ done $(INSTALL) -m 644 include/SDL_config.h $(includedir)/SDL/SDL_config.h install-lib: @@ -110,8 +111,7 @@ uninstall: uninstall-bin uninstall-hdrs uninstall-lib uninstall-data uninstall-m uninstall-bin: rm -f $(bindir)/sdl-config uninstall-hdrs: - for src in $(srcdir)/include/*.h; do \ - file=`echo $$src | sed -e 's|^.*/||'`; \ + for file in $(HDRS); do \ rm -f $(includedir)/SDL/$$file; \ done rm -f $(includedir)/SDL/SDL_config.h From 51bddc2dc9fb2772195752fd9c4677006ecfb03f Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 15 Jun 2007 06:29:52 +0000 Subject: [PATCH 116/241] Support for Gamma Ramps on Mac OS Classic in both the macrom and macdsp video targets, thanks to Gregory Smith! Fixes Bugzilla #431. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402351 --- src/video/maccommon/SDL_macwm.c | 398 ++++++++++++++++++++++++++++++ src/video/maccommon/SDL_macwm_c.h | 13 + src/video/macdsp/SDL_dspvideo.c | 8 + src/video/macrom/SDL_romvideo.c | 8 + 4 files changed, 427 insertions(+) diff --git a/src/video/maccommon/SDL_macwm.c b/src/video/maccommon/SDL_macwm.c index 667774467..66828bfd9 100644 --- a/src/video/maccommon/SDL_macwm.c +++ b/src/video/maccommon/SDL_macwm.c @@ -30,6 +30,15 @@ #include #endif +#if SDL_MACCLASSIC_GAMMA_SUPPORT +#include +#include +#include +#include +#include +#include +#endif + #include "SDL_stdinc.h" #include "SDL_macwm_c.h" @@ -42,3 +51,392 @@ void Mac_SetCaption(_THIS, const char *title, const char *icon) if (SDL_Window) SetWTitle(SDL_Window, ptitle); /* MJS */ } + +#if SDL_MACCLASSIC_GAMMA_SUPPORT +/* + * ADC Gamma Ramp support... + * + * Mac Gamma Ramp code was originally from sample code provided by + * Apple Developer Connection, and not written specifically for SDL: + * "Contains: Functions to enable Mac OS device gamma adjustments using 3 channel 256 element 8 bit gamma ramps + * Written by: Geoff Stahl (ggs) + * Copyright: Copyright (c) 1999 Apple Computer, Inc., All Rights Reserved + * Disclaimer: You may incorporate this sample code into your applications without + * restriction, though the sample code has been provided "AS IS" and the + * responsibility for its operation is 100% yours. However, what you are + * not permitted to do is to redistribute the source as "DSC Sample Code" + * after having made changes. If you're going to re-distribute the source, + * we require that you make it clear in the source that the code was + * descended from Apple Sample Code, but that you've made changes." + * (The sample code has been integrated into this file, and thus is modified from the original Apple sources.) + */ + +typedef struct recDeviceGamma /* storage for device handle and gamma table */ +{ + GDHandle hGD; /* handle to device */ + GammaTblPtr pDeviceGamma; /* pointer to device gamma table */ +} recDeviceGamma; +typedef recDeviceGamma * precDeviceGamma; + +typedef struct recSystemGamma /* storage for system devices and gamma tables */ +{ + short numDevices; /* number of devices */ + precDeviceGamma * devGamma; /* array of pointers to device gamma records */ +} recSystemGamma; +typedef recSystemGamma * precSystemGamma; + +static Ptr CopyGammaTable (GammaTblPtr pTableGammaIn) +{ + GammaTblPtr pTableGammaOut = NULL; + short tableSize, dataWidth; + + if (pTableGammaIn) /* if there is a table to copy */ + { + dataWidth = (pTableGammaIn->gDataWidth + 7) / 8; /* number of bytes per entry */ + tableSize = sizeof (GammaTbl) + pTableGammaIn->gFormulaSize + + (pTableGammaIn->gChanCnt * pTableGammaIn->gDataCnt * dataWidth); + pTableGammaOut = (GammaTblPtr) NewPtr (tableSize); /* allocate new table */ + if (pTableGammaOut) + BlockMove( (Ptr)pTableGammaIn, (Ptr)pTableGammaOut, tableSize); /* move everything */ + } + return (Ptr)pTableGammaOut; /* return whatever we allocated, could be NULL */ +} + +static OSErr GetGammaTable (GDHandle hGD, GammaTblPtr * ppTableGammaOut) +{ + VDGammaRecord DeviceGammaRec; + CntrlParam cParam; + OSErr err; + + cParam.ioCompletion = NULL; /* set up control params */ + cParam.ioNamePtr = NULL; + cParam.ioVRefNum = 0; + cParam.ioCRefNum = (**hGD).gdRefNum; + cParam.csCode = cscGetGamma; /* Get Gamma commnd to device */ + *(Ptr *)cParam.csParam = (Ptr) &DeviceGammaRec; /* record for gamma */ + + err = PBStatusSync( (ParmBlkPtr)&cParam ); /* get gamma */ + + *ppTableGammaOut = (GammaTblPtr)(DeviceGammaRec.csGTable); /* pull table out of record */ + + return err; +} + +static Ptr GetDeviceGamma (GDHandle hGD) +{ + GammaTblPtr pTableGammaDevice = NULL; + GammaTblPtr pTableGammaReturn = NULL; + OSErr err; + + err = GetGammaTable (hGD, &pTableGammaDevice); /* get a pointer to the devices table */ + if ((noErr == err) && pTableGammaDevice) /* if succesful */ + pTableGammaReturn = (GammaTblPtr) CopyGammaTable (pTableGammaDevice); /* copy to global */ + + return (Ptr) pTableGammaReturn; +} + +static void DisposeGammaTable (Ptr pGamma) +{ + if (pGamma) + DisposePtr((Ptr) pGamma); /* get rid of it */ +} + +static void DisposeSystemGammas (Ptr* ppSystemGammas) +{ + precSystemGamma pSysGammaIn; + if (ppSystemGammas) + { + pSysGammaIn = (precSystemGamma) *ppSystemGammas; + if (pSysGammaIn) + { + short i; + for (i = 0; i < pSysGammaIn->numDevices; i++) /* for all devices */ + if (pSysGammaIn->devGamma [i]) /* if pointer is valid */ + { + DisposeGammaTable ((Ptr) pSysGammaIn->devGamma [i]->pDeviceGamma); /* dump gamma table */ + DisposePtr ((Ptr) pSysGammaIn->devGamma [i]); /* dump device info */ + } + DisposePtr ((Ptr) pSysGammaIn->devGamma); /* dump device pointer array */ + DisposePtr ((Ptr) pSysGammaIn); /* dump system structure */ + *ppSystemGammas = NULL; + } + } +} + +static Boolean GetDeviceGammaRampGD (GDHandle hGD, Ptr pRamp) +{ + GammaTblPtr pTableGammaTemp = NULL; + long indexChan, indexEntry; + OSErr err; + + if (pRamp) /* ensure pRamp is allocated */ + { + err = GetGammaTable (hGD, &pTableGammaTemp); /* get a pointer to the current gamma */ + if ((noErr == err) && pTableGammaTemp) /* if successful */ + { + /* fill ramp */ + unsigned char * pEntry = (unsigned char *) &pTableGammaTemp->gFormulaData + pTableGammaTemp->gFormulaSize; /* base of table */ + short bytesPerEntry = (pTableGammaTemp->gDataWidth + 7) / 8; /* size, in bytes, of the device table entries */ + short shiftRightValue = pTableGammaTemp->gDataWidth - 8; /* number of right shifts device -> ramp */ + short channels = pTableGammaTemp->gChanCnt; + short entries = pTableGammaTemp->gDataCnt; + if (3 == channels) /* RGB format */ + { /* note, this will create runs of entries if dest. is bigger (not linear interpolate) */ + for (indexChan = 0; indexChan < channels; indexChan++) + for (indexEntry = 0; indexEntry < 256; indexEntry++) + *((unsigned char *) pRamp + (indexChan * 256) + indexEntry) = + *(pEntry + indexChan * entries * bytesPerEntry + indexEntry * entries * bytesPerEntry / 256) >> shiftRightValue; + } + else /* single channel format */ + { + for (indexChan = 0; indexChan < 768; indexChan += 256) /* repeat for all 3 channels (step by ramp size) */ + for (indexEntry = 0; indexEntry < 256; indexEntry++) /* for all entries set vramp value */ + *((unsigned char *) pRamp + indexChan + indexEntry) = + *(pEntry + indexEntry * entries * bytesPerEntry / 256) >> shiftRightValue; + } + return true; + } + } + return false; +} + +static Ptr GetSystemGammas (void) +{ + precSystemGamma pSysGammaOut; /* return pointer to system device gamma info */ + short devCount = 0; /* number of devices attached */ + Boolean fail = false; + GDHandle hGDevice; + + pSysGammaOut = (precSystemGamma) NewPtr (sizeof (recSystemGamma)); /* allocate for structure */ + + hGDevice = GetDeviceList (); /* top of device list */ + do /* iterate */ + { + devCount++; /* count devices */ + hGDevice = GetNextDevice (hGDevice); /* next device */ + } while (hGDevice); + + pSysGammaOut->devGamma = (precDeviceGamma *) NewPtr (sizeof (precDeviceGamma) * devCount); /* allocate for array of pointers to device records */ + if (pSysGammaOut) + { + pSysGammaOut->numDevices = devCount; /* stuff count */ + + devCount = 0; /* reset iteration */ + hGDevice = GetDeviceList (); + do + { + pSysGammaOut->devGamma [devCount] = (precDeviceGamma) NewPtr (sizeof (recDeviceGamma)); /* new device record */ + if (pSysGammaOut->devGamma [devCount]) /* if we actually allocated memory */ + { + pSysGammaOut->devGamma [devCount]->hGD = hGDevice; /* stuff handle */ + pSysGammaOut->devGamma [devCount]->pDeviceGamma = (GammaTblPtr)GetDeviceGamma (hGDevice); /* copy gamma table */ + } + else /* otherwise dump record on exit */ + fail = true; + devCount++; /* next device */ + hGDevice = GetNextDevice (hGDevice); + } while (hGDevice); + } + if (!fail) /* if we did not fail */ + return (Ptr) pSysGammaOut; /* return pointer to structure */ + else + { + DisposeSystemGammas ((Ptr *) &pSysGammaOut); /* otherwise dump the current structures (dispose does error checking) */ + return NULL; /* could not complete */ + } +} + +static void RestoreDeviceGamma (GDHandle hGD, Ptr pGammaTable) +{ + VDSetEntryRecord setEntriesRec; + VDGammaRecord gameRecRestore; + CTabHandle hCTabDeviceColors; + Ptr csPtr; + OSErr err = noErr; + + if (pGammaTable) /* if we have a table to restore */ + { + gameRecRestore.csGTable = pGammaTable; /* setup restore record */ + csPtr = (Ptr) &gameRecRestore; + err = Control((**hGD).gdRefNum, cscSetGamma, (Ptr) &csPtr); /* restore gamma */ + + if ((noErr == err) && (8 == (**(**hGD).gdPMap).pixelSize)) /* if successful and on an 8 bit device */ + { + hCTabDeviceColors = (**(**hGD).gdPMap).pmTable; /* do SetEntries to force CLUT update */ + setEntriesRec.csTable = (ColorSpec *) &(**hCTabDeviceColors).ctTable; + setEntriesRec.csStart = 0; + setEntriesRec.csCount = (**hCTabDeviceColors).ctSize; + csPtr = (Ptr) &setEntriesRec; + + err = Control((**hGD).gdRefNum, cscSetEntries, (Ptr) &csPtr); /* SetEntries in CLUT */ + } + } +} + +static void RestoreSystemGammas (Ptr pSystemGammas) +{ + short i; + precSystemGamma pSysGammaIn = (precSystemGamma) pSystemGammas; + if (pSysGammaIn) + for (i = 0; i < pSysGammaIn->numDevices; i++) /* for all devices */ + RestoreDeviceGamma (pSysGammaIn->devGamma [i]->hGD, (Ptr) pSysGammaIn->devGamma [i]->pDeviceGamma); /* restore gamma */ +} + +static Ptr CreateEmptyGammaTable (short channels, short entries, short bits) +{ + GammaTblPtr pTableGammaOut = NULL; + short tableSize, dataWidth; + + dataWidth = (bits + 7) / 8; /* number of bytes per entry */ + tableSize = sizeof (GammaTbl) + (channels * entries * dataWidth); + pTableGammaOut = (GammaTblPtr) NewPtrClear (tableSize); /* allocate new tabel */ + + if (pTableGammaOut) /* if we successfully allocated */ + { + pTableGammaOut->gVersion = 0; /* set parameters based on input */ + pTableGammaOut->gType = 0; + pTableGammaOut->gFormulaSize = 0; + pTableGammaOut->gChanCnt = channels; + pTableGammaOut->gDataCnt = entries; + pTableGammaOut->gDataWidth = bits; + } + return (Ptr)pTableGammaOut; /* return whatever we allocated */ +} + +static Boolean SetDeviceGammaRampGD (GDHandle hGD, Ptr pRamp) +{ + VDSetEntryRecord setEntriesRec; + VDGammaRecord gameRecRestore; + GammaTblPtr pTableGammaNew; + GammaTblPtr pTableGammaCurrent = NULL; + CTabHandle hCTabDeviceColors; + Ptr csPtr; + OSErr err; + short dataBits, entries, channels = 3; /* force three channels in the gamma table */ + + if (pRamp) /* ensure pRamp is allocated */ + { + err= GetGammaTable (hGD, &pTableGammaCurrent); /* get pointer to current table */ + if ((noErr == err) && pTableGammaCurrent) + { + dataBits = pTableGammaCurrent->gDataWidth; /* table must have same data width */ + entries = pTableGammaCurrent->gDataCnt; /* table must be same size */ + pTableGammaNew = (GammaTblPtr) CreateEmptyGammaTable (channels, entries, dataBits); /* our new table */ + if (pTableGammaNew) /* if successful fill table */ + { + unsigned char * pGammaBase = (unsigned char *) &pTableGammaNew->gFormulaData + pTableGammaNew->gFormulaSize; /* base of table */ + if ((256 == entries) && (8 == dataBits)) /* simple case: direct mapping */ + BlockMove ((Ptr)pRamp, (Ptr)pGammaBase, channels * entries); /* move everything */ + else /* tough case handle entry, channel and data size disparities */ + { + short indexChan, indexEntry; + short bytesPerEntry = (dataBits + 7) / 8; /* size, in bytes, of the device table entries */ + short shiftRightValue = 8 - dataBits; /* number of right shifts ramp -> device */ + shiftRightValue += ((bytesPerEntry - 1) * 8); /* multibyte entries and the need to map a byte at a time most sig. to least sig. */ + for (indexChan = 0; indexChan < channels; indexChan++) /* for all the channels */ + for (indexEntry = 0; indexEntry < entries; indexEntry++) /* for all the entries */ + { + short currentShift = shiftRightValue; /* reset current bit shift */ + long temp = *((unsigned char *)pRamp + (indexChan << 8) + (indexEntry << 8) / entries); /* get data from ramp */ + short indexByte; + for (indexByte = 0; indexByte < bytesPerEntry; indexByte++) /* for all bytes */ + { + if (currentShift < 0) /* shift data correctly for current byte */ + *(pGammaBase++) = temp << -currentShift; + else + *(pGammaBase++) = temp >> currentShift; + currentShift -= 8; /* increment shift to align to next less sig. byte */ + } + } + } + + /* set gamma */ + gameRecRestore.csGTable = (Ptr) pTableGammaNew; /* setup restore record */ + csPtr = (Ptr) &gameRecRestore; + err = Control((**hGD).gdRefNum, cscSetGamma, (Ptr) &csPtr); /* restore gamma (note, display drivers may delay returning from this until VBL) */ + + if ((8 == (**(**hGD).gdPMap).pixelSize) && (noErr == err)) /* if successful and on an 8 bit device */ + { + hCTabDeviceColors = (**(**hGD).gdPMap).pmTable; /* do SetEntries to force CLUT update */ + setEntriesRec.csTable = (ColorSpec *) &(**hCTabDeviceColors).ctTable; + setEntriesRec.csStart = 0; + setEntriesRec.csCount = (**hCTabDeviceColors).ctSize; + csPtr = (Ptr) &setEntriesRec; + err = Control((**hGD).gdRefNum, cscSetEntries, (Ptr) &csPtr); /* SetEntries in CLUT */ + } + DisposeGammaTable ((Ptr) pTableGammaNew); /* dump table */ + if (noErr == err) + return true; + } + } + } + else /* set NULL gamma -> results in linear map */ + { + gameRecRestore.csGTable = (Ptr) NULL; /* setup restore record */ + csPtr = (Ptr) &gameRecRestore; + err = Control((**hGD).gdRefNum, cscSetGamma, (Ptr) &csPtr); /* restore gamma */ + + if ((8 == (**(**hGD).gdPMap).pixelSize) && (noErr == err)) /* if successful and on an 8 bit device */ + { + hCTabDeviceColors = (**(**hGD).gdPMap).pmTable; /* do SetEntries to force CLUT update */ + setEntriesRec.csTable = (ColorSpec *) &(**hCTabDeviceColors).ctTable; + setEntriesRec.csStart = 0; + setEntriesRec.csCount = (**hCTabDeviceColors).ctSize; + csPtr = (Ptr) &setEntriesRec; + err = Control((**hGD).gdRefNum, cscSetEntries, (Ptr) &csPtr); /* SetEntries in CLUT */ + } + if (noErr == err) + return true; + } + return false; /* memory allocation or device control failed if we get here */ +} + +/* end of ADC Gamma Ramp support code... */ + +static Ptr systemGammaPtr; + +void Mac_QuitGamma(_THIS) +{ + if (systemGammaPtr) + { + RestoreSystemGammas(systemGammaPtr); + DisposeSystemGammas(&systemGammaPtr); + } +} + +static unsigned char shiftedRamp[3 * 256]; + +int Mac_SetGammaRamp(_THIS, Uint16 *ramp) +{ + int i; + if (!systemGammaPtr) + systemGammaPtr = GetSystemGammas(); + for (i = 0; i < 3 * 256; i++) + { + shiftedRamp[i] = ramp[i] >> 8; + } + + if (SetDeviceGammaRampGD(GetMainDevice(), (Ptr) shiftedRamp)) + return 0; + else + return -1; +} + +int Mac_GetGammaRamp(_THIS, Uint16 *ramp) +{ + if (GetDeviceGammaRampGD(GetMainDevice(), (Ptr) shiftedRamp)) + { + int i; + for (i = 0; i < 3 * 256; i++) + { + ramp[i] = shiftedRamp[i] << 8; + } + return 0; + } + else + return -1; +} + +#endif /* SDL_MACCLASSIC_GAMMA_SUPPORT */ + + diff --git a/src/video/maccommon/SDL_macwm_c.h b/src/video/maccommon/SDL_macwm_c.h index 5f56b699d..5add86120 100644 --- a/src/video/maccommon/SDL_macwm_c.h +++ b/src/video/maccommon/SDL_macwm_c.h @@ -26,3 +26,16 @@ /* Functions to be exported */ extern void Mac_SetCaption(_THIS, const char *title, const char *icon); +/* + * There's no Carbonized gamma support in Mac OS X, since PBStatusSync() and + * Control() aren't supported in OS X's Carbonlib. Use the Quartz driver + * instead. + */ +#define SDL_MACCLASSIC_GAMMA_SUPPORT ((defined(__APPLE__) && defined(__MACH__)) == 0) + +#if SDL_MACCLASSIC_GAMMA_SUPPORT +extern void Mac_QuitGamma(_THIS); +extern int Mac_SetGammaRamp(_THIS, Uint16 *ramp); +extern int Mac_GetGammaRamp(_THIS, Uint16 *ramp); +#endif + diff --git a/src/video/macdsp/SDL_dspvideo.c b/src/video/macdsp/SDL_dspvideo.c index 060833fe6..ed3f8c48f 100644 --- a/src/video/macdsp/SDL_dspvideo.c +++ b/src/video/macdsp/SDL_dspvideo.c @@ -297,6 +297,10 @@ static SDL_VideoDevice *DSp_CreateDevice(int devindex) device->UnlockHWSurface = DSp_UnlockHWSurface; device->FlipHWSurface = DSp_FlipHWSurface; device->FreeHWSurface = DSp_FreeHWSurface; +#if SDL_MACCLASSIC_GAMMA_SUPPORT + device->SetGammaRamp = Mac_SetGammaRamp; + device->GetGammaRamp = Mac_GetGammaRamp; +#endif #if SDL_VIDEO_OPENGL device->GL_MakeCurrent = Mac_GL_MakeCurrent; device->GL_SwapBuffers = DSp_GL_SwapBuffers; @@ -1381,6 +1385,10 @@ void DSp_VideoQuit(_THIS) /* Free Palette and restore original */ DSp_DestroyPalette (this); +#if SDL_MACCLASSIC_GAMMA_SUPPORT + Mac_QuitGamma(this); +#endif + /* Free list of video modes */ if ( SDL_modelist != NULL ) { for ( i=0; SDL_modelist[i]; i++ ) { diff --git a/src/video/macrom/SDL_romvideo.c b/src/video/macrom/SDL_romvideo.c index 3113b206d..f0ab8dedc 100644 --- a/src/video/macrom/SDL_romvideo.c +++ b/src/video/macrom/SDL_romvideo.c @@ -158,6 +158,10 @@ static SDL_VideoDevice *ROM_CreateDevice(int devindex) device->UnlockHWSurface = ROM_UnlockHWSurface; device->FlipHWSurface = NULL; device->FreeHWSurface = ROM_FreeHWSurface; +#if SDL_MACCLASSIC_GAMMA_SUPPORT + device->SetGammaRamp = Mac_SetGammaRamp; + device->GetGammaRamp = Mac_GetGammaRamp; +#endif #if SDL_VIDEO_OPENGL device->GL_MakeCurrent = Mac_GL_MakeCurrent; device->GL_SwapBuffers = Mac_GL_SwapBuffers; @@ -725,6 +729,10 @@ void ROM_VideoQuit(_THIS) } RestoreDeviceClut(GetMainDevice()); +#if SDL_MACCLASSIC_GAMMA_SUPPORT + Mac_QuitGamma(this); +#endif + /* Free list of video modes */ if ( SDL_modelist != NULL ) { for ( i=0; SDL_modelist[i]; ++i ) { From 43816f49159d3e7328b42b8eabea1f2a5b2c3932 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 15 Jun 2007 06:49:14 +0000 Subject: [PATCH 117/241] Added docs for revision 3073 - Ryan, feel free to do this yourself, if you want. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402352 --- docs.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs.html b/docs.html index 160fe1754..21a22cffe 100644 --- a/docs.html +++ b/docs.html @@ -102,6 +102,14 @@ SDL 1.2.12 is a minor bug fix release.

+

Mac OS Classic Notes

+ +
+

+ Added support for gamma ramps to both toolbox and DrawSprocket video drivers. +

+
+

BeOS Notes

From 4c8d994db9edc40557370f030c50236991dfb516 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 15 Jun 2007 06:57:31 +0000 Subject: [PATCH 118/241] Clean up have-initialized resources in some failing edge cases. Maybe fixes Bugzilla #426. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402353 --- src/video/x11/SDL_x11video.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 28cf61007..63a2ad356 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -408,7 +408,7 @@ static void create_aux_windows(_THIS) } } - /* Setup the communication with the IM server */ + /* Setup the communication with the IM server */ SDL_IM = NULL; SDL_IC = NULL; @@ -483,6 +483,8 @@ static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat) */ GFX_Display = XOpenDisplay(display); if ( GFX_Display == NULL ) { + XCloseDisplay(SDL_Display); + SDL_Display = NULL; SDL_SetError("Couldn't open X11 display"); return(-1); } @@ -508,8 +510,13 @@ static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat) #endif /* NO_SHARED_MEMORY */ /* Get the available video modes */ - if(X11_GetVideoModes(this) < 0) + if(X11_GetVideoModes(this) < 0) { + XCloseDisplay(GFX_Display); + GFX_Display = NULL; + XCloseDisplay(SDL_Display); + SDL_Display = NULL; return -1; + } /* Determine the current screen size */ this->info.current_w = DisplayWidth(SDL_Display, SDL_Screen); From 1e4e38831883fbdf2cf583bd967f66d014d88e56 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 15 Jun 2007 07:19:05 +0000 Subject: [PATCH 119/241] Make sure __inline__ isn't defined before #defining it, since some compilers (like Sun Studio) have this as a predefined macro. Fixes Bugzilla #434. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402354 --- include/begin_code.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/begin_code.h b/include/begin_code.h index 40279337f..88fbc2f3d 100644 --- a/include/begin_code.h +++ b/include/begin_code.h @@ -123,7 +123,9 @@ #define SDL_INLINE_OKAY #else #if !defined(__MRC__) && !defined(_SGI_SOURCE) +#ifndef __inline__ #define __inline__ inline +#endif #define SDL_INLINE_OKAY #endif /* Not a funky compiler */ #endif /* Visual C++ */ From 65296278a35cecb36bc5e372452f93a3f318c282 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 15 Jun 2007 11:43:14 +0000 Subject: [PATCH 120/241] Added patch note for subversion revision 3076 --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402357 --- docs.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs.html b/docs.html index 21a22cffe..e12676a05 100644 --- a/docs.html +++ b/docs.html @@ -37,6 +37,9 @@ SDL 1.2.12 is a minor bug fix release.

Fixed off-by-one error in the C implementation of SDL_revcpy()

+

+ Fixed compiling with Sun Studio. +

Support for AmigaOS has been removed from the main SDL code.

From 92435d924ac527daa2181441faf1c0a782da8fc8 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 15 Jun 2007 12:26:29 +0000 Subject: [PATCH 121/241] Make sure to check for glu.h before enabling glX support. We don't directly need GLU, but SDL_opengl.h tries to include it, and it shows that the workstation is misconfigured or incompletely configured if just this one header is missing. Fixes Bugzilla #336. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402358 --- configure.in | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.in b/configure.in index 5d0e33ab7..f702c74f9 100644 --- a/configure.in +++ b/configure.in @@ -1550,6 +1550,7 @@ CheckOpenGLX11() AC_TRY_COMPILE([ #include #include + #include ],[ ],[ video_opengl=yes From 52001505d8e140041b5baf5b76c3b7373948530a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 15 Jun 2007 15:42:15 +0000 Subject: [PATCH 122/241] Removed EPOC port...it's being replaced by an updated Symbian port with the original author's blessing. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402360 --- EpocBuildFiles.zip | Bin 2012 -> 0 bytes README.Epoc | 75 ---- docs.html | 3 + src/thread/epoc/SDL_sysmutex.cpp | 105 ----- src/thread/epoc/SDL_syssem.cpp | 193 --------- src/thread/epoc/SDL_systhread.cpp | 124 ------ src/thread/epoc/SDL_systhread_c.h | 31 -- src/timer/epoc/SDL_systimer.cpp | 116 ----- src/video/epoc/SDL_epocevents.cpp | 419 ------------------ src/video/epoc/SDL_epocevents_c.h | 46 -- src/video/epoc/SDL_epocvideo.cpp | 697 ------------------------------ src/video/epoc/SDL_epocvideo.h | 90 ---- 12 files changed, 3 insertions(+), 1896 deletions(-) delete mode 100644 EpocBuildFiles.zip delete mode 100644 README.Epoc delete mode 100644 src/thread/epoc/SDL_sysmutex.cpp delete mode 100644 src/thread/epoc/SDL_syssem.cpp delete mode 100644 src/thread/epoc/SDL_systhread.cpp delete mode 100644 src/thread/epoc/SDL_systhread_c.h delete mode 100644 src/timer/epoc/SDL_systimer.cpp delete mode 100644 src/video/epoc/SDL_epocevents.cpp delete mode 100644 src/video/epoc/SDL_epocevents_c.h delete mode 100644 src/video/epoc/SDL_epocvideo.cpp delete mode 100644 src/video/epoc/SDL_epocvideo.h diff --git a/EpocBuildFiles.zip b/EpocBuildFiles.zip deleted file mode 100644 index 9de7244f97e583faca089e0a27331bc2b4c2aa18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2012 zcmZ{lc{mj69>?FoG#DDoIF=ksmNd30!c&p47Gh9@#MIbFmN5u1%5pNKaE;0oif}}h zLv~|3mSagIOJ(2JnJfw2$L-w9y-)Z3>wTa1`8@CQ{NC?^HD+Z)0sz>7<9$DQ5<%rx zTL3^L000I6xK6+;x!rVzvom54D?VI4Oay~_YI1CnbK?u#%A1R^#^%F9F3RVH>|!M8 z===gN@{^bG@+smAW6!Bi?11xxtn(B`gNG!UPnT?Qe@EeyZ^s!KSx}7mh@2<+B(DPO zf1ZyDsYVTOB!;g508$|UzySa*zPMWfZa0-YJ-zMY>G$tS@I-YDy;w%OAW}-q92JLB zX5LGPnN+1^$l&_OS&Ku;cRV|Mahuc6yh207&vvnfn_w){oKOJ7;` z#Frp*H*KYq`fq+Qn#&o6+w{@CO#K-9{_G>j$siWZzjCL#Ia?Lcl~dA<;u1QO_>f8X zRWD%f&|W@@E}ET+qQs6#Z*h!oSD}rx4zI0ZWBN9i?TyTZuRX;v9u>-4H#l1>pqi4r zCC6vK?E@5lzDF}po+ z+fGxpl=j|E25f&Y=VKz|hcg465?BBT;P~+`L_A?{C~?US#0)e~-LqMfTHUAL(gGHb zr5V{RVMQA|HO6E48*GV_pJm8F&vsjy&vjo<5>%_K{ismMaiP{sOib)Il~ovC_3;D2 zeqswn{K0JZ{H-PC&c_{l2Nm5b%p}3H#+f}){ws446JJ{7mYPCHsu9e4&$+Wxw~8G{ zOcquy$_H0RBJ+4PE#5+;;ukO@cFCvKsg@fgLU4OoagXp&*VE$0h_1o(Gx}@FVOrcD z>C4N>bo7eh=e~8q%vPN0HAyJu#?fL6H0{3W&USk4$vn$yHp!Ddt#7iRalsv4q0_wh ztQ-_nA&H5a(zhN_E8O;BWik&n*Mti@;1Y(pUR$&*xzipY9!vMePK3Y;RaL^LvCR@{ zmPI_+*Bt`cNRPHUu5`S?x)Vv@ifrrBY3VYm@UbqTJ6L#h9%EZp1a%&svoiSUN{PSl zYIDZo21%hkqm8^Im-9kN#OAWlBJU-GV3t;yV2c8nPwSgZfs)d+M1$0jioago|O8)Sj1xnWlB znK$Iv?qdtq!U8mXH^&QBZ63@W#mcaU+AKl&VrYfk@oZ)S9!bwZP<{sa9T9Uu8; zVtq0(1i4RfEryM2zs{c9mu-?=AF8R`rIa56!1&*Ow!{-I;(qwq6FcA@fkxgI+>VAb zd$!WhOsJL0s}X}sF%n4XhjPcuvHqd8Hd&q6$5iR*PsQG%FokxO1X(dXbIxfAX>U_G ze5g=4h7e7sxTQor-w1g>{+qn16xDU9$2y@QG*CUHPh*f(t+t`cdifoKecnOCv}di8=NsJE)SayQST?weMIZr#&ktrdLyK`HX^it(L=f*N0kY7rIR-+ z$YmLV#X>=U_~#gEorv6cQvUdn=$WWZO2g;WUygs8stCSg{_4;v1V zVSMSnnaQvUEy?(?Oi5=4j*)$i+OG=2>y4V&vAM+N;O5hPpI>2_NaD$74h^CuTdVQj3quS`A2RhI;X}6mbjZe z4|U`B`-^8}fFPo#^>Y0WOc(@f3}Hcn|6f>p3j!oSY53mm@A^6j{j6s8p|JlhorB=d zVt5}+fq;L9@ Support for AmigaOS has been removed from the main SDL code.

+

+ Support for Nokia 9210 "EPOC" driver has been removed from the main SDL code. +

Unix Notes

diff --git a/src/thread/epoc/SDL_sysmutex.cpp b/src/thread/epoc/SDL_sysmutex.cpp deleted file mode 100644 index 179201261..000000000 --- a/src/thread/epoc/SDL_sysmutex.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - SDL_sysmutex.cpp - - Epoc version by Markus Mertama (w@iki.fi) -*/ - - -/* Mutex functions using the Win32 API */ - -#include - -#include "SDL_error.h" -#include "SDL_mutex.h" - - - -struct SDL_mutex - { - TInt handle; - }; - -extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*); - -TInt NewMutex(const TDesC& aName, TAny* aPtr1, TAny*) - { - return ((RMutex*)aPtr1)->CreateGlobal(aName); - } - -/* Create a mutex */ -SDL_mutex *SDL_CreateMutex(void) -{ - RMutex rmutex; - - TInt status = CreateUnique(NewMutex, &rmutex, NULL); - if(status != KErrNone) - { - SDL_SetError("Couldn't create mutex"); - } - SDL_mutex* mutex = new /*(ELeave)*/ SDL_mutex; - mutex->handle = rmutex.Handle(); - return(mutex); -} - -/* Free the mutex */ -void SDL_DestroyMutex(SDL_mutex *mutex) -{ - if ( mutex ) - { - RMutex rmutex; - rmutex.SetHandle(mutex->handle); - rmutex.Signal(); - rmutex.Close(); - delete(mutex); - mutex = NULL; - } -} - -/* Lock the mutex */ -int SDL_mutexP(SDL_mutex *mutex) -{ - if ( mutex == NULL ) { - SDL_SetError("Passed a NULL mutex"); - return -1; - } - RMutex rmutex; - rmutex.SetHandle(mutex->handle); - rmutex.Wait(); - return(0); -} - -/* Unlock the mutex */ -int SDL_mutexV(SDL_mutex *mutex) -{ - if ( mutex == NULL ) { - SDL_SetError("Passed a NULL mutex"); - return -1; - } - RMutex rmutex; - rmutex.SetHandle(mutex->handle); - rmutex.Signal(); - return(0); -} diff --git a/src/thread/epoc/SDL_syssem.cpp b/src/thread/epoc/SDL_syssem.cpp deleted file mode 100644 index c3982d2df..000000000 --- a/src/thread/epoc/SDL_syssem.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - SDL_syssem.cpp - - Epoc version by Markus Mertama (w@iki.fi) -*/ - -/* Semaphore functions using the Win32 API */ - -#include - -#include "SDL_error.h" -#include "SDL_thread.h" - - -#define SDL_MUTEX_TIMEOUT -2 - -struct SDL_semaphore - { - TInt handle; - TInt count; - }; - -extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*); -extern TInt NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2); - -TInt NewSema(const TDesC& aName, TAny* aPtr1, TAny* aPtr2) - { - TInt value = *((TInt*) aPtr2); - return ((RSemaphore*)aPtr1)->CreateGlobal(aName, value); - } - -/* Create a semaphore */ -SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) -{ - RSemaphore s; - TInt status = CreateUnique(NewSema, &s, &initial_value); - if(status != KErrNone) - { - SDL_SetError("Couldn't create semaphore"); - } - SDL_semaphore* sem = new /*(ELeave)*/ SDL_semaphore; - sem->handle = s.Handle(); - sem->count = initial_value; - return(sem); -} - -/* Free the semaphore */ -void SDL_DestroySemaphore(SDL_sem *sem) -{ - if ( sem ) - { - RSemaphore sema; - sema.SetHandle(sem->handle); - sema.Signal(sema.Count()); - sema.Close(); - delete sem; - sem = NULL; - } -} - - - struct TInfo - { - TInfo(TInt aTime, TInt aHandle) : - iTime(aTime), iHandle(aHandle), iVal(0) {} - TInt iTime; - TInt iHandle; - TInt iVal; - }; - -TBool ThreadRun(TAny* aInfo) - { - TInfo* info = STATIC_CAST(TInfo*, aInfo); - User::After(info->iTime); - RSemaphore sema; - sema.SetHandle(info->iHandle); - sema.Signal(); - info->iVal = SDL_MUTEX_TIMEOUT; - return 0; - } - - - - -void _WaitAll(SDL_sem *sem) - { - //since SemTryWait may changed the counter. - //this may not be atomic, but hopes it works. - RSemaphore sema; - sema.SetHandle(sem->handle); - sema.Wait(); - while(sem->count < 0) - { - sema.Wait(); - } - } - -int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) -{ - if ( ! sem ) { - SDL_SetError("Passed a NULL sem"); - return -1; - } - - if ( timeout == SDL_MUTEX_MAXWAIT ) - { - _WaitAll(sem); - return SDL_MUTEX_MAXWAIT; - } - - - RThread thread; - - TInfo* info = new (ELeave)TInfo(timeout, sem->handle); - - TInt status = CreateUnique(NewThread, &thread, info); - - if(status != KErrNone) - return status; - - thread.Resume(); - - _WaitAll(sem); - - if(thread.ExitType() == EExitPending) - { - thread.Kill(SDL_MUTEX_TIMEOUT); - } - - thread.Close(); - - return info->iVal; -} - -int SDL_SemTryWait(SDL_sem *sem) -{ - if(sem->count > 0) - { - sem->count--; - } - return SDL_MUTEX_TIMEOUT; -} - -int SDL_SemWait(SDL_sem *sem) -{ - return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); -} - -/* Returns the current count of the semaphore */ -Uint32 SDL_SemValue(SDL_sem *sem) -{ - if ( ! sem ) { - SDL_SetError("Passed a NULL sem"); - return 0; - } - return sem->count; -} - -int SDL_SemPost(SDL_sem *sem) -{ - if ( ! sem ) { - SDL_SetError("Passed a NULL sem"); - return -1; - } - sem->count++; - RSemaphore sema; - sema.SetHandle(sem->handle); - sema.Signal(); - return 0; -} diff --git a/src/thread/epoc/SDL_systhread.cpp b/src/thread/epoc/SDL_systhread.cpp deleted file mode 100644 index 708f004dc..000000000 --- a/src/thread/epoc/SDL_systhread.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - SDL_systhread.cpp - Epoc thread management routines for SDL - - Epoc version by Markus Mertama (w@iki.fi) -*/ - - -extern "C" { -#undef NULL -#include "SDL_error.h" -#include "SDL_thread.h" -#include "../SDL_systhread.h" - }; - -#include - - -static int object_count; - -int RunThread(TAny* data) -{ - SDL_RunThread(data); - return(0); -} - - -TInt NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2) - { - return ((RThread*)(aPtr1))->Create(aName, - RunThread, - KDefaultStackSize, - NULL, - aPtr2); - } - -int CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny* aPtr1, TAny* aPtr2) - { - TBuf<16> name; - TInt status = KErrNone; - do - { - object_count++; - name.Format(_L("SDL_%x"), object_count); - status = aFunc(name, aPtr1, aPtr2); - } - while(status == KErrAlreadyExists); - return status; - } - - -int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) -{ - RThread rthread; - - TInt status = CreateUnique(NewThread, &rthread, args); - if (status != KErrNone) - { - delete(((RThread*)(thread->handle))); - thread->handle = NULL; - SDL_SetError("Not enough resources to create thread"); - return(-1); - } - rthread.Resume(); - thread->handle = rthread.Handle(); - return(0); -} - -void SDL_SYS_SetupThread(void) -{ - return; -} - -Uint32 SDL_ThreadID(void) -{ - RThread current; - TThreadId id = current.Id(); - return id; -} - -void SDL_SYS_WaitThread(SDL_Thread *thread) -{ - RUndertaker taker; - taker.Create(); - TRequestStatus status; - taker.Logon(status, thread->handle); - User::WaitForRequest(status); - taker.Close(); -} - -/* WARNING: This function is really a last resort. - * Threads should be signaled and then exit by themselves. - * TerminateThread() doesn't perform stack and DLL cleanup. - */ -void SDL_SYS_KillThread(SDL_Thread *thread) -{ - RThread rthread; - rthread.SetHandle(thread->handle); - rthread.Kill(0); - rthread.Close(); -} diff --git a/src/thread/epoc/SDL_systhread_c.h b/src/thread/epoc/SDL_systhread_c.h deleted file mode 100644 index 6f5fd943b..000000000 --- a/src/thread/epoc/SDL_systhread_c.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2004 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - SDL_systhread_c.h - - Epoc version by Markus Mertama (w@iki.fi) -*/ - -typedef int SYS_ThreadHandle; - diff --git a/src/timer/epoc/SDL_systimer.cpp b/src/timer/epoc/SDL_systimer.cpp deleted file mode 100644 index 413135c79..000000000 --- a/src/timer/epoc/SDL_systimer.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_TIMER_EPOC - -/* - SDL_systimer.cpp - - Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi) -*/ - -#include -#include - -extern "C" { -#include "SDL_error.h" -#include "SDL_thread.h" -#include "SDL_timer.h" -#include "../SDL_timer_c.h" - -static TUint start = 0; -static TInt tickPeriodMilliSeconds; - - -void SDL_StartTicks(void) -{ - /* Set first ticks value */ - start = User::TickCount(); - - TTimeIntervalMicroSeconds32 period; - TInt tmp = UserHal::TickPeriod(period); - tickPeriodMilliSeconds = period.Int() / 1000; -} - -Uint32 SDL_GetTicks(void) -{ - TUint deltaTics = User::TickCount() - start; - return(deltaTics * tickPeriodMilliSeconds); -} - -void SDL_Delay(Uint32 ms) -{ - - User::After(TTimeIntervalMicroSeconds32(ms*1000)); -} - -/* Data to handle a single periodic alarm */ -static int timer_alive = 0; -static SDL_Thread *timer = NULL; - -static int RunTimer(void *unused) -{ - Uint32 ms; - - while ( timer_alive ) { - if ( SDL_timer_running ) { - SDL_ThreadedTimerCheck(); - } - SDL_Delay(10); - } - return(0); -} - -/* This is only called if the event thread is not running */ -int SDL_SYS_TimerInit(void) -{ - timer_alive = 1; - timer = SDL_CreateThread(RunTimer, NULL); - if ( timer == NULL ) - return(-1); - return(SDL_SetTimerThreaded(1)); -} - -void SDL_SYS_TimerQuit(void) -{ - timer_alive = 0; - if ( timer ) { - SDL_WaitThread(timer, NULL); - timer = NULL; - } -} - -int SDL_SYS_StartTimer(void) -{ - SDL_SetError("Internal logic error: Epoc uses threaded timer"); - return(-1); -} - -void SDL_SYS_StopTimer(void) -{ - return; -} - -}; // extern "C" - -#endif /* SDL_TIMER_EPOC */ diff --git a/src/video/epoc/SDL_epocevents.cpp b/src/video/epoc/SDL_epocevents.cpp deleted file mode 100644 index f0e6945e3..000000000 --- a/src/video/epoc/SDL_epocevents.cpp +++ /dev/null @@ -1,419 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - SDL_epocevents.cpp - Handle the event stream, converting Epoc events into SDL events - - Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi) -*/ - - -#include -#undef NULL - -extern "C" { -#include "SDL_error.h" -#include "SDL_video.h" -#include "SDL_keysym.h" -#include "SDL_keyboard.h" -#include "SDL_timer.h" -#include "../../events/SDL_events_c.h" -}; /* extern "C" */ - -#include "SDL_epocvideo.h" -#include "SDL_epocevents_c.h" - -#include - -extern "C" { -/* The translation tables from a console scancode to a SDL keysym */ -static SDLKey keymap[MAX_SCANCODE]; -static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym); -}; /* extern "C" */ - -TBool isCursorVisible = ETrue; - -int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent) -{ - int posted = 0; - SDL_keysym keysym; - - - switch (aWsEvent.Type()) { - - case EEventPointer: /* Mouse pointer events */ - { - const TPointerEvent* pointerEvent = aWsEvent.Pointer(); - TPoint mousePos = pointerEvent->iPosition; - - //SDL_TRACE1("SDL: EPOC_HandleWsEvent, pointerEvent->iType=%d", pointerEvent->iType); //!! - - if (Private->EPOC_ShrinkedHeight) { - mousePos.iY <<= 1; /* Scale y coordinate to shrinked screen height */ - } - posted += SDL_PrivateMouseMotion(0, 0, mousePos.iX, mousePos.iY); /* Absolute position on screen */ - if (pointerEvent->iType==TPointerEvent::EButton1Down) { - posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0); - } - else if (pointerEvent->iType==TPointerEvent::EButton1Up) { - posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0); - } - else if (pointerEvent->iType==TPointerEvent::EButton2Down) { - posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0); - } - else if (pointerEvent->iType==TPointerEvent::EButton2Up) { - posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0); - } - //!!posted += SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(aWsEvent.Key()->iScanCode, &keysym)); - break; - } - - case EEventKeyDown: /* Key events */ - { - (void*)TranslateKey(aWsEvent.Key()->iScanCode, &keysym); - - /* Special handling */ - switch((int)keysym.sym) { - case SDLK_CAPSLOCK: - if (!isCursorVisible) { - /* Enable virtual cursor */ - HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible); - } - else { - /* Disable virtual cursor */ - HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible); - } - isCursorVisible = !isCursorVisible; - break; - } - - posted += SDL_PrivateKeyboard(SDL_PRESSED, &keysym); - break; - } - - case EEventKeyUp: /* Key events */ - { - posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(aWsEvent.Key()->iScanCode, &keysym)); - break; - } - - case EEventFocusGained: /* SDL window got focus */ - { - //Private->EPOC_IsWindowFocused = ETrue; - /* Draw window background and screen buffer */ - RedrawWindowL(_this); - break; - } - - case EEventFocusLost: /* SDL window lost focus */ - { - //Private->EPOC_IsWindowFocused = EFalse; - - // Wait and eat events until focus is gained again - /* - while (ETrue) { - Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus); - User::WaitForRequest(Private->EPOC_WsEventStatus); - Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent); - TInt eventType = Private->EPOC_WsEvent.Type(); - Private->EPOC_WsEventStatus = KRequestPending; - //Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus); - if (eventType == EEventFocusGained) { - RedrawWindowL(_this); - break; - } - } - */ - break; - } - - case EEventModifiersChanged: - { - TModifiersChangedEvent* modEvent = aWsEvent.ModifiersChanged(); - TUint modstate = KMOD_NONE; - if (modEvent->iModifiers == EModifierLeftShift) - modstate |= KMOD_LSHIFT; - if (modEvent->iModifiers == EModifierRightShift) - modstate |= KMOD_RSHIFT; - if (modEvent->iModifiers == EModifierLeftCtrl) - modstate |= KMOD_LCTRL; - if (modEvent->iModifiers == EModifierRightCtrl) - modstate |= KMOD_RCTRL; - if (modEvent->iModifiers == EModifierLeftAlt) - modstate |= KMOD_LALT; - if (modEvent->iModifiers == EModifierRightAlt) - modstate |= KMOD_RALT; - if (modEvent->iModifiers == EModifierLeftFunc) - modstate |= KMOD_LMETA; - if (modEvent->iModifiers == EModifierRightFunc) - modstate |= KMOD_RMETA; - if (modEvent->iModifiers == EModifierCapsLock) - modstate |= KMOD_CAPS; - SDL_SetModState(STATIC_CAST(SDLMod,(modstate | KMOD_LSHIFT))); - break; - } - default: - break; - } - - return posted; -} - -extern "C" { - -void EPOC_PumpEvents(_THIS) -{ - int posted = 0; // !! Do we need this? - //Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus); - while (Private->EPOC_WsEventStatus != KRequestPending) { - - Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent); - posted = EPOC_HandleWsEvent(_this, Private->EPOC_WsEvent); - Private->EPOC_WsEventStatus = KRequestPending; - Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus); - } -} - - -void EPOC_InitOSKeymap(_THIS) -{ - int i; - - /* Initialize the key translation table */ - for ( i=0; iscancode = scancode; - - if ((scancode >= MAX_SCANCODE) && - ((scancode - ENonCharacterKeyBase + 0x0081) >= MAX_SCANCODE)) { - SDL_SetError("Too big scancode"); - keysym->scancode = SDLK_UNKNOWN; - keysym->mod = KMOD_NONE; - return keysym; - } - - keysym->mod = SDL_GetModState(); //!!Is this right?? - - /* Handle function keys: F1, F2, F3 ... */ - if (keysym->mod & KMOD_META) { - if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphapet keys */ - switch(scancode) { - case 'Q': scancode = EStdKeyF1; break; - case 'W': scancode = EStdKeyF2; break; - case 'E': scancode = EStdKeyF3; break; - case 'R': scancode = EStdKeyF4; break; - case 'T': scancode = EStdKeyF5; break; - case 'Y': scancode = EStdKeyF6; break; - case 'U': scancode = EStdKeyF7; break; - case 'I': scancode = EStdKeyF8; break; - case 'A': scancode = EStdKeyF9; break; - case 'S': scancode = EStdKeyF10; break; - case 'D': scancode = EStdKeyF11; break; - case 'F': scancode = EStdKeyF12; break; - } - keysym->sym = keymap[scancode]; - } - } - - if (scancode >= ENonCharacterKeyBase) { - // Non character keys - keysym->sym = keymap[scancode - - ENonCharacterKeyBase + 0x0081]; // !!hard coded - } else { - keysym->sym = keymap[scancode]; - } - - - /* If UNICODE is on, get the UNICODE value for the key */ - keysym->unicode = 0; - -#if 0 // !!TODO:unicode - - if ( SDL_TranslateUNICODE ) - { - /* Populate the unicode field with the ASCII value */ - keysym->unicode = scancode; - } -#endif - - //!! - //sprintf(debug, "SDL: TranslateKey: keysym->scancode=%d, keysym->sym=%d, keysym->mod=%d", - // keysym->scancode, keysym->sym, keysym->mod); - //SDL_TRACE(debug); //!! - - return(keysym); -} - -}; /* extern "C" */ - - diff --git a/src/video/epoc/SDL_epocevents_c.h b/src/video/epoc/SDL_epocevents_c.h deleted file mode 100644 index 8455c153b..000000000 --- a/src/video/epoc/SDL_epocevents_c.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - SDL_epocevents_c.h - Handle the event stream, converting Epoc events into SDL events - - Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi) -*/ - - -extern "C" { -#include "../SDL_sysvideo.h" -}; - -#define MAX_SCANCODE 255 - -/* Variables and functions exported by SDL_sysevents.c to other parts - of the native video subsystem (SDL_sysvideo.c) -*/ - -extern "C" { -extern void EPOC_InitOSKeymap(_THIS); -extern void EPOC_PumpEvents(_THIS); -}; - diff --git a/src/video/epoc/SDL_epocvideo.cpp b/src/video/epoc/SDL_epocvideo.cpp deleted file mode 100644 index 3694f467f..000000000 --- a/src/video/epoc/SDL_epocvideo.cpp +++ /dev/null @@ -1,697 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - SDL_epocvideo.cpp - Epoc based SDL video driver implementation - - Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi) -*/ - -extern "C" { -#include "SDL_timer.h" -#include "SDL_video.h" -#undef NULL -#include "../SDL_pixels_c.h" -}; - -#include "SDL_epocvideo.h" -#include "SDL_epocevents_c.h" - -#include -#include - -/* For debugging */ - -void RDebug_Print_b(char* error_str, void* param) - { - TBuf8<128> error8((TUint8*)error_str); - TBuf<128> error; - error.Copy(error8); - if (param) //!! Do not work if the parameter is really 0!! - RDebug::Print(error, param); - else - RDebug::Print(error); - } - -extern "C" void RDebug_Print(char* error_str, void* param) - { - RDebug_Print_b(error_str, param); - } - - -int Debug_AvailMem2() - { - //User::CompressAllHeaps(); - TMemoryInfoV1Buf membuf; - User::LeaveIfError(UserHal::MemoryInfo(membuf)); - TMemoryInfoV1 minfo = membuf(); - return(minfo.iFreeRamInBytes); - } - -extern "C" int Debug_AvailMem() - { - return(Debug_AvailMem2()); - } - - -extern "C" { - -/* Initialization/Query functions */ - -static int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat); -static SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); -static SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); -static int EPOC_SetColors(_THIS, int firstcolor, int ncolors, - SDL_Color *colors); -static void EPOC_VideoQuit(_THIS); - -/* Hardware surface functions */ - -static int EPOC_AllocHWSurface(_THIS, SDL_Surface *surface); -static int EPOC_LockHWSurface(_THIS, SDL_Surface *surface); -static int EPOC_FlipHWSurface(_THIS, SDL_Surface *surface); -static void EPOC_UnlockHWSurface(_THIS, SDL_Surface *surface); -static void EPOC_FreeHWSurface(_THIS, SDL_Surface *surface); -static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); - -static int EPOC_Available(void); -static SDL_VideoDevice *EPOC_CreateDevice(int devindex); - -/* Mouse functions */ - -static WMcursor *EPOC_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); -static void EPOC_FreeWMCursor(_THIS, WMcursor *cursor); -static int EPOC_ShowWMCursor(_THIS, WMcursor *cursor); - - - -/* !! Table for fast conversion from 8 bit to 12 bit */ -static TUint16 EPOC_HWPalette_256_to_4k[256]; - -VideoBootStrap EPOC_bootstrap = { - "epoc", "EPOC system", - EPOC_Available, EPOC_CreateDevice -}; - -const TUint32 WindowClientHandle = 9210; //!! - -/* Epoc video driver bootstrap functions */ - -static int EPOC_Available(void) -{ - return 1; /* Always available */ -} - -static void EPOC_DeleteDevice(SDL_VideoDevice *device) -{ - SDL_free(device->hidden); - SDL_free(device); -} - -static SDL_VideoDevice *EPOC_CreateDevice(int devindex) -{ - SDL_VideoDevice *device; - - /* Allocate all variables that we free on delete */ - device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); - if ( device ) { - SDL_memset(device, 0, (sizeof *device)); - device->hidden = (struct SDL_PrivateVideoData *) - SDL_malloc((sizeof *device->hidden)); - } - if ( (device == NULL) || (device->hidden == NULL) ) { - SDL_OutOfMemory(); - if ( device ) { - SDL_free(device); - } - return(0); - } - SDL_memset(device->hidden, 0, (sizeof *device->hidden)); - - /* Set the function pointers */ - device->VideoInit = EPOC_VideoInit; - device->ListModes = EPOC_ListModes; - device->SetVideoMode = EPOC_SetVideoMode; - device->SetColors = EPOC_SetColors; - device->UpdateRects = NULL; - device->VideoQuit = EPOC_VideoQuit; - device->AllocHWSurface = EPOC_AllocHWSurface; - device->CheckHWBlit = NULL; - device->FillHWRect = NULL; - device->SetHWColorKey = NULL; - device->SetHWAlpha = NULL; - device->LockHWSurface = EPOC_LockHWSurface; - device->UnlockHWSurface = EPOC_UnlockHWSurface; - device->FlipHWSurface = EPOC_FlipHWSurface; - device->FreeHWSurface = EPOC_FreeHWSurface; - device->SetIcon = NULL; - device->SetCaption = NULL; - device->GetWMInfo = NULL; - device->FreeWMCursor = EPOC_FreeWMCursor; - device->CreateWMCursor = EPOC_CreateWMCursor; - device->ShowWMCursor = EPOC_ShowWMCursor; - device->WarpWMCursor = NULL; - device->InitOSKeymap = EPOC_InitOSKeymap; - device->PumpEvents = EPOC_PumpEvents; - device->free = EPOC_DeleteDevice; - - return device; -} - - -int GetBpp(TDisplayMode displaymode) -{ - TInt numColors = TDisplayModeUtils::NumDisplayModeColors(displaymode); - TInt bitsPerPixel = 1; - for (TInt32 i = 2; i < numColors; i <<= 1, bitsPerPixel++); - return bitsPerPixel; -} - -void ConstructWindowL(_THIS) -{ - TInt error; - - error = Private->EPOC_WsSession.Connect(); - User::LeaveIfError(error); - Private->EPOC_WsScreen=new(ELeave) CWsScreenDevice(Private->EPOC_WsSession); - User::LeaveIfError(Private->EPOC_WsScreen->Construct()); - User::LeaveIfError(Private->EPOC_WsScreen->CreateContext(Private->EPOC_WindowGc)); - - Private->EPOC_WsWindowGroup=RWindowGroup(Private->EPOC_WsSession); - User::LeaveIfError(Private->EPOC_WsWindowGroup.Construct(WindowClientHandle)); - Private->EPOC_WsWindowGroup.SetOrdinalPosition(0); - - //!! - TBuf<32> winGroupName; - winGroupName.Append(0); - winGroupName.Append(0); - winGroupName.Append(0);// uid - winGroupName.Append(0); - winGroupName.Append(_L("SDL")); // caption - winGroupName.Append(0); - winGroupName.Append(0); //doc name - Private->EPOC_WsWindowGroup.SetName(winGroupName); //!! - - Private->EPOC_WsWindow=RWindow(Private->EPOC_WsSession); - User::LeaveIfError(Private->EPOC_WsWindow.Construct(Private->EPOC_WsWindowGroup,WindowClientHandle)); - Private->EPOC_WsWindow.SetBackgroundColor(KRgbWhite); - Private->EPOC_WsWindow.Activate(); - Private->EPOC_WsWindow.SetSize(Private->EPOC_WsScreen->SizeInPixels()); - Private->EPOC_WsWindow.SetVisible(ETrue); - - Private->EPOC_WsWindowGroupID = Private->EPOC_WsWindowGroup.Identifier(); - Private->EPOC_IsWindowFocused = EFalse; -} - - -int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat) -{ - // !!TODO:handle leave functions! - - int i; - - /* Initialize all variables that we clean on shutdown */ - - for ( i=0; iSDL_modelist[i] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); - Private->SDL_modelist[i]->x = Private->SDL_modelist[i]->y = 0; - } - /* Modes sorted largest to smallest !!TODO:sorting order??*/ - Private->SDL_modelist[0]->w = 640; Private->SDL_modelist[0]->h = 200; - Private->SDL_modelist[1]->w = 320; Private->SDL_modelist[1]->h = 200; - Private->SDL_modelist[2]->w = 640; Private->SDL_modelist[2]->h = 400; - Private->SDL_modelist[3]->w = 640; Private->SDL_modelist[3]->h = 480; - Private->SDL_modelist[4] = NULL; - - /* Construct Epoc window */ - - ConstructWindowL(_this); - - /* Initialise Epoc frame buffer */ - - TDisplayMode displayMode = Private->EPOC_WsScreen->DisplayMode(); - - #ifndef __WINS__ - - TScreenInfoV01 screenInfo; - TPckg sInfo(screenInfo); - UserSvr::ScreenInfo(sInfo); - - Private->EPOC_ScreenSize = screenInfo.iScreenSize; - Private->EPOC_DisplayMode = displayMode; - Private->EPOC_HasFrameBuffer = screenInfo.iScreenAddressValid; - Private->EPOC_FrameBuffer = Private->EPOC_HasFrameBuffer ? (TUint8*) screenInfo.iScreenAddress : NULL; - Private->EPOC_BytesPerPixel = ((GetBpp(displayMode)-1) / 8) + 1; - Private->EPOC_BytesPerScanLine = screenInfo.iScreenSize.iWidth * Private->EPOC_BytesPerPixel; - - /* It seems that in SA1100 machines for 8bpp displays there is a 512 palette table at the - * beginning of the frame buffer. E.g. Series 7 and Netbook. - * In 12 bpp machines the table has 16 entries. - */ - if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 8) - Private->EPOC_FrameBuffer += 512; - if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 12) - Private->EPOC_FrameBuffer += 16 * 2; - - #else /* defined __WINS__ */ - - /* Create bitmap, device and context for screen drawing */ - Private->EPOC_ScreenSize = Private->EPOC_WsScreen->SizeInPixels(); - - Private->EPOC_Bitmap = new (ELeave) CWsBitmap(Private->EPOC_WsSession); - Private->EPOC_Bitmap->Create(Private->EPOC_ScreenSize, displayMode); - - Private->EPOC_DisplayMode = displayMode; - Private->EPOC_HasFrameBuffer = ETrue; - Private->EPOC_FrameBuffer = NULL; /* Private->EPOC_Bitmap->DataAddress() can change any time */ - Private->EPOC_BytesPerPixel = ((GetBpp(displayMode)-1) / 8) + 1; - Private->EPOC_BytesPerScanLine = Private->EPOC_WsScreen->SizeInPixels().iWidth * Private->EPOC_BytesPerPixel; - - #endif /* __WINS__ */ - - _this->info.current_w = Private->EPOC_ScreenSize.iWidth; - _this->info.current_h = Private->EPOC_ScreenSize.iHeight; - - /* The "best" video format should be returned to caller. */ - - vformat->BitsPerPixel = /*!!GetBpp(displayMode) */ 8; - vformat->BytesPerPixel = /*!!Private->EPOC_BytesPerPixel*/ 1; - - /* Activate events for me */ - - Private->EPOC_WsEventStatus = KRequestPending; - Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus); - Private->EPOC_RedrawEventStatus = KRequestPending; - Private->EPOC_WsSession.RedrawReady(&Private->EPOC_RedrawEventStatus); - Private->EPOC_WsWindow.PointerFilter(EPointerFilterDrag, 0); - - Private->EPOC_ScreenOffset = 0; - - //!! TODO: error handling - //if (ret != KErrNone) - // return(-1); - //else - return(0); -} - - -SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) -{ - if (format->BitsPerPixel == 12 || format->BitsPerPixel == 8) - return Private->SDL_modelist; - return NULL; -} - -int EPOC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) -{ - for(int i = firstcolor; i < ncolors; i++) { - // 4k value: 000rgb - TUint16 color4K = 0; - color4K |= (colors[i].r & 0x0000f0) << 4; - color4K |= (colors[i].g & 0x0000f0); - color4K |= (colors[i].b & 0x0000f0) >> 4; - EPOC_HWPalette_256_to_4k[i] = color4K; - } - return(0); -} - - -SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current, - int width, int height, int bpp, Uint32 flags) -{ - /* Check parameters */ - if (!((width == 640 && height == 200 && bpp == 12) || - (width == 640 && height == 400 && bpp == 12) || - (width == 640 && height == 480 && bpp == 12) || - (width == 320 && height == 200 && bpp == 12) || - (width == 640 && height == 200 && bpp == 8) || - (width == 640 && height == 400 && bpp == 8) || - (width == 640 && height == 480 && bpp == 8) || - (width == 320 && height == 200 && bpp == 8))) { - SDL_SetError("Requested video mode is not supported"); - return NULL; - } - - if (current && current->pixels) { - SDL_free(current->pixels); - current->pixels = NULL; - } - if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) { - return(NULL); - } - - /* Set up the new mode framebuffer */ - if (bpp == 8) - current->flags = (SDL_FULLSCREEN|SDL_SWSURFACE|SDL_PREALLOC|SDL_HWPALETTE); - else // 12 bpp - current->flags = (SDL_FULLSCREEN|SDL_SWSURFACE|SDL_PREALLOC); - current->w = width; - current->h = height; - int numBytesPerPixel = ((bpp-1)>>3) + 1; - current->pitch = numBytesPerPixel * width; // Number of bytes in scanline - current->pixels = SDL_malloc(width * height * numBytesPerPixel); - SDL_memset(current->pixels, 0, width * height * numBytesPerPixel); - - /* Set the blit function */ - _this->UpdateRects = EPOC_DirectUpdate; - - /* Must buffer height be shrinked to screen by 2 ? */ - if (current->h >= 400) - Private->EPOC_ShrinkedHeight = ETrue; - - /* Centralize game window on device screen */ - Private->EPOC_ScreenOffset = (Private->EPOC_ScreenSize.iWidth - current->w) / 2; - - /* We're done */ - return(current); -} - -void RedrawWindowL(_THIS) -{ - SDL_Rect fullScreen; - fullScreen.x = 0; - fullScreen.y = 0; - fullScreen.w = _this->screen->w; - fullScreen.h = _this->screen->h; - -#ifdef __WINS__ - TBitmapUtil lock(Private->EPOC_Bitmap); - lock.Begin(TPoint(0,0)); // Lock bitmap heap - Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow); -#endif - - if (fullScreen.w < Private->EPOC_ScreenSize.iWidth - && fullScreen.w < Private->EPOC_ScreenSize.iWidth) { - /* Draw blue stripes background */ -#ifdef __WINS__ - TUint16* screenBuffer = (TUint16*)Private->EPOC_Bitmap->DataAddress(); -#else - TUint16* screenBuffer = (TUint16*)Private->EPOC_FrameBuffer; -#endif - for (int y=0; y < Private->EPOC_ScreenSize.iHeight; y++) { - for (int x=0; x < Private->EPOC_ScreenSize.iWidth; x++) { - TUint16 color = ((x+y)>>1) & 0xf; /* Draw pattern */ - *screenBuffer++ = color; - } - } - } - - - /* Tell the system that something has been drawn */ - TRect rect = TRect(Private->EPOC_WsWindow.Size()); - Private->EPOC_WsWindow.Invalidate(rect); - -#ifdef __WINS__ - Private->EPOC_WsWindow.BeginRedraw(rect); - Private->EPOC_WindowGc->BitBlt(TPoint(), Private->EPOC_Bitmap); - Private->EPOC_WsWindow.EndRedraw(); - Private->EPOC_WindowGc->Deactivate(); - lock.End(); // Unlock bitmap heap - Private->EPOC_WsSession.Flush(); -#endif - - /* Draw current buffer */ - EPOC_DirectUpdate(_this, 1, &fullScreen); -} - - -/* We don't actually allow hardware surfaces other than the main one */ -static int EPOC_AllocHWSurface(_THIS, SDL_Surface *surface) -{ - return(-1); -} -static void EPOC_FreeHWSurface(_THIS, SDL_Surface *surface) -{ - return; -} - -static int EPOC_LockHWSurface(_THIS, SDL_Surface *surface) -{ - return(0); -} -static void EPOC_UnlockHWSurface(_THIS, SDL_Surface *surface) -{ - return; -} - -static int EPOC_FlipHWSurface(_THIS, SDL_Surface *surface) -{ - return(0); -} - -static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) -{ - TInt focusWindowGroupId = Private->EPOC_WsSession.GetFocusWindowGroup(); - if (focusWindowGroupId != Private->EPOC_WsWindowGroupID) { - - /* Force focus window to redraw again for cleaning away SDL screen graphics */ - - - TInt pos = Private->EPOC_WsWindowGroup.OrdinalPosition(); - Private->EPOC_WsWindowGroup.SetOrdinalPosition(0, KMaxTInt); - TRect rect = TRect(Private->EPOC_WsWindow.Size()); - Private->EPOC_WsWindow.Invalidate(rect); - Private->EPOC_WsWindowGroup.SetOrdinalPosition(pos, ECoeWinPriorityNormal); - - /* If this is not the topmost window, wait here! Sleep for 1 second to give cpu to - multitasking and poll for being the topmost window. - */ - while (Private->EPOC_WsSession.GetFocusWindowGroup() != Private->EPOC_WsWindowGroupID) - SDL_Delay(1000); - - RedrawWindowL(_this); - } - - TInt i; - TInt sourceNumBytesPerPixel = ((_this->screen->format->BitsPerPixel-1)>>3) + 1; - TInt targetNumBytesPerPixel = Private->EPOC_BytesPerPixel; - TInt fixedOffset = Private->EPOC_ScreenOffset; - TInt screenW = _this->screen->w; - TInt screenH = _this->screen->h; - TInt sourceScanlineLength = screenW; - if (Private->EPOC_ShrinkedHeight) { /* simulate 400 pixel height in 200 pixel screen */ - sourceScanlineLength <<= 1; - screenH >>= 1; - } - TInt targetScanlineLength = Private->EPOC_ScreenSize.iWidth; -#ifdef __WINS__ - TBitmapUtil lock(Private->EPOC_Bitmap); - lock.Begin(TPoint(0,0)); // Lock bitmap heap - Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow); - TUint16* screenBuffer = (TUint16*)Private->EPOC_Bitmap->DataAddress(); -#else - TUint16* screenBuffer = (TUint16*)Private->EPOC_FrameBuffer; -#endif - - - /* Render the rectangles in the list */ - - for ( i=0; i < numrects; ++i ) { - SDL_Rect rect2; - const SDL_Rect& currentRect = rects[i]; - rect2.x = currentRect.x; - rect2.y = currentRect.y; - rect2.w = currentRect.w; - rect2.h = currentRect.h; - - if (rect2.w <= 0 || rect2.h <= 0) /* sanity check */ - continue; - - if (Private->EPOC_ShrinkedHeight) { /* simulate 400 pixel height in 200 pixel screen */ - rect2.y >>= 1; - if (!(rect2.h >>= 1)) - rect2.h = 1; // always at least 1 pixel height! - } - - /* All variables are measured in pixels */ - - /* Check rects validity, i.e. upper and lower bounds */ - TInt maxX = Min(screenW - 1, rect2.x + rect2.w - 1); - TInt maxY = Min(screenH - 1, rect2.y + rect2.h - 1); - if (maxX < 0 || maxY < 0) /* sanity check */ - continue; - maxY = Min(maxY, 199); - - TInt sourceRectWidth = maxX - rect2.x + 1; - TInt sourceRectWidthInBytes = sourceRectWidth * sourceNumBytesPerPixel; - TInt sourceRectHeight = maxY - rect2.y + 1; - TInt sourceStartOffset = rect2.x + rect2.y * sourceScanlineLength; - TInt targetStartOffset = fixedOffset + rect2.x + rect2.y * targetScanlineLength; - - // !! Nokia9210 native mode: 12 bpp --> 12 bpp - if (_this->screen->format->BitsPerPixel == 12) { - TUint16* bitmapLine = (TUint16*)_this->screen->pixels + sourceStartOffset; - TUint16* screenMemory = screenBuffer + targetStartOffset; - for(TInt y = 0 ; y < sourceRectHeight ; y++) { - __ASSERT_DEBUG(screenMemory < (screenBuffer - + Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight), - User::Panic(_L("SDL"), KErrCorrupt)); - __ASSERT_DEBUG(screenMemory >= screenBuffer, - User::Panic(_L("SDL"), KErrCorrupt)); - __ASSERT_DEBUG(bitmapLine < ((TUint16*)_this->screen->pixels + - + (_this->screen->w * _this->screen->h)), - User::Panic(_L("SDL"), KErrCorrupt)); - __ASSERT_DEBUG(bitmapLine >= (TUint16*)_this->screen->pixels, - User::Panic(_L("SDL"), KErrCorrupt)); - Mem::Copy(screenMemory, bitmapLine, sourceRectWidthInBytes); - bitmapLine += sourceScanlineLength; - screenMemory += targetScanlineLength; - } - } - // !! 256 color paletted mode: 8 bpp --> 12 bpp - else { - TUint8* bitmapLine = (TUint8*)_this->screen->pixels + sourceStartOffset; - TUint16* screenMemory = screenBuffer + targetStartOffset; - for(TInt y = 0 ; y < sourceRectHeight ; y++) { - TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */ - TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */ - /* Convert each pixel from 256 palette to 4k color values */ - for(TInt x = 0 ; x < sourceRectWidth ; x++) { - __ASSERT_DEBUG(screenMemoryLinePos < (screenBuffer - + (Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight)), - User::Panic(_L("SDL"), KErrCorrupt)); - __ASSERT_DEBUG(screenMemoryLinePos >= screenBuffer, - User::Panic(_L("SDL"), KErrCorrupt)); - __ASSERT_DEBUG(bitmapPos < ((TUint8*)_this->screen->pixels + - + (_this->screen->w * _this->screen->h)), - User::Panic(_L("SDL"), KErrCorrupt)); - __ASSERT_DEBUG(bitmapPos >= (TUint8*)_this->screen->pixels, - User::Panic(_L("SDL"), KErrCorrupt)); - *screenMemoryLinePos = EPOC_HWPalette_256_to_4k[*bitmapPos]; - bitmapPos++; - screenMemoryLinePos++; - } - bitmapLine += sourceScanlineLength; - screenMemory += targetScanlineLength; - } - } - - } - -#ifdef __WINS__ - - TRect rect = TRect(Private->EPOC_WsWindow.Size()); - Private->EPOC_WsWindow.Invalidate(rect); - Private->EPOC_WsWindow.BeginRedraw(rect); - Private->EPOC_WindowGc->BitBlt(TPoint(), Private->EPOC_Bitmap); - Private->EPOC_WsWindow.EndRedraw(); - Private->EPOC_WindowGc->Deactivate(); - lock.End(); // Unlock bitmap heap - Private->EPOC_WsSession.Flush(); - -#endif - - /* Update virtual cursor */ - //!!Private->EPOC_WsSession.SetPointerCursorPosition(Private->EPOC_WsSession.PointerCursorPosition()); - - return; -} - - -/* Note: If we are terminated, this could be called in the middle of - another SDL video routine -- notably UpdateRects. -*/ -void EPOC_VideoQuit(_THIS) -{ - int i; - - /* Free video mode lists */ - for ( i=0; iSDL_modelist[i] != NULL ) { - SDL_free(Private->SDL_modelist[i]); - Private->SDL_modelist[i] = NULL; - } - } - - if ( _this->screen && (_this->screen->flags & SDL_HWSURFACE) ) { - /* Direct screen access, no memory buffer */ - _this->screen->pixels = NULL; - } - - if (_this->screen && _this->screen->pixels) { - SDL_free(_this->screen->pixels); - _this->screen->pixels = NULL; - } - - /* Free Epoc resources */ - - /* Disable events for me */ - if (Private->EPOC_WsEventStatus != KRequestPending) - Private->EPOC_WsSession.EventReadyCancel(); - if (Private->EPOC_RedrawEventStatus != KRequestPending) - Private->EPOC_WsSession.RedrawReadyCancel(); - - #ifdef __WINS__ - delete Private->EPOC_Bitmap; - Private->EPOC_Bitmap = NULL; - #endif - - if (Private->EPOC_WsWindow.WsHandle()) - Private->EPOC_WsWindow.Close(); - - if (Private->EPOC_WsWindowGroup.WsHandle()) - Private->EPOC_WsWindowGroup.Close(); - - delete Private->EPOC_WindowGc; - Private->EPOC_WindowGc = NULL; - - delete Private->EPOC_WsScreen; - Private->EPOC_WsScreen = NULL; - - if (Private->EPOC_WsSession.WsHandle()) - Private->EPOC_WsSession.Close(); -} - - -WMcursor *EPOC_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) -{ - return (WMcursor *) 9210; // it's ok to return something unuseful but true -} - -void EPOC_FreeWMCursor(_THIS, WMcursor *cursor) -{ - /* Disable virtual cursor */ - HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible); - Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNone); -} - -int EPOC_ShowWMCursor(_THIS, WMcursor *cursor) -{ - - if (cursor == (WMcursor *)9210) { - /* Enable virtual cursor */ - HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible); - Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNormal); - } - else { - /* Disable virtual cursor */ - HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible); - Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNone); - } - - return(1); -} - -}; // extern "C" - diff --git a/src/video/epoc/SDL_epocvideo.h b/src/video/epoc/SDL_epocvideo.h deleted file mode 100644 index efff50a98..000000000 --- a/src/video/epoc/SDL_epocvideo.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2004 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - SDL_epocvideo.h - Epoc based SDL video driver implementation - - Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi) -*/ - -#ifndef _SDL_epocvideo_h -#define _SDL_epocvideo_h - -extern "C" { -#include "SDL_mouse.h" -#include "../SDL_sysvideo.h" -}; - -#include -#include -#include - -/* Hidden "this" pointer for the video functions */ -#define _THIS SDL_VideoDevice *_this -#define Private _this->hidden - -#define SDL_NUMMODES 4 - -/* Private display data */ -struct SDL_PrivateVideoData { - - SDL_Rect *SDL_modelist[SDL_NUMMODES+1]; - - /* Epoc window server info */ - - RWsSession EPOC_WsSession; - RWindowGroup EPOC_WsWindowGroup; - TInt EPOC_WsWindowGroupID; - RWindow EPOC_WsWindow; - CWsScreenDevice* EPOC_WsScreen; - CWindowGc* EPOC_WindowGc; - TRequestStatus EPOC_WsEventStatus; - TRequestStatus EPOC_RedrawEventStatus; - TWsEvent EPOC_WsEvent; - TWsRedrawEvent EPOC_RedrawEvent; - #ifdef __WINS__ - CWsBitmap* EPOC_Bitmap; - #endif - TBool EPOC_IsWindowFocused; //!!Not used for anything yet! - - /* Screen hardware frame buffer info */ - - TBool EPOC_HasFrameBuffer; - TInt EPOC_BytesPerPixel; - TInt EPOC_BytesPerScanLine; - TDisplayMode EPOC_DisplayMode; - TSize EPOC_ScreenSize; - TUint8* EPOC_FrameBuffer; /* if NULL in HW we can't do direct screen access */ - TInt EPOC_ScreenOffset; - - /* Simulate double screen height */ - TBool EPOC_ShrinkedHeight; -}; - -extern "C" { -extern void RedrawWindowL(_THIS); -}; - - -#endif /* _SDL_epocvideo_h */ From bacb61113ec9d97c23174957f0d3d8cd0cb2e1b4 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 15 Jun 2007 15:52:04 +0000 Subject: [PATCH 123/241] Removed some more EPOC stuff I missed. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402361 --- Makefile.in | 2 +- docs/html/sdlenvvars.html | 15 ----- src/main/epoc/SDL_main.cpp | 129 ------------------------------------- 3 files changed, 1 insertion(+), 145 deletions(-) delete mode 100644 src/main/epoc/SDL_main.cpp diff --git a/Makefile.in b/Makefile.in index 6d18f3791..81a18f65d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -38,7 +38,7 @@ SDLMAIN_TARGET = libSDLmain.a SDLMAIN_SOURCES = @SDLMAIN_SOURCES@ SDLMAIN_OBJECTS = @SDLMAIN_OBJECTS@ -DIST = acinclude.m4 autogen.sh Borland.html Borland.zip BUGS build-scripts configure configure.in COPYING CREDITS CWprojects.sea.bin docs docs.html EpocBuildFiles.zip include INSTALL Makefile.dc Makefile.minimal Makefile.in MPWmake.sea.bin README* sdl-config.in sdl.m4 sdl.pc.in SDL.qpg.in SDL.spec SDL.spec.in src test TODO VisualCE.zip VisualC.html VisualC.zip Watcom-OS2.zip Watcom-Win32.zip WhatsNew Xcode.tar.gz +DIST = acinclude.m4 autogen.sh Borland.html Borland.zip BUGS build-scripts configure configure.in COPYING CREDITS CWprojects.sea.bin docs docs.html include INSTALL Makefile.dc Makefile.minimal Makefile.in MPWmake.sea.bin README* sdl-config.in sdl.m4 sdl.pc.in SDL.qpg.in SDL.spec SDL.spec.in src test TODO VisualCE.zip VisualC.html VisualC.zip Watcom-OS2.zip Watcom-Win32.zip WhatsNew Xcode.tar.gz HDRS = SDL.h SDL_active.h SDL_audio.h SDL_byteorder.h SDL_cdrom.h SDL_cpuinfo.h SDL_endian.h SDL_error.h SDL_events.h SDL_getenv.h SDL_joystick.h SDL_keyboard.h SDL_keysym.h SDL_loadso.h SDL_main.h SDL_mouse.h SDL_mutex.h SDL_name.h SDL_opengl.h SDL_platform.h SDL_quit.h SDL_rwops.h SDL_stdinc.h SDL_syswm.h SDL_thread.h SDL_timer.h SDL_types.h SDL_version.h SDL_video.h begin_code.h close_code.h diff --git a/docs/html/sdlenvvars.html b/docs/html/sdlenvvars.html index 6b4ca3b28..4e677cdc8 100644 --- a/docs/html/sdlenvvars.html +++ b/docs/html/sdlenvvars.html @@ -436,21 +436,6 @@ ALIGN="LEFT" VALIGN="TOP" >epoc

(Epoc)

dummy -#include -#include -#include -#include -#include -#include -#include -#include - -#include "SDL_error.h" - -#ifndef EXPORT_C -# ifdef __VC32__ -# define IMPORT_C __declspec(dllexport) -# define EXPORT_C __declspec(dllexport) -# endif -# ifdef __GCC32__ -# define IMPORT_C -# define EXPORT_C __declspec(dllexport) -# endif -#endif - -#if defined(__WINS__) -#include -IMPORT_C void RegisterWsExe(const TDesC &aName); -#endif - -/* The prototype for the application's main() function */ -#define main SDL_main -extern "C" int main (int argc, char *argv[], char *envp[]); -extern "C" void exit (int ret); - - -/* Epoc main function */ - -GLDEF_C TInt E32Main() - { - /* Get the clean-up stack */ - CTrapCleanup* cleanup = CTrapCleanup::New(); - - #if defined(__WINS__) - /* arrange for access to Win32 stdin/stdout/stderr */ - RWin32Stream::StartServer(); - #endif - - /* Arrange for multi-threaded operation */ - SpawnPosixServerThread(); - - /* Get args and environment */ - int argc=0; - char** argv=0; - char** envp=0; - __crt0(argc,argv,envp); - - #if defined(__WINS__) - /* Cause the graphical Window Server to come into existence */ - RSemaphore sem; - sem.CreateGlobal(_L("WsExeSem"),0); - RegisterWsExe(sem.FullName()); - #endif - - - /* Start the application! */ - - /* Create stdlib */ - _REENT; - - /* Set process and thread priority */ - RThread currentThread; - - currentThread.Rename(_L("SdlProgram")); - currentThread.SetProcessPriority(EPriorityLow); - currentThread.SetPriority(EPriorityMuchLess); - - /* Call stdlib main */ - int ret = main(argc, argv, envp); /* !! process exits here if there is "exit()" in main! */ - - /* Call exit */ - exit(ret); /* !! process exits here! */ - - /* Free resources and return */ - CloseSTDLIB(); - delete cleanup; - return(KErrNone); - } - -/* Epoc dll entry point */ -#if defined(__WINS__) -GLDEF_C TInt E32Dll(TDllReason) - { - return(KErrNone); - } - -EXPORT_C TInt WinsMain(TAny *) - { - E32Main(); - return KErrNone; - } -#endif From f9e2e9d6354d2be909e01285523d44bb6d21ee5f Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 16 Jun 2007 05:10:47 +0000 Subject: [PATCH 124/241] Added support for WM_XBUTTON to the windib driver, to support more mouse buttons. Fixes Bugzilla #311. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402363 --- docs.html | 3 +++ src/video/wincommon/SDL_sysevents.c | 39 ++++++++++++++++++++++++++++- src/video/wincommon/wmmsg.h | 4 +-- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/docs.html b/docs.html index 97f2ecc56..08e0d3a2d 100644 --- a/docs.html +++ b/docs.html @@ -74,6 +74,9 @@ SDL 1.2.12 is a minor bug fix release.

Windows Notes

+

+ The windib driver now supports more mouse buttons with WM_XBUTTON events. +

Added support for UTF-8 window titles on Windows.

diff --git a/src/video/wincommon/SDL_sysevents.c b/src/video/wincommon/SDL_sysevents.c index 584c18463..f5d4d1c33 100644 --- a/src/video/wincommon/SDL_sysevents.c +++ b/src/video/wincommon/SDL_sysevents.c @@ -24,6 +24,17 @@ #define WIN32_LEAN_AND_MEAN #include +/* Make sure XBUTTON stuff is defined that isn't in older Platform SDKs... */ +#ifndef WM_XBUTTONDOWN +#define WM_XBUTTONDOWN 0x020B +#endif +#ifndef WM_XBUTTONUP +#define WM_XBUTTONUP 0x020C +#endif +#ifndef GET_XBUTTON_WPARAM +#define GET_XBUTTON_WPARAM(w) (HIWORD(w)) +#endif + #include "SDL_events.h" #include "SDL_video.h" #include "SDL_syswm.h" @@ -466,9 +477,12 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_RBUTTONDOWN: - case WM_RBUTTONUP: { + case WM_RBUTTONUP: + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: { /* Mouse is handled by DirectInput when fullscreen */ if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) { + WORD xbuttonval = 0; Sint16 x, y; Uint8 button, state; @@ -505,6 +519,16 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) button = SDL_BUTTON_RIGHT; state = SDL_RELEASED; break; + case WM_XBUTTONDOWN: + xbuttonval = GET_XBUTTON_WPARAM(wParam); + button = SDL_BUTTON_WHEELDOWN + xbuttonval; + state = SDL_PRESSED; + break; + case WM_XBUTTONUP: + xbuttonval = GET_XBUTTON_WPARAM(wParam); + button = SDL_BUTTON_WHEELDOWN + xbuttonval; + state = SDL_RELEASED; + break; default: /* Eh? Unknown button? */ return(0); @@ -535,6 +559,19 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) } posted = SDL_PrivateMouseButton( state, button, x, y); + + /* + * MSDN says: + * "Unlike the WM_LBUTTONUP, WM_MBUTTONUP, and WM_RBUTTONUP + * messages, an application should return TRUE from [an + * XBUTTON message] if it processes it. Doing so will allow + * software that simulates this message on Microsoft Windows + * systems earlier than Windows 2000 to determine whether + * the window procedure processed the message or called + * DefWindowProc to process it. + */ + if (xbuttonval > 0) + return(TRUE); } } return(0); diff --git a/src/video/wincommon/wmmsg.h b/src/video/wincommon/wmmsg.h index d057fc56d..98aba7331 100644 --- a/src/video/wincommon/wmmsg.h +++ b/src/video/wincommon/wmmsg.h @@ -525,8 +525,8 @@ char *wmtab[] = { "WM_MBUTTONUP", "WM_MOUSELAST", "WM_MOUSELAST", - "UNKNOWN (523)", - "UNKNOWN (524)", + "WM_XBUTTONDOWN", + "WM_XBUTTONUP", "UNKNOWN (525)", "UNKNOWN (526)", "UNKNOWN (527)", From 1358a199de4584d9f8749204c86e079620bb414c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 16 Jun 2007 05:24:55 +0000 Subject: [PATCH 125/241] Fixed win32 event name list (WM_MOUSELAST was listed twice, one should be WM_MOUSEWHEEL). --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402364 --- src/video/wincommon/wmmsg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/wincommon/wmmsg.h b/src/video/wincommon/wmmsg.h index 98aba7331..175a8ceec 100644 --- a/src/video/wincommon/wmmsg.h +++ b/src/video/wincommon/wmmsg.h @@ -524,7 +524,7 @@ char *wmtab[] = { "WM_MBUTTONDOWN", "WM_MBUTTONUP", "WM_MOUSELAST", - "WM_MOUSELAST", + "WM_MOUSEWHEEL", "WM_XBUTTONDOWN", "WM_XBUTTONUP", "UNKNOWN (525)", From 24ea7c9a315ade1a5fdc288ad25499c825810fee Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 16 Jun 2007 05:51:51 +0000 Subject: [PATCH 126/241] Fixed assembler command line for older yasm releases and documented nasm switches. Fixes Bugzilla #440. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402366 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index f702c74f9..0332be004 100644 --- a/configure.in +++ b/configure.in @@ -706,7 +706,7 @@ AC_HELP_STRING([--enable-nasm], [use nasm assembly blitters on x86 [[default=yes if test "x$NASM" != x -a "x$NASM" != x'"$NASM"'; then AC_DEFINE(SDL_HERMES_BLITTERS) SOURCES="$SOURCES $srcdir/src/hermes/*.asm" - NASMFLAGS="$NASMFLAGS -i $srcdir/src/hermes/" + NASMFLAGS="$NASMFLAGS -I $srcdir/src/hermes/" dnl See if hidden visibility is supported echo "GLOBAL _bar:function hidden" > symbol-visibility From be8f728aaa35bcf7832318889e157e8e4c2dd639 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 21 Jun 2007 18:20:59 +0000 Subject: [PATCH 127/241] Fixes for Visual C++ 6.0 with and without the Processor Pack. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402371 --- include/SDL_config_win32.h | 11 +++++++++++ src/video/SDL_blit_A.c | 30 +++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/include/SDL_config_win32.h b/include/SDL_config_win32.h index 8d32b13cd..ea4204f71 100644 --- a/include/SDL_config_win32.h +++ b/include/SDL_config_win32.h @@ -46,6 +46,17 @@ typedef unsigned int uintptr_t; #endif #define _UINTPTR_T_DEFINED #endif +/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ +#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) +#define DWORD_PTR DWORD +#endif +#if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) +#define LONG_PTR LONG +#endif +#ifndef GWLP_HINSTANCE +#define GWLP_HINSTANCE GWL_HINSTANCE +#endif +#endif #else /* !__GNUC__ && !_MSC_VER */ typedef signed char int8_t; typedef unsigned char uint8_t; diff --git a/src/video/SDL_blit_A.c b/src/video/SDL_blit_A.c index 9319d1e3c..b46d3f613 100644 --- a/src/video/SDL_blit_A.c +++ b/src/video/SDL_blit_A.c @@ -24,14 +24,30 @@ #include "SDL_video.h" #include "SDL_blit.h" +/* + In Visual C, VC6 has mmintrin.h in the "Processor Pack" add-on. + Checking if _mm_free is #defined in malloc.h is is the only way to + determine if the Processor Pack is installed, as far as I can tell. +*/ + #if SDL_ASSEMBLY_ROUTINES -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -#define MMX_ASMBLIT 1 -#define GCC_ASMBLIT 1 -#elif defined(_MSC_VER) && (_MSC_VER >= 1200) && defined(_M_IX86) -#define MMX_ASMBLIT 1 -#define MSVC_ASMBLIT 1 -#endif +# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +# define MMX_ASMBLIT 1 +# define GCC_ASMBLIT 1 +# elif defined(_MSC_VER) && defined(_M_IX86) +# if (_MSC_VER <= 1200) +# include +# if defined(_mm_free) +# define HAVE_MMINTRIN_H 1 +# endif +# else /* Visual Studio > VC6 always has mmintrin.h */ +# define HAVE_MMINTRIN_H 1 +# endif +# if HAVE_MMINTRIN_H +# define MMX_ASMBLIT 1 +# define MSVC_ASMBLIT 1 +# endif +# endif #endif /* SDL_ASSEMBLY_ROUTINES */ /* Function to check the CPU flags */ From 6fb707a2a2fc84da4b16a8bc788e4a38d9e0dbef Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 21 Jun 2007 18:48:13 +0000 Subject: [PATCH 128/241] Whoops, fixed previous VC6 support patch. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402373 --- include/SDL_config_win32.h | 4 ---- src/video/wincommon/SDL_lowvideo.h | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/include/SDL_config_win32.h b/include/SDL_config_win32.h index ea4204f71..cfb44d2a0 100644 --- a/include/SDL_config_win32.h +++ b/include/SDL_config_win32.h @@ -53,10 +53,6 @@ typedef unsigned int uintptr_t; #if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) #define LONG_PTR LONG #endif -#ifndef GWLP_HINSTANCE -#define GWLP_HINSTANCE GWL_HINSTANCE -#endif -#endif #else /* !__GNUC__ && !_MSC_VER */ typedef signed char int8_t; typedef unsigned char uint8_t; diff --git a/src/video/wincommon/SDL_lowvideo.h b/src/video/wincommon/SDL_lowvideo.h index eb8d9581b..f8ea258fa 100644 --- a/src/video/wincommon/SDL_lowvideo.h +++ b/src/video/wincommon/SDL_lowvideo.h @@ -39,6 +39,9 @@ #ifndef GWLP_WNDPROC #define GWLP_WNDPROC GWL_WNDPROC #endif +#ifndef GWLP_HINSTANCE +#define GWLP_HINSTANCE GWL_HINSTANCE +#endif #ifndef GCLP_HICON #define GCLP_HICON GCL_HICON #endif From 10ab421d01c20e12e224a6a45dde13e25c068ab8 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 24 Jun 2007 18:26:35 +0000 Subject: [PATCH 129/241] Added S60 port. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402375 --- README.Symbian | 32 + docs.html | 3 + include/SDL_config.h.default | 2 + include/SDL_config.h.in | 3 - include/SDL_config_symbian.h | 146 ++ include/SDL_stdinc.h | 2 + include/SDL_thread.h | 2 +- include/begin_code.h | 10 +- src/SDL.c | 2 +- src/audio/SDL_audio.c | 5 +- src/audio/SDL_sysaudio.h | 3 + src/audio/symbian/SDL_epocaudio.cpp | 614 +++++++++ src/audio/symbian/SDL_epocaudio.h | 37 + src/audio/symbian/streamplayer.cpp | 279 ++++ src/audio/symbian/streamplayer.h | 89 ++ src/events/SDL_events.c | 2 +- src/file/SDL_rwops.c | 4 +- src/main/symbian/EKA1/SDL_main.cpp | 152 +++ src/main/symbian/EKA2/SDL_main.cpp | 1035 ++++++++++++++ src/main/symbian/EKA2/sdlexe.cpp | 809 +++++++++++ src/main/symbian/EKA2/sdllib.cpp | 12 + src/main/symbian/EKA2/vectorbuffer.cpp | 62 + src/main/symbian/EKA2/vectorbuffer.h | 240 ++++ src/stdlib/SDL_getenv.c | 2 +- src/thread/SDL_thread_c.h | 4 +- src/thread/symbian/SDL_sysmutex.cpp | 130 ++ src/thread/symbian/SDL_syssem.cpp | 214 +++ src/thread/symbian/SDL_systhread.cpp | 146 ++ src/thread/symbian/SDL_systhread_c.h | 30 + src/timer/symbian/SDL_systimer.cpp | 114 ++ src/video/symbian/EKA1/SDL_epocevents.cpp | 626 +++++++++ src/video/symbian/EKA1/SDL_epocvideo.cpp | 1356 +++++++++++++++++++ src/video/symbian/EKA1/SDL_epocvideo.h | 34 + src/video/symbian/EKA2/SDL_epocevents.cpp | 521 +++++++ src/video/symbian/EKA2/SDL_epocvideo.cpp | 594 ++++++++ src/video/symbian/EKA2/SDL_epocvideo.h | 51 + src/video/symbian/EKA2/dsa.cpp | 1504 +++++++++++++++++++++ src/video/symbian/EKA2/dsa_new.cpp | 1443 ++++++++++++++++++++ src/video/symbian/EKA2/dsa_old.cpp | 1075 +++++++++++++++ src/video/symbian/SDL_epocevents_c.h | 60 + 40 files changed, 11434 insertions(+), 15 deletions(-) create mode 100644 README.Symbian create mode 100644 include/SDL_config_symbian.h create mode 100644 src/audio/symbian/SDL_epocaudio.cpp create mode 100644 src/audio/symbian/SDL_epocaudio.h create mode 100644 src/audio/symbian/streamplayer.cpp create mode 100644 src/audio/symbian/streamplayer.h create mode 100644 src/main/symbian/EKA1/SDL_main.cpp create mode 100644 src/main/symbian/EKA2/SDL_main.cpp create mode 100644 src/main/symbian/EKA2/sdlexe.cpp create mode 100644 src/main/symbian/EKA2/sdllib.cpp create mode 100644 src/main/symbian/EKA2/vectorbuffer.cpp create mode 100644 src/main/symbian/EKA2/vectorbuffer.h create mode 100644 src/thread/symbian/SDL_sysmutex.cpp create mode 100644 src/thread/symbian/SDL_syssem.cpp create mode 100644 src/thread/symbian/SDL_systhread.cpp create mode 100644 src/thread/symbian/SDL_systhread_c.h create mode 100644 src/timer/symbian/SDL_systimer.cpp create mode 100644 src/video/symbian/EKA1/SDL_epocevents.cpp create mode 100644 src/video/symbian/EKA1/SDL_epocvideo.cpp create mode 100644 src/video/symbian/EKA1/SDL_epocvideo.h create mode 100644 src/video/symbian/EKA2/SDL_epocevents.cpp create mode 100644 src/video/symbian/EKA2/SDL_epocvideo.cpp create mode 100644 src/video/symbian/EKA2/SDL_epocvideo.h create mode 100644 src/video/symbian/EKA2/dsa.cpp create mode 100644 src/video/symbian/EKA2/dsa_new.cpp create mode 100644 src/video/symbian/EKA2/dsa_old.cpp create mode 100644 src/video/symbian/SDL_epocevents_c.h diff --git a/README.Symbian b/README.Symbian new file mode 100644 index 000000000..d1f2a4ae0 --- /dev/null +++ b/README.Symbian @@ -0,0 +1,32 @@ +============================================================================== +Using the Simple DirectMedia Layer with S60 3.x / Symbian 9.x +============================================================================== + +These instuctions are for people developing for S60 3.x. S60 3.x +uses Symbian OS so you need S60 SDK. + +extract "symbian.zip" into this folder. + +go to symbian folder + +bldmake bldfiles +abld build + +That produces WINSCW and ARMV5 versions of sdl.dll runtime library +and sdl.lib for development. + +Eaudiolib.lib and dll are generated as well, and must be delivered +along SDL as it uses it for audio. + +There are certain problems with GCC compiler when building for +target, it may compile or binaries are buggy - please use RVCT +compiler as it works and produces far more effient code. + +Its likely that SDL application should be integrated into S60 +work and behave well there. So there is CSDL class (sdlepocapi.h) +to make this easy. If you do porting from other system, then +implement a S60 application and use CSDL class, they you may +not need to modify original SDL code at all! + + + diff --git a/docs.html b/docs.html index 08e0d3a2d..8c55e52b0 100644 --- a/docs.html +++ b/docs.html @@ -46,6 +46,9 @@ SDL 1.2.12 is a minor bug fix release.

Support for Nokia 9210 "EPOC" driver has been removed from the main SDL code.

+

+ Unofficial support for the S60/SymbianOS platform has been added. +

Unix Notes

diff --git a/include/SDL_config.h.default b/include/SDL_config.h.default index cc5ab6574..c82f42adf 100644 --- a/include/SDL_config.h.default +++ b/include/SDL_config.h.default @@ -32,6 +32,8 @@ #include "SDL_config_macos.h" #elif defined(__MACOSX__) #include "SDL_config_macosx.h" +#elif defined(__SYMBIAN32__) +#include "SDL_config_symbian.h" /* must be before win32! */ #elif defined(__WIN32__) #include "SDL_config_win32.h" #elif defined(__OS2__) diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index c2a76950d..abb1b447d 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -224,7 +224,6 @@ /* Enable various threading systems */ #undef SDL_THREAD_BEOS #undef SDL_THREAD_DC -#undef SDL_THREAD_EPOC #undef SDL_THREAD_OS2 #undef SDL_THREAD_PTH #undef SDL_THREAD_PTHREAD @@ -237,7 +236,6 @@ #undef SDL_TIMER_BEOS #undef SDL_TIMER_DC #undef SDL_TIMER_DUMMY -#undef SDL_TIMER_EPOC #undef SDL_TIMER_MACOS #undef SDL_TIMER_MINT #undef SDL_TIMER_OS2 @@ -255,7 +253,6 @@ #undef SDL_VIDEO_DRIVER_DIRECTFB #undef SDL_VIDEO_DRIVER_DRAWSPROCKET #undef SDL_VIDEO_DRIVER_DUMMY -#undef SDL_VIDEO_DRIVER_EPOC #undef SDL_VIDEO_DRIVER_FBCON #undef SDL_VIDEO_DRIVER_GAPI #undef SDL_VIDEO_DRIVER_GEM diff --git a/include/SDL_config_symbian.h b/include/SDL_config_symbian.h new file mode 100644 index 000000000..acb49abf0 --- /dev/null +++ b/include/SDL_config_symbian.h @@ -0,0 +1,146 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* + +Symbian version Markus Mertama + +*/ + + +#ifndef _SDL_CONFIG_SYMBIAN_H +#define _SDL_CONFIG_SYMBIAN_H + +#include "SDL_platform.h" + +/* This is the minimal configuration that can be used to build SDL */ + + +#include +#include + + +#ifdef __GCCE__ +#define SYMBIAN32_GCCE +#endif + +#ifndef _SIZE_T_DEFINED +typedef unsigned int size_t; +#endif + +#ifndef _INTPTR_T_DECLARED +typedef unsigned int uintptr_t; +#endif + +#ifndef _INT8_T_DECLARED +typedef signed char int8_t; +#endif + +#ifndef _UINT8_T_DECLARED +typedef unsigned char uint8_t; +#endif + +#ifndef _INT16_T_DECLARED +typedef signed short int16_t; +#endif + +#ifndef _UINT16_T_DECLARED +typedef unsigned short uint16_t; +#endif + +#ifndef _INT32_T_DECLARED +typedef signed int int32_t; +#endif + +#ifndef _UINT32_T_DECLARED +typedef unsigned int uint32_t; +#endif + +#ifndef _INT64_T_DECLARED +typedef signed long long int64_t; +#endif + +#ifndef _UINT64_T_DECLARED +typedef unsigned long long uint64_t; +#endif + +#define SDL_AUDIO_DRIVER_EPOCAUDIO 1 + + +/* Enable the stub cdrom driver (src/cdrom/dummy/\*.c) */ +#define SDL_CDROM_DISABLED 1 + +/* Enable the stub joystick driver (src/joystick/dummy/\*.c) */ +#define SDL_JOYSTICK_DISABLED 1 + +/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */ +#define SDL_LOADSO_DISABLED 1 + +#define SDL_THREAD_SYMBIAN 1 + +#define SDL_VIDEO_DRIVER_EPOC 1 + +#define SDL_VIDEO_OPENGL 0 + +#define SDL_HAS_64BIT_TYPE 1 + +#define HAVE_LIBC 1 +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STRING_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_MATH_H 1 + +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +//#define HAVE_ALLOCA 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRUPR 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_ITOA 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE_SSCANF 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 + + + +#endif /* _SDL_CONFIG_SYMBIAN_H */ diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index 53d1288f0..21a86794a 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -91,7 +91,9 @@ typedef uint32_t Uint32; #ifdef SDL_HAS_64BIT_TYPE typedef int64_t Sint64; +#ifndef SYMBIAN32_GCCE typedef uint64_t Uint64; +#endif #else /* This is really just a hack to prevent the compiler from complaining */ typedef struct { diff --git a/include/SDL_thread.h b/include/SDL_thread.h index e0a35b1ab..403ee4620 100644 --- a/include/SDL_thread.h +++ b/include/SDL_thread.h @@ -45,7 +45,7 @@ struct SDL_Thread; typedef struct SDL_Thread SDL_Thread; /* Create a thread */ -#if (defined(__WIN32__) && !defined(HAVE_LIBC)) || defined(__OS2__) +#if ((defined(__WIN32__) && !defined(HAVE_LIBC)) || defined(__OS2__)) && !defined(__SYMBIAN32__) /* We compile SDL into a DLL on OS/2. This means, that it's the DLL which creates a new thread for the calling process with the SDL_CreateThread() diff --git a/include/begin_code.h b/include/begin_code.h index 88fbc2f3d..b03787f4a 100644 --- a/include/begin_code.h +++ b/include/begin_code.h @@ -83,11 +83,15 @@ #endif #endif /* SDLCALL */ -/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */ #ifdef __SYMBIAN32__ +#ifndef EKA2 #undef DECLSPEC #define DECLSPEC -#endif /* __SYMBIAN32__ */ +#elif !defined(__WINS__) +#undef DECLSPEC +#define DECLSPEC __declspec(dllexport) +#endif //EKA2 +#endif //__SYMBIAN32__ /* Force structure packing at 4 byte alignment. This is necessary if the header is included in code which has structure @@ -116,7 +120,7 @@ #if defined(_MSC_VER) || defined(__BORLANDC__) || \ defined(__DMC__) || defined(__SC__) || \ defined(__WATCOMC__) || defined(__LCC__) || \ - defined(__DECC) + defined(__DECC) || defined(__EABI__) #ifndef __inline__ #define __inline__ __inline #endif diff --git a/src/SDL.c b/src/SDL.c index 64a3e93dc..353d1a575 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -323,7 +323,7 @@ unsigned _System LibMain(unsigned hmod, unsigned termination) } #endif /* __WATCOMC__ */ -#elif defined(__WIN32__) +#elif defined(__WIN32__) && !defined(__SYMBIAN32__) #if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL)) /* Need to include DllMain() on Watcom C for some reason.. */ diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 91d6945ed..81e890aaf 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -106,6 +106,9 @@ static AudioBootStrap *bootstrap[] = { #endif #if SDL_AUDIO_DRIVER_DART &DART_bootstrap, +#endif +#if SDL_AUDIO_DRIVER_EPOCAUDIO + &EPOCAudio_bootstrap, #endif NULL }; @@ -545,7 +548,7 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) switch (audio->opened) { case 1: /* Start the audio thread */ -#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) +#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) && !defined(__SYMBIAN32__) #undef SDL_CreateThread audio->thread = SDL_CreateThread(SDL_RunAudio, audio, NULL, NULL); #else diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index b73748aab..0fdd3ae10 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -171,6 +171,9 @@ extern AudioBootStrap MMEAUDIO_bootstrap; #if SDL_AUDIO_DRIVER_DART extern AudioBootStrap DART_bootstrap; #endif +#if SDL_AUDIO_DRIVER_EPOCAUDIO +extern AudioBootStrap EPOCAudio_bootstrap; +#endif /* This is the current audio device */ extern SDL_AudioDevice *current_audio; diff --git a/src/audio/symbian/SDL_epocaudio.cpp b/src/audio/symbian/SDL_epocaudio.cpp new file mode 100644 index 000000000..6c36671bc --- /dev/null +++ b/src/audio/symbian/SDL_epocaudio.cpp @@ -0,0 +1,614 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* + SDL_epocaudio.cpp + Epoc based SDL audio driver implementation + + Markus Mertama +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_epocaudio.c,v 0.0.0.0 2001/06/19 17:19:56 hercules Exp $"; +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "epoc_sdl.h" + +#include + + +extern "C" { +#include "SDL_audio.h" +#include "SDL_error.h" +#include "SDL_audiomem.h" +#include "SDL_audio_c.h" +#include "SDL_timer.h" +#include "SDL_audiodev_c.h" +} + +#include "SDL_epocaudio.h" + +#include "streamplayer.h" + + +//#define DEBUG_AUDIO + + +/* Audio driver functions */ + +static int EPOC_OpenAudio(SDL_AudioDevice *thisdevice, SDL_AudioSpec *spec); +static void EPOC_WaitAudio(SDL_AudioDevice *thisdevice); +static void EPOC_PlayAudio(SDL_AudioDevice *thisdevice); +static Uint8 *EPOC_GetAudioBuf(SDL_AudioDevice *thisdevice); +static void EPOC_CloseAudio(SDL_AudioDevice *thisdevice); +static void EPOC_ThreadInit(SDL_AudioDevice *thisdevice); + +static int Audio_Available(void); +static SDL_AudioDevice *Audio_CreateDevice(int devindex); +static void Audio_DeleteDevice(SDL_AudioDevice *device); + + +//void sos_adump(SDL_AudioDevice* thisdevice, void* data, int len); + +#ifdef __WINS__ +#define DODUMP +#endif + +#ifdef DODUMP +NONSHARABLE_CLASS(TDump) + { + public: + TInt Open(); + void Close(); + void Dump(const TDesC8& aDes); + private: + RFile iFile; + RFs iFs; + }; + +TInt TDump::Open() + { + TInt err = iFs.Connect(); + if(err == KErrNone) + { +#ifdef __WINS__ +_LIT(target, "C:\\sdlau.raw"); +#else +_LIT(target, "E:\\sdlau.raw"); +#endif + err = iFile.Replace(iFs, target, EFileWrite); + } + return err; + } +void TDump::Close() + { + iFile.Close(); + iFs.Close(); + } +void TDump::Dump(const TDesC8& aDes) + { + iFile.Write(aDes); + } +#endif + + +NONSHARABLE_CLASS(CSimpleWait) : public CTimer + { + public: + void Wait(TTimeIntervalMicroSeconds32 aWait); + static CSimpleWait* NewL(); + private: + CSimpleWait(); + void RunL(); + }; + + +CSimpleWait* CSimpleWait::NewL() + { + CSimpleWait* wait = new (ELeave) CSimpleWait(); + CleanupStack::PushL(wait); + wait->ConstructL(); + CleanupStack::Pop(); + return wait; + } + +void CSimpleWait::Wait(TTimeIntervalMicroSeconds32 aWait) + { + After(aWait); + CActiveScheduler::Start(); + } + +CSimpleWait::CSimpleWait() : CTimer(CActive::EPriorityStandard) + { + CActiveScheduler::Add(this); + } + +void CSimpleWait::RunL() + { + CActiveScheduler::Stop(); + } + +const TInt KAudioBuffers(2); + + +NONSHARABLE_CLASS(CEpocAudio) : public CBase, public MStreamObs, public MStreamProvider + { + public: + static void* NewL(TInt BufferSize, TInt aFill); + inline static CEpocAudio& Current(SDL_AudioDevice* thisdevice); + + static void Free(SDL_AudioDevice* thisdevice); + + void Wait(); + void Play(); + // void SetBuffer(const TDesC8& aBuffer); + void ThreadInitL(TAny* aDevice); + void Open(TInt iRate, TInt iChannels, TUint32 aType, TInt aBytes); + ~CEpocAudio(); + TUint8* Buffer(); + TBool SetPause(TBool aPause); + #ifdef DODUMP + void Dump(const TDesC8& aBuf) {iDump.Dump(aBuf);} + #endif + private: + CEpocAudio(TInt aBufferSize); + void Complete(TInt aState, TInt aError); + TPtrC8 Data(); + void ConstructL(TInt aFill); + private: + TInt iBufferSize; + CStreamPlayer* iPlayer; + TInt iBufferRate; + TInt iRate; + TInt iChannels; + TUint32 iType; + TInt iPosition; + TThreadId iTid; + TUint8* iAudioPtr; + TUint8* iBuffer; + // TTimeIntervalMicroSeconds iStart; + TTime iStart; + TInt iTune; + CSimpleWait* iWait; + #ifdef DODUMP + TDump iDump; + #endif + }; + +inline CEpocAudio& CEpocAudio::Current(SDL_AudioDevice* thisdevice) + { + return *static_cast((void*)thisdevice->hidden); + } + +/* + +TBool EndSc(TAny*) + { + CActiveScheduler::Stop(); + } + +LOCAL_C void CleanScL() + { + CIdle* d = CIdle::NewLC(CActive:::EPriorityIdle); + d->Start(TCallBack(EndSc)); + CActiveScheduler::Start(); + + } +*/ + +void CEpocAudio::Free(SDL_AudioDevice* thisdevice) + { + CEpocAudio* ea = static_cast((void*)thisdevice->hidden); + if(ea) + { + ASSERT(ea->iTid == RThread().Id()); + delete ea; + thisdevice->hidden = NULL; + + CActiveScheduler* as = CActiveScheduler::Current(); + ASSERT(as->StackDepth() == 0); + delete as; + CActiveScheduler::Install(NULL); + } + ASSERT(thisdevice->hidden == NULL); + } + +CEpocAudio::CEpocAudio(TInt aBufferSize) : iBufferSize(aBufferSize), iPosition(-1) + { + } + +void* CEpocAudio::NewL(TInt aBufferSize, TInt aFill) + { + CEpocAudio* eAudioLib = new (ELeave) CEpocAudio(aBufferSize); + CleanupStack::PushL(eAudioLib); + eAudioLib->ConstructL(aFill); + CleanupStack::Pop(); + return eAudioLib; + } + +void CEpocAudio::ConstructL(TInt aFill) + { + iBuffer = (TUint8*) User::AllocL(KAudioBuffers * iBufferSize); + memset(iBuffer, aFill, KAudioBuffers * iBufferSize); + iAudioPtr = iBuffer; + } + + +TBool CEpocAudio::SetPause(TBool aPause) + { + if(aPause && iPosition >= 0) + { + iPosition = -1; + if(iPlayer != NULL) + iPlayer->Stop(); + } + if(!aPause && iPosition < 0) + { + iPosition = 0; + if(iPlayer != NULL) + iPlayer->Start(); + } + return iPosition < 0; + } + +void CEpocAudio::ThreadInitL(TAny* aDevice) + { + iTid = RThread().Id(); + CActiveScheduler* as = new (ELeave) CActiveScheduler(); + CActiveScheduler::Install(as); + + EpocSdlEnv::AppendCleanupItem(TSdlCleanupItem((TSdlCleanupOperation)EPOC_CloseAudio, aDevice)); + + iWait = CSimpleWait::NewL(); + + iPlayer = new (ELeave) CStreamPlayer(*this, *this); + iPlayer->ConstructL(); + iPlayer->OpenStream(iRate, iChannels, iType); + + #ifdef DODUMP + User::LeaveIfError(iDump.Open()); + #endif + } + + + +TUint8* CEpocAudio::Buffer() + { + iStart.UniversalTime(); +// iStart = iPlayer->Position(); + return iAudioPtr; + + } + +CEpocAudio::~CEpocAudio() + { + if(iWait != NULL) + iWait->Cancel(); + delete iWait; + if(iPlayer != NULL) + iPlayer->Close(); + delete iPlayer; + delete iBuffer; + } + +void CEpocAudio::Complete(TInt aState, TInt aError) + { + if(aState == MStreamObs::EClose) + { + } + if(iPlayer->Closed()) + return; + switch(aError) + { + case KErrUnderflow: + case KErrInUse: + iPlayer->Start(); + break; + case KErrAbort: + iPlayer->Open(); + } + } + + +void sos_adump(SDL_AudioDevice* thisdevice, void* data, int len) + { +#ifdef DODUMP + const TPtrC8 buf((TUint8*)data, len); + CEpocAudio::Current(thisdevice).Dump(buf); +#endif + } + +const TInt KClip(256); + +TPtrC8 CEpocAudio::Data() + { + if(iPosition < 0) + return KNullDesC8(); + + TPtrC8 data(iAudioPtr + iPosition, KClip); + +#ifdef DODUMP + iDump.Dump(data); +#endif + + iPosition += KClip; + if(iPosition >= iBufferSize) + { + +/* if(iAudioPtr == iBuffer) + iAudioPtr = iBuffer + iBufferSize; + else + iAudioPtr = iBuffer; +*/ + iAudioPtr += iBufferSize; + + if((iAudioPtr - iBuffer) >= KAudioBuffers * iBufferSize) + iAudioPtr = iBuffer; + + iPosition = -1; + if(iWait->IsActive()) + { + iWait->Cancel(); + CActiveScheduler::Stop(); + } + } + return data; + } + + + + +void CEpocAudio::Play() + { + iPosition = 0; + } + +void CEpocAudio::Wait() + { + if(iPosition >= 0 /*&& iPlayer->Playing()*/) + { + const TInt64 bufMs = TInt64(iBufferSize - KClip) * TInt64(1000000); + const TInt64 specTime = bufMs / TInt64(iRate * iChannels * 2); + iWait->After(specTime); + + CActiveScheduler::Start(); + TTime end; + end.UniversalTime(); + const TTimeIntervalMicroSeconds delta = end.MicroSecondsFrom(iStart); + + +// const TTimeIntervalMicroSeconds end = iPlayer->Position(); + + + + + const TInt diff = specTime - delta.Int64(); + + if(diff > 0 && diff < 200000) + { + User::After(diff); + } + + } + else + { + User::After(10000); +// iWait->Wait(10000); //just give some time... + } + } + +void CEpocAudio::Open(TInt aRate, TInt aChannels, TUint32 aType, TInt aBytes) + { + iRate = aRate; + iChannels = aChannels; + iType = aType; + iBufferRate = iRate * iChannels * aBytes; //1/x + } + + +/* Audio driver bootstrap functions */ + +AudioBootStrap EPOCAudio_bootstrap = { + "epoc\0\0\0", + "EPOC streaming audio\0\0\0", + Audio_Available, + Audio_CreateDevice +}; + + +static SDL_AudioDevice *Audio_CreateDevice(int /*devindex*/) +{ + SDL_AudioDevice *thisdevice; + + /* Initialize all variables that we clean on shutdown */ + thisdevice = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice)); + if ( thisdevice ) { + memset(thisdevice, 0, (sizeof *thisdevice)); + thisdevice->hidden = NULL; /*(struct SDL_PrivateAudioData *) + malloc((sizeof thisdevice->hidden)); */ + } + if ( (thisdevice == NULL) /*|| (thisdevice->hidden == NULL) */) { + SDL_OutOfMemory(); + if ( thisdevice ) { + free(thisdevice); + } + return(0); + } +// memset(thisdevice->hidden, 0, (sizeof *thisdevice->hidden)); + + /* Set the function pointers */ + thisdevice->OpenAudio = EPOC_OpenAudio; + thisdevice->WaitAudio = EPOC_WaitAudio; + thisdevice->PlayAudio = EPOC_PlayAudio; + thisdevice->GetAudioBuf = EPOC_GetAudioBuf; + thisdevice->CloseAudio = EPOC_CloseAudio; + thisdevice->ThreadInit = EPOC_ThreadInit; + thisdevice->free = Audio_DeleteDevice; + + return thisdevice; +} + + +static void Audio_DeleteDevice(SDL_AudioDevice *device) + { + //free(device->hidden); + free(device); + } + +static int Audio_Available(void) +{ + return(1); // Audio stream modules should be always there! +} + + +static int EPOC_OpenAudio(SDL_AudioDevice *thisdevice, SDL_AudioSpec *spec) +{ + SDL_TRACE("SDL:EPOC_OpenAudio"); + + + TUint32 type = KMMFFourCCCodePCM16; + TInt bytes = 2; + + switch(spec->format) + { + case AUDIO_U16LSB: + type = KMMFFourCCCodePCMU16; + break; + case AUDIO_S16LSB: + type = KMMFFourCCCodePCM16; + break; + case AUDIO_U16MSB: + type = KMMFFourCCCodePCMU16B; + break; + case AUDIO_S16MSB: + type = KMMFFourCCCodePCM16B; + break; + //8 bit not supported! + case AUDIO_U8: + case AUDIO_S8: + default: + spec->format = AUDIO_S16LSB; + }; + + + + if(spec->channels > 2) + spec->channels = 2; + + spec->freq = CStreamPlayer::ClosestSupportedRate(spec->freq); + + + /* Allocate mixing buffer */ + const TInt buflen = spec->size;// * bytes * spec->channels; +// audiobuf = NULL; + + TRAPD(err, thisdevice->hidden = static_cast(CEpocAudio::NewL(buflen, spec->silence))); + if(err != KErrNone) + return -1; + + CEpocAudio::Current(thisdevice).Open(spec->freq, spec->channels, type, bytes); + + CEpocAudio::Current(thisdevice).SetPause(ETrue); + + // isSDLAudioPaused = 1; + + thisdevice->enabled = 0; /* enable only after audio engine has been initialized!*/ + + /* We're ready to rock and roll. :-) */ + return(0); +} + + +static void EPOC_CloseAudio(SDL_AudioDevice* thisdevice) + { +#ifdef DEBUG_AUDIO + SDL_TRACE("Close audio\n"); +#endif + + CEpocAudio::Free(thisdevice); + } + + +static void EPOC_ThreadInit(SDL_AudioDevice *thisdevice) + { + SDL_TRACE("SDL:EPOC_ThreadInit"); + CEpocAudio::Current(thisdevice).ThreadInitL(thisdevice); + RThread().SetPriority(EPriorityMore); + thisdevice->enabled = 1; + } + +/* This function waits until it is possible to write a full sound buffer */ +static void EPOC_WaitAudio(SDL_AudioDevice* thisdevice) +{ +#ifdef DEBUG_AUDIO + SDL_TRACE1("wait %d audio\n", CEpocAudio::AudioLib().StreamPlayer(KSfxChannel).SyncTime()); + TInt tics = User::TickCount(); +#endif + + CEpocAudio::Current(thisdevice).Wait(); + +#ifdef DEBUG_AUDIO + TInt ntics = User::TickCount() - tics; + SDL_TRACE1("audio waited %d\n", ntics); + SDL_TRACE1("audio at %d\n", tics); +#endif +} + + + +static void EPOC_PlayAudio(SDL_AudioDevice* thisdevice) + { + if(CEpocAudio::Current(thisdevice).SetPause(SDL_GetAudioStatus() == SDL_AUDIO_PAUSED)) + SDL_Delay(500); //hold on the busy loop + else + CEpocAudio::Current(thisdevice).Play(); + +#ifdef DEBUG_AUDIO + SDL_TRACE("buffer has audio data\n"); +#endif + + +#ifdef DEBUG_AUDIO + SDL_TRACE1("Wrote %d bytes of audio data\n", buflen); +#endif +} + +static Uint8 *EPOC_GetAudioBuf(SDL_AudioDevice* thisdevice) + { + return CEpocAudio::Current(thisdevice).Buffer(); + } + + + diff --git a/src/audio/symbian/SDL_epocaudio.h b/src/audio/symbian/SDL_epocaudio.h new file mode 100644 index 000000000..d08c4c24f --- /dev/null +++ b/src/audio/symbian/SDL_epocaudio.h @@ -0,0 +1,37 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_epocaudio.h,v 1.1.2.2 2001/02/10 07:20:03 hercules Exp $"; +#endif + +#ifndef _SDL_EPOCAUDIO_H +#define _SDL_EPOCAUDIO_H + +extern "C" { +#include "SDL_sysaudio.h" +} + + +#endif /* _SDL_EPOCAUDIO_H */ diff --git a/src/audio/symbian/streamplayer.cpp b/src/audio/symbian/streamplayer.cpp new file mode 100644 index 000000000..dd733a1d1 --- /dev/null +++ b/src/audio/symbian/streamplayer.cpp @@ -0,0 +1,279 @@ +#include "streamplayer.h" +#include + + + +const TInt KMaxVolume(256); + +LOCAL_C TInt GetSampleRate(TInt aRate) + { + switch(aRate) + { + case 8000: return TMdaAudioDataSettings::ESampleRate8000Hz; + case 11025: return TMdaAudioDataSettings::ESampleRate11025Hz; + case 12000: return TMdaAudioDataSettings::ESampleRate12000Hz; + case 16000: return TMdaAudioDataSettings::ESampleRate16000Hz; + case 22050: return TMdaAudioDataSettings::ESampleRate22050Hz; + case 24000: return TMdaAudioDataSettings::ESampleRate24000Hz; + case 32000: return TMdaAudioDataSettings::ESampleRate32000Hz; + case 44100: return TMdaAudioDataSettings::ESampleRate44100Hz; + case 48000: return TMdaAudioDataSettings::ESampleRate48000Hz; + case 96000: return TMdaAudioDataSettings::ESampleRate96000Hz; + case 64000: return TMdaAudioDataSettings::ESampleRate64000Hz; + } + return KErrNotFound; + } + +LOCAL_C TInt GetChannels(TInt aChannels) + { + switch(aChannels) + { + case 1: return TMdaAudioDataSettings::EChannelsMono; + case 2: return TMdaAudioDataSettings::EChannelsStereo; + } + return KErrNotFound; + } + +TInt CStreamPlayer::ClosestSupportedRate(TInt aRate) + { + if(aRate > 96000) + return 96000; + TInt rate = aRate; + while(GetSampleRate(rate) == KErrNotFound) + { + ++rate; + } + return rate; + } + +CStreamPlayer::CStreamPlayer(MStreamProvider& aProvider, MStreamObs& aObs) : + iProvider(aProvider), iObs(aObs), iVolume(KMaxVolume) + { + } + +CStreamPlayer::~CStreamPlayer() + { + iState |= EDied; + if(iState & EInited) + Close(); + User::After(100000); //wait buffer to be flushed + ASSERT(iPtr.Length() == 0); + delete iStream; + } + + +void CStreamPlayer::ConstructL() + { + iStream = CMdaAudioOutputStream::NewL(*this, EMdaPriorityMax); + iSilence.SetMax(); + iSilence.FillZ(); + } + + +TInt CStreamPlayer::OpenStream(TInt aRate, TInt aChannels, TUint32 aType) + { + Close(); + + iType = aType; + + iRate = GetSampleRate(aRate); + if(iRate == KErrNotFound) + return KErrNotSupported; + + iChannels = GetChannels(aChannels); + if(iChannels == KErrNotFound) + return KErrNotSupported; + + Open(); + + return KErrNone; + } + + +TInt CStreamPlayer::MaxVolume() const + { + return KMaxVolume; + } + +void CStreamPlayer::SetVolume(TInt aNew) + { + + const TInt maxi = MaxVolume(); + if(aNew > maxi) + return; + if(aNew < 0) + return; + + iVolume = aNew; + + iState |= EVolumeChange; + } + + TInt CStreamPlayer::Volume() const + { + return iVolume; + } + +void CStreamPlayer::Open() + { + TMdaAudioDataSettings audioSettings; + audioSettings.Query(); + audioSettings.iCaps = TMdaAudioDataSettings::ERealTime | + TMdaAudioDataSettings::ESampleRateFixed; + audioSettings.iSampleRate = iRate; + audioSettings.iChannels = iChannels; + audioSettings.iFlags = TMdaAudioDataSettings::ENoNetworkRouting; + audioSettings.iVolume = 0; + + iState &= ~EStopped; + iStream->Open(&audioSettings); + } + +void CStreamPlayer::Stop() + { + if(iState & (EStarted | EInited)) + { + Close(); + iState |= EStopped; + } + } + +void CStreamPlayer::Start() + { + if(iPtr.Length() == 0) + { + iState |= EStarted; + if(iState & EInited) + { + Request(); + } + else if(iState & EStopped) + { + Open(); + } + } + } + +void CStreamPlayer::Close() + { + iState &= ~EInited; + iStream->Stop(); + iState &= ~EStarted; + } + +void CStreamPlayer::Request() + { + if(iState & EInited) + { + iPtr.Set(KNullDesC8); + + if(iState & EVolumeChange) + { + const TReal newVol = iVolume; + const TReal newMax = MaxVolume(); + const TInt maxVol = iStream->MaxVolume(); + const TReal max = static_cast(maxVol); + const TReal newvolume = (newVol * max) / newMax; + const TInt vol = static_cast(newvolume); + iStream->SetVolume(vol); + iState &= ~EVolumeChange; + } + + if(iState & EStarted) + { + iPtr.Set(iProvider.Data()); + } + if(iPtr.Length() == 0) + { + iPtr.Set(iSilence); + } + TRAPD(err, iStream->WriteL(iPtr)); + if(err != KErrNone) + { + iObs.Complete(MStreamObs::EWrite, err); + } + /* else + { + iProvider.Written(iPtr.Length()); + }*/ + } + } + + +void CStreamPlayer::SetCapsL() + { + iStream->SetDataTypeL(iType); + iStream->SetAudioPropertiesL(iRate, iChannels); + } + +void CStreamPlayer::MaoscOpenComplete(TInt aError) + { + if(aError == KErrNone) + { + TRAPD(err, SetCapsL()); + if(err == KErrNone) + { + iStream->SetPriority(EPriorityNormal, EMdaPriorityPreferenceTime); + iState |= EInited; + + + SetVolume(Volume()); + + if(iState & EStarted) + { + Request(); + } + + } + aError = err; + } + if(!(iState & EDied)) + iObs.Complete(MStreamObs::EInit, aError); + } + +void CStreamPlayer::MaoscBufferCopied(TInt aError, const TDesC8& /*aBuffer*/) + { + iPtr.Set(KNullDesC8); + if(aError == KErrNone) + { + if(iState & EInited) + Request(); + else + iStream->Stop(); + } + else if(!(iState & EDied)) + iObs.Complete(MStreamObs::EPlay, aError); + } + +void CStreamPlayer::MaoscPlayComplete(TInt aError) + { + iPtr.Set(KNullDesC8); + iState &= ~EStarted; + if(!(iState & EDied)) + iObs.Complete(MStreamObs::EClose, aError); + } + +TBool CStreamPlayer::Playing() const + { + return (iState & EInited) && (iState & EStarted); + } + +TBool CStreamPlayer::Closed() const + { + return !(iState & EInited) && !(iState & EDied); + } + + /* +void CStreamPlayer::Request() + { + SetActive(); + TRequestStatus* s = &iStatus; + User::RequestComplete(s, KErrNone); + } + // iTimer.After(0); + */ + + + + + diff --git a/src/audio/symbian/streamplayer.h b/src/audio/symbian/streamplayer.h new file mode 100644 index 000000000..8c6e74f92 --- /dev/null +++ b/src/audio/symbian/streamplayer.h @@ -0,0 +1,89 @@ +#ifndef STREAMPLAYER_H +#define STREAMPLAYER_H + +#include + +const TInt KSilenceBuffer = 256; + +class MStreamObs + { + public: + enum + { + EInit, + EPlay, + EWrite, + EClose, + }; + virtual void Complete(TInt aState, TInt aError) = 0; + }; + +class MStreamProvider + { + public: + virtual TPtrC8 Data() = 0; + }; + +NONSHARABLE_CLASS(CStreamPlayer) : public CBase, public MMdaAudioOutputStreamCallback + { + public: + CStreamPlayer(MStreamProvider& aProvider, MStreamObs& aObs); + ~CStreamPlayer(); + void ConstructL(); + + static TInt ClosestSupportedRate(TInt aRate); + + TInt OpenStream(TInt aRate, TInt aChannels, TUint32 aType = KMMFFourCCCodePCM16); + + void SetVolume(TInt aNew); + TInt Volume() const; + TInt MaxVolume() const; + + void Stop(); + void Start(); + void Open(); + void Close(); + + TBool Playing() const; + TBool Closed() const; + + private: + + void MaoscOpenComplete(TInt aError) ; + void MaoscBufferCopied(TInt aError, const TDesC8& aBuffer); + void MaoscPlayComplete(TInt aError); + + private: + void Request(); + void SetCapsL(); + + private: + MStreamProvider& iProvider; + MStreamObs& iObs; + TInt iVolume; + + CMdaAudioOutputStream* iStream; + + TInt iRate; + TInt iChannels; + TUint32 iType; + + enum + { + ENone = 0, + EInited = 0x1, + EStarted = 0x2, + EStopped = 0x4, + EVolumeChange = 0x8, + EDied = 0x10 + }; + + TInt iState; + TBuf8 iSilence; + TPtrC8 iPtr; + + }; + + +#endif + diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 1a51dbd7e..e246fb78b 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -169,7 +169,7 @@ static int SDL_StartEventThread(Uint32 flags) /* The event thread will handle timers too */ SDL_SetTimerThreaded(2); -#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) +#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) && !defined(__SYMBIAN32__) #undef SDL_CreateThread SDL_EventThread = SDL_CreateThread(SDL_GobbleEvents, NULL, NULL, NULL); #else diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index add218fd2..c47f43862 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -29,7 +29,7 @@ #include "SDL_rwops.h" -#if defined(__WIN32__) +#if defined(__WIN32__) && !defined(__SYMBIAN32__) /* Functions to read/write Win32 API file pointers */ /* Will not use it on WinCE because stdio is buffered, it means @@ -372,7 +372,7 @@ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode) return NULL; } -#if defined(__WIN32__) +#if defined(__WIN32__) && !defined(__SYMBIAN32__) rwops = SDL_AllocRW(); if (!rwops) return NULL; /* SDL_SetError already setup by SDL_AllocRW() */ diff --git a/src/main/symbian/EKA1/SDL_main.cpp b/src/main/symbian/EKA1/SDL_main.cpp new file mode 100644 index 000000000..a3296e43a --- /dev/null +++ b/src/main/symbian/EKA1/SDL_main.cpp @@ -0,0 +1,152 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* + SDL_main.cpp + The Epoc executable startup functions + + Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SDL_error.h" + +#if defined(__WINS__) +#include +IMPORT_C void RegisterWsExe(const TDesC &aName); +#endif + +/* The prototype for the application's main() function */ +#define main SDL_main +extern "C" int main (int argc, char *argv[], char *envp[]); +extern "C" void exit (int ret); + + +/* Epoc main function */ + +#ifdef __WINS__ + + +void GetCmdLine(int& aArgc, char**& aArgv) + { + RChunk chunk; + + if(chunk.OpenGlobal(RThread().Name(), ETrue) != KErrNone) + return; + + TUint* ptr = (TUint*) chunk.Base(); + if(ptr != NULL) + { + aArgc = (int) *(ptr); // count + aArgv = (char**) *(ptr + 1); + } + chunk.Close(); + } + +#endif + + +TInt E32Main() + { + /* Get the clean-up stack */ + CTrapCleanup* cleanup = CTrapCleanup::New(); + + /* Arrange for multi-threaded operation */ + SpawnPosixServerThread(); + + /* Get args and environment */ + int argc=0; + char** argv=0; + char** envp=0; + +#ifndef __WINS__ + __crt0(argc,argv,envp); +#else + GetCmdLine(argc, argv); +#endif + /* Start the application! */ + + /* Create stdlib */ + _REENT; + + /* Set process and thread priority and name */ + + RThread currentThread; + RProcess thisProcess; + TParse exeName; + exeName.Set(thisProcess.FileName(), NULL, NULL); + currentThread.Rename(exeName.Name()); + currentThread.SetProcessPriority(EPriorityLow); + currentThread.SetPriority(EPriorityMuchLess); + + /* Call stdlib main */ + int ret = main(argc, argv, envp); /* !! process exits here if there is "exit()" in main! */ + + /* Call exit */ + //exit(ret); /* !! process exits here! */ + //Markus: I do not understand above + //I commented it at let this function + //to return ret value - was it purpose + //that cleanup below is not called at all - why? + + /* Free resources and return */ + + _cleanup(); //this is normally called at exit, I call it here, Markus + + CloseSTDLIB(); + delete cleanup; +#ifdef __WINS__ +// User::Panic(_L("exit"), ret); + // RThread().Kill(ret); //Markus get rid of this thread + // RThread().RaiseException(EExcKill); +#endif + return ret;//Markus, or exit(ret); ?? + //return(KErrNone); + } + + +#ifdef __WINS__ +EXPORT_C TInt WinsMain() + { + return E32Main(); + // return WinsMain(0, 0, 0); + } +#endif + +/* Epoc dll entry point */ +#if defined(__WINS__) +GLDEF_C TInt E32Dll(TDllReason) + { + return(KErrNone); + } +#endif + + diff --git a/src/main/symbian/EKA2/SDL_main.cpp b/src/main/symbian/EKA2/SDL_main.cpp new file mode 100644 index 000000000..3dc69d4aa --- /dev/null +++ b/src/main/symbian/EKA2/SDL_main.cpp @@ -0,0 +1,1035 @@ +/* + SDL_Main.cpp + Symbian OS services for SDL + + Markus Mertama +*/ + + +#include "epoc_sdl.h" + +#include"sdlepocapi.h" +#include +#include +#include +#include + +#include "vectorbuffer.h" +#include +#include +#include +#include "SDL_epocevents_c.h" +#include "SDL_keysym.h" +#include "dsa.h" + + +#ifdef SYMBIANC +#include +#endif + +//Markus Mertama + + +extern SDLKey* KeyMap(); +extern void ResetKeyMap(); + +class CCurrentAppUi; + +//const TUid KSDLUid = { 0xF01F3D69 }; + +NONSHARABLE_CLASS(EnvUtils) + { + public: + static void DisableKeyBlocking(); + static TBool Rendezvous(RThread& aThread, TRequestStatus& aStatus); + }; + +TInt Panic(TInt aErr, TInt aLine) + { + TBuf<64> b; + b.Format(_L("Main at %d"), aLine); + User::Panic(b, aErr); + return 0; + } + + +NONSHARABLE_CLASS(CCurrentAppUi) : public CAknAppUi + { + public: + static CCurrentAppUi* Cast(CEikAppUi* aUi); + void DisableKeyBlocking(); + }; + + +CCurrentAppUi* CCurrentAppUi::Cast(CEikAppUi* aUi) + { + return static_cast(aUi); + } + +void CCurrentAppUi::DisableKeyBlocking() + { + SetKeyBlockMode(ENoKeyBlock); + } + + +class CEventQueue : public CBase, public MEventQueue + { + public: + static CEventQueue* NewL(); + ~CEventQueue(); + public: + TInt Append(const TWsEvent& aEvent); + const TWsEvent& Shift(); + void Lock(); + void Unlock(); + TBool HasData(); + private: + TVector iVector; + RCriticalSection iCS; + }; + + CEventQueue* CEventQueue::NewL() + { + CEventQueue* q = new (ELeave) CEventQueue(); + CleanupStack::PushL(q); + User::LeaveIfError(q->iCS.CreateLocal()); + CleanupStack::Pop(); + return q; + } + +CEventQueue::~CEventQueue() + { + iCS.Close(); + } + +TInt CEventQueue::Append(const TWsEvent& aEvent) + { + iCS.Wait(); + const TInt err = iVector.Append(aEvent); + iCS.Signal(); + return err; + } + + +TBool CEventQueue::HasData() + { + return iVector.Size() > 0; + } + + +void CEventQueue::Lock() + { + iCS.Wait(); + } + +void CEventQueue::Unlock() + { + iCS.Signal(); + } + +const TWsEvent& CEventQueue::Shift() + { + const TWsEvent& event = iVector.Shift(); + return event; + } + + +TSdlCleanupItem::TSdlCleanupItem(TSdlCleanupOperation aOperation, TAny* aItem) : +iOperation(aOperation), iItem(aItem), iThread(RThread().Id()) + { + } + +class CEikonEnv; +class CSdlAppServ; + + +NONSHARABLE_CLASS(EpocSdlEnvData) + { + public: + void Free(); + CEventQueue* iEventQueue; + TMainFunc iMain; + TInt iEpocEnvFlags; + int iArgc; + char** iArgv; + CDsa* iDsa; + CSdlAppServ* iAppSrv; + TThreadId iId; + CArrayFix* iCleanupItems; + CEikAppUi* iAppUi; + CSDL* iSdl; + }; + + +EpocSdlEnvData* gEpocEnv; + +#define MAINFUNC(x) EXPORT_C TMainFunc::TMainFunc(mainfunc##x aFunc){Mem::FillZ(iMainFunc, sizeof(iMainFunc)); iMainFunc[x - 1] = (void*) aFunc;} + +MAINFUNC(1) +MAINFUNC(2) +MAINFUNC(3) +MAINFUNC(4) +MAINFUNC(5) +MAINFUNC(6) + +EXPORT_C TMainFunc::TMainFunc() + { + Mem::FillZ(iMainFunc, sizeof(iMainFunc)); + } + + +const void* TMainFunc::operator[](TInt aIndex) const + { + return iMainFunc[aIndex]; + } + + +NONSHARABLE_CLASS(CSdlAppServ) : public CActive + { + public: + enum + { + EAppSrvNoop = CDsa::ELastDsaRequest, + EAppSrvWindowWidth, + EAppSrvWindowHeight, + EAppSrvWindowDisplayMode, + EAppSrvWindowPointerCursorMode, + EAppSrvDsaStatus, + EAppSrvStopThread, + EAppSrvWaitDsa + }; + CSdlAppServ(); + void ConstructL(); + ~CSdlAppServ(); + TInt Request(TInt aService); + TInt RequestValue(TInt aService); + void Init(); + void PanicMain(TInt aReason); + void PanicMain(const TDesC& aInfo, TInt aReason); + void SetObserver(MSDLObserver* aObserver); + TInt ObserverEvent(TInt aEvent, TInt aParam); + void SetParam(TInt aParam); + void HandleObserverValue(TInt aService, TInt aReturnValue, TBool aMainThread); + MSDLObserver* Observer(); + private: + void RunL(); + void DoCancel(); + private: + const TThreadId iMainId; + RThread iAppThread; + TInt iService; + TInt iReturnValue; + RSemaphore iSema; + MSDLObserver* iObserver; + TRequestStatus* iStatusPtr; + }; + +CSdlAppServ::CSdlAppServ() : CActive(CActive::EPriorityHigh), iMainId(RThread().Id()) + { + } + + + +MSDLObserver* CSdlAppServ::Observer() + { + return iObserver; + } + + +void CSdlAppServ::SetObserver(MSDLObserver* aObserver) + { + iObserver = aObserver; + } + +TInt CSdlAppServ::ObserverEvent(TInt aEvent, TInt aParam) + { + if(iObserver != NULL) + { + if(RThread().Id() == gEpocEnv->iId) + { + return iObserver->SdlThreadEvent(aEvent, aParam); + } + else if(RThread().Id() == iMainId) + { + return iObserver->SdlEvent(aEvent, aParam); + } + PANIC(KErrNotSupported); + } + return 0; + } + +void CSdlAppServ::PanicMain(TInt aReason) + { + iAppThread.Panic(RThread().Name(), aReason); + } + +void CSdlAppServ::PanicMain(const TDesC& aInfo, TInt aReason) + { + iAppThread.Panic(aInfo, aReason); + } + +void CSdlAppServ::ConstructL() + { + CActiveScheduler::Add(this); + User::LeaveIfError(iSema.CreateLocal(1)); + iStatus = KRequestPending; + iStatusPtr = &iStatus; + SetActive(); + } + + CSdlAppServ::~CSdlAppServ() + { + Cancel(); + if(iSema.Handle() != NULL) + iSema.Signal(); + iSema.Close(); + iAppThread.Close(); + } + +TInt CSdlAppServ::Request(TInt aService) + { + if(RThread().Id() != iAppThread.Id()) + { + iSema.Wait(); + iService = aService; + iAppThread.RequestComplete(iStatusPtr, KErrNone); + return KErrNone; + } + return KErrBadHandle; + } + +TInt CSdlAppServ::RequestValue(TInt aService) + { + Request(aService); + Request(EAppSrvNoop); + return iReturnValue; + } + +void CSdlAppServ::Init() + { + PANIC_IF_ERROR(iAppThread.Open(iMainId)); + } + +void CSdlAppServ::SetParam(TInt aParam) + { + iReturnValue = aParam; + } + +void CSdlAppServ::HandleObserverValue(TInt aService, TInt aReturnValue, TBool aMainThread) + { + if(iObserver != NULL && aMainThread) + { + switch(aService) + { + case MSDLObserver::EEventScreenSizeChanged: + if(aReturnValue == MSDLObserver::EScreenSizeChangedDefaultPalette) + EpocSdlEnv::LockPalette(EFalse); + break; + } + } + if(!aMainThread && aService == MSDLObserver::EEventSuspend) + { + if(iObserver == NULL || + (gEpocEnv->iDsa->Stopped() && aReturnValue != MSDLObserver::ESuspendNoSuspend)) + { + EpocSdlEnv::Suspend(); + } + } + } + +void CSdlAppServ::RunL() + { + if(iStatus == KErrNone) + { + switch(iService) + { + case CSdlAppServ::EAppSrvWaitDsa: + EpocSdlEnv::SetWaitDsa(); + iReturnValue = EpocSdlEnv::IsDsaAvailable(); + // } + // gEpocEnv->iDsa->Stop(); + // gEpocEnv->iDsa->RestartL(); + break; + case CSdlAppServ::EAppSrvStopThread: + gEpocEnv->iDsa->SetSuspend(); + break; + case EpocSdlEnv::EDisableKeyBlocking: + EnvUtils::DisableKeyBlocking(); + break; + + case EAppSrvWindowPointerCursorMode: + iReturnValue = gEpocEnv->iDsa != NULL ? + gEpocEnv->iDsa->Session().PointerCursorMode() : KErrNotReady; + break; + case EAppSrvDsaStatus: + gEpocEnv->iDsa->Stop(); + iReturnValue = KErrNone; + break; + case CDsa::ERequestUpdate: + gEpocEnv->iDsa->UnlockHWSurfaceRequestComplete(); + break; + case EAppSrvNoop: + break; + case MSDLObserver::EEventResume: + case MSDLObserver::EEventSuspend: + case MSDLObserver::EEventScreenSizeChanged: + case MSDLObserver::EEventWindowReserved: + case MSDLObserver::EEventKeyMapInit: + case MSDLObserver::EEventWindowNotAvailable: + case MSDLObserver::EEventMainExit: + iReturnValue = ObserverEvent(iService, iReturnValue); + HandleObserverValue(iService, iReturnValue, ETrue); + break; + default: + PANIC(KErrNotSupported); + } + iStatus = KRequestPending; + iStatusPtr = &iStatus; + SetActive(); + } + iSema.Signal(); + } + +void CSdlAppServ::DoCancel() + { + iSema.Wait(); + TRequestStatus* s = &iStatus; + iAppThread.RequestComplete(s, KErrCancel); + } + + + +MEventQueue& EpocSdlEnv::EventQueue() + { + __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady)); + return *gEpocEnv->iEventQueue; + } + + +TBool EpocSdlEnv::Flags(TInt aFlag) + { + const TInt flag = gEpocEnv->iEpocEnvFlags & aFlag; + return flag == aFlag; + } + +TInt EpocSdlEnv::Argc() + { + __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady)); + return gEpocEnv->iArgc; + } + + +char** EpocSdlEnv::Argv() + { + __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady)); + return gEpocEnv->iArgv; + } + + +TBool EpocSdlEnv::IsDsaAvailable() + { + __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady)); + return gEpocEnv->iDsa != NULL && gEpocEnv->iDsa->IsDsaAvailable(); + } + + +void EpocSdlEnv::WaitDsaAvailable() + { + EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowNotAvailable, 0); + gEpocEnv->iAppSrv->Request(CSdlAppServ::EAppSrvStopThread); + if(EpocSdlEnv::Flags(CSDL::EEnableFocusStop)) + { + EpocSdlEnv::ObserverEvent(MSDLObserver::EEventSuspend, 0); + } + } + +void EpocSdlEnv::Suspend() + { + if(gEpocEnv->iDsa->Stopped() || EpocSdlEnv::Flags(CSDL::EEnableFocusStop)) + { + // gEpocEnv->iDsa->ReleaseStop(); + gEpocEnv->iDsa->SetSuspend(); + RThread().Suspend(); + EpocSdlEnv::ObserverEvent(MSDLObserver::EEventResume, 0); + } + } + +void EpocSdlEnv::SetWaitDsa() + { + if(!IsDsaAvailable()) + { + RThread th; + th.Open(gEpocEnv->iId); + th.Suspend(); + th.Close(); + gEpocEnv->iDsa->SetSuspend(); + } + } + +void EpocSdlEnv::Resume() + { + gEpocEnv->iDsa->Resume(); + RThread th; + th.Open(gEpocEnv->iId); + th.Resume(); + th.Close(); + + const TInt value = gEpocEnv->iAppSrv->ObserverEvent(MSDLObserver::EEventResume, 0); + gEpocEnv->iAppSrv->HandleObserverValue(MSDLObserver::EEventResume, value, ETrue); + } + + +TInt EpocSdlEnv::AllocSwSurface(const TSize& aSize, TDisplayMode aMode) + { + return gEpocEnv->iDsa->AllocSurface(EFalse, aSize, aMode); + } + +TInt EpocSdlEnv::AllocHwSurface(const TSize& aSize, TDisplayMode aMode) + { + return gEpocEnv->iDsa->AllocSurface(ETrue, aSize, aMode); + } + + +void EpocSdlEnv::UnlockHwSurface() + { + gEpocEnv->iDsa->UnlockHwSurface(); + } + +TUint8* EpocSdlEnv::LockHwSurface() + { + return gEpocEnv->iDsa->LockHwSurface(); + } + + +void EpocSdlEnv::UpdateSwSurface() + { + gEpocEnv->iDsa->UpdateSwSurface(); + } + +TBool EpocSdlEnv::AddUpdateRect(TUint8* aAddress, const TRect& aUpdateRect, const TRect& aRect) + { + return gEpocEnv->iDsa->AddUpdateRect(aAddress, aUpdateRect, aRect); + } + +void EpocSdlEnv::Request(TInt aService) + { + __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady)); + gEpocEnv->iAppSrv->Request(aService); + } + + +TSize EpocSdlEnv::WindowSize(const TSize& aRequestedSize) + { + __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady)); + if(EpocSdlEnv::Flags(CSDL::EAllowImageResize) && gEpocEnv->iDsa->WindowSize() != aRequestedSize) + { + TRAP_IGNORE(gEpocEnv->iDsa->CreateZoomerL(aRequestedSize)); + } + return gEpocEnv->iDsa->WindowSize(); + } + + TSize EpocSdlEnv::WindowSize() + { + __ASSERT_DEBUG(gEpocEnv != NULL, PANIC(KErrNotReady)); + return gEpocEnv->iDsa->WindowSize(); + } + +TDisplayMode EpocSdlEnv::DisplayMode() + { + return gEpocEnv->iDsa->DisplayMode(); + } + +TPointerCursorMode EpocSdlEnv::PointerMode() + { + return static_cast + (gEpocEnv->iAppSrv->RequestValue(CSdlAppServ::EAppSrvWindowPointerCursorMode)); + } + +TInt EpocSdlEnv::SetPalette(TInt aFirstcolor, TInt aColorCount, TUint32* aPalette) + { + return gEpocEnv->iDsa->SetPalette(aFirstcolor, aColorCount, aPalette); + } + +void EpocSdlEnv::PanicMain(TInt aErr) + { + gEpocEnv->iAppSrv->PanicMain(aErr); + } + + +TInt EpocSdlEnv::AppendCleanupItem(const TSdlCleanupItem& aItem) + { + TRAPD(err, gEpocEnv->iCleanupItems->AppendL(aItem)); + return err; + } + +void EpocSdlEnv::RemoveCleanupItem(TAny* aItem) + { + for(TInt i = 0; i < gEpocEnv->iCleanupItems->Count(); i++) + { + if(gEpocEnv->iCleanupItems->At(i).iItem == aItem) + gEpocEnv->iCleanupItems->Delete(i); + } + } + +void EpocSdlEnv::CleanupItems() + { + const TThreadId id = RThread().Id(); + TInt last = gEpocEnv->iCleanupItems->Count() - 1; + TInt i; + for(i = last; i >= 0 ; i--) + { + TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i); + if(item.iThread == id) + { + item.iThread = TThreadId(0); + item.iOperation(item.iItem); + } + } + last = gEpocEnv->iCleanupItems->Count() - 1; + for(i = last; i >= 0 ; i--) + { + TSdlCleanupItem& item = gEpocEnv->iCleanupItems->At(i); + if(item.iThread == TThreadId(0)) + { + gEpocEnv->iCleanupItems->Delete(i); + } + } + } + +void EpocSdlEnv::FreeSurface() + { + Request(CSdlAppServ::EAppSrvDsaStatus); + gEpocEnv->iDsa->Free(); + } + +void EpocSdlEnv::LockPalette(TBool aLock) + { + gEpocEnv->iDsa->LockPalette(aLock); + } + +void EpocSdlEnv::ObserverEvent(TInt aService, TInt aParam) + { + const TBool sdlThread = RThread().Id() == gEpocEnv->iId; + const TInt valuea = gEpocEnv->iAppSrv->ObserverEvent(aService, aParam); + gEpocEnv->iAppSrv->HandleObserverValue(aService, valuea, !sdlThread); + if(sdlThread) + { + gEpocEnv->iAppSrv->SetParam(aParam); + const TInt valuet = gEpocEnv->iAppSrv->RequestValue(aService); + gEpocEnv->iAppSrv->HandleObserverValue(aService, valuet, EFalse); + } + } + + +TPoint EpocSdlEnv::WindowCoordinates(const TPoint& aPoint) + { + return gEpocEnv->iDsa->WindowCoordinates(aPoint); + } + +void EpocSdlEnv::PanicMain(const TDesC& aInfo, TInt aErr) + { + gEpocEnv->iAppSrv->PanicMain(aInfo, aErr); + } +//Dsa is a low priority ao, it has to wait if its pending event, but ws +//event has been prioritized before it +//this is not called from app thread! +void EpocSdlEnv::WaitDeviceChange() + { + LockPalette(ETrue); + gEpocEnv->iAppSrv->RequestValue(CSdlAppServ::EAppSrvWaitDsa); + const TSize sz = WindowSize(); + const TInt param = reinterpret_cast(&sz); + ObserverEvent(MSDLObserver::EEventScreenSizeChanged, param); + + // RThread().Suspend(); + } + +LOCAL_C TBool CheckSdl() + { + TInt isExit = ETrue; + RThread sdl; + if(sdl.Open(gEpocEnv->iId) == KErrNone) + { + if(sdl.ExitType() == EExitPending) + { + isExit = EFalse; + } + sdl.Close(); + } + return isExit; + } + +void EpocSdlEnvData::Free() + { + if(RThread().Id() == gEpocEnv->iId) + { + iDsa->Free(); + return; + } + + __ASSERT_ALWAYS(iArgv == NULL || CheckSdl(), PANIC(KErrNotReady)); + + for(TInt i = 0; i < iArgc; i++) + User::Free( iArgv[i] ); + + User::Free(iArgv); + + + delete iEventQueue; + + if(iDsa != NULL) + iDsa->Free(); + + delete iDsa; + delete iAppSrv; + } + +_LIT(KSDLMain, "SDLMain"); + +LOCAL_C int MainL() + { + gEpocEnv->iCleanupItems = new (ELeave) CArrayFixFlat(8); + + char** envp=0; + /* !! process exits here if there is "exit()" in main! */ + int ret = 0; + for(TInt i = 0; i < 6; i++) + { + void* f = (void*) gEpocEnv->iMain[i]; + if(f != NULL) + { + switch(i) + { + case 0: + ret = ((mainfunc1)f)(); + return ret; + case 3: + ((mainfunc1)f)(); + return ret; + case 1: + ret = ((mainfunc2)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv()); + return ret; + case 4: + ((mainfunc2)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv()); + return ret; + case 2: + ret = ((mainfunc3)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp); + return ret; + case 5: + ((mainfunc3)f)(EpocSdlEnv::Argc(), EpocSdlEnv::Argv(), envp); + return ret; + } + } + } + PANIC(KErrNotFound); + return 0; + } + +LOCAL_C TInt DoMain(TAny* /*aParam*/) + { + + + CTrapCleanup* cleanup = CTrapCleanup::New(); + + TBool fbsconnected = EFalse; + if(RFbsSession::GetSession() == NULL) + { + PANIC_IF_ERROR(RFbsSession::Connect()); + fbsconnected = ETrue; + } + + gEpocEnv->iAppSrv->Init(); + +#ifdef SYMBIANC + // Create stdlib + _REENT; +#endif + + // Call stdlib main + int ret = 0; + + //completes waiting rendesvous + RThread::Rendezvous(KErrNone); + + TRAPD(err, err = MainL()); + + EpocSdlEnv::ObserverEvent(MSDLObserver::EEventMainExit, err); + + // Free resources and return + + EpocSdlEnv::CleanupItems(); + + gEpocEnv->iCleanupItems->Reset(); + delete gEpocEnv->iCleanupItems; + gEpocEnv->iCleanupItems = NULL; + + gEpocEnv->Free(); //free up in thread resources + +#ifdef SYMBIANC + _cleanup(); //this is normally called at exit, I call it here +#endif + + if(fbsconnected) + RFbsSession::Disconnect(); + +#ifdef SYMBIANC + CloseSTDLIB(); +#endif + + // delete as; + delete cleanup; + + return err == KErrNone ? ret : err;; + } + + + +EXPORT_C CSDL::~CSDL() + { + gEpocEnv->Free(); + User::Free(gEpocEnv); + gEpocEnv->iSdl = NULL; + } + +EXPORT_C CSDL* CSDL::NewL(TInt aFlags) + { + __ASSERT_ALWAYS(gEpocEnv == NULL, PANIC(KErrAlreadyExists)); + gEpocEnv = (EpocSdlEnvData*) User::AllocL(sizeof(EpocSdlEnvData)); + Mem::FillZ(gEpocEnv, sizeof(EpocSdlEnvData)); + + gEpocEnv->iEpocEnvFlags = aFlags; + gEpocEnv->iEventQueue = CEventQueue::NewL(); + + gEpocEnv->iAppSrv = new (ELeave) CSdlAppServ(); + gEpocEnv->iAppSrv->ConstructL(); + + CSDL* sdl = new (ELeave) CSDL(); + + gEpocEnv->iSdl = sdl; + + return sdl; + } + + /* +EXPORT_C void CSDL::ReInitL(TFlags aFlags) + { + const TFlags prevFlags = gEpocEnv->iEpocEnvFlags; + gEpocEnv->iEpocEnvFlags = aFlags; + TInt err = KErrNone; + if(((prevFlags & EDrawModeDSB) != (aFlags & EDrawModeDSB)) && gEpocEnv->iDsa) + { + delete gEpocEnv->iDsa; + gEpocEnv->iDsa = NULL; + gEpocEnv->iDsa = CDsa::RecreateL(EpocSdlEnv::Flags(CSDL::EDrawModeDSB)); + } + } + */ + + +EXPORT_C void CSDL::SetContainerWindowL(RWindow& aWindow, RWsSession& aSession, CWsScreenDevice& aDevice) + { + if(gEpocEnv->iDsa == NULL) + gEpocEnv->iDsa = CDsa::CreateL(aSession); + gEpocEnv->iDsa->ConstructL(aWindow, aDevice); + } + + +EXPORT_C TThreadId CSDL::CallMainL(const TMainFunc& aFunc, TRequestStatus* const aStatus, const CDesC8Array* const aArg, TInt aFlags, TInt aStackSize) + { + ASSERT(gEpocEnv != NULL); + gEpocEnv->iMain = aFunc; + const TBool args = aArg != NULL; + + gEpocEnv->iArgc = aArg->Count() + 1; + gEpocEnv->iArgv = (char**) User::AllocL(sizeof(char*) * (gEpocEnv->iArgc + 1)); + + TInt k = 0; + const TFileName processName = RProcess().FileName(); + const TInt len = processName.Length(); + gEpocEnv->iArgv[k] = (char*) User::AllocL(len + 1); + Mem::Copy(gEpocEnv->iArgv[k], processName.Ptr(), len); + gEpocEnv->iArgv[k][len] = 0; + + for(TInt i = 0; args && (i < aArg->Count()); i++) + { + k++; + const TInt len = aArg->MdcaPoint(i).Length(); + gEpocEnv->iArgv[k] = (char*) User::AllocL(len + 1); + Mem::Copy(gEpocEnv->iArgv[k], aArg->MdcaPoint(i).Ptr(), len); + gEpocEnv->iArgv[k][len] = 0; + } + + gEpocEnv->iArgv[gEpocEnv->iArgc] = NULL; + + RThread thread; + User::LeaveIfError(thread.Create(KSDLMain, DoMain, aStackSize, NULL, NULL)); + + if(aStatus != NULL) + { + thread.Logon(*aStatus); + } + + gEpocEnv->iId = thread.Id(); + thread.SetPriority(EPriorityLess); + if((aFlags & CSDL::ERequestResume) == 0) + { + thread.Resume(); + } + thread.Close(); + return gEpocEnv->iId; + } + +EXPORT_C TInt CSDL::AppendWsEvent(const TWsEvent& aEvent) + { + return EpocSdlEnv::EventQueue().Append(aEvent); + } + +EXPORT_C void CSDL::SDLPanic(const TDesC& aInfo, TInt aErr) + { + EpocSdlEnv::PanicMain(aInfo, aErr); + } + +EXPORT_C TInt CSDL::GetSDLCode(TInt aScanCode) + { + if(aScanCode < 0) + return MAX_SCANCODE; + if(aScanCode >= MAX_SCANCODE) + return -1; + return KeyMap()[aScanCode]; + } + +EXPORT_C TInt CSDL::SDLCodesCount() const + { + return MAX_SCANCODE; + } + +EXPORT_C void CSDL::ResetSDLCodes() + { + ResetKeyMap(); + } + +EXPORT_C void CSDL::SetOrientation(TOrientationMode aMode) + { + gEpocEnv->iDsa->SetOrientation(aMode); + } + +EXPORT_C TInt CSDL::SetSDLCode(TInt aScanCode, TInt aSDLCode) + { + const TInt current = GetSDLCode(aScanCode); + if(aScanCode >= 0 && aScanCode < MAX_SCANCODE) + KeyMap()[aScanCode] = static_cast(aSDLCode); + return current; + } + + +EXPORT_C MSDLObserver* CSDL::Observer() + { + return gEpocEnv->iAppSrv->Observer(); + } + +EXPORT_C void CSDL::SetObserver(MSDLObserver* aObserver) + { + gEpocEnv->iAppSrv->SetObserver(aObserver); + } + +EXPORT_C void CSDL::Resume() + { + EpocSdlEnv::Resume(); + } + +EXPORT_C void CSDL::Suspend() + { + gEpocEnv->iDsa->DoStop(); + } + +EXPORT_C CSDL::CSDL() + { + } + +EXPORT_C void CSDL::DisableKeyBlocking(CAknAppUi& aAppUi) const + { + gEpocEnv->iAppUi = &aAppUi; + EnvUtils::DisableKeyBlocking(); + } + +EXPORT_C TInt CSDL::SetBlitter(MBlitter* aBlitter) + { + if(gEpocEnv && gEpocEnv->iDsa) + { + gEpocEnv->iDsa->SetBlitter(aBlitter); + return KErrNone; + } + return KErrNotReady; + } + + +EXPORT_C TInt CSDL::AppendOverlay(MOverlay& aOverlay, TInt aPriority) + { + if(gEpocEnv && gEpocEnv->iDsa) + { + return gEpocEnv->iDsa->AppendOverlay(aOverlay, aPriority); + } + return KErrNotReady; + } + +EXPORT_C TInt CSDL::RemoveOverlay(MOverlay& aOverlay) + { + if(gEpocEnv && gEpocEnv->iDsa) + { + return gEpocEnv->iDsa->RemoveOverlay(aOverlay); + } + return KErrNotReady; + } + +EXPORT_C TInt CSDL::RedrawRequest() + { + if(gEpocEnv && gEpocEnv->iDsa) + { + return gEpocEnv->iDsa->RedrawRequest(); + } + return KErrNotReady; + } + +/* +EXPORT_C CSDL* CSDL::Current() + { + return gEpocEnv != NULL ? gEpocEnv->iSdl : NULL; + } + + +EXPORT_C TInt CSDL::SetVolume(TInt aVolume) + { + return EpocSdlEnv::SetVolume(aVolume); + } + +EXPORT_C TInt CSDL::Volume() const + { + return EpocSdlEnv::Volume(); + } + +EXPORT_C TInt CSDL::MaxVolume() const + { + return EpocSdlEnv::MaxVolume(); + } +*/ + +void EnvUtils::DisableKeyBlocking() + { + if(gEpocEnv->iAppUi != NULL) + return CCurrentAppUi::Cast(gEpocEnv->iAppUi)->DisableKeyBlocking(); + } + +TBool EnvUtils::Rendezvous(RThread& aThread, TRequestStatus& aStatus) + { + if(gEpocEnv->iId != TThreadId(0) && + aThread.Open(gEpocEnv->iId) && + aThread.ExitType() == EExitPending) + { + aThread.Rendezvous(aStatus); + return ETrue; + } + return EFalse; + } + + + diff --git a/src/main/symbian/EKA2/sdlexe.cpp b/src/main/symbian/EKA2/sdlexe.cpp new file mode 100644 index 000000000..bb160c409 --- /dev/null +++ b/src/main/symbian/EKA2/sdlexe.cpp @@ -0,0 +1,809 @@ +// INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +// FORWARD DECLARATIONS +class CApaDocument; + + +//const TUid KSDLUID = { 0xF01F605E }; + +LOCAL_C void MakeCCmdLineL(const TDesC8& aParam, CDesC8Array& aArray) + { + + const TChar dq('\"'); + + TLex8 lex(aParam); + TBool in = EFalse; + + lex.SkipSpaceAndMark(); + + while(!lex.Eos()) + { + TPtrC8 ptr; + if(in) + { + const TPtrC8 rem = lex.RemainderFromMark(); + const TInt pos = rem.Locate(dq); + if(pos > 0) + { + lex.Inc(pos); + ptr.Set(lex.MarkedToken()); + lex.SkipAndMark(1); + } + else + { + ptr.Set(rem); + } + in = EFalse; + } + else + { + ptr.Set(lex.NextToken()); + const TInt pos = ptr.Locate(dq); + if(pos == 0) + { + lex.UnGetToMark(); + lex.SkipAndMark(1); + in = ETrue; + continue; // back to in brace + } + else + lex.SkipSpaceAndMark(); + } + + aArray.AppendL(ptr); + + } + } + +NONSHARABLE_CLASS(TVirtualCursor) : public MOverlay + { + public: + TVirtualCursor(); + void Set(const TRect& aRect, CFbsBitmap* aBmp, CFbsBitmap* aAlpha); + void Move(TInt aX, TInt aY); + void MakeEvent(TWsEvent& aEvent, const TPoint& aBasePos) const; + void Toggle(); + TBool IsOn() const; + private: + void Draw(CBitmapContext& aGc, const TRect& aTargetRect, const TSize& aSize); + private: + TRect iRect; + TPoint iInc; + TPoint iPos; + TBool iIsOn; + CFbsBitmap* iCBmp; + CFbsBitmap* iAlpha; + }; + + +TVirtualCursor::TVirtualCursor() : iInc(0, 0), iIsOn(EFalse), iCBmp(NULL) + { + } + +const TInt KMaxMove = 10; + +void TVirtualCursor::Move(TInt aX, TInt aY) + { + if(aX > 0 && iInc.iX > 0) + ++iInc.iX; + else if(aX < 0 && iInc.iX < 0) + --iInc.iX; + else + iInc.iX = aX; + + if(aY > 0 && iInc.iY > 0) + ++iInc.iY; + else if(aY < 0 && iInc.iY < 0) + --iInc.iY; + else + iInc.iY = aY; + + iInc.iX = Min(KMaxMove, iInc.iX); + + iInc.iX = Max(-KMaxMove, iInc.iX); + + iInc.iY = Min(KMaxMove, iInc.iY); + + iInc.iY =Max(-KMaxMove, iInc.iY); + + const TPoint pos = iPos + iInc; + if(iRect.Contains(pos)) + { + iPos = pos; + } + else + { + iInc = TPoint(0, 0); + } + } + + +void TVirtualCursor::Toggle() + { + iIsOn = !iIsOn; + } + + +TBool TVirtualCursor::IsOn() const + { + return iIsOn; + } + +void TVirtualCursor::Set(const TRect& aRect, CFbsBitmap* aBmp, CFbsBitmap* aAlpha) + { + iRect = aRect; + iCBmp = aBmp; + iAlpha = aAlpha; + } + + +void TVirtualCursor::MakeEvent(TWsEvent& aEvent, const TPoint& aBasePos) const + { + aEvent.SetType(EEventPointer), + aEvent.SetTimeNow(); + TPointerEvent& pointer = *aEvent.Pointer(); + pointer.iType = TPointerEvent::EButton1Down; + pointer.iPosition = iPos; + pointer.iParentPosition = aBasePos; + } + + +void TVirtualCursor::Draw(CBitmapContext& aGc, const TRect& /*aTargetRect*/, const TSize& /*aSize*/) + { + if(iIsOn && iCBmp != NULL) + { + const TRect rect(TPoint(0, 0), iCBmp->SizeInPixels()); + aGc.AlphaBlendBitmaps(iPos, iCBmp, rect, iAlpha, TPoint(0, 0)); + } + + } + +NONSHARABLE_CLASS(TSdlClass) + { + public: + TSdlClass(); + void SetMain(const TMainFunc& aFunc, TInt aFlags, MSDLMainObs* aObs, TInt aExeFlags); + TInt SdlFlags() const; + const TMainFunc& Main() const; + void SendEvent(TInt aEvent, TInt aParam, CSDL* aSDL); + TInt AppFlags() const; + void AppFlags(TInt aFlags); + private: + TMainFunc iFunc; + TInt iSdlFlags; + TInt iExeFlags; + MSDLMainObs* iObs; + }; + + +void TSdlClass::AppFlags(TInt aFlags) + { + iExeFlags |= aFlags; + } + +void TSdlClass::SendEvent(TInt aEvent, TInt aParam, CSDL* aSDL) + { + if(iObs != NULL) + iObs->SDLMainEvent(aEvent, aParam, aSDL); + } + +TInt TSdlClass::AppFlags() const + { + return iExeFlags; + } + +void TSdlClass::SetMain(const TMainFunc& aFunc, TInt aFlags, MSDLMainObs* aObs, TInt aExeFlags) + { + iFunc = aFunc; + iSdlFlags = aFlags; + iExeFlags = aExeFlags; + iObs = aObs; + } + +const TMainFunc& TSdlClass::Main() const + { + return iFunc; + } + + + TInt TSdlClass::SdlFlags() const + { + return iSdlFlags; + } + + + +TSdlClass::TSdlClass() + { + Mem::FillZ(this, sizeof(this)); + } + +TSdlClass gSDLClass; + + +//////////////////////////////////////////////////////////////// + +NONSHARABLE_CLASS(CSDLApplication) : public CAknApplication + { + public: + CSDLApplication(); + private: + CApaDocument* CreateDocumentL(); + TFileName ResourceFileName() const; + TUid AppDllUid() const; + void FindMeL(); + TUid iUid; + }; + +NONSHARABLE_CLASS(CSDLDocument) : public CEikDocument + { + public: + CSDLDocument(CEikApplication& aApp); + private: + CEikAppUi* CreateAppUiL(); + + }; + + //////////////////////////////////////////////////////////////////// + + +NONSHARABLE_CLASS(MExitWait) + { + public: + virtual void DoExit(TInt aErr) = 0; + }; + +///////////////////////////////////////////////////////////////////////// + +NONSHARABLE_CLASS(CExitWait) : public CActive + { + public: + CExitWait(MExitWait& aWait); + ~CExitWait(); + private: + void RunL(); + void DoCancel(); + private: + MExitWait& iWait; + TRequestStatus* iStatusPtr; + }; + +//////////////////////////////////////////////////////////////////////// + + +NONSHARABLE_CLASS(CSDLWin) : public CCoeControl + { + public: + void ConstructL(const TRect& aRect); + RWindow& GetWindow() const; + void SetNoDraw(); + private: + void Draw(const TRect& aRect) const; + private: + TBool iNoDraw; + }; + + +//////////////////////////////////////////////////////////////////////////// + +NONSHARABLE_CLASS(CSDLAppUi) : public CAknAppUi, public MExitWait, MSDLObserver + { + public: + ~CSDLAppUi(); + private: // New functions + void ConstructL(); + void HandleCommandL(TInt aCommand); + void HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination); + void HandleResourceChangeL(TInt aType); + + void DoExit(TInt aErr); + + TInt SdlEvent(TInt aEvent, TInt aParam); + TInt SdlThreadEvent(TInt aEvent, TInt aParam); + + void StartL(); + static TBool StartL(TAny* aThis); + + TBool ParamEditorL(TDes& aCheat); + + TBool ProcessCommandParametersL(CApaCommandLine &aCommandLine); + + void PrepareToExit(); + void HandleConsoleWindowL(); + void HandleConsoleWindow(); + void HandleForegroundEventL(TBool aForeground); + + static TBool IdleRequestL(TAny* aThis); + + TBool HandleKeyL(const TWsEvent& aEvent); + + + private: + CExitWait* iWait; + CSDLWin* iSDLWin; + CSDL* iSdl; + CIdle* iStarter; + TBool iExitRequest; + CDesC8Array* iParams; + TInt iResOffset; + CIdle* iIdle; + TInt iStdOut; + TVirtualCursor iCursor; + CFbsBitmap* iCBmp; + CFbsBitmap* iAlpha; + // TTime iLastPress; + // CSDL::TOrientationMode iOrientation; + }; + +////////////////////////////////////////////////////////////////////////////////////////7 + +CApaDocument* CSDLApplication::CreateDocumentL() + { + return new (ELeave) CSDLDocument(*this); + } + +TUid CSDLApplication::AppDllUid() const + { + return iUid; + } + + +CSDLApplication::CSDLApplication() + { + TRAPD(err, FindMeL()); + ASSERT(err == KErrNone); + } + +void CSDLApplication::FindMeL() + { + RApaLsSession apa; + User::LeaveIfError(apa.Connect()); + CleanupClosePushL(apa); + User::LeaveIfError(apa.GetAllApps()); + TFileName name = RProcess().FileName(); + TApaAppInfo info; + while(apa.GetNextApp(info) == KErrNone) + { + if(info.iFullName.CompareF(name) == 0) + { + iUid = info.iUid; + break; + } + } + CleanupStack::PopAndDestroy(); + } + +TFileName CSDLApplication::ResourceFileName() const + { + return KNullDesC(); + } + +/////////////////////////////////////////////////////////////////////////////////////////// + +CExitWait::CExitWait(MExitWait& aWait) : CActive(CActive::EPriorityStandard), iWait(aWait) + { + CActiveScheduler::Add(this); + SetActive(); + iStatusPtr = &iStatus; + } + +CExitWait::~CExitWait() + { + Cancel(); + } + +void CExitWait::RunL() + { + if(iStatusPtr != NULL ) + iWait.DoExit(iStatus.Int()); + } + +void CExitWait::DoCancel() + { + if(iStatusPtr != NULL ) + User::RequestComplete(iStatusPtr , KErrCancel); + } + + +////////////////////////////////////////////////////////////////////////////////////////////// + +CSDLDocument::CSDLDocument(CEikApplication& aApp) : CEikDocument(aApp) + {} + +CEikAppUi* CSDLDocument::CreateAppUiL() + { + return new (ELeave) CSDLAppUi; + } + +/////////////////////////////////////////////////////////////////////////// + +void CSDLWin:: ConstructL(const TRect& aRect) + { + CreateWindowL(); + SetRect(aRect); + ActivateL(); + } + + +RWindow& CSDLWin::GetWindow() const + { + return Window(); + } + + +void CSDLWin::Draw(const TRect& /*aRect*/) const + { + if(!iNoDraw) + { + CWindowGc& gc = SystemGc(); + gc.SetPenStyle(CGraphicsContext::ESolidPen); + gc.SetPenColor(KRgbGray); + gc.SetBrushStyle(CGraphicsContext::ESolidBrush); + gc.SetBrushColor(0xaaaaaa); + gc.DrawRect(Rect()); + } + } + +void CSDLWin::SetNoDraw() + { + iNoDraw = ETrue; + } + +///////////////////////////////////////////////////////////////////////// + +CSDLAppUi::~CSDLAppUi() + { + if(iIdle) + iIdle->Cancel(); + delete iIdle; + if(iStarter != NULL) + iStarter->Cancel(); + delete iStarter; + delete iWait; + delete iSdl; + delete iSDLWin; + delete iParams; + delete iCBmp; + delete iAlpha; + } + + +void CSDLAppUi::ConstructL() + { + BaseConstructL(ENoAppResourceFile | ENoScreenFurniture); + + + RLibrary lib; + User::LeaveIfError(lib.Load(_L("sdlexe.dll"))); + TFileName name = lib.FileName(); + lib.Close(); + name.Replace(3, name.Length() - 3, _L("resource\\apps\\sdlexe.rsc")); + BaflUtils::NearestLanguageFile(iEikonEnv->FsSession(), name); + iResOffset = iCoeEnv->AddResourceFileL(name); + + name.Replace(name.Length() - 3, 3, _L("mbm")); + + TEntry e; + const TInt err = iEikonEnv->FsSession().Entry(name, e); + + iCBmp = iEikonEnv->CreateBitmapL(name, 0); + iAlpha = iEikonEnv->CreateBitmapL(name, 1); + + iIdle = CIdle::NewL(CActive::EPriorityIdle); + + iSDLWin = new (ELeave) CSDLWin; + iSDLWin->ConstructL(ApplicationRect()); + + iSdl = CSDL::NewL(gSDLClass.SdlFlags()); + + gSDLClass.SendEvent(MSDLMainObs::ESDLCreated, 0, iSdl); + + iSdl->SetObserver(this); + iSdl->DisableKeyBlocking(*this); + iSdl->SetContainerWindowL( + iSDLWin->GetWindow(), + iEikonEnv->WsSession(), + *iEikonEnv->ScreenDevice()); + iSdl->AppendOverlay(iCursor, 0); + + iCursor.Set(TRect(TPoint(0, 0), iSDLWin->Size()), iCBmp, iAlpha); + + iStarter = CIdle::NewL(CActive::EPriorityLow); + iStarter->Start(TCallBack(StartL, this)); + + + } + + + +TBool CSDLAppUi::StartL(TAny* aThis) + { + static_cast(aThis)->StartL(); + return EFalse; + } + + +void CSDLAppUi::PrepareToExit() + { + CAknAppUiBase::PrepareToExit(); //aknappu::PrepareToExit crashes + iCoeEnv->DeleteResourceFile(iResOffset); + } + +TBool CSDLAppUi::ProcessCommandParametersL(CApaCommandLine &aCommandLine) + { + const TPtrC8 cmdLine = aCommandLine.TailEnd(); + iParams = new (ELeave) CDesC8ArrayFlat(8); + MakeCCmdLineL(cmdLine, *iParams); + return EFalse; + } + + + TBool CSDLAppUi::ParamEditorL(TDes& aCheat) + { + CAknTextQueryDialog* query = CAknTextQueryDialog::NewL(aCheat); + CleanupStack::PushL(query); + query->SetPromptL(_L("Enter parameters")); + CleanupStack::Pop(); + return query->ExecuteLD(R_PARAMEDITOR); + } + + void CSDLAppUi::StartL() + { + if(gSDLClass.AppFlags() & SDLEnv::EParamQuery) + { + TBuf8<256> cmd; + RFile file; + TInt err = file.Open(iEikonEnv->FsSession(), _L("sdl_param.txt"),EFileRead); + if(err == KErrNone) + { + file.Read(cmd); + file.Close(); + MakeCCmdLineL(cmd, *iParams); + } + if(err != KErrNone || gSDLClass.AppFlags() & (SDLEnv::EParamQueryDialog ^ SDLEnv::EParamQuery)) + { + TBuf<256> buffer; + if(ParamEditorL(buffer)) + { + cmd.Copy(buffer); + MakeCCmdLineL(cmd, *iParams); + } + } + } + iWait = new (ELeave) CExitWait(*this); + iSdl->CallMainL(gSDLClass.Main(), &iWait->iStatus, iParams, CSDL::ENoParamFlags, 0xA000); + } + +void CSDLAppUi::HandleCommandL(TInt aCommand) + { + switch(aCommand) + { + case EAknSoftkeyBack: + case EAknSoftkeyExit: + case EAknCmdExit: + case EEikCmdExit: + gSDLClass.AppFlags(SDLEnv::EAllowConsoleView); + if(iWait == NULL || !iWait->IsActive() || iSdl == NULL) + { + Exit(); + } + else if(!iExitRequest) + { + iExitRequest = ETrue; //trick how SDL can be closed! + iSdl->Suspend(); + } + break; + } + } + + + +TBool CSDLAppUi::HandleKeyL(const TWsEvent& aEvent) + { + const TInt type = aEvent.Type(); + if(!(type == EEventKey || type == EEventKeyUp || type == EEventKeyDown)) + { + return ETrue; + } + const TKeyEvent& key = *aEvent.Key(); + if((key.iScanCode == EStdKeyYes) && (gSDLClass.AppFlags() & SDLEnv::EVirtualMouse)) + { + if(type == EEventKeyUp) + { + iCursor.Toggle(); + iSdl->RedrawRequest(); + } + return EFalse; + } + if(iCursor.IsOn()) + { + switch(key.iScanCode) + { + case EStdKeyUpArrow: + iCursor.Move(0, -1); + break; + case EStdKeyDownArrow: + iCursor.Move(0, 1); + break; + case EStdKeyLeftArrow: + iCursor.Move(-1, 0); + break; + case EStdKeyRightArrow: + iCursor.Move(1, 0); + break; + case EStdKeyDevice3: + if(type == EEventKeyUp) + { + TWsEvent event; + iCursor.MakeEvent(event, iSDLWin->Position()); + iSdl->AppendWsEvent(event); + } + return EFalse; + default: + return ETrue; + } + iSdl->RedrawRequest(); + return EFalse; + } + return ETrue; + } + + void CSDLAppUi::HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination) + { + if(iSdl && iWait && HandleKeyL(aEvent)) + iSdl->AppendWsEvent(aEvent); + CAknAppUi::HandleWsEventL(aEvent, aDestination); + } + + void CSDLAppUi::HandleResourceChangeL(TInt aType) + { + CAknAppUi::HandleResourceChangeL(aType); + if(aType == KEikDynamicLayoutVariantSwitch) + { + iSDLWin->SetRect(ApplicationRect()); + iSdl->SetContainerWindowL( + iSDLWin->GetWindow(), + iEikonEnv->WsSession(), + *iEikonEnv->ScreenDevice()); + } + } + + +void CSDLAppUi::DoExit(TInt/*Err*/) + { + iExitRequest = ETrue; + Exit(); + } + + + TInt CSDLAppUi::SdlThreadEvent(TInt aEvent, TInt /*aParam*/) + { + switch(aEvent) + { + case MSDLObserver::EEventResume: + break; + case MSDLObserver::EEventSuspend: + if(iExitRequest) + return MSDLObserver::ESuspendNoSuspend; + break; + case MSDLObserver::EEventWindowReserved: + break; + case MSDLObserver::EEventWindowNotAvailable: + break; + case MSDLObserver::EEventScreenSizeChanged: + break; + } + return MSDLObserver::EParameterNone; + } + +TInt CSDLAppUi::SdlEvent(TInt aEvent, TInt /*aParam*/) + { + switch(aEvent) + { + case MSDLObserver::EEventResume: + break; + case MSDLObserver::EEventSuspend: + if(iExitRequest) + return MSDLObserver::ESuspendNoSuspend; + break; + case MSDLObserver::EEventWindowReserved: + break; + case MSDLObserver::EEventWindowNotAvailable: + { + TRAP_IGNORE(HandleConsoleWindowL()); + } + break; + case MSDLObserver::EEventScreenSizeChanged: + break; + case MSDLObserver::EEventKeyMapInit: + break; + case MSDLObserver::EEventMainExit: + if(iStdOut != 0) + { + gSDLClass.AppFlags(SDLEnv::EAllowConsoleView); + iEikonEnv->WsSession().SetWindowGroupOrdinalPosition(iStdOut, 0); + } + break; + } + return MSDLObserver::EParameterNone; + } + +void CSDLAppUi::HandleForegroundEventL(TBool aForeground) + { + CAknAppUi::HandleForegroundEventL(aForeground); + if(!aForeground) + HandleConsoleWindow(); + } + +void CSDLAppUi::HandleConsoleWindow() + { + if(!iIdle->IsActive()) + iIdle->Start(TCallBack(IdleRequestL, this)); + } + +TBool CSDLAppUi::IdleRequestL(TAny* aThis) + { + static_cast(aThis)->HandleConsoleWindowL(); + return EFalse; + } + +void CSDLAppUi::HandleConsoleWindowL() + { + if(gSDLClass.AppFlags() & SDLEnv::EAllowConsoleView) + { + return; + } + RWsSession& ses = iEikonEnv->WsSession(); + const TInt focus = ses.GetFocusWindowGroup(); + CApaWindowGroupName* name = CApaWindowGroupName::NewLC(ses, focus); + const TPtrC caption = name->Caption(); + if(0 == caption.CompareF(_L("STDOUT"))) + { + iStdOut = focus; + ses.SetWindowGroupOrdinalPosition(iEikonEnv->RootWin().Identifier(), 0); + } + CleanupStack::PopAndDestroy(); //name + } + + +//////////////////////////////////////////////////////////////////////// + + +CApaApplication* NewApplication() + { + return new CSDLApplication(); + } + + +EXPORT_C TInt SDLEnv::SetMain(const TMainFunc& aFunc, TInt aSdlFlags, MSDLMainObs* aObs, TInt aSdlExeFlags) + { + gSDLClass.SetMain(aFunc, aSdlFlags, aObs, aSdlExeFlags); + return EikStart::RunApplication(NewApplication); + } + +////////////////////////////////////////////////////////////////////// + +TInt SDLUiPrint(const TDesC8& /*aInfo*/) + { + return KErrNotFound; + } + + + diff --git a/src/main/symbian/EKA2/sdllib.cpp b/src/main/symbian/EKA2/sdllib.cpp new file mode 100644 index 000000000..7c09996ec --- /dev/null +++ b/src/main/symbian/EKA2/sdllib.cpp @@ -0,0 +1,12 @@ +#include +#include +#include + + +GLREF_C TInt E32Main() + { + return SDLEnv::SetMain(SDL_main, CSDL::EEnableFocusStop | CSDL::EAllowImageResize, + NULL, SDLEnv::EParamQuery | SDLEnv::EVirtualMouse); + } + + \ No newline at end of file diff --git a/src/main/symbian/EKA2/vectorbuffer.cpp b/src/main/symbian/EKA2/vectorbuffer.cpp new file mode 100644 index 000000000..72c3b3e5c --- /dev/null +++ b/src/main/symbian/EKA2/vectorbuffer.cpp @@ -0,0 +1,62 @@ +/* + vectorbuffer.cpp + yet another circle buffer + + Markus Mertama +*/ + +#include"vectorbuffer.h" + + + +void VectorPanic(TInt aErr, TInt aLine) + { + TBuf<64> b; + b.Format(_L("vector buffer at % d "), aLine); + User::Panic(b, aErr); + } + +void TNodeBuffer::TNode::Terminator(TNodeBuffer::TNode* aNode) + { + Mem::Copy(iSucc, &aNode, sizeof(TNode*)); + } + +TInt TNodeBuffer::TNode::Size() const + { + return reinterpret_cast(iSucc) - Ptr(); + } + +const TUint8* TNodeBuffer::TNode::Ptr() const + { + return reinterpret_cast(this) + sizeof(TNode); + } + +TNodeBuffer::TNode* TNodeBuffer::TNode::Empty(TUint8* aBuffer) + { + TNode* node = reinterpret_cast(aBuffer); + node->iSucc = node + 1; + return node; + } + + TNodeBuffer::TNode* TNodeBuffer::TNode::New(TNode* aPred, const TDesC8& aData) + { + TNode* node = aPred->Size() == 0 ? aPred : aPred->iSucc; + + + TUint8* start = reinterpret_cast(node) + sizeof(TNode); + node->iSucc = reinterpret_cast(start + aData.Size()); + node->iSucc->iSucc = NULL; //terminator + + __ASSERT_DEBUG(node->Size() == aData.Size(), VECPANIC(KErrCorrupt)); + + Mem::Copy(start, aData.Ptr(), aData.Size()); + return node; + } + + + + + + + + \ No newline at end of file diff --git a/src/main/symbian/EKA2/vectorbuffer.h b/src/main/symbian/EKA2/vectorbuffer.h new file mode 100644 index 000000000..3d8be58d6 --- /dev/null +++ b/src/main/symbian/EKA2/vectorbuffer.h @@ -0,0 +1,240 @@ +/* + vectorbuffer.cpp + yet another circle buffer + + Markus Mertama +*/ + +#ifndef __VECTORBUFFER_H__ +#define __VECTORBUFFER_H__ + +#include +#define VLOG(x) +#define VECPANIC(x) VectorPanic(x, __LINE__) +void VectorPanic(TInt, TInt); + + +//int DEBUG_INT; + +NONSHARABLE_CLASS(TNodeBuffer) + { + public: + protected: + NONSHARABLE_CLASS(TNode) + { + public: + static TNode* Empty(TUint8* iBuffer); + static TNode* New(TNode* aPrev, const TDesC8& aData); + const TUint8* Ptr() const; + TInt Size() const; + inline TNode* Succ(); + static void SetSucc(TNode*& aNode); + void Terminator(TNode* aNode); + private: + TNode* iSucc; + }; + }; + +inline TNodeBuffer::TNode* TNodeBuffer::TNode::Succ() + { + return iSucc; + } + +template +NONSHARABLE_CLASS(TVectorBuffer) : public TNodeBuffer + { + public: + TVectorBuffer(); + TInt Append(const TDesC8& aData); + // TInt AppendOverwrite(const TDesC8& aData); + TPtrC8 Shift(); + TPtrC8 operator[](TInt aIndex) const; + TInt Size() const; + private: + TInt GetRoom(TInt aSize) const; + TInt Unreserved() const; + private: + TNode* iTop; + TNode* iBottom; + TInt iSize; + TUint8 iBuffer[C]; + }; + +template +TVectorBuffer::TVectorBuffer() : iSize(0) + { + Mem::FillZ(iBuffer, C); + iTop = TNode::Empty(iBuffer); //these points to buffer + iBottom = TNode::Empty(iBuffer); + } + +template +TInt TVectorBuffer::Unreserved() const + { + __ASSERT_DEBUG(iBottom < iBottom->Succ(), VECPANIC(KErrCorrupt)); + const TInt bytesbetween = + reinterpret_cast(iBottom->Succ()) - + reinterpret_cast(iTop); + const TInt topsize = sizeof(TNode); + if(bytesbetween > 0) //bytesbetween is room between bottom and top + { //therefore free room is subracted from free space + + const TInt room = C - bytesbetween - topsize; + return room; + } + if(bytesbetween == 0) + { + + if(Size() > 0) + return 0; + else + return C - topsize; + } + const TInt room = -bytesbetween - topsize; //free is space between pointers + return room; + } + +template +TInt TVectorBuffer::GetRoom(TInt aSize) const + { + const TInt bytesnew = sizeof(TNode) + aSize; + const TInt room = Unreserved() - bytesnew; + return room; + } + +template +TInt TVectorBuffer::Append(const TDesC8& aData) //ei ole ok! + { + const TInt len = aData.Length(); + if(GetRoom(len) < 0) + { + return KErrOverflow; + } + if(iBottom->Succ()->Ptr() - iBuffer > (C - (len + TInt(sizeof(TNode))))) + { + VLOG("rc"); + // RDebug::Print(_L("vector: append")); + TNode* p = TNode::Empty(iBuffer); + iBottom->Terminator(p); + iBottom = p; + return Append(aData); + // Append(); + // iBottom = TNode::New(p, aData); //just append something into end + } + + //DEBUG_INT++; + + iBottom = TNode::New(iBottom, aData); + + iSize += len; + return KErrNone; + } + +/* +template +TInt TVectorBuffer::AppendOverwrite(const TDesC8& aData) //ei ole ok! + { + while(Append(aData) == KErrOverflow) + { + if(iTop->Succ() == NULL) + { + return KErrUnderflow; + } + //Shift(); //data is lost + } + return KErrNone; + } +*/ +template +TPtrC8 TVectorBuffer::Shift() + { + __ASSERT_ALWAYS(iTop->Succ() != NULL, VECPANIC(KErrUnderflow)); //can never pass-by bottom + TNode* node = iTop; + iTop = iTop->Succ(); + if(iTop > node) + { + // DEBUG_INT--; + iSize -= node->Size(); + return TPtrC8(node->Ptr(), node->Size()); + } + else + { + // RDebug::Print(_L("vector: shift")); + return Shift(); //this happens when buffer is terminated, and data lies in next + } + } + +template +TInt TVectorBuffer::Size() const + { + return iSize; + } + +template +TPtrC8 TVectorBuffer::operator[](TInt aIndex) const + { + TInt index = 0; + TNode* t = iTop->Size() > 0 ? iTop : iTop->Succ(); //eliminate terminator + while(index < aIndex) + { + TNode* nt = t->Succ(); + if(nt < t) + { + nt = nt->Succ(); + } + t = nt; + if(t->Size() > 0) + index++; + __ASSERT_ALWAYS(t->Succ() != NULL, VECPANIC(KErrUnderflow)); //can never pass-by bottom + } + return t->Ptr(); + } + + +template +NONSHARABLE_CLASS(TVector) : public TVectorBuffer + { + public: + TVector(); + TInt Append(const T& aData); + const T& Shift(); + TInt Size() const; + const T& operator[](TInt aIndex) const; + }; + +template +TVector::TVector() : TVectorBuffer() + { + } + +template +TInt TVector::Append(const T& aData) + { + const TPckgC data(aData); + return TVectorBuffer::Append(data); + } + +template +const T& TVector::Shift() + { + const TPtrC8 ptr = TVectorBuffer::Shift(); + return *(reinterpret_cast(ptr.Ptr())); + } + + +template +TInt TVector::Size() const + { + return TVectorBuffer::Size() / sizeof(T); + } + +template +const T& TVector::operator[](TInt aIndex) const + { + const TPtrC8 ptr = TVectorBuffer::operator[](aIndex); + return *(reinterpret_cast(ptr.Ptr())); + } + +#endif + + diff --git a/src/stdlib/SDL_getenv.c b/src/stdlib/SDL_getenv.c index 74116cc97..d52707ab5 100644 --- a/src/stdlib/SDL_getenv.c +++ b/src/stdlib/SDL_getenv.c @@ -25,7 +25,7 @@ #ifndef HAVE_GETENV -#if defined(__WIN32__) && !defined(_WIN32_WCE) +#if defined(__WIN32__) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) #define WIN32_LEAN_AND_MEAN #include diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h index 6f83bea46..472d8a071 100644 --- a/src/thread/SDL_thread_c.h +++ b/src/thread/SDL_thread_c.h @@ -31,8 +31,6 @@ #include "beos/SDL_systhread_c.h" #elif SDL_THREAD_DC #include "dc/SDL_systhread_c.h" -#elif SDL_THREAD_EPOC -#include "epoc/SDL_systhread_c.h" #elif SDL_THREAD_OS2 #include "os2/SDL_systhread_c.h" #elif SDL_THREAD_PTH @@ -43,6 +41,8 @@ #include "irix/SDL_systhread_c.h" #elif SDL_THREAD_WIN32 #include "win32/SDL_systhread_c.h" +#elif SDL_THREAD_SYMBIAN +#include "symbian/SDL_systhread_c.h" #else #error Need thread implementation for this platform #include "generic/SDL_systhread_c.h" diff --git a/src/thread/symbian/SDL_sysmutex.cpp b/src/thread/symbian/SDL_sysmutex.cpp new file mode 100644 index 000000000..ac20744a4 --- /dev/null +++ b/src/thread/symbian/SDL_sysmutex.cpp @@ -0,0 +1,130 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* + SDL_sysmutex.cpp + + Epoc version by Markus Mertama (w@iki.fi) +*/ + + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_sysmutex.c,v 1.1.2.3 2000/06/22 15:25:23 hercules Exp $"; +#endif + +/* Mutex functions using the Win32 API */ + +//#include +//#include + +#include + +#include "epoc_sdl.h" + +#include "SDL_error.h" +#include "SDL_mutex.h" + + +#ifdef EKA2 //??? +struct SDL_mutex + { + TInt handle; + }; +#else +struct _SDL_mutex + { + TInt handle; + }; +#endif + +extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*); + +TInt NewMutex(const TDesC& aName, TAny* aPtr1, TAny*) + { + return ((RMutex*)aPtr1)->CreateGlobal(aName); + } + +void DeleteMutex(TAny* aMutex) + { + SDL_DestroyMutex ((SDL_mutex*) aMutex); + } + +/* Create a mutex */ +SDL_mutex *SDL_CreateMutex(void) +{ + RMutex rmutex; + + TInt status = CreateUnique(NewMutex, &rmutex, NULL); + if(status != KErrNone) + { + SDL_SetError("Couldn't create mutex"); + } + SDL_mutex* mutex = new /*(ELeave)*/ SDL_mutex; + mutex->handle = rmutex.Handle(); + EpocSdlEnv::AppendCleanupItem(TSdlCleanupItem(DeleteMutex, mutex)); + return(mutex); +} + +/* Free the mutex */ +void SDL_DestroyMutex(SDL_mutex *mutex) +{ + if ( mutex ) + { + RMutex rmutex; + rmutex.SetHandle(mutex->handle); + if(rmutex.IsHeld()) + { + rmutex.Signal(); + } + rmutex.Close(); + EpocSdlEnv::RemoveCleanupItem(mutex); + delete(mutex); + mutex = NULL; + } +} + +/* Lock the mutex */ +int SDL_mutexP(SDL_mutex *mutex) +{ + if ( mutex == NULL ) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + RMutex rmutex; + rmutex.SetHandle(mutex->handle); + rmutex.Wait(); + return(0); +} + +/* Unlock the mutex */ +int SDL_mutexV(SDL_mutex *mutex) +{ + if ( mutex == NULL ) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + RMutex rmutex; + rmutex.SetHandle(mutex->handle); + rmutex.Signal(); + return(0); +} diff --git a/src/thread/symbian/SDL_syssem.cpp b/src/thread/symbian/SDL_syssem.cpp new file mode 100644 index 000000000..55036952b --- /dev/null +++ b/src/thread/symbian/SDL_syssem.cpp @@ -0,0 +1,214 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* + SDL_syssem.cpp + + Epoc version by Markus Mertama (w@iki.fi) +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_syssem.c,v 1.1.2.4 2000/06/22 15:24:48 hercules Exp $"; +#endif + +/* Semaphore functions using the Win32 API */ + +//#include +//#include +#include + +#include "SDL_error.h" +#include "SDL_thread.h" + + +#define SDL_MUTEX_TIMEOUT -2 + +struct SDL_semaphore + { + TInt handle; + TInt count; + }; + + +extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*); +#ifndef EKA2 +extern TInt NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2); +#endif + +TInt NewSema(const TDesC& aName, TAny* aPtr1, TAny* aPtr2) + { + TInt value = *((TInt*) aPtr2); + return ((RSemaphore*)aPtr1)->CreateGlobal(aName, value); + } + +/* Create a semaphore */ +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) +{ + RSemaphore s; + TInt status = CreateUnique(NewSema, &s, &initial_value); + if(status != KErrNone) + { + SDL_SetError("Couldn't create semaphore"); + } + SDL_semaphore* sem = new /*(ELeave)*/ SDL_semaphore; + sem->handle = s.Handle(); + sem->count = initial_value; + return(sem); +} + +/* Free the semaphore */ +void SDL_DestroySemaphore(SDL_sem *sem) +{ + if ( sem ) + { + RSemaphore sema; + sema.SetHandle(sem->handle); + while(--sem->count) + sema.Signal(); + sema.Close(); + delete sem; + sem = NULL; + } +} + +#ifndef EKA2 + + struct TInfo + { + TInfo(TInt aTime, TInt aHandle) : + iTime(aTime), iHandle(aHandle), iVal(0) {} + TInt iTime; + TInt iHandle; + TInt iVal; + }; + + + +TBool ThreadRun(TAny* aInfo) + { + TInfo* info = STATIC_CAST(TInfo*, aInfo); + User::After(info->iTime); + RSemaphore sema; + sema.SetHandle(info->iHandle); + sema.Signal(); + info->iVal = SDL_MUTEX_TIMEOUT; + return 0; + } + +#endif + + +void _WaitAll(SDL_sem *sem) + { + //since SemTryWait may changed the counter. + //this may not be atomic, but hopes it works. + RSemaphore sema; + sema.SetHandle(sem->handle); + sema.Wait(); + while(sem->count < 0) + { + sema.Wait(); + } + } + +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) +{ + if ( ! sem ) { + SDL_SetError("Passed a NULL sem"); + return -1; + } + + if ( timeout == SDL_MUTEX_MAXWAIT ) + { + _WaitAll(sem); + return SDL_MUTEX_MAXWAIT; + } + +#ifdef EKA2 + + RSemaphore sema; + sema.SetHandle(sem->handle); + if(KErrNone == sema.Wait(timeout)) + return 0; + return -1; +#else + RThread thread; + + TInfo* info = new (ELeave)TInfo(timeout, sem->handle); + + TInt status = CreateUnique(NewThread, &thread, info); + + if(status != KErrNone) + return status; + + thread.Resume(); + + _WaitAll(sem); + + if(thread.ExitType() == EExitPending) + { + thread.Kill(SDL_MUTEX_TIMEOUT); + } + + thread.Close(); + + return info->iVal; +#endif +} + +int SDL_SemTryWait(SDL_sem *sem) +{ + if(sem->count > 0) + { + sem->count--; + } + return SDL_MUTEX_TIMEOUT; +} + +int SDL_SemWait(SDL_sem *sem) +{ + return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); +} + +/* Returns the current count of the semaphore */ +Uint32 SDL_SemValue(SDL_sem *sem) +{ + if ( ! sem ) { + SDL_SetError("Passed a NULL sem"); + return 0; + } + return sem->count; +} + +int SDL_SemPost(SDL_sem *sem) +{ + if ( ! sem ) { + SDL_SetError("Passed a NULL sem"); + return -1; + } + sem->count++; + RSemaphore sema; + sema.SetHandle(sem->handle); + sema.Signal(); + return 0; +} diff --git a/src/thread/symbian/SDL_systhread.cpp b/src/thread/symbian/SDL_systhread.cpp new file mode 100644 index 000000000..180391868 --- /dev/null +++ b/src/thread/symbian/SDL_systhread.cpp @@ -0,0 +1,146 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* + SDL_systhread.cpp + Epoc thread management routines for SDL + + Epoc version by Markus Mertama (w@iki.fi) +*/ + +#include "epoc_sdl.h" + +//#include +//#include + + + +extern "C" { +#undef NULL +#include "SDL_error.h" +#include "SDL_thread.h" +#include "SDL_systhread.h" +#include "SDL_thread_c.h" + } + +#include +#include "epoc_sdl.h" + + +static int object_count; + +int RunThread(TAny* data) +{ + CTrapCleanup* cleanup = CTrapCleanup::New(); + TRAPD(err, SDL_RunThread(data)); + EpocSdlEnv::CleanupItems(); + delete cleanup; + return(err); +} + + +TInt NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2) + { + return ((RThread*)(aPtr1))->Create(aName, + RunThread, + KDefaultStackSize, + NULL, + aPtr2); + } + +int CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny* aPtr1, TAny* aPtr2) + { + TBuf<16> name; + TInt status = KErrNone; + do + { + object_count++; + name.Format(_L("SDL_%x"), object_count); + status = aFunc(name, aPtr1, aPtr2); + } + while(status == KErrAlreadyExists); + return status; + } + + +int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) +{ + RThread rthread; + + const TInt status = CreateUnique(NewThread, &rthread, args); + if (status != KErrNone) + { + delete(((RThread*)(thread->handle))); + thread->handle = NULL; + SDL_SetError("Not enough resources to create thread"); + return(-1); + } + rthread.Resume(); + thread->handle = rthread.Handle(); + return(0); +} + +void SDL_SYS_SetupThread(void) +{ + return; +} + +Uint32 SDL_ThreadID(void) +{ + RThread current; + const TThreadId id = current.Id(); + return id; +} + +void SDL_SYS_WaitThread(SDL_Thread *thread) +{ + SDL_TRACE1("Close thread", thread); + RThread t; + const TInt err = t.Open(thread->threadid); + if(err == KErrNone && t.ExitType() == EExitPending) + { + TRequestStatus status; + t.Logon(status); + User::WaitForRequest(status); + } + t.Close(); + + /* RUndertaker taker; + taker.Create(); + TRequestStatus status; + taker.Logon(status, thread->handle); + User::WaitForRequest(status); + taker.Close();*/ + SDL_TRACE1("Closed thread", thread); +} + +/* WARNING: This function is really a last resort. + * Threads should be signaled and then exit by themselves. + * TerminateThread() doesn't perform stack and DLL cleanup. + */ +void SDL_SYS_KillThread(SDL_Thread *thread) +{ + RThread rthread; + rthread.SetHandle(thread->handle); + rthread.Kill(0); + rthread.Close(); +} diff --git a/src/thread/symbian/SDL_systhread_c.h b/src/thread/symbian/SDL_systhread_c.h new file mode 100644 index 000000000..be8b164c1 --- /dev/null +++ b/src/thread/symbian/SDL_systhread_c.h @@ -0,0 +1,30 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* + SDL_systhread_c.h + + Epoc version by Markus Mertama (w@iki.fi) +*/ + +typedef int SYS_ThreadHandle; + diff --git a/src/timer/symbian/SDL_systimer.cpp b/src/timer/symbian/SDL_systimer.cpp new file mode 100644 index 000000000..f2fba3214 --- /dev/null +++ b/src/timer/symbian/SDL_systimer.cpp @@ -0,0 +1,114 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* + SDL_systimer.cpp + + Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi) + Markus Mertama +*/ + +#include +#include + +extern "C" { +#include "SDL_error.h" +#include "SDL_thread.h" +#include "SDL_timer.h" +#include "SDL_timer_c.h" + +static TUint start = 0; +static TInt tickPeriodMilliSeconds; + + +void SDL_StartTicks(void) + { + /* Set first ticks value */ + start = User::TickCount(); + + TTimeIntervalMicroSeconds32 period; + TInt tmp = UserHal::TickPeriod(period); + tickPeriodMilliSeconds = period.Int() / 1000; + } + +Uint32 SDL_GetTicks(void) + { + TUint deltaTics = User::TickCount() - start; + return(deltaTics * tickPeriodMilliSeconds); + } + +void SDL_Delay(Uint32 ms) + { + User::After(TTimeIntervalMicroSeconds32(ms*1000)); + } + +/* Data to handle a single periodic alarm */ +static int timer_alive = 0; +static SDL_Thread *timer = NULL; + +static int RunTimer(void *unused) + { + while ( timer_alive ) + { + if (SDL_timer_running) + { + SDL_ThreadedTimerCheck(); + } + SDL_Delay(10); + } + return(0); + } + +/* This is only called if the event thread is not running */ +int SDL_SYS_TimerInit(void) + { + if(timer != NULL) + return (-1); + timer_alive = 1; + timer = SDL_CreateThread(RunTimer, NULL); + if ( timer == NULL ) + return(-1); + return(SDL_SetTimerThreaded(1)); + } + +void SDL_SYS_TimerQuit(void) + { + timer_alive = 0; + if ( timer ) + { + SDL_WaitThread(timer, NULL); + timer = NULL; + } + } + +int SDL_SYS_StartTimer(void) + { + SDL_SetError("Internal logic error: Epoc uses threaded timer"); + return(-1); + } + +void SDL_SYS_StopTimer(void) + { + return; + } + +} // extern "C" diff --git a/src/video/symbian/EKA1/SDL_epocevents.cpp b/src/video/symbian/EKA1/SDL_epocevents.cpp new file mode 100644 index 000000000..159193342 --- /dev/null +++ b/src/video/symbian/EKA1/SDL_epocevents.cpp @@ -0,0 +1,626 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* + SDL_epocevents.cpp + Handle the event stream, converting Epoc events into SDL events + + Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi) +*/ + + +#include +#undef NULL +extern "C" { +//#define DEBUG_TRACE_ENABLED +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_keysym.h" +#include "SDL_keyboard.h" +#include "SDL_events_c.h" +#include "SDL_timer.h" +}; /* extern "C" */ + +#include "SDL_epocvideo.h" +#include "SDL_epocevents_c.h" + +#include +#include + + +#include + +extern "C" { +/* The translation tables from a console scancode to a SDL keysym */ +static SDLKey keymap[MAX_SCANCODE]; +static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym); +void DisableKeyBlocking(_THIS); +}; /* extern "C" */ + +TBool isCursorVisible = EFalse; + +int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent) +{ + int posted = 0; + SDL_keysym keysym; + +// SDL_TRACE1("hws %d", aWsEvent.Type()); + + switch (aWsEvent.Type()) + { + case EEventPointer: /* Mouse pointer events */ + { + + const TPointerCursorMode mode = Private->EPOC_WsSession.PointerCursorMode(); + + if(mode == EPointerCursorNone) + { + return 0; //TODO: Find out why events are get despite of cursor should be off + } + + const TPointerEvent* pointerEvent = aWsEvent.Pointer(); + TPoint mousePos = pointerEvent->iPosition; + + /*!! TODO Pointer do not yet work properly + //SDL_TRACE1("SDL: EPOC_HandleWsEvent, pointerEvent->iType=%d", pointerEvent->iType); //!! + + if (Private->EPOC_ShrinkedHeight) { + mousePos.iY <<= 1; // Scale y coordinate to shrinked screen height + } + if (Private->EPOC_ShrinkedWidth) { + mousePos.iX <<= 1; // Scale x coordinate to shrinked screen width + } + */ + + posted += SDL_PrivateMouseMotion(0, 0, mousePos.iX, mousePos.iY); /* Absolute position on screen */ + + switch (pointerEvent->iType) + { + case TPointerEvent::EButton1Down: + posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0); + break; + case TPointerEvent::EButton1Up: + posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0); + break; + case TPointerEvent::EButton2Down: + posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0); + break; + case TPointerEvent::EButton2Up: + posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0); + break; + case TPointerEvent::EButton3Down: + posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_MIDDLE, 0, 0); + break; + case TPointerEvent::EButton3Up: + posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0); + break; + } // switch + break; + } + + case EEventKeyDown: /* Key events */ + { +#ifdef SYMBIAN_CRYSTAL + // special case: 9300/9500 rocker down, simulate left mouse button + if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA) + { + const TPointerCursorMode mode = Private->EPOC_WsSession.PointerCursorMode(); + if(mode != EPointerCursorNone) + posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0); + } +#endif + (void*)TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym); + +#ifndef DISABLE_JOYSTICK + /* Special handling */ + switch((int)keysym.sym) { + case SDLK_CAPSLOCK: + if (!isCursorVisible) { + /* Enable virtual cursor */ + HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible); + } + else { + /* Disable virtual cursor */ + HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible); + } + isCursorVisible = !isCursorVisible; + break; + } +#endif + posted += SDL_PrivateKeyboard(SDL_PRESSED, &keysym); + break; + } + + case EEventKeyUp: /* Key events */ + { +#ifdef SYMBIAN_CRYSTAL + // special case: 9300/9500 rocker up, simulate left mouse button + if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA) + { + posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0); + } +#endif + posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym)); + break; + } + + case EEventFocusGained: /* SDL window got focus */ + { + Private->EPOC_IsWindowFocused = ETrue; + posted += SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS); + /* Draw window background and screen buffer */ + DisableKeyBlocking(_this); //Markus: guess why:-) + + RedrawWindowL(_this); + break; + } + + case EEventFocusLost: /* SDL window lost focus */ + { +/* + CFbsBitmap* bmp = new (ELeave) CFbsBitmap(); + bmp->Create(Private->EPOC_ScreenSize, Private->EPOC_DisplayMode); + Private->EPOC_WsScreen->CopyScreenToBitmap(bmp); + Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow); + Private->EPOC_WsWindow.BeginRedraw(TRect(Private->EPOC_WsWindow.Size())); + Private->EPOC_WindowGc->BitBlt(TPoint(0, 0), bmp); + Private->EPOC_WsWindow.EndRedraw(); + Private->EPOC_WindowGc->Deactivate(); + bmp->Save(_L("C:\\scr.mbm")); + delete bmp; +*/ + + Private->EPOC_IsWindowFocused = EFalse; + + posted += SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS); + + RWsSession s; + s.Connect(); + RWindowGroup g(s); + g.Construct(TUint32(&g), EFalse); + g.EnableReceiptOfFocus(EFalse); + RWindow w(s); + w.Construct(g, TUint32(&w)); + w.SetExtent(TPoint(0, 0), Private->EPOC_WsWindow.Size()); + w.SetOrdinalPosition(0); + w.Activate(); + w.Close(); + g.Close(); + s.Close(); + +/* + Private->EPOC_WsSession.SetWindowGroupOrdinalPosition(Private->EPOC_WsWindowGroupID, -1); + + + SDL_Delay(500); + TInt focus = -1; + while(focus < 0) + { + const TInt curr = Private->EPOC_WsSession.GetFocusWindowGroup(); + if(curr != Private->EPOC_WsWindowGroupID) + focus = curr; + else + SDL_Delay(500); + } + + if(1 < Private->EPOC_WsSession.GetWindowGroupOrdinalPriority(Private->EPOC_WsWindowGroupID)) + { + Private->EPOC_WsSession.SetWindowGroupOrdinalPosition(focus, -1); + SDL_Delay(500); + Private->EPOC_WsSession.SetWindowGroupOrdinalPosition(focus, 0); + } +*/ + /*//and the request redraw + TRawEvent redrawEvent; + redrawEvent.Set(TRawEvent::ERedraw); + Private->EPOC_WsSession.SimulateRawEvent(redrawEvent); + Private->EPOC_WsSession.Flush();*/ +#if 0 + //!! Not used + // Wait and eat events until focus is gained again + while (ETrue) { + Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus); + User::WaitForRequest(Private->EPOC_WsEventStatus); + Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent); + TInt eventType = Private->EPOC_WsEvent.Type(); + Private->EPOC_WsEventStatus = KRequestPending; + //Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus); + if (eventType == EEventFocusGained) { + RedrawWindowL(_this); + break; + } + } +#endif + break; + } + + case EEventModifiersChanged: + { + TModifiersChangedEvent* modEvent = aWsEvent.ModifiersChanged(); + TUint modstate = KMOD_NONE; + if (modEvent->iModifiers == EModifierLeftShift) + modstate |= KMOD_LSHIFT; + if (modEvent->iModifiers == EModifierRightShift) + modstate |= KMOD_RSHIFT; + if (modEvent->iModifiers == EModifierLeftCtrl) + modstate |= KMOD_LCTRL; + if (modEvent->iModifiers == EModifierRightCtrl) + modstate |= KMOD_RCTRL; + if (modEvent->iModifiers == EModifierLeftAlt) + modstate |= KMOD_LALT; + if (modEvent->iModifiers == EModifierRightAlt) + modstate |= KMOD_RALT; + if (modEvent->iModifiers == EModifierLeftFunc) + modstate |= KMOD_LMETA; + if (modEvent->iModifiers == EModifierRightFunc) + modstate |= KMOD_RMETA; + if (modEvent->iModifiers == EModifierCapsLock) + modstate |= KMOD_CAPS; + SDL_SetModState(STATIC_CAST(SDLMod,(modstate | KMOD_LSHIFT))); + break; + } + default: + break; + } + + return posted; +} + +extern "C" { + +void EPOC_PumpEvents(_THIS) +{ + int posted = 0; // !! Do we need this? + //Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus); + while (Private->EPOC_WsEventStatus != KRequestPending) { + + Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent); + posted = EPOC_HandleWsEvent(_this, Private->EPOC_WsEvent); + Private->EPOC_WsEventStatus = KRequestPending; + Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus); + } +} + + +_LIT(KMapFileName, "C:\\sdl_info\\sdlkeymap.cfg"); +LOCAL_C void ReadL(RFs& aFs, RArray& aArray) + { + TInt drive = -1; + TFileName name(KMapFileName); + for(TInt i = 'z'; drive < 0 && i >= 'a'; i--) + { + name[0] = (TUint16)i; + if(BaflUtils::FileExists(aFs, name)) + drive = i; + } + if(drive < 0) + return; + CLineReader* reader = CLineReader::NewLC(aFs, name); + while(reader->NextL()) + { + TPtrC ln = reader->Current(); + TLex line(ln); + TInt n = 0; + for(;;) + { + const TPtrC token = line.NextToken(); + if(token.Length() == 0) + break; + if((n & 1) != 0) + { + TInt value; + TLex lex(token); + User::LeaveIfError(lex.Val(value)); + User::LeaveIfError(aArray.Append(value)); + } + n++; + } + } + CleanupStack::PopAndDestroy(); + } + + +void EPOC_InitOSKeymap(_THIS) +{ + int i; + + /* Initialize the key translation table */ + for ( i=0; i array; + TRAPD(err, ReadL(fs, array)); + if(err == KErrNone && array.Count() > 0) + { + + SDLKey temp[MAX_SCANCODE]; + Mem::Copy(temp, keymap, MAX_SCANCODE * sizeof(SDLKey)); + + for(TInt k = 0; k < array.Count(); k+= 2) + { + const TInt oldval = array[k]; + const TInt newval = array[k + 1]; + if(oldval >= 0 && oldval < MAX_SCANCODE && newval >= 0 && newval < MAX_SCANCODE) + { + keymap[oldval] = temp[newval]; + } + } + } + array.Close(); + } + + fs.Close(); + /////////////////////////////////////////////////////////// + + /* !!TODO + EStdKeyNumLock=0x1b, + EStdKeyScrollLock=0x1c, + + EStdKeyNkpForwardSlash=0x84, + EStdKeyNkpAsterisk=0x85, + EStdKeyNkpMinus=0x86, + EStdKeyNkpPlus=0x87, + EStdKeyNkpEnter=0x88, + EStdKeyNkp1=0x89, + EStdKeyNkp2=0x8a, + EStdKeyNkp3=0x8b, + EStdKeyNkp4=0x8c, + EStdKeyNkp5=0x8d, + EStdKeyNkp6=0x8e, + EStdKeyNkp7=0x8f, + EStdKeyNkp8=0x90, + EStdKeyNkp9=0x91, + EStdKeyNkp0=0x92, + EStdKeyNkpFullStop=0x93, + EStdKeyMenu=0x94, + EStdKeyBacklightOn=0x95, + EStdKeyBacklightOff=0x96, + EStdKeyBacklightToggle=0x97, + EStdKeyIncContrast=0x98, + EStdKeyDecContrast=0x99, + EStdKeySliderDown=0x9a, + EStdKeySliderUp=0x9b, + EStdKeyDictaphonePlay=0x9c, + EStdKeyDictaphoneStop=0x9d, + EStdKeyDictaphoneRecord=0x9e, + EStdKeyHelp=0x9f, + EStdKeyOff=0xa0, + EStdKeyDial=0xa1, + EStdKeyIncVolume=0xa2, + EStdKeyDecVolume=0xa3, + EStdKeyDevice0=0xa4, + EStdKeyDevice1=0xa5, + EStdKeyDevice2=0xa6, + EStdKeyDevice3=0xa7, + EStdKeyDevice4=0xa8, + EStdKeyDevice5=0xa9, + EStdKeyDevice6=0xaa, + EStdKeyDevice7=0xab, + EStdKeyDevice8=0xac, + EStdKeyDevice9=0xad, + EStdKeyDeviceA=0xae, + EStdKeyDeviceB=0xaf, + EStdKeyDeviceC=0xb0, + EStdKeyDeviceD=0xb1, + EStdKeyDeviceE=0xb2, + EStdKeyDeviceF=0xb3, + EStdKeyApplication0=0xb4, + EStdKeyApplication1=0xb5, + EStdKeyApplication2=0xb6, + EStdKeyApplication3=0xb7, + EStdKeyApplication4=0xb8, + EStdKeyApplication5=0xb9, + EStdKeyApplication6=0xba, + EStdKeyApplication7=0xbb, + EStdKeyApplication8=0xbc, + EStdKeyApplication9=0xbd, + EStdKeyApplicationA=0xbe, + EStdKeyApplicationB=0xbf, + EStdKeyApplicationC=0xc0, + EStdKeyApplicationD=0xc1, + EStdKeyApplicationE=0xc2, + EStdKeyApplicationF=0xc3, + EStdKeyYes=0xc4, + EStdKeyNo=0xc5, + EStdKeyIncBrightness=0xc6, + EStdKeyDecBrightness=0xc7, + EStdKeyCaseOpen=0xc8, + EStdKeyCaseClose=0xc9 + */ + +} + + + +static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym) +{ +// char debug[256]; + //SDL_TRACE1("SDL: TranslateKey, scancode=%d", scancode); //!! + + /* Set the keysym information */ + + keysym->scancode = scancode; + + if ((scancode >= MAX_SCANCODE) && + ((scancode - ENonCharacterKeyBase + 0x0081) >= MAX_SCANCODE)) { + SDL_SetError("Too big scancode"); + keysym->scancode = SDLK_UNKNOWN; + keysym->mod = KMOD_NONE; + return keysym; + } + + keysym->mod = SDL_GetModState(); + + /* Handle function keys: F1, F2, F3 ... */ + if (keysym->mod & KMOD_META) { + if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphabet keys */ + switch(scancode) { + case 'Q': scancode = EStdKeyF1; break; + case 'W': scancode = EStdKeyF2; break; + case 'E': scancode = EStdKeyF3; break; + case 'R': scancode = EStdKeyF4; break; + case 'T': scancode = EStdKeyF5; break; + case 'Y': scancode = EStdKeyF6; break; + case 'U': scancode = EStdKeyF7; break; + case 'I': scancode = EStdKeyF8; break; + case 'A': scancode = EStdKeyF9; break; + case 'S': scancode = EStdKeyF10; break; + case 'D': scancode = EStdKeyF11; break; + case 'F': scancode = EStdKeyF12; break; + } + keysym->sym = keymap[scancode]; + } + } + + if (scancode >= ENonCharacterKeyBase) { + // Non character keys + keysym->sym = keymap[scancode - + ENonCharacterKeyBase + 0x0081]; // !!hard coded + } else { + keysym->sym = keymap[scancode]; + } + + /* Remap the arrow keys if the device is rotated */ + if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) { + switch(keysym->sym) { + case SDLK_UP: keysym->sym = SDLK_LEFT; break; + case SDLK_DOWN: keysym->sym = SDLK_RIGHT; break; + case SDLK_LEFT: keysym->sym = SDLK_DOWN; break; + case SDLK_RIGHT:keysym->sym = SDLK_UP; break; + } + } + + /* If UNICODE is on, get the UNICODE value for the key */ + keysym->unicode = 0; + +#if 0 // !!TODO:unicode + + if ( SDL_TranslateUNICODE ) + { + /* Populate the unicode field with the ASCII value */ + keysym->unicode = scancode; + } +#endif + + //!! + //sprintf(debug, "SDL: TranslateKey: keysym->scancode=%d, keysym->sym=%d, keysym->mod=%d", + // keysym->scancode, keysym->sym, keysym->mod); + //SDL_TRACE(debug); //!! + + return(keysym); +} + +}; /* extern "C" */ + + diff --git a/src/video/symbian/EKA1/SDL_epocvideo.cpp b/src/video/symbian/EKA1/SDL_epocvideo.cpp new file mode 100644 index 000000000..b944dfc9a --- /dev/null +++ b/src/video/symbian/EKA1/SDL_epocvideo.cpp @@ -0,0 +1,1356 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* + SDL_epocvideo.cpp + Epoc based SDL video driver implementation + + Thanks to Peter van Sebille, the author of EMame. It is a great example of + low level graphics coding in Epoc. + + Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi) + Assembler routines by Kimmo Kinnunen +*/ + + + +#include +#include +#include + +extern "C" { +#include "SDL_error.h" +#include "SDL_timer.h" +#include "SDL_video.h" +#undef NULL +#include "SDL_pixels_c.h" +#include "SDL.h" +}; + +#include "SDL_epocvideo.h" +#include "SDL_epocevents_c.h" + +#include "sdl_epocruntime.h" + +#include +#include +#include + +#ifdef SYMBIAN_QUARTZ +SDL_VideoDevice* _thisDevice; +#endif + +_LIT(KLibName, "SDL"); + +/* For debugging */ + +//if old SOS, from 7.x this is public! +class CLockable : public CFbsBitmap + { + public: + static CLockable* Lockable(CFbsBitmap* aBmp) {return static_cast(aBmp);} + void Lock() {LockHeap();} + void Unlock() {UnlockHeap();} + }; +#define LockHeap(x) CLockable::Lockable(x)->Lock() +#define UnlockHeap(x) CLockable::Lockable(x)->Unlock() + +void RDebug_Print_b(char* error_str, void* param) + { + TBuf8<128> error8((TUint8*)error_str); + TBuf<128> error; + error.Copy(error8); + +#ifndef TRACE_TO_FILE + if (param) //!! Do not work if the parameter is really 0!! + RDebug::Print(error, param); + else + RDebug::Print(error); +#else + if (param) //!! Do not work if the parameter is really 0!! + RFileLogger::WriteFormat(KLibName, _L("SDL.txt"), EFileLoggingModeAppend, error, param); + else + RFileLogger::Write(KLibName, _L("SDL.txt"), EFileLoggingModeAppend, error); +#endif + + } + +extern "C" void RDebug_Print(char* error_str, void* param) + { + RDebug_Print_b(error_str, param); + } + + +int Debug_AvailMem2() + { + //User::CompressAllHeaps(); + TMemoryInfoV1Buf membuf; + User::LeaveIfError(UserHal::MemoryInfo(membuf)); + TMemoryInfoV1 minfo = membuf(); + return(minfo.iFreeRamInBytes); + } + +extern "C" int Debug_AvailMem() + { + return(Debug_AvailMem2()); + } + + +extern "C" { + +/* Initialization/Query functions */ + +static int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat); +static SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); +static SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); +static int EPOC_SetColors(_THIS, int firstcolor, int ncolors, + SDL_Color *colors); +static void EPOC_VideoQuit(_THIS); + +/* Hardware surface functions */ + +static int EPOC_AllocHWSurface(_THIS, SDL_Surface *surface); +static int EPOC_LockHWSurface(_THIS, SDL_Surface *surface); +static int EPOC_FlipHWSurface(_THIS, SDL_Surface *surface); +static void EPOC_UnlockHWSurface(_THIS, SDL_Surface *surface); +static void EPOC_FreeHWSurface(_THIS, SDL_Surface *surface); +static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); + +static int EPOC_Available(void); +static SDL_VideoDevice *EPOC_CreateDevice(int devindex); + +void DrawBackground(_THIS); +void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer); +void DirectDrawRotated(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer); + +/* Mouse functions */ + +static WMcursor *EPOC_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); +static void EPOC_FreeWMCursor(_THIS, WMcursor *cursor); +static int EPOC_ShowWMCursor(_THIS, WMcursor *cursor); + + + +/* !!For 12 bit screen HW. Table for fast conversion from 8 bit to 12 bit */ +// TUint16 is enough, but using TUint32 so we can use better instruction selection on ARMI +static TUint32 EPOC_HWPalette_256_to_Screen[256]; + +VideoBootStrap EPOC_bootstrap = { + "epoc", "EPOC system", + EPOC_Available, EPOC_CreateDevice +}; + +const TUint32 WindowClientHandle = 9210; //!! const + +/* Epoc video driver bootstrap functions */ + +static int EPOC_Available(void) +{ + return 1; /* Always available */ +} + +static void EPOC_DeleteDevice(SDL_VideoDevice *device) +{ + free(device->hidden); + free(device); +} + +static SDL_VideoDevice *EPOC_CreateDevice(int /*devindex*/) +{ + SDL_VideoDevice *device; + + SDL_TRACE("SDL:EPOC_CreateDevice"); + + /* Allocate all variables that we free on delete */ + device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); + if ( device ) { + memset(device, 0, (sizeof *device)); + device->hidden = (struct SDL_PrivateVideoData *) + malloc((sizeof *device->hidden)); + } + if ( (device == NULL) || (device->hidden == NULL) ) { + SDL_OutOfMemory(); + if ( device ) { + free(device); + } + return(0); + } + memset(device->hidden, 0, (sizeof *device->hidden)); + + /* Set the function pointers */ + device->VideoInit = EPOC_VideoInit; + device->ListModes = EPOC_ListModes; + device->SetVideoMode = EPOC_SetVideoMode; + device->SetColors = EPOC_SetColors; + device->UpdateRects = NULL; + device->VideoQuit = EPOC_VideoQuit; + device->AllocHWSurface = EPOC_AllocHWSurface; + device->CheckHWBlit = NULL; + device->FillHWRect = NULL; + device->SetHWColorKey = NULL; + device->SetHWAlpha = NULL; + device->LockHWSurface = EPOC_LockHWSurface; + device->UnlockHWSurface = EPOC_UnlockHWSurface; + device->FlipHWSurface = EPOC_FlipHWSurface; + device->FreeHWSurface = EPOC_FreeHWSurface; + device->SetIcon = NULL; + device->SetCaption = NULL; + device->GetWMInfo = NULL; + device->FreeWMCursor = EPOC_FreeWMCursor; + device->CreateWMCursor = EPOC_CreateWMCursor; + device->ShowWMCursor = EPOC_ShowWMCursor; + device->WarpWMCursor = NULL; + device->InitOSKeymap = EPOC_InitOSKeymap; + device->PumpEvents = EPOC_PumpEvents; + device->free = EPOC_DeleteDevice; + + return device; +} + + +int GetBpp(TDisplayMode displaymode) +{ + /*TInt numColors = TDisplayModeUtils::NumDisplayModeColors(displaymode); + TInt bitsPerPixel = 1; + for (TInt32 i = 2; i < numColors; i <<= 1, bitsPerPixel++); + return bitsPerPixel;*/ + return TDisplayModeUtils::NumDisplayModeBitsPerPixel(displaymode); +} + + +void DisableKeyBlocking(_THIS) + { + // Disable key blocking + TRawEvent event; + event.Set((TRawEvent::TType)/*EDisableKeyBlock*/51); // !!EDisableKeyBlock not found in epoc32\include! + Private->EPOC_WsSession.SimulateRawEvent(event); + } + +void ConstructWindowL(_THIS) +{ + TInt error; + + SDL_TRACE("SDL:ConstructWindowL"); + error = Private->EPOC_WsSession.Connect(); + User::LeaveIfError(error); + Private->EPOC_WsScreen=new(ELeave) CWsScreenDevice(Private->EPOC_WsSession); + User::LeaveIfError(Private->EPOC_WsScreen->Construct()); + User::LeaveIfError(Private->EPOC_WsScreen->CreateContext(Private->EPOC_WindowGc)); + + Private->EPOC_WsWindowGroup=RWindowGroup(Private->EPOC_WsSession); + User::LeaveIfError(Private->EPOC_WsWindowGroup.Construct(WindowClientHandle)); + Private->EPOC_WsWindowGroup.SetOrdinalPosition(0); + + // Set window group name (the same as process name)) !!Gives always "EPOC" in WINS + RProcess thisProcess; + TParse exeName; + exeName.Set(thisProcess.FileName(), NULL, NULL); + TBuf<32> winGroupName; + winGroupName.Append(0); + winGroupName.Append(0); + winGroupName.Append(0);// uid + winGroupName.Append(0); + winGroupName.Append(exeName.Name()); // caption + winGroupName.Append(0); + winGroupName.Append(0); //doc name + Private->EPOC_WsWindowGroup.SetName(winGroupName); + + Private->EPOC_WsWindow=RWindow(Private->EPOC_WsSession); + // Markus, it was: + // User::LeaveIfError(Private->EPOC_WsWindow.Construct(Private->EPOC_WsWindowGroup,WindowClientHandle )); + // but SOS 7.0s debug does not accept same window handle twice + User::LeaveIfError(Private->EPOC_WsWindow.Construct(Private->EPOC_WsWindowGroup,WindowClientHandle - 1)); + Private->EPOC_WsWindow.SetBackgroundColor(KRgbWhite); + Private->EPOC_WsWindow.Activate(); + Private->EPOC_WsWindow.SetSize(Private->EPOC_WsScreen->SizeInPixels()); + Private->EPOC_WsWindow.SetVisible(ETrue); + + Private->EPOC_WsWindowGroupID = Private->EPOC_WsWindowGroup.Identifier(); + Private->EPOC_IsWindowFocused = EFalse; + + DisableKeyBlocking(_this); //disable key blocking +} + +int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat) +{ + // !!TODO:handle leave functions! + + int i; + + SDL_TRACE("SDL:EPOC_VideoInit"); + + /* Initialize all variables that we clean on shutdown */ + + for ( i=0; iSDL_modelist[i] = (SDL_Rect *)malloc(sizeof(SDL_Rect)); + Private->SDL_modelist[i]->x = Private->SDL_modelist[i]->y = 0; + } + + /* Modes sorted largest to smallest */ + Private->SDL_modelist[0]->w = 800; Private->SDL_modelist[0]->h = 250; + Private->SDL_modelist[1]->w = 640; Private->SDL_modelist[1]->h = 480; + Private->SDL_modelist[2]->w = 480; Private->SDL_modelist[2]->h = 600; + Private->SDL_modelist[3]->w = 640; Private->SDL_modelist[3]->h = 400; + Private->SDL_modelist[4]->w = 352; Private->SDL_modelist[4]->h = 416; + Private->SDL_modelist[5]->w = 416; Private->SDL_modelist[5]->h = 352; + Private->SDL_modelist[6]->w = 416; Private->SDL_modelist[6]->h = 312; + Private->SDL_modelist[7]->w = 352; Private->SDL_modelist[7]->h = 264; + Private->SDL_modelist[8]->w = 800; Private->SDL_modelist[8]->h = 240; //for doom all these.. + Private->SDL_modelist[9]->w = 640; Private->SDL_modelist[9]->h = 240; + Private->SDL_modelist[10]->w = 480; Private->SDL_modelist[10]->h = 240; + Private->SDL_modelist[11]->w = 640; Private->SDL_modelist[11]->h = 240; + Private->SDL_modelist[12]->w = 352; Private->SDL_modelist[12]->h = 240; + Private->SDL_modelist[13]->w = 416; Private->SDL_modelist[13]->h = 240; + Private->SDL_modelist[14]->w = 416; Private->SDL_modelist[14]->h = 240; + Private->SDL_modelist[15]->w = 352; Private->SDL_modelist[15]->h = 240; + Private->SDL_modelist[16]->w = 640; Private->SDL_modelist[16]->h = 200; + Private->SDL_modelist[17]->w = 320; Private->SDL_modelist[17]->h = 240; //...for doom, currently engine renders no-higher windows :-(, propably should get fixed + Private->SDL_modelist[18]->w = 320; Private->SDL_modelist[18]->h = 200; + Private->SDL_modelist[19]->w = 256; Private->SDL_modelist[19]->h = 192; + Private->SDL_modelist[20]->w = 176; Private->SDL_modelist[20]->h = 208; + Private->SDL_modelist[21]->w = 208; Private->SDL_modelist[21]->h = 176; // Rotated + Private->SDL_modelist[22]->w = 160; Private->SDL_modelist[22]->h = 144; + + Private->SDL_modelist[23]->w = 640; Private->SDL_modelist[2]->h = 200; //s80 some new modes + Private->SDL_modelist[24]->w = 640; Private->SDL_modelist[2]->h = 320; //s90 modes are added + Private->SDL_modelist[25]->w = 640; Private->SDL_modelist[2]->h = 240; //here + Private->SDL_modelist[26]->w = 640; Private->SDL_modelist[4]->h = 200; //now + + Private->SDL_modelist[27] = NULL; + + /* Construct Epoc window */ + + ConstructWindowL(_this); + + /* Initialise Epoc frame buffer */ + + TDisplayMode displayMode = Private->EPOC_WsScreen->DisplayMode(); + +#if !defined(__WINS__) && !defined(TEST_BM_DRAW) + + TScreenInfoV01 screenInfo; + TPckg sInfo(screenInfo); + UserSvr::ScreenInfo(sInfo); + + Private->EPOC_ScreenSize = screenInfo.iScreenSize; + Private->EPOC_DisplayMode = displayMode; + Private->EPOC_HasFrameBuffer = screenInfo.iScreenAddressValid; + Private->EPOC_FrameBuffer = Private->EPOC_HasFrameBuffer ? (TUint8*) screenInfo.iScreenAddress : NULL; + Private->EPOC_BytesPerPixel = ((GetBpp(displayMode)-1) / 8) + 1; + + Private->EPOC_BytesPerScanLine = screenInfo.iScreenSize.iWidth * Private->EPOC_BytesPerPixel; + Private->EPOC_BytesPerScreen = Private->EPOC_BytesPerScanLine * Private->EPOC_ScreenSize.iHeight; + + SDL_TRACE1("Screen width %d", screenInfo.iScreenSize.iWidth); + SDL_TRACE1("Screen height %d", screenInfo.iScreenSize.iHeight); + SDL_TRACE1("Screen dmode %d", displayMode); + SDL_TRACE1("Screen valid %d", screenInfo.iScreenAddressValid); + + SDL_TRACE1("bpp %d", Private->EPOC_BytesPerPixel); + SDL_TRACE1("bpsl %d", Private->EPOC_BytesPerScanLine); + SDL_TRACE1("bps %d", Private->EPOC_BytesPerScreen); + + + /* It seems that in SA1100 machines for 8bpp displays there is a 512 palette table at the + * beginning of the frame buffer. E.g. Series 7 and Netbook. + * In 12 bpp machines the table has 16 entries. + */ + if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 8) + { + Private->EPOC_FrameBuffer += 512; + } + else + { + Private->EPOC_FrameBuffer += 32; + } + /*if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 12) + Private->EPOC_FrameBuffer += 16 * 2; + if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 16) + Private->EPOC_FrameBuffer += 16 * 2; + */ +#else /* defined __WINS__ */ + + /* Create bitmap, device and context for screen drawing */ + Private->EPOC_ScreenSize = Private->EPOC_WsScreen->SizeInPixels(); + + Private->EPOC_Bitmap = new (ELeave) CWsBitmap(Private->EPOC_WsSession); + Private->EPOC_Bitmap->Create(Private->EPOC_ScreenSize, displayMode); + + Private->EPOC_DisplayMode = displayMode; + Private->EPOC_HasFrameBuffer = ETrue; + Private->EPOC_FrameBuffer = NULL; /* Private->EPOC_Bitmap->DataAddress() can change any time */ + Private->EPOC_BytesPerPixel = ((GetBpp(displayMode)-1) / 8) + 1; + Private->EPOC_BytesPerScanLine = Private->EPOC_WsScreen->SizeInPixels().iWidth * Private->EPOC_BytesPerPixel; + +#endif /* __WINS__ */ + +#ifndef SYMBIAN_CRYSTAL + // Get draw device for updating the screen + TScreenInfoV01 screenInfo2; + + Epoc_Runtime::GetScreenInfo(screenInfo2); + + TRAPD(status, Private->EPOC_DrawDevice = CFbsDrawDevice::NewScreenDeviceL(screenInfo2, displayMode)); + User::LeaveIfError(status); +#endif + + /* The "best" video format should be returned to caller. */ + + vformat->BitsPerPixel = /*!!GetBpp(displayMode) */ 8; + vformat->BytesPerPixel = /*!!Private->EPOC_BytesPerPixel*/ 1; + + /* Activate events for me */ + + Private->EPOC_WsEventStatus = KRequestPending; + Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus); + + SDL_TRACE("SDL:WsEventStatus"); + User::WaitForRequest(Private->EPOC_WsEventStatus); //Markus: I added this and ... + + Private->EPOC_RedrawEventStatus = KRequestPending; + Private->EPOC_WsSession.RedrawReady(&Private->EPOC_RedrawEventStatus); + + SDL_TRACE("SDL:RedrawEventStatus"); + User::WaitForRequest(Private->EPOC_RedrawEventStatus); //...this, if not catches a stray event is risen + //if there are active objects used, or confucing + //actions with User::WaitForAnyRequest + Private->EPOC_WsWindow.PointerFilter(EPointerFilterDrag, 0); + + Private->EPOC_ScreenOffset = TPoint(0, 0); + +#if defined(__WINS__) || defined(TEST_BM_DRAW) + LockHeap(Private->EPOC_Bitmap); // Lock bitmap heap +#endif + + SDL_TRACE("SDL:DrawBackground"); + DrawBackground(_this); // Clear screen + +#if defined(__WINS__) || defined(TEST_BM_DRAW) + UnlockHeap(Private->EPOC_Bitmap); // Unlock bitmap heap +#endif + //!! TODO: error handling + //if (ret != KErrNone) + // return(-1); + //else + return(0); +} + + +SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 /*flags*/) +{ + if (format->BitsPerPixel == 12 || format->BitsPerPixel == 8) + return Private->SDL_modelist; + return NULL; +} + +int EPOC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) +{ + if ((firstcolor+ncolors) > 256) + return -1; +// SDL_TRACE1("colors %d", (TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode))); + if(TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode) == 4096) + { + // Set 12 bit palette + for(int i = firstcolor; i < ncolors; i++) + { + // 4k value: 0000 rrrr gggg bbbb + TUint32 color4K = (colors[i].r & 0x0000f0) << 4; + color4K |= (colors[i].g & 0x0000f0); + color4K |= (colors[i].b & 0x0000f0) >> 4; + EPOC_HWPalette_256_to_Screen[i] = color4K; + } + } + else if(TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode) == 65536) + { + for(int i = firstcolor; i < ncolors; i++) + { + // 64k-colour displays effectively support RGB values + // with 5 bits allocated to red, 6 to green and 5 to blue + // 64k value: rrrr rggg gggb bbbb + TUint32 color64K = (colors[i].r & 0x0000f8) << 8; + color64K |= (colors[i].g & 0x0000fc) << 3; + color64K |= (colors[i].b & 0x0000f8) >> 3; + EPOC_HWPalette_256_to_Screen[i] = color64K; + } + } + else if(TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode) == 16777216) + { + for(int i = firstcolor; i < ncolors; i++) + { + // 16M-colour + //0000 0000 rrrr rrrr gggg gggg bbbb bbbb + TUint32 color16M = colors[i].r << 16; + color16M |= colors[i].g << 8; + color16M |= colors[i].b; + EPOC_HWPalette_256_to_Screen[i] = color16M; + } + } + else + { + return -2; + } + return(0); +} + + +SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current, + int width, int height, int bpp, Uint32 /*flags*/) +{ + SDL_TRACE("SDL:EPOC_SetVideoMode"); + /* Check parameters */ +#ifdef SYMBIAN_CRYSTAL + if (! (bpp == 8 || bpp == 12 || bpp == 16) && + ( + (width == 640 && height == 200) || + (width == 640 && height == 400) || + (width == 640 && height == 480) || + (width == 320 && height == 200) || + (width == 320 && height == 240) + )) { + SDL_SetError("Requested video mode is not supported"); + return NULL; + } +#else // SYMBIAN_SERIES60 + if (! (bpp == 8 || bpp == 12 || bpp == 16) && + ( + (width == 320 && height == 200) || + (width == 320 && height == 240) || + (width == 256 && height == 192) || + (width == 176 && height == 208) || + (width == 208 && height == 176) || // Rotated + (width == 160 && height == 144) + )) { + SDL_SetError("Requested video mode is not supported"); + return NULL; + } +#endif + + if (current && current->pixels) { + free(current->pixels); + current->pixels = NULL; + } + if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) { + return(NULL); + } + + /* Set up the new mode framebuffer */ + if (bpp == 8) + current->flags = (SDL_FULLSCREEN|SDL_SWSURFACE|SDL_PREALLOC|SDL_HWPALETTE); + else // 12 bpp, 16 bpp + current->flags = (SDL_FULLSCREEN|SDL_SWSURFACE|SDL_PREALLOC); + current->w = width; + current->h = height; + int numBytesPerPixel = ((bpp-1)>>3) + 1; + current->pitch = numBytesPerPixel * width; // Number of bytes in scanline + current->pixels = malloc(width * height * numBytesPerPixel); + memset(current->pixels, 0, width * height * numBytesPerPixel); + + /* Set the blit function */ + _this->UpdateRects = EPOC_DirectUpdate; + + /* + * Logic for getting suitable screen dimensions, offset, scaling and orientation + */ + + int w = current->w; + int h = current->h; + + // Rotate, if the screen does not fit horizontally and it is landscape screen +/* + if ((width>Private->EPOC_ScreenSize.iWidth) && (width>height)) { + Private->EPOC_ScreenOrientation = CFbsBitGc::EGraphicsOrientationRotated270; + w = current->h; + h = current->w; + } +*/ + // Get nearest stepwise scale values for width and height. The smallest supported scaled screen is 1/2. + TInt scaleValue = 0; + Private->EPOC_ScreenXScaleValue = 1; + Private->EPOC_ScreenYScaleValue = 1; + if (w > Private->EPOC_ScreenSize.iWidth) { + // Find the biggest scale value that result the width that fits in the screen HW + for (scaleValue = 2; scaleValue++;) { + TInt scaledWidth = (w * (scaleValue-1))/scaleValue; + if (scaledWidth > Private->EPOC_ScreenSize.iWidth) + break; + } + Private->EPOC_ScreenXScaleValue = Max(2, scaleValue - 1); + w = (w * (Private->EPOC_ScreenXScaleValue-1))/Private->EPOC_ScreenXScaleValue; + } + if (h > Private->EPOC_ScreenSize.iHeight) { + // Find the biggest scale value that result the height that fits in the screen HW + for (scaleValue = 2; scaleValue++;) { + TInt scaledHeight = (h * (scaleValue-1))/scaleValue; + if (scaledHeight > Private->EPOC_ScreenSize.iHeight) + break; + } + Private->EPOC_ScreenYScaleValue = Max(2, scaleValue - 1); + h = (h * (Private->EPOC_ScreenYScaleValue-1))/Private->EPOC_ScreenYScaleValue; + } + + /* Centralize game window on device screen */ + Private->EPOC_ScreenOffset.iX = (Private->EPOC_ScreenSize.iWidth - w) / 2; + if (Private->EPOC_ScreenOffset.iX < 0) + Private->EPOC_ScreenOffset.iX = 0; + Private->EPOC_ScreenOffset.iY = (Private->EPOC_ScreenSize.iHeight - h) / 2; + if (Private->EPOC_ScreenOffset.iY < 0) + Private->EPOC_ScreenOffset.iY = 0; + + + SDL_TRACE1("View width %d", w); + SDL_TRACE1("View height %d", h); + SDL_TRACE1("View bmode %d", bpp); + SDL_TRACE1("View s %d", scaleValue); + SDL_TRACE1("View x %d", Private->EPOC_ScreenOffset.iX); + SDL_TRACE1("View y %d", Private->EPOC_ScreenOffset.iY); + + /* We're done */ + return(current); +} + + +void RedrawWindowL(_THIS) +{ + +#if defined(__WINS__) || defined(TEST_BM_DRAW) + LockHeap(Private->EPOC_Bitmap); // Lock bitmap heap + Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow); +#endif + + int w = _this->screen->w; + int h = _this->screen->h; + if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) { + w = _this->screen->h; + h = _this->screen->w; + } + if ((w < Private->EPOC_ScreenSize.iWidth) + || (h < Private->EPOC_ScreenSize.iHeight)) { + DrawBackground(_this); + } + + /* Tell the system that something has been drawn */ + TRect rect = TRect(Private->EPOC_WsWindow.Size()); + Private->EPOC_WsWindow.Invalidate(rect); + +#if defined(__WINS__) || defined(TEST_BM_DRAW) + Private->EPOC_WsWindow.BeginRedraw(rect); + Private->EPOC_WindowGc->BitBlt(TPoint(), Private->EPOC_Bitmap); + Private->EPOC_WsWindow.EndRedraw(); + Private->EPOC_WindowGc->Deactivate(); + UnlockHeap(Private->EPOC_Bitmap);; // Unlock bitmap heap + Private->EPOC_WsSession.Flush(); +#endif + + /* Draw current buffer */ + SDL_Rect fullScreen; + fullScreen.x = 0; + fullScreen.y = 0; + fullScreen.w = _this->screen->w; + fullScreen.h = _this->screen->h; + EPOC_DirectUpdate(_this, 1, &fullScreen); +} + + +void DrawBackground(_THIS) +{ + /* Draw background */ +#if defined(__WINS__) || defined(TEST_BM_DRAW) + //warning heap is not locked! - a function calling must ensure that it's ok + TUint16* screenBuffer = (TUint16*)Private->EPOC_Bitmap->DataAddress(); +#else + TUint16* screenBuffer = (TUint16*)Private->EPOC_FrameBuffer; +#endif + // Draw black background + Mem::FillZ(screenBuffer, Private->EPOC_BytesPerScreen); + +#if 0 + for (int y = 0; y < Private->EPOC_ScreenSize.iHeight; y++) { + for (int x = 0; x < Private->EPOC_ScreenSize.iWidth; x++) { +#ifdef SYMBIAN_CRYSTAL + const TUint16 color = 0; // ((x+y)>>1) & 0xf; /* Draw blue stripes pattern, because in e.g. 320x200 mode there is a big background area*/ +#else // SYMBIAN_SERIES60 + const TUint16 color = 0; /* Draw black background */ +#endif + *screenBuffer++ = color; + } + } +#endif +} + + +/* We don't actually allow hardware surfaces other than the main one */ +static int EPOC_AllocHWSurface(_THIS, SDL_Surface* /*surface*/) +{ + return(-1); +} +static void EPOC_FreeHWSurface(_THIS, SDL_Surface* /*surface*/) +{ + return; +} + +static int EPOC_LockHWSurface(_THIS, SDL_Surface* /*surface*/) +{ + return(0); +} +static void EPOC_UnlockHWSurface(_THIS, SDL_Surface* /*surface*/) +{ + return; +} + +static int EPOC_FlipHWSurface(_THIS, SDL_Surface* /*surface*/) +{ + return(0); +} + +static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) +{ + //TInt focusWindowGroupId = Private->EPOC_WsSession.GetFocusWindowGroup();//these are async services + // if (focusWindowGroupId != Private->EPOC_WsWindowGroupID) { //for that cannot be called from + //SDL threads ??? + if (!Private->EPOC_IsWindowFocused) + { + /* Force focus window to redraw again for cleaning away SDL screen graphics */ +/* + TInt pos = Private->EPOC_WsWindowGroup.OrdinalPosition(); + Private->EPOC_WsWindowGroup.SetOrdinalPosition(0, KMaxTInt); + TRect rect = TRect(Private->EPOC_WsWindow.Size()); + Private->EPOC_WsWindow.Invalidate(rect); + Private->EPOC_WsWindowGroup.SetOrdinalPosition(pos, ECoeWinPriorityNormal); + */ /* If this is not the topmost window, wait here! Sleep for 1 second to give cpu time to + multitasking and poll for being the topmost window. + */ + // if (Private->EPOC_WsSession.GetFocusWindowGroup() != Private->EPOC_WsWindowGroupID) { + + /* !!TODO: Could call GetRedraw() etc. for WsSession and redraw the screen if needed. That might be + needed if a small dialog comes in front of Game screen. + */ + // while (Private->EPOC_WsSession.GetFocusWindowGroup() != Private->EPOC_WsWindowGroupID) + + SDL_PauseAudio(1); + SDL_Delay(1000); + return; + // } + + // RedrawWindowL(_this); + } + + SDL_PauseAudio(0); + + // if we are not focused, do not draw +// if (!Private->EPOC_IsWindowFocused) +// return; +#if defined(__WINS__) || defined(TEST_BM_DRAW) + TBitmapUtil lock(Private->EPOC_Bitmap); + lock.Begin(TPoint(0,0)); // Lock bitmap heap + Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow); + TUint16* screenBuffer = (TUint16*)Private->EPOC_Bitmap->DataAddress(); +#else + TUint16* screenBuffer = (TUint16*)Private->EPOC_FrameBuffer; +#endif + + if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) + DirectDrawRotated(_this, numrects, rects, screenBuffer); + else + DirectDraw(_this, numrects, rects, screenBuffer); + + +#if defined(__WINS__) || defined(TEST_BM_DRAW) + + TRect rect = TRect(Private->EPOC_WsWindow.Size()); + Private->EPOC_WsWindow.Invalidate(rect); + Private->EPOC_WsWindow.BeginRedraw(rect); + Private->EPOC_WindowGc->BitBlt(TPoint(), Private->EPOC_Bitmap); + Private->EPOC_WsWindow.EndRedraw(); + Private->EPOC_WindowGc->Deactivate(); + lock.End(); // Unlock bitmap heap + Private->EPOC_WsSession.Flush(); +#else +#ifndef SYMBIAN_CRYSTAL + // This is not needed in Crystal. What is the performance penalty in SERIES60? + TRect rect2 = TRect(Private->EPOC_WsWindow.Size()); + + Private->EPOC_DrawDevice->UpdateRegion(rect2); // Should we update rects parameter area only?? + Private->EPOC_DrawDevice->Update(); +#endif +#endif + + /* Update virtual cursor. !!Do not yet work properly + Private->EPOC_WsSession.SetPointerCursorPosition(Private->EPOC_WsSession.PointerCursorPosition()); + */ + + /*static int foo = 1; + + for ( int i=0; i < numrects; ++i ) { + const SDL_Rect& currentRect = rects[i]; + SDL_Rect rect2; + rect2.x = currentRect.x; + rect2.y = currentRect.y; + rect2.w = currentRect.w; + rect2.h = currentRect.h; + + if (rect2.w <= 0 || rect2.h <= 0) + continue; + + + foo++; + if((foo % 200) == 0) + { + SDL_TRACE1("foo %d", foo); + CFbsBitmap* b = new (ELeave) CFbsBitmap; + SDL_TRACE1("bee %d", (int)b); + int e = b->Create(TSize(currentRect.w, currentRect.h), Private->EPOC_DisplayMode); + + SDL_TRACE1("err %d", e); + if(e != KErrNone) + User::Panic(_L("damn"), e); + + TBitmapUtil u(b); + u.Begin(TPoint(0, 0)); + TUint32* d = b->DataAddress(); + + SDL_TRACE1("addr %d", (int)d); + + for(TInt o = 0; o < currentRect.h; o++) + for(TInt p = 0; p < currentRect.w; p++) + { + u.SetPos(TPoint(p, o)); + u.SetPixel(0xFFFF); + } + + SDL_TRACE1("w %d", (int)currentRect.w); + SDL_TRACE1("h %d", (int)currentRect.h); + + SDL_TRACE1("addr %d", (int)Private->EPOC_DisplayMode); + + + const TUint f = (TUint)Private->EPOC_FrameBuffer; + const TUint y = (TUint)Private->EPOC_BytesPerScreen; + + + SDL_TRACE1("frame %u", f); + SDL_TRACE1("bytes %u", y); + + Mem::Copy(d, Private->EPOC_FrameBuffer, Private->EPOC_BytesPerScreen); + + SDL_TRACE("kopied"); + + u.End(); + TBuf<32> name; + name.Format(_L("C:\\nokia\\images\\doom%d.mbm"), (foo / 200)); + e= b->Save(name); + if(e != KErrNone) + User::Panic(_L("damned"), e); + delete b; + }}*/ +} + + +void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer) +{ + TInt i; + + const TInt sourceNumBytesPerPixel = ((_this->screen->format->BitsPerPixel-1)>>3) + 1; + const TPoint fixedOffset = Private->EPOC_ScreenOffset; + const TInt screenW = _this->screen->w; + const TInt screenH = _this->screen->h; + const TInt sourceScanlineLength = screenW; + const TInt targetScanlineLength = Private->EPOC_ScreenSize.iWidth; + + /* Render the rectangles in the list */ + + for ( i=0; i < numrects; ++i ) { + const SDL_Rect& currentRect = rects[i]; + SDL_Rect rect2; + rect2.x = currentRect.x; + rect2.y = currentRect.y; + rect2.w = currentRect.w; + rect2.h = currentRect.h; + + if (rect2.w <= 0 || rect2.h <= 0) /* sanity check */ + continue; + + /* All variables are measured in pixels */ + + /* Check rects validity, i.e. upper and lower bounds */ + TInt maxX = Min(screenW - 1, rect2.x + rect2.w - 1); + TInt maxY = Min(screenH - 1, rect2.y + rect2.h - 1); + if (maxX < 0 || maxY < 0) /* sanity check */ + continue; + /* Clip from bottom */ + maxY = Min(maxY, Private->EPOC_ScreenSize.iHeight-1); + /* TODO: Clip from the right side */ + + const TInt sourceRectWidth = maxX - rect2.x + 1; + const TInt sourceRectWidthInBytes = sourceRectWidth * sourceNumBytesPerPixel; + const TInt sourceRectHeight = maxY - rect2.y + 1; + const TInt sourceStartOffset = rect2.x + rect2.y * sourceScanlineLength; + const TUint skipValue = 1; // no skip + + TInt targetStartOffset = fixedOffset.iX + rect2.x + (fixedOffset.iY +rect2.y) * targetScanlineLength; + + // Nokia7650 native mode: 12 bpp --> 12 bpp + // + + switch (_this->screen->format->BitsPerPixel) + { + case 12: + { + TUint16* bitmapLine = (TUint16*)_this->screen->pixels + sourceStartOffset; + TUint16* screenMemory = screenBuffer + targetStartOffset; + if (skipValue == 1) + { + for(TInt y = 0 ; y < sourceRectHeight ; y++) + { + Mem::Copy(screenMemory, bitmapLine, sourceRectWidthInBytes); + } + bitmapLine += sourceScanlineLength; + screenMemory += targetScanlineLength; + } + else + { + for(TInt y = 0 ; y < sourceRectHeight ; y++) + { + //TODO: optimize: separate loops for 1, 2 and n skip. Mem::Copy() can be used in unscaled case. + TUint16* bitmapPos = bitmapLine; /* 2 bytes per pixel */ + TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */ + for(TInt x = 0 ; x < sourceRectWidth ; x++) + { + __ASSERT_DEBUG(screenMemory < (screenBuffer + Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(screenMemory >= screenBuffer, User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapLine < ((TUint16*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapLine >= (TUint16*)_this->screen->pixels, User::Panic(_L("SDL"), KErrCorrupt)); + + *screenMemoryLinePos++ = *bitmapPos; + bitmapPos+=skipValue; + } + bitmapLine += sourceScanlineLength; + screenMemory += targetScanlineLength; + } + } + } + break; + // 256 color paletted mode: 8 bpp --> 12 bpp + // + default: + { + if(Private->EPOC_BytesPerPixel <= 2) + { + TUint8* bitmapLine = (TUint8*)_this->screen->pixels + sourceStartOffset; + TUint16* screenMemory = screenBuffer + targetStartOffset; + for(TInt y = 0 ; y < sourceRectHeight ; y++) + { + TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */ + TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */ + /* Convert each pixel from 256 palette to 4k color values */ + for(TInt x = 0 ; x < sourceRectWidth ; x++) + { + __ASSERT_DEBUG(screenMemoryLinePos < (screenBuffer + (Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight)), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(screenMemoryLinePos >= screenBuffer, User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapPos < ((TUint8*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapPos >= (TUint8*)_this->screen->pixels, User::Panic(_L("SDL"), KErrCorrupt)); + *screenMemoryLinePos++ = EPOC_HWPalette_256_to_Screen[*bitmapPos++]; + // bitmapPos+=skipValue; //TODO: optimize: separate loops for 1, 2 and n skip + } + bitmapLine += sourceScanlineLength; + screenMemory += targetScanlineLength; + } + } + else + { + TUint8* bitmapLine = (TUint8*)_this->screen->pixels + sourceStartOffset; + TUint32* screenMemory = reinterpret_cast(screenBuffer + targetStartOffset); + for(TInt y = 0 ; y < sourceRectHeight ; y++) + { + TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */ + TUint32* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */ + /* Convert each pixel from 256 palette to 4k color values */ + for(TInt x = 0 ; x < sourceRectWidth ; x++) + { + __ASSERT_DEBUG(screenMemoryLinePos < (reinterpret_cast(screenBuffer) + (Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight)), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(screenMemoryLinePos >= reinterpret_cast(screenBuffer), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapPos < ((TUint8*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapPos >= (TUint8*)_this->screen->pixels, User::Panic(_L("SDL"), KErrCorrupt)); + *screenMemoryLinePos++ = EPOC_HWPalette_256_to_Screen[*bitmapPos++]; + // bitmapPos+=skipValue; //TODO: optimize: separate loops for 1, 2 and n skip + } + bitmapLine += sourceScanlineLength; + screenMemory += targetScanlineLength; + } + } + } + } // switch + } // for +} + +/* +void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer) +{ + TInt i; + const TInt sourceNumBytesPerPixel = ((_this->screen->format->BitsPerPixel-1)>>3) + 1; + const TPoint fixedOffset = Private->EPOC_ScreenOffset; + const TInt screenW = _this->screen->w; + const TInt screenH = _this->screen->h; + const TInt sourceScanlineLength = screenW; + const TInt targetScanlineLength = Private->EPOC_ScreenSize.iWidth; + + /* Render the rectangles in the list */ + +/* for ( i=0; i < numrects; ++i ) { + const SDL_Rect& currentRect = rects[i]; + SDL_Rect rect2; + rect2.x = currentRect.x; + rect2.y = currentRect.y; + rect2.w = currentRect.w; + rect2.h = currentRect.h; + + if (rect2.w <= 0 || rect2.h <= 0) /* sanity check */ +/* continue; + + /* All variables are measured in pixels */ + + /* Check rects validity, i.e. upper and lower bounds */ +/* TInt maxX = Min(screenW - 1, rect2.x + rect2.w - 1); + TInt maxY = Min(screenH - 1, rect2.y + rect2.h - 1); + if (maxX < 0 || maxY < 0) /* sanity check */ +/* continue; + /* Clip from bottom */ +/* maxY = Min(maxY, Private->EPOC_ScreenSize.iHeight-1); + /* TODO: Clip from the right side */ + +/* TInt sourceRectWidth = maxX - rect2.x + 1; + const TInt sourceRectWidthInBytes = sourceRectWidth * sourceNumBytesPerPixel; + const TInt sourceRectHeight = maxY - rect2.y + 1; + const TInt sourceStartOffset = rect2.x + rect2.y * sourceScanlineLength; + const TUint skipValue = Private->EPOC_ScreenXScaleValue; //1; // no skip + + const TInt targetStartOffset = // = (fixedOffset.iX + (rect2.x / skipValue) + (fixedOffset.iY + rect2.y) * targetScanlineLength ) ; + (skipValue > 1 ? + (fixedOffset.iX + (rect2.x / skipValue) + (fixedOffset.iY + rect2.y) * targetScanlineLength ) : + (fixedOffset.iX + rect2.x + (fixedOffset.iY + rect2.y) * targetScanlineLength )); + + __ASSERT_DEBUG(skipValue >= 1, User::Panic(KLibName, KErrArgument)); + + // Nokia7650 native mode: 12 bpp --> 12 bpp + // + switch (_this->screen->format->BitsPerPixel) + { + case 12: + { + TUint16* bitmapLine = (TUint16*)_this->screen->pixels + sourceStartOffset; + TUint16* screenMemory = screenBuffer + targetStartOffset; + if (skipValue == 1) + { + for(TInt y = 0 ; y < sourceRectHeight ; y++) + { + Mem::Copy(screenMemory, bitmapLine, sourceRectWidthInBytes); + } + bitmapLine += sourceScanlineLength; + screenMemory += targetScanlineLength; + } + else + { + for(TInt y = 0 ; y < sourceRectHeight ; y++) + { + //TODO: optimize: separate loops for 1, 2 and n skip. Mem::Copy() can be used in unscaled case. + TUint16* bitmapPos = bitmapLine; /* 2 bytes per pixel */ +/* TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */ +/* for(TInt x = 0 ; x < sourceRectWidth ; x++) + { + __ASSERT_DEBUG(screenMemory < (screenBuffer + Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight), User::Panic(KLibName, KErrCorrupt)); + __ASSERT_DEBUG(screenMemory >= screenBuffer, User::Panic(KLibName, KErrCorrupt)); + __ASSERT_DEBUG(bitmapLine < ((TUint16*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(KLibName, KErrCorrupt)); + __ASSERT_DEBUG(bitmapLine >= (TUint16*)_this->screen->pixels, User::Panic(KLibName, KErrCorrupt)); + + *screenMemoryLinePos++ = *bitmapPos; + bitmapPos+=skipValue; + } + bitmapLine += sourceScanlineLength; + screenMemory += targetScanlineLength; + } + } + } + break; + // 256 color paletted mode: 8 bpp --> 12 bpp + // + default: + { + TUint8* bitmapLine = (TUint8*)_this->screen->pixels + sourceStartOffset; + TUint16* screenMemory = screenBuffer + targetStartOffset; + if (skipValue > 1) + sourceRectWidth /= skipValue; +#if defined __MARM_ARMI__ + __asm volatile(" + mov %4, %4, lsl #1 @ targetScanLineLength is in pixels, we need it in bytes + 1: + mov r6, %0 @ bitmapLine + mov r7, %2 @ screenMemory + mov r8, %6 @ sourceRectWidth + 2: + ldrb r4, [%0], %7 @ r4 = *bitmapPos; bitmapPos += skipValue + ldr r5, [%1, r4, lsl #2] @ only 16 lower bits actually used + subs r8, r8, #1 @ x-- + strh r5, [%2], #2 @ *screenMemoryLinePos++ = r4 + bne 2b + + add %0, r6, %3 @ bitmapLine += sourceScanlineLength + add %2, r7, %4 @ screenMemory += targetScanlineLength + subs %5, %5, #1 @ sourceRectHeight-- + bne 1b + " + : // no output + // %0 %1 %2 %3 %4 %5 %6 %7 + : "r" (bitmapLine), "r" (&EPOC_HWPalette_256_to_Screen[0]), "r" (screenMemory), "r" (sourceScanlineLength), "r" (targetScanlineLength), "r" (sourceRectHeight), "r" (sourceRectWidth), "r" (skipValue) + : "r4", "r5", "r6", "r7", "r8" + ); +#else + for(TInt y = 0 ; y < sourceRectHeight ; y++) + { + TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */ +/* TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */ + /* Convert each pixel from 256 palette to 4k color values */ +/* for (TInt x = 0 ; x < sourceRectWidth ; x++) + { + //__ASSERT_DEBUG(screenMemoryLinePos < (screenBuffer + (Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight)), User::Panic(KLibName, KErrCorrupt)); + //__ASSERT_DEBUG(screenMemoryLinePos >= screenBuffer, User::Panic(KLibName, KErrCorrupt)); + //__ASSERT_DEBUG(bitmapPos < ((TUint8*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(KLibName, KErrCorrupt)); + //__ASSERT_DEBUG(bitmapPos >= (TUint8*)_this->screen->pixels, User::Panic(KLibName, KErrCorrupt)); + + *screenMemoryLinePos++ = EPOC_HWPalette_256_to_Screen[*bitmapPos]; + bitmapPos += skipValue; + } + bitmapLine += sourceScanlineLength; + screenMemory += targetScanlineLength; + } +//#endif + } + } // switch + } // for +} +*/ + +void DirectDrawRotated(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer) +{ + TInt i; +// TInt sourceNumBytesPerPixel = ((_this->screen->format->BitsPerPixel-1)>>3) + 1; + TPoint fixedScreenOffset = Private->EPOC_ScreenOffset; + TInt bufferW = _this->screen->w; + TInt bufferH = _this->screen->h; + TInt ScreenW = Private->EPOC_ScreenSize.iWidth; +// TInt ScreenH = Private->EPOC_ScreenSize.iWidth; + TInt sourceW = bufferW; + TInt sourceH = bufferH; + TInt targetW = ScreenW - fixedScreenOffset.iX * 2; +// TInt targetH = ScreenH - fixedScreenOffset.iY * 2; + TInt sourceScanlineLength = bufferW; + TInt targetScanlineLength = Private->EPOC_ScreenSize.iWidth; + + /* Render the rectangles in the list */ + + for ( i=0; i < numrects; ++i ) { + SDL_Rect rect2; + const SDL_Rect& currentRect = rects[i]; + rect2.x = currentRect.x; + rect2.y = currentRect.y; + rect2.w = currentRect.w; + rect2.h = currentRect.h; + + if (rect2.w <= 0 || rect2.h <= 0) /* sanity check */ + continue; + + /* All variables are measured in pixels */ + + /* Check rects validity, i.e. upper and lower bounds */ + TInt maxX = Min(sourceW - 1, rect2.x + rect2.w - 1); + TInt maxY = Min(sourceH - 1, rect2.y + rect2.h - 1); + if (maxX < 0 || maxY < 0) /* sanity check */ + continue; + /* Clip from bottom */ + //maxX = Min(maxX, Private->EPOC_ScreenSize.iHeight-1); + /* TODO: Clip from the right side */ + + TInt sourceRectWidth = maxX - rect2.x + 1; +// TInt sourceRectWidthInBytes = sourceRectWidth * sourceNumBytesPerPixel; + TInt sourceRectHeight = maxY - rect2.y + 1; + TInt sourceStartOffset = rect2.x + rect2.y * sourceScanlineLength; + TInt targetStartOffset = fixedScreenOffset.iX + (targetW-1 - rect2.y) + (fixedScreenOffset.iY +rect2.x) * targetScanlineLength; + + // Nokia7650 native mode: 12 bpp --> 12 bpp + if (_this->screen->format->BitsPerPixel == 12) { + + /* !!TODO: not yet implemented + + TUint16* bitmapLine = (TUint16*)_this->screen->pixels + sourceStartOffset; + TUint16* screenMemory = screenBuffer + targetStartOffset; + for(TInt y = 0 ; y < sourceRectHeight ; y++) { + //TODO: optimize: separate loops for 1, 2 and n skip + //Mem::Copy(screenMemory, bitmapLine, sourceRectWidthInBytes); + TUint16* bitmapPos = bitmapLine; // 2 bytes per pixel + TUint16* screenMemoryLinePos = screenMemory; // 2 bytes per pixel + for(TInt x = 0 ; x < sourceRectWidth ; x++) { + + __ASSERT_DEBUG(screenMemory < (screenBuffer + Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight), User::Panic(KLibName, KErrCorrupt)); + __ASSERT_DEBUG(screenMemory >= screenBuffer, User::Panic(KLibName, KErrCorrupt)); + __ASSERT_DEBUG(bitmapLine < ((TUint16*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(KLibName, KErrCorrupt)); + __ASSERT_DEBUG(bitmapLine >= (TUint16*)_this->screen->pixels, User::Panic(KLibName, KErrCorrupt)); + + *screenMemoryLinePos = *bitmapPos; + bitmapPos++; + screenMemoryLinePos += targetScanlineLength; + } + bitmapLine += sourceScanlineLength; + screenMemory--; + } + + */ + } + // 256 color paletted mode: 8 bpp --> 12 bpp + else { + TUint8* bitmapLine = (TUint8*)_this->screen->pixels + sourceStartOffset; + TUint16* screenMemory = screenBuffer + targetStartOffset; + TInt screenXScaleValue = Private->EPOC_ScreenXScaleValue; + TInt debug_ycount=0; + for(TInt y = 0 ; y < sourceRectHeight ; y++) { + if(--screenXScaleValue) { + TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */ + TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */ + TInt screenYScaleValue = Private->EPOC_ScreenYScaleValue; + TInt debug_xcount=0; + /* Convert each pixel from 256 palette to 4k color values */ + for(TInt x = 0 ; x < sourceRectWidth ; x++) { + if(--screenYScaleValue) { + + __ASSERT_DEBUG(screenMemoryLinePos < (screenBuffer + (Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight)), User::Panic(KLibName, KErrCorrupt)); + __ASSERT_DEBUG(screenMemoryLinePos >= screenBuffer, User::Panic(KLibName, KErrCorrupt)); + __ASSERT_DEBUG(bitmapPos < ((TUint8*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(KLibName, KErrCorrupt)); + __ASSERT_DEBUG(bitmapPos >= (TUint8*)_this->screen->pixels, User::Panic(KLibName, KErrCorrupt)); + + *screenMemoryLinePos = TUint16(EPOC_HWPalette_256_to_Screen[*bitmapPos]); + screenMemoryLinePos += targetScanlineLength; debug_xcount++; + } + else + screenYScaleValue = Private->EPOC_ScreenYScaleValue; + bitmapPos++; + } + screenMemory--; debug_ycount++; + } // endif + else + screenXScaleValue = Private->EPOC_ScreenXScaleValue; + bitmapLine += sourceScanlineLength; + } + } + } +} + + +/* Note: If we are terminated, this could be called in the middle of + another SDL video routine -- notably UpdateRects. +*/ +void EPOC_VideoQuit(_THIS) +{ + int i; + + /* Free video mode lists */ + for ( i=0; iSDL_modelist[i] != NULL ) { + free(Private->SDL_modelist[i]); + Private->SDL_modelist[i] = NULL; + } + } + + if ( _this->screen && (_this->screen->flags & SDL_HWSURFACE) ) { + /* Direct screen access, no memory buffer */ + _this->screen->pixels = NULL; + } + + if (_this->screen && _this->screen->pixels) { + free(_this->screen->pixels); + _this->screen->pixels = NULL; + } + + /* Free Epoc resources */ + + /* Disable events for me */ + if (Private->EPOC_WsEventStatus != KRequestPending) + Private->EPOC_WsSession.EventReadyCancel(); + if (Private->EPOC_RedrawEventStatus != KRequestPending) + Private->EPOC_WsSession.RedrawReadyCancel(); + + #if defined(__WINS__) || defined(TEST_BM_DRAW) + delete Private->EPOC_Bitmap; + Private->EPOC_Bitmap = NULL; + #else + #endif + +#ifndef SYMBIAN_CRYSTAL + free(Private->EPOC_DrawDevice); +#endif + + if (Private->EPOC_WsWindow.WsHandle()) + Private->EPOC_WsWindow.Close(); + + if (Private->EPOC_WsWindowGroup.WsHandle()) + Private->EPOC_WsWindowGroup.Close(); + + delete Private->EPOC_WindowGc; + Private->EPOC_WindowGc = NULL; + + delete Private->EPOC_WsScreen; + Private->EPOC_WsScreen = NULL; + + if (Private->EPOC_WsSession.WsHandle()) + Private->EPOC_WsSession.Close(); +} + + +WMcursor *EPOC_CreateWMCursor(_THIS, Uint8* /*data*/, Uint8* /*mask*/, int /*w*/, int /*h*/, int /*hot_x*/, int /*hot_y*/) +{ + return (WMcursor *) 9210; // it's ok to return something unuseful but true +} + +void EPOC_FreeWMCursor(_THIS, WMcursor* /*cursor*/) +{ + /* Disable virtual cursor */ + HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible); + Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNone); +} + +int EPOC_ShowWMCursor(_THIS, WMcursor *cursor) +{ + + if (cursor == (WMcursor *)9210) { + /* Enable virtual cursor */ + Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNormal); + if (isCursorVisible) + HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible); + else + Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNone); + } + else { + /* Disable virtual cursor */ + HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible); + Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNone); + } + + return(1); +} + +}; // extern "C" diff --git a/src/video/symbian/EKA1/SDL_epocvideo.h b/src/video/symbian/EKA1/SDL_epocvideo.h new file mode 100644 index 000000000..a83a1e7f0 --- /dev/null +++ b/src/video/symbian/EKA1/SDL_epocvideo.h @@ -0,0 +1,34 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifndef _SDL_epocvideo_h +#define _SDL_epocvideo_h + +#ifndef EKA2 +#include"SDL_epocvideo_org.h" +#else +#include"SDL_epocvideo2.h" +#endif + + +#endif + diff --git a/src/video/symbian/EKA2/SDL_epocevents.cpp b/src/video/symbian/EKA2/SDL_epocevents.cpp new file mode 100644 index 000000000..2452daed6 --- /dev/null +++ b/src/video/symbian/EKA2/SDL_epocevents.cpp @@ -0,0 +1,521 @@ +#include "epoc_sdl.h" + +#include +#undef NULL +extern "C" { +//#define DEBUG_TRACE_ENABLED +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_keysym.h" +#include "SDL_keyboard.h" +#include "SDL_events_c.h" +#include "SDL_timer.h" +} /* extern "C" */ + +#include "SDL_epocvideo.h" +#include "SDL_epocevents_c.h" + +#include "sdlepocapi.h" + +#include + +#include + + +extern "C" + { + static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym); + } + +//extern "C" { +/* The translation tables from a console scancode to a SDL keysym */ +static SDLKey keymap[MAX_SCANCODE]; +static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym); +void DisableKeyBlocking(_THIS); +//} /* extern "C" */ + +SDLKey* KeyMap() + { + return keymap; + } + +TBool isCursorVisible = EFalse; + +void ResetKeyMap() + { + int i; + + /* Initialize the key translation table */ + for ( i=0; i array; + TRAPD(err, ReadL(fs, array)); + if(err == KErrNone && array.Count() > 0) + { + + SDLKey temp[MAX_SCANCODE]; + Mem::Copy(temp, keymap, MAX_SCANCODE * sizeof(SDLKey)); + + for(TInt k = 0; k < array.Count(); k+= 2) + { + const TInt oldval = array[k]; + const TInt newval = array[k + 1]; + if(oldval >= 0 && oldval < MAX_SCANCODE && newval >= 0 && newval < MAX_SCANCODE) + { + keymap[oldval] = temp[newval]; + } + } + } + array.Close(); + } + + fs.Close();*/ + /////////////////////////////////////////////////////////// + + + keymap[EStdKeyNumLock] = SDLK_NUMLOCK; + keymap[EStdKeyScrollLock] = SDLK_SCROLLOCK; + + keymap[EStdKeyNkpForwardSlash] = SDLK_KP_DIVIDE; + keymap[EStdKeyNkpAsterisk] = SDLK_KP_MULTIPLY; + keymap[EStdKeyNkpMinus] = SDLK_KP_MINUS; + keymap[EStdKeyNkpPlus] = SDLK_KP_PLUS; + keymap[EStdKeyNkpEnter] = SDLK_KP_ENTER; + keymap[EStdKeyNkp1] = SDLK_KP1; + keymap[EStdKeyNkp2] = SDLK_KP2; + keymap[EStdKeyNkp3] = SDLK_KP3; + keymap[EStdKeyNkp4] = SDLK_KP4; + keymap[EStdKeyNkp5] = SDLK_KP5; + keymap[EStdKeyNkp6] = SDLK_KP6; + keymap[EStdKeyNkp7] = SDLK_KP7; + keymap[EStdKeyNkp8] = SDLK_KP8; + keymap[EStdKeyNkp9] = SDLK_KP9; + keymap[EStdKeyNkp0] = SDLK_KP0; + keymap[EStdKeyNkpFullStop] = SDLK_KP_PERIOD; + /* + keymap[EStdKeyMenu] = SDLK_MENU; should be, but not yet + keymap[EStdKeyBacklightOn] = + keymap[EStdKeyBacklightOff] = + keymap[EStdKeyBacklightToggle] = + keymap[EStdKeyIncContrast] = + keymap[EStdKeyDecContrast] = + keymap[EStdKeySliderDown] = + keymap[EStdKeySliderUp] = + keymap[EStdKeyDictaphonePlay] = + keymap[EStdKeyDictaphoneStop] = + keymap[EStdKeyDictaphoneRecord] = + keymap[EStdKeyHelp] = + keymap[EStdKeyOff] = + keymap[EStdKeyDial] = + keymap[EStdKeyIncVolume] = + keymap[EStdKeyDecVolume] = + keymap[EStdKeyDevice0] = + keymap[EStdKeyDevice1] = + keymap[EStdKeyDevice2] = + keymap[EStdKeyDevice3] = + keymap[EStdKeyDevice4] = + keymap[EStdKeyDevice5] = + keymap[EStdKeyDevice6] = + keymap[EStdKeyDevice7] = + keymap[EStdKeyDevice8] = + keymap[EStdKeyDevice9] = + keymap[EStdKeyDeviceA] = + keymap[EStdKeyDeviceB] = + keymap[EStdKeyDeviceC] = + keymap[EStdKeyDeviceD] = + keymap[EStdKeyDeviceE] = + keymap[EStdKeyDeviceF] = + keymap[EStdKeyApplication0] = + keymap[EStdKeyApplication1] = + keymap[EStdKeyApplication2] = + keymap[EStdKeyApplication3] = + keymap[EStdKeyApplication4] = + keymap[EStdKeyApplication5] = + keymap[EStdKeyApplication6] = + keymap[EStdKeyApplication7] = + keymap[EStdKeyApplication8] = + keymap[EStdKeyApplication9] = + keymap[EStdKeyApplicationA] = + keymap[EStdKeyApplicationB] = + keymap[EStdKeyApplicationC] = + keymap[EStdKeyApplicationD] = + keymap[EStdKeyApplicationE] = + keymap[EStdKeyApplicationF] = + keymap[EStdKeyYes] = + keymap[EStdKeyNo] = + keymap[EStdKeyIncBrightness] = + keymap[EStdKeyDecBrightness] = + keymap[EStdKeyCaseOpen] = + keymap[EStdKeyCaseClose] = */ + + + +} + + +int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent) +{ + int posted = 0; + SDL_keysym keysym; + +// SDL_TRACE1("hws %d", aWsEvent.Type()); + + switch (aWsEvent.Type()) + { + case EEventPointer: /* Mouse pointer events */ + { +/* const TPointerCursorMode mode = EpocSdlEnv::PointerMode(); + + + if(mode == EPointerCursorNone) + { + return 0; //TODO: Find out why events are get despite of cursor should be off + } +*/ + const TPointerEvent* pointerEvent = aWsEvent.Pointer(); + const TPoint mousePos = EpocSdlEnv::WindowCoordinates(pointerEvent->iPosition); + + /*!! TODO Pointer do not yet work properly + //SDL_TRACE1("SDL: EPOC_HandleWsEvent, pointerEvent->iType=%d", pointerEvent->iType); //!! + + if (Private->EPOC_ShrinkedHeight) { + mousePos.iY <<= 1; // Scale y coordinate to shrinked screen height + } + if (Private->EPOC_ShrinkedWidth) { + mousePos.iX <<= 1; // Scale x coordinate to shrinked screen width + } + */ + + posted += SDL_PrivateMouseMotion(0, 0, mousePos.iX, mousePos.iY); /* Absolute position on screen */ + + switch (pointerEvent->iType) + { + case TPointerEvent::EButton1Down: + posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0); + break; + case TPointerEvent::EButton1Up: + posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0); + break; + case TPointerEvent::EButton2Down: + posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0); + break; + case TPointerEvent::EButton2Up: + posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0); + break; + case TPointerEvent::EButton3Down: + posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_MIDDLE, 0, 0); + break; + case TPointerEvent::EButton3Up: + posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0); + break; + } // switch + break; + } + + case EEventKeyDown: /* Key events */ + { +#ifdef SYMBIAN_CRYSTAL + // special case: 9300/9500 rocker down, simulate left mouse button + if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA) + { + const TPointerCursorMode mode = Private->EPOC_WsSession.PointerCursorMode(); + if(mode != EPointerCursorNone) + posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0); + } +#endif + (void*)TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym); + +#ifndef DISABLE_JOYSTICK + /* Special handling */ + switch((int)keysym.sym) { + case SDLK_CAPSLOCK: + if (!isCursorVisible) { + /* Enable virtual cursor */ + HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible); + } + else { + /* Disable virtual cursor */ + HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible); + } + isCursorVisible = !isCursorVisible; + break; + } +#endif + posted += SDL_PrivateKeyboard(SDL_PRESSED, &keysym); + break; + } + + case EEventKeyUp: /* Key events */ + { +#ifdef SYMBIAN_CRYSTAL + // special case: 9300/9500 rocker up, simulate left mouse button + if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA) + { + posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0); + } +#endif + posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym)); + break; + } + + case EEventFocusGained: /* SDL window got focus */ + { + Private->iIsWindowFocused = ETrue; + posted += SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS); + /* Draw window background and screen buffer */ + DisableKeyBlocking(_this); //Markus: guess why:-) + + //RedrawWindowL(_this); + break; + } + + case EEventFocusLost: /* SDL window lost focus */ + { + + Private->iIsWindowFocused = EFalse; + + posted += SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS); + + + break; + } + + case EEventModifiersChanged: + { + TModifiersChangedEvent* modEvent = aWsEvent.ModifiersChanged(); + TUint modstate = KMOD_NONE; + if (modEvent->iModifiers == EModifierLeftShift) + modstate |= KMOD_LSHIFT; + if (modEvent->iModifiers == EModifierRightShift) + modstate |= KMOD_RSHIFT; + if (modEvent->iModifiers == EModifierLeftCtrl) + modstate |= KMOD_LCTRL; + if (modEvent->iModifiers == EModifierRightCtrl) + modstate |= KMOD_RCTRL; + if (modEvent->iModifiers == EModifierLeftAlt) + modstate |= KMOD_LALT; + if (modEvent->iModifiers == EModifierRightAlt) + modstate |= KMOD_RALT; + if (modEvent->iModifiers == EModifierLeftFunc) + modstate |= KMOD_LMETA; + if (modEvent->iModifiers == EModifierRightFunc) + modstate |= KMOD_RMETA; + if (modEvent->iModifiers == EModifierCapsLock) + modstate |= KMOD_CAPS; + SDL_SetModState(STATIC_CAST(SDLMod,(modstate | KMOD_LSHIFT))); + break; + } + case EEventScreenDeviceChanged: + { + EpocSdlEnv::WaitDeviceChange(); + } + break; + default: + break; + } + + return posted; +} + +extern "C" { + +void EPOC_PumpEvents(_THIS) + { + MEventQueue& events = EpocSdlEnv::EventQueue(); + while(events.HasData()) + { + events.Lock(); + + //there have to be a copy, so we can release + //lock immediately. HandleWsEvent may cause + //deadlock otherwise. + + const TWsEvent event = events.Shift(); + events.Unlock(); +// const TWsEvent& event = events.Top(); + EPOC_HandleWsEvent(_this, event); +// events.Shift(); + } + } + + + +void EPOC_InitOSKeymap(_THIS) + { + ResetKeyMap(); + EpocSdlEnv::ObserverEvent(MSDLObserver::EEventKeyMapInit ,0); + } + +static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym) +{ +// char debug[256]; + //SDL_TRACE1("SDL: TranslateKey, scancode=%d", scancode); //!! + + /* Set the keysym information */ + + keysym->scancode = scancode; + + if ((scancode >= MAX_SCANCODE) && + ((scancode - ENonCharacterKeyBase + 0x0081) >= MAX_SCANCODE)) { + SDL_SetError("Too big scancode"); + keysym->scancode = SDLK_UNKNOWN; + keysym->mod = KMOD_NONE; + return keysym; + } + + keysym->mod = SDL_GetModState(); + + /* Handle function keys: F1, F2, F3 ... */ + if (keysym->mod & KMOD_META) { + if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphabet keys */ + switch(scancode) { + case 'Q': scancode = EStdKeyF1; break; + case 'W': scancode = EStdKeyF2; break; + case 'E': scancode = EStdKeyF3; break; + case 'R': scancode = EStdKeyF4; break; + case 'T': scancode = EStdKeyF5; break; + case 'Y': scancode = EStdKeyF6; break; + case 'U': scancode = EStdKeyF7; break; + case 'I': scancode = EStdKeyF8; break; + case 'A': scancode = EStdKeyF9; break; + case 'S': scancode = EStdKeyF10; break; + case 'D': scancode = EStdKeyF11; break; + case 'F': scancode = EStdKeyF12; break; + } + keysym->sym = keymap[scancode]; + } + } + + if (scancode >= ENonCharacterKeyBase) { + // Non character keys + keysym->sym = keymap[scancode - + ENonCharacterKeyBase + 0x0081]; // !!hard coded + } else { + keysym->sym = keymap[scancode]; + } + + /* Remap the arrow keys if the device is rotated */ +/* + if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) { + switch(keysym->sym) { + case SDLK_UP: keysym->sym = SDLK_LEFT; break; + case SDLK_DOWN: keysym->sym = SDLK_RIGHT; break; + case SDLK_LEFT: keysym->sym = SDLK_DOWN; break; + case SDLK_RIGHT:keysym->sym = SDLK_UP; break; + } + } +*/ + /* If UNICODE is on, get the UNICODE value for the key */ + keysym->unicode = 0; + +#if 0 // !!TODO:unicode + + if ( SDL_TranslateUNICODE ) + { + /* Populate the unicode field with the ASCII value */ + keysym->unicode = scancode; + } +#endif + + //!! + //sprintf(debug, "SDL: TranslateKey: keysym->scancode=%d, keysym->sym=%d, keysym->mod=%d", + // keysym->scancode, keysym->sym, keysym->mod); + //SDL_TRACE(debug); //!! + + return(keysym); +} + +} /* extern "C" */ + + diff --git a/src/video/symbian/EKA2/SDL_epocvideo.cpp b/src/video/symbian/EKA2/SDL_epocvideo.cpp new file mode 100644 index 000000000..fc201bd2f --- /dev/null +++ b/src/video/symbian/EKA2/SDL_epocvideo.cpp @@ -0,0 +1,594 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* + SDL_epocvideo.cpp + Epoc based SDL video driver implementation + + Markus Mertama +*/ + + + +#include "epoc_sdl.h" + +#include +#include +#include + +extern "C" { +#include "SDL_error.h" +#include "SDL_timer.h" +#include "SDL_video.h" +#undef NULL +#include "SDL_pixels_c.h" +#include "SDL.h" +#include "SDL_mouse.h" +} + +#include "SDL_epocvideo.h" +#include "SDL_epocevents_c.h" + + + +#include +#include + +#include +#include +#include +#include "sdlepocapi.h" + + +//////////////////////////////////////////////////////////////// + + + + +_LIT(KLibName, "SDL"); + +void RDebug_Print_b(char* error_str, void* param) + { + TBuf8<128> error8((TUint8*)error_str); + TBuf<128> error; + error.Copy(error8); + +#ifndef TRACE_TO_FILE + if (param) //!! Do not work if the parameter is really 0!! + RDebug::Print(error, param); + else + RDebug::Print(error); +#else + if (param) //!! Do not work if the parameter is really 0!! + RFileLogger::WriteFormat(KLibName, _L("SDL.txt"), EFileLoggingModeAppend, error, param); + else + RFileLogger::Write(KLibName, _L("SDL.txt"), EFileLoggingModeAppend, error); +#endif + + } + +extern "C" void RDebug_Print(char* error_str, void* param) + { + RDebug_Print_b(error_str, param); + } + +/* +int Debug_AvailMem2() + { + //User::CompressAllHeaps(); + TMemoryInfoV1Buf membuf; + User::LeaveIfError(UserHal::MemoryInfo(membuf)); + TMemoryInfoV1 minfo = membuf(); + return(minfo.iFreeRamInBytes); + } + +extern "C" int Debug_AvailMem() + { + return(Debug_AvailMem2()); + } + +*/ + +extern "C" { + +/* Initialization/Query functions */ + +static int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat); +static SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); +static SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); +static int EPOC_SetColors(_THIS, int firstcolor, int ncolors, + SDL_Color *colors); +static void EPOC_VideoQuit(_THIS); + +/* Hardware surface functions */ + +static int EPOC_AllocHWSurface(_THIS, SDL_Surface *surface); +static int EPOC_LockHWSurface(_THIS, SDL_Surface *surface); +static int EPOC_FlipHWSurface(_THIS, SDL_Surface *surface); +static void EPOC_UnlockHWSurface(_THIS, SDL_Surface *surface); +static void EPOC_FreeHWSurface(_THIS, SDL_Surface *surface); +static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); + +static int EPOC_Available(void); +static SDL_VideoDevice *EPOC_CreateDevice(int devindex); + +void DrawBackground(_THIS); +void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer); +void DirectDrawRotated(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer); + +/* Mouse functions */ + +static WMcursor *EPOC_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); +static void EPOC_FreeWMCursor(_THIS, WMcursor *cursor); +static int EPOC_ShowWMCursor(_THIS, WMcursor *cursor); +} + + +extern "C" + { + struct WMcursor + { + }; + } + +/* Epoc video driver bootstrap functions */ + + +static int EPOC_Available(void) + { + return 1; /* Always available */ + } + +static void EPOC_DeleteDevice(SDL_VideoDevice *device) + { + User::Free(device->hidden); + User::Free(device); + } + +static SDL_VideoDevice *EPOC_CreateDevice(int /*devindex*/) + { + SDL_VideoDevice *device; + + SDL_TRACE("SDL:EPOC_CreateDevice"); + + /* Allocate all variables that we free on delete */ + device = static_cast(User::Alloc(sizeof(SDL_VideoDevice))); + if ( device ) + { + Mem::FillZ(device, (sizeof *device)); + device->hidden = static_cast + (User::Alloc((sizeof *device->hidden))); + } + if ( (device == NULL) || (device->hidden == NULL) ) + { + SDL_OutOfMemory(); + if ( device ) { + User::Free(device); + } + return(0); + } + Mem::FillZ(device->hidden, (sizeof *device->hidden)); + + /* Set the function pointers */ + device->VideoInit = EPOC_VideoInit; + device->ListModes = EPOC_ListModes; + device->SetVideoMode = EPOC_SetVideoMode; + device->SetColors = EPOC_SetColors; + device->UpdateRects = NULL; + device->VideoQuit = EPOC_VideoQuit; + device->AllocHWSurface = EPOC_AllocHWSurface; + device->CheckHWBlit = NULL; + device->FillHWRect = NULL; + device->SetHWColorKey = NULL; + device->SetHWAlpha = NULL; + device->LockHWSurface = EPOC_LockHWSurface; + device->UnlockHWSurface = EPOC_UnlockHWSurface; + device->FlipHWSurface = EPOC_FlipHWSurface; + device->FreeHWSurface = EPOC_FreeHWSurface; + device->SetIcon = NULL; + device->SetCaption = NULL; + device->GetWMInfo = NULL; + device->FreeWMCursor = EPOC_FreeWMCursor; + device->CreateWMCursor = EPOC_CreateWMCursor; + device->ShowWMCursor = EPOC_ShowWMCursor; + device->WarpWMCursor = NULL; + device->InitOSKeymap = EPOC_InitOSKeymap; + device->PumpEvents = EPOC_PumpEvents; + device->free = EPOC_DeleteDevice; + + return device; +} + + +VideoBootStrap EPOC_bootstrap = { + "epoc\0\0\0", "EPOC system", + EPOC_Available, EPOC_CreateDevice +}; + + + +void DisableKeyBlocking(_THIS) + { + EpocSdlEnv::Request(EpocSdlEnv::EDisableKeyBlocking); + } + +void ConstructWindowL(_THIS) + { + SDL_TRACE("SDL:ConstructWindowL"); + DisableKeyBlocking(_this); //disable key blocking + } + + +int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat) + { + /* Construct Epoc window */ + + ConstructWindowL(_this); + + /* Initialise Epoc frame buffer */ + + + const TDisplayMode displayMode = EpocSdlEnv::DisplayMode(); + + /* The "best" video format should be returned to caller. */ + + vformat->BitsPerPixel = TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode); + vformat->BytesPerPixel = TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode) / 8; + + + //?? Private->iWindow->PointerFilter(EPointerFilterDrag, 0); + + Private->iScreenPos = TPoint(0, 0); + + Private->iRect.x = Private->iScreenPos.iX; + Private->iRect.y = Private->iScreenPos.iY; + + const TSize sz = EpocSdlEnv::WindowSize(); + + Private->iRect.w = sz.iWidth; + Private->iRect.h = sz.iHeight; + Private->iRectPtr = &Private->iRect; + + return(0); + } + + +SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) + { + if(flags & SDL_HWSURFACE) + { + if(format->BytesPerPixel != 4) //in HW only full color is supported + return NULL; + } + if(flags & SDL_FULLSCREEN) + { + return &Private->iRectPtr; + } + return (SDL_Rect **)(-1); //everythingisok, unless too small shoes + } + + +int EPOC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) + { + if ((firstcolor+ncolors) > 256) + return -1; + TUint32 palette[256]; + const TDisplayMode mode = EpocSdlEnv::DisplayMode(); + if(TDisplayModeUtils::NumDisplayModeColors(mode) == 4096) + { + // Set 12 bit palette + for(int i = firstcolor; i < ncolors; i++) + { + // 4k value: 0000 rrrr gggg bbbb + TUint32 color4K = (colors[i].r & 0x0000f0) << 4; + color4K |= (colors[i].g & 0x0000f0); + color4K |= (colors[i].b & 0x0000f0) >> 4; + palette[i] = color4K; + } + } + else if(TDisplayModeUtils::NumDisplayModeColors(mode) == 65536) + { + for(int i = firstcolor; i < ncolors; i++) + { + // 64k-colour displays effectively support RGB values + // with 5 bits allocated to red, 6 to green and 5 to blue + // 64k value: rrrr rggg gggb bbbb + TUint32 color64K = (colors[i].r & 0x0000f8) << 8; + color64K |= (colors[i].g & 0x0000fc) << 3; + color64K |= (colors[i].b & 0x0000f8) >> 3; + palette[i] = color64K; + } + } + else if(TDisplayModeUtils::NumDisplayModeColors(mode) == 16777216) + { + for(int i = firstcolor; i < ncolors; i++) + { + // 16M-colour + //0000 0000 rrrr rrrr gggg gggg bbbb bbbb + TUint32 color16M = colors[i].r << 16; + color16M |= colors[i].g << 8; + color16M |= colors[i].b; + palette[i] = color16M; + } + } + else + { + return -2; + } + if(EpocSdlEnv::SetPalette(firstcolor, ncolors, palette) == KErrNone) + return 0; + return -1; + } + + +/* +void AllocHWSurfaceL(CFbsBitmap*& aBitmap, const TDisplayMode& aMode, const TSize& aSize) + { + aBitmap = new (ELeave) CFbsBitmap(); + if(KErrNone != aBitmap->CreateHardwareBitmap(aSize, aMode, + EpocSdlEnv::EikonEnv().EikAppUi()->Application()->AppDllUid())) + //...if it fails - should we use wsbitmaps??? + {//the good reason to use hw bitmaps is that they wont need lock heap + PANIC_IF_ERROR(aBitmap->Create(aSize, aMode)); + } + } + +int CreateSurfaceL(_THIS, SDL_Surface* surface) + { + __ASSERT_ALWAYS(Private->iFrame == NULL, PANIC(KErrAlreadyExists)); +; + TInt dmode = EColorLast; + + TDisplayMode displayMode; + EpocSdlEnv::GetDiplayMode(displayMode); + + if( + TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode) + == surface->format->BitsPerPixel) + { + dmode = displayMode; + } + else + { + --dmode; + while(TDisplayModeUtils::IsDisplayModeColor(TDisplayMode(dmode)) && + TDisplayModeUtils::NumDisplayModeBitsPerPixel(TDisplayMode(dmode)) != + surface->format->BitsPerPixel) + --dmode; + } + + __ASSERT_ALWAYS(TDisplayModeUtils::IsDisplayModeColor(TDisplayMode(dmode)), PANIC(KErrNotSupported)); + TRAPD(err, AllocHWSurfaceL(Private->iFrame, TDisplayMode(dmode), TSize(surface->w, surface->h))); + return err == KErrNone ? 0 : -1; + } +*/ + +TDisplayMode GetDisplayMode(TInt aBitsPerPixel) + { + const TDisplayMode displayMode = EpocSdlEnv::DisplayMode(); + TInt dmode = EColorLast; + if( + TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode) + == aBitsPerPixel) + { + dmode = displayMode; + } + else + { + --dmode; + while(TDisplayModeUtils::IsDisplayModeColor(TDisplayMode(dmode)) && + TDisplayModeUtils::NumDisplayModeBitsPerPixel(TDisplayMode(dmode)) != + aBitsPerPixel) + --dmode; + } + return TDisplayMode(dmode); + } + +SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current, + int width, int height, int bpp, Uint32 flags) + { + const TSize screenSize = EpocSdlEnv::WindowSize(TSize(width, height)); + if(width > screenSize.iWidth || height > screenSize.iHeight) + { + if(flags & SDL_FULLSCREEN) + { + width = screenSize.iWidth; + height = screenSize.iHeight; + } + else + return NULL; + } + + if(current && current->pixels) + { + // free(current->pixels); + current->pixels = NULL; + } + + if(!SDL_ReallocFormat(current, bpp, 0, 0, 0, 0)) + { + return(NULL); + } + + current->flags = 0; + if(width == screenSize.iWidth && height == screenSize.iHeight) + current->flags |= SDL_FULLSCREEN; + + const int numBytesPerPixel = ((bpp-1)>>3) + 1; + current->pitch = numBytesPerPixel * width; // Number of bytes in scanline + + /* Set up the new mode framebuffer */ + current->flags |= SDL_PREALLOC; + + if(bpp <= 8) + current->flags |= SDL_HWPALETTE; + + User::Free(Private->iSwSurface); + current->pixels = NULL; + Private->iSwSurface = NULL; + + if(flags & SDL_HWSURFACE) + { + current->flags |= SDL_HWSURFACE; + // current->pixels = NULL; + // Private->iSwSurface = NULL; + } + else + { + current->flags |= SDL_SWSURFACE; + const TInt surfacesize = width * height * numBytesPerPixel; + Private->iSwSurfaceSize = TSize(width, height); + delete Private->iSwSurface; + Private->iSwSurface = NULL; + current->pixels = (TUint8*) User::AllocL(surfacesize); + Private->iSwSurface = (TUint8*) current->pixels; + const TInt err = EpocSdlEnv::AllocSwSurface + (TSize(width, height), GetDisplayMode(current->format->BitsPerPixel)); + if(err != KErrNone) + return NULL; + } + + current->w = width; + current->h = height; + + + + /* Set the blit function */ + _this->UpdateRects = EPOC_DirectUpdate; + + /* + * Logic for getting suitable screen dimensions, offset, scaling and orientation + */ + + + /* Centralize game window on device screen */ + + + Private->iScreenPos.iX = Max(0, (screenSize.iWidth - width) / 2); + Private->iScreenPos.iY = Max(0, (screenSize.iHeight - height) / 2); + + // delete (Private->iFrame); +// Private->iFrame = NULL; + + // TRAPD(err, CreateSurfaceL(_this, current)); + // PANIC_IF_ERROR(err); + + SDL_TRACE1("View width %d", width); + SDL_TRACE1("View height %d", height); + SDL_TRACE1("View bmode %d", bpp); + SDL_TRACE1("View x %d", Private->iScreenPos.iX); + SDL_TRACE1("View y %d", Private->iScreenPos.iY); + + EpocSdlEnv::LockPalette(EFalse); + /* We're done */ + return(current); +} + + + +static int EPOC_AllocHWSurface(_THIS, SDL_Surface* surface) + { + return KErrNone == EpocSdlEnv::AllocHwSurface(TSize(surface->w, surface->h), GetDisplayMode(surface->format->BitsPerPixel)); + } + +static void EPOC_FreeHWSurface(_THIS, SDL_Surface* /*surface*/) + { + } + +static int EPOC_LockHWSurface(_THIS, SDL_Surface* surface) + { + if(EpocSdlEnv::IsDsaAvailable()) + { + TUint8* address = EpocSdlEnv::LockHwSurface(); + if(address != NULL) + { + surface->pixels = address; + return 1; + } + } + return 0; + } +static void EPOC_UnlockHWSurface(_THIS, SDL_Surface* /*surface*/) + { + EpocSdlEnv::UnlockHwSurface(); + } + +static int EPOC_FlipHWSurface(_THIS, SDL_Surface* /*surface*/) + { + return(0); + } + +static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) + { + if(EpocSdlEnv::IsDsaAvailable()) + { + if(Private->iSwSurface) + { + const TRect target(Private->iScreenPos, Private->iSwSurfaceSize); + for(TInt i = 0; i < numrects ;i++) + { + const TRect rect(TPoint(rects[i].x, rects[i].y), + TSize(rects[i].w, rects[i].h)); + if(!EpocSdlEnv::AddUpdateRect(Private->iSwSurface, rect, target)) + return; //not succesful + } + EpocSdlEnv::UpdateSwSurface(); + } + SDL_PauseAudio(0); + } + else + { + SDL_PauseAudio(1); + EpocSdlEnv::WaitDsaAvailable(); + } + } + + +/* Note: If we are terminated, this could be called in the middle of + another SDL video routine -- notably UpdateRects. +*/ +void EPOC_VideoQuit(_THIS) + { +// delete Private->iFrame; +// Private->iFrame = NULL; + User::Free(Private->iSwSurface); + Private->iSwSurface = NULL; + EpocSdlEnv::FreeSurface(); + } + + + + +WMcursor *EPOC_CreateWMCursor(_THIS, Uint8* /*data*/, Uint8* /*mask*/, int /*w*/, int /*h*/, int /*hot_x*/, int /*hot_y*/) + { + return (WMcursor*) 1; //hii! prevents SDL to view a std cursor + } + +void EPOC_FreeWMCursor(_THIS, WMcursor* /*cursor*/) + { + } + +int EPOC_ShowWMCursor(_THIS, WMcursor *cursor) + { + return true; + } + diff --git a/src/video/symbian/EKA2/SDL_epocvideo.h b/src/video/symbian/EKA2/SDL_epocvideo.h new file mode 100644 index 000000000..d823413f7 --- /dev/null +++ b/src/video/symbian/EKA2/SDL_epocvideo.h @@ -0,0 +1,51 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifndef EPOCVIDEO_H +#define EPOCVIDEO_H + +#include + +/* Hidden "this" pointer for the video functions */ +#define _THIS SDL_VideoDevice *_this +#define Private _this->hidden + +class CFbsBitmap; + +struct SDL_VideoDevice; +void DisableKeyBlocking(SDL_VideoDevice*); + +struct SDL_PrivateVideoData + { + TPoint iScreenPos; + TBool iIsWindowFocused; + TSize iSwSurfaceSize; + TUint8* iSwSurface; + SDL_Rect iRect; //same info in SDL format + SDL_Rect* iRectPtr; + }; + +#endif + + + + \ No newline at end of file diff --git a/src/video/symbian/EKA2/dsa.cpp b/src/video/symbian/EKA2/dsa.cpp new file mode 100644 index 000000000..6702075b4 --- /dev/null +++ b/src/video/symbian/EKA2/dsa.cpp @@ -0,0 +1,1504 @@ +#include "dsa.h" +#include "sdlepocapi.h" +#include + + +LOCAL_C TInt BytesPerPixel(TDisplayMode aMode) + { + return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1; + } + + + + +template +class CBitmapSurface : public T + { +public: + CBitmapSurface(RWsSession& aSession); +private: + void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); + ~CBitmapSurface(); + TUint8* LockSurface(); + void UnlockHwSurface(); + void CreateSurfaceL(); + void Wipe(TInt aLength); + void Free(); + void Update(CFbsBitmap& aBmp); + TInt ExternalUpdate(); +private: + CFbsBitmap* iBmp; + CFbsBitmap* iCopyBmp; + }; + + +template +void CBitmapSurface::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) + { + delete iCopyBmp; + iCopyBmp = NULL; + iCopyBmp = new (ELeave) CFbsBitmap(); + T::ConstructL(aWindow, aDevice); + } + +template +CBitmapSurface::CBitmapSurface(RWsSession& aSession) : T(aSession) + { + } + +template +void CBitmapSurface::Free() + { + delete iBmp; + iBmp = NULL; + T::Free(); + } + +template +CBitmapSurface::~CBitmapSurface() + { + __ASSERT_DEBUG(iBmp == NULL, PANIC(KErrNotReady)); + delete iCopyBmp; + } + +template +TUint8* CBitmapSurface::LockSurface() + { + iBmp->LockHeap(); + return reinterpret_cast(iBmp->DataAddress()); + } + + +template +void CBitmapSurface::UnlockHwSurface() + { + iBmp->UnlockHeap(); + T::SetUpdating(EFalse); + Update(*iBmp); + } + + +template +void CBitmapSurface::Update(CFbsBitmap& aBmp) + { + if(!T::Blitter(aBmp)) + { + if(T::SwSize() == T::HwRect().Size()) + T::Gc().BitBlt(T::HwRect().iTl, &aBmp); + else + T::Gc().DrawBitmap(T::HwRect(), &aBmp); + } + T::DrawOverlays(); + T::CompleteUpdate(); + } + +template +void CBitmapSurface::CreateSurfaceL() + { + Free(); + iBmp = new (ELeave) CFbsBitmap(); + User::LeaveIfError(iBmp->Create(T::SwSize(), T::DisplayMode())); + T::CreateSurfaceL(*iBmp); + } + +template +void CBitmapSurface::Wipe(TInt aLength) //dont call in drawing + { + iBmp->LockHeap(); + Mem::FillZ(iBmp->DataAddress(), aLength); + iBmp->UnlockHeap(); + } + +template +TInt CBitmapSurface::ExternalUpdate() + { + if(iCopyBmp->Handle() == 0) + { + const TInt err = iCopyBmp->Duplicate(iBmp->Handle()); + if(err != KErrNone) + return err; + } + Update(*iCopyBmp); + return KErrNone; + } + + +////////////////////////////////////////////////////////////////////// + + + +NONSHARABLE_CLASS(CDsaBitgdi) : public CDsa + { +public: + CDsaBitgdi(RWsSession& aSession); +protected: + void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); + CBitmapContext& Gc(); + void CompleteUpdate(); + ~CDsaBitgdi(); + void CreateSurfaceL(CFbsBitmap& aBmp); + void Free(); + void UnlockHWSurfaceRequestComplete(); +private: + void Resume(); + + CFbsBitGc* iGc; + CFbsDevice* iDevice; + CFbsBitmap* iBitGdiBmp; + CWindowGc* iWinGc; + RWindow* iWindow; + TInt iHandle; + }; + + +CDsaBitgdi::CDsaBitgdi(RWsSession& aSession) : CDsa(aSession) + { + } + +CDsaBitgdi::~CDsaBitgdi() + { + delete iWinGc; + delete iBitGdiBmp; + } + +void CDsaBitgdi::CompleteUpdate() + { + EpocSdlEnv::Request(CDsa::ERequestUpdate); + } + + +void CDsaBitgdi::UnlockHWSurfaceRequestComplete() + { + if(iHandle == 0) + return; + + if(iBitGdiBmp == NULL) + { + iBitGdiBmp = new CFbsBitmap(); + if(iBitGdiBmp == NULL) + return; + iBitGdiBmp->Duplicate(iHandle); + } + + iWindow->Invalidate(); + + iWindow->BeginRedraw(); + iWinGc->Activate(*iWindow); + iWinGc->BitBlt(TPoint(0, 0), iBitGdiBmp); + iWinGc->Deactivate(); + iWindow->EndRedraw(); + } + +void CDsaBitgdi::Resume() + { + Start(); + } + +CBitmapContext& CDsaBitgdi::Gc() + { + return *iGc; + } + + void CDsaBitgdi::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) + { + + delete iBitGdiBmp; + iBitGdiBmp = NULL; + delete iWinGc; + iWinGc = NULL; + iHandle = 0; + + iWindow = &aWindow; + User::LeaveIfError(aDevice.CreateContext(iWinGc)); + CDsa::ConstructL(aWindow, aDevice); + Start(); + } + +void CDsaBitgdi::CreateSurfaceL(CFbsBitmap& aBmp) + { + iDevice = CFbsBitmapDevice::NewL(&aBmp); + User::LeaveIfError(iDevice->CreateContext(iGc)); + iHandle = aBmp.Handle(); + } + +void CDsaBitgdi::Free() + { + delete iGc; + iGc = NULL; + delete iDevice; + iDevice = NULL; + } + +//////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////// + +NONSHARABLE_CLASS(CDsaBase) : public CDsa, public MDirectScreenAccess + { +protected: + inline CDirectScreenAccess& Dsa() const; + CDsaBase(RWsSession& aSession); + ~CDsaBase(); + void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); + void Stop(); + void Resume(); + CBitmapContext& Gc(); +protected: + CDirectScreenAccess* iDsa; +private: + void AbortNow(RDirectScreenAccess::TTerminationReasons aReason); + void Restart(RDirectScreenAccess::TTerminationReasons aReason); +private: + void RestartL(); + }; + + +inline CDirectScreenAccess& CDsaBase::Dsa() const + { + return *iDsa; + } + + +CDsaBase::CDsaBase(RWsSession& aSession) : CDsa(aSession) + { + } + +CBitmapContext& CDsaBase::Gc() + { + return *Dsa().Gc(); + } + +void CDsaBase::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) + { + CDsa::ConstructL(aWindow, aDevice); + if(iDsa != NULL) + { + iDsa->Cancel(); + delete iDsa; + iDsa = NULL; + } + + iDsa = CDirectScreenAccess::NewL( + Session(), + aDevice, + aWindow, + *this); + RestartL(); + } + +void CDsaBase::Resume() + { + if(Stopped()) + Restart(RDirectScreenAccess::ETerminateRegion); + } + +CDsaBase::~CDsaBase() + { + if(iDsa != NULL) + { + iDsa->Cancel(); + } + delete iDsa; + } + + +void CDsaBase::RestartL() + { + + + iDsa->StartL(); + + const RRegion* r = iDsa->DrawingRegion(); + const TRect rect = r->BoundingRect(); + iDsa->Gc()->SetClippingRegion(r); + + if(rect != ScreenRect()) + { + return ; + } + + + SetTargetRect(); + RecreateL(); + + Start(); + + + } + +void CDsaBase::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/) + { + Stop(); + } + +void CDsaBase::Restart(RDirectScreenAccess::TTerminationReasons aReason) + { + if(aReason == RDirectScreenAccess::ETerminateRegion) //auto restart + { + TRAPD(err, RestartL()); + PANIC_IF_ERROR(err); + } + } + + +void CDsaBase::Stop() + { + CDsa::Stop(); + iDsa->Cancel(); + } + + + /////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////// +NONSHARABLE_CLASS(TDsa) + { + public: + inline TDsa(const CDsa& aDsa); + inline TBool IsFlip() const; + inline TBool IsTurn() const; + inline const TSize& SwSize() const; + inline void Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const; + private: + const CDsa& iDsa; + }; + + + + +inline TDsa::TDsa(const CDsa& aDsa) : iDsa(aDsa) + { + } + +inline TBool TDsa::IsTurn() const + { + return iDsa.iStateFlags & CDsa::EOrientation90; + } + +inline TBool TDsa::IsFlip() const + { + return iDsa.iStateFlags & CDsa::EOrientation180; + } + +inline const TSize& TDsa::SwSize() const + { + return iDsa.SwSize(); + } + +inline void TDsa::Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const + { + iDsa.iCopyFunction(iDsa, aTarget, aSrc, aBytes, aHeight); + } + +template +void ClipCopy(const TDsa& iDsa, TUint8* aTarget, + const TUint8* aSource, + const TRect& aUpdateRect, + const TRect& aSourceRect) + { + const S* source = reinterpret_cast(aSource); + const TInt lineWidth = aSourceRect.Width(); + + source += (aUpdateRect.iTl.iY * lineWidth); + const TInt sourceStartOffset = aUpdateRect.iTl.iX; + source += sourceStartOffset; + + T* targetPtr = reinterpret_cast(aTarget); + + const TInt scanLineWidth = iDsa.SwSize().iWidth; + + targetPtr += (aSourceRect.iTl.iY + aUpdateRect.iTl.iY ) * scanLineWidth; + const TInt targetStartOffset = (aUpdateRect.iTl.iX + aSourceRect.iTl.iX); + + targetPtr += targetStartOffset; + + + const TInt height = aUpdateRect.Height(); + + const TInt lineMove = iDsa.IsTurn() ? 1 : lineWidth; + const TInt copyLen = aUpdateRect.Width(); + + + if(iDsa.IsFlip()) + { + + targetPtr += scanLineWidth * (height - 1); + + for(TInt i = 0; i < height; i++) //source is always smaller + { + iDsa.Copy(reinterpret_cast(targetPtr), reinterpret_cast(source), copyLen, height); + source += lineMove; + targetPtr -= scanLineWidth; + } + } + else + { + + + for(TInt i = 0; i < height; i++) //source is always smaller + { + iDsa.Copy(reinterpret_cast(targetPtr), reinterpret_cast(source), copyLen, height); + source += lineMove; + targetPtr += scanLineWidth; // >> 2; + } + } + + } + + + +NONSHARABLE_CLASS(CDsaA) : public CDsaBase + { + public: + CDsaA(RWsSession& aSession); + protected: + void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); + void CompleteUpdate(); + void CreateSurfaceL(CFbsBitmap& aBmp); + void Free(); + void UnlockHWSurfaceRequestComplete(); + }; + + +CDsaA::CDsaA(RWsSession& aSession) : CDsaBase(aSession) + { + } + + +void CDsaA::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) + { + CDsaBase::ConstructL(aWindow, aDevice); + } + +void CDsaA::CompleteUpdate() + { + iDsa->ScreenDevice()->Update(); + } + +void CDsaA::CreateSurfaceL(CFbsBitmap& /*aBmp*/) + { + } + +void CDsaA::Free() + { + + } + +void CDsaA::UnlockHWSurfaceRequestComplete() + { + PANIC(KErrNotSupported); + } + + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +NONSHARABLE_CLASS(MDsbObs) + { + public: + virtual void SurfaceReady() = 0; + virtual CDirectScreenBitmap& Dsb() = 0; + }; + +NONSHARABLE_CLASS(CDsbSurface) : public CActive + { + public: + CDsbSurface(MDsbObs& aDsb); + TUint8* Address(); + void Complete(); + ~CDsbSurface(); + private: + void RunL(); + void DoCancel(); + private: + MDsbObs& iDsb; + TUint8* iAddress; + }; + +CDsbSurface::CDsbSurface(MDsbObs& aDsb) : CActive(CActive::EPriorityHigh) , iDsb(aDsb) + { + CActiveScheduler::Add(this); + } + +CDsbSurface::~CDsbSurface() + { + Cancel(); + } + +void CDsbSurface::Complete() + { + if(iAddress != NULL && !IsActive()) + { + iAddress = NULL; + SetActive(); + iDsb.Dsb().EndUpdate(iStatus); + } + } + +TUint8* CDsbSurface::Address() + { + if(iAddress == NULL && !IsActive()) + { + TAcceleratedBitmapInfo info; + if(KErrNone == iDsb.Dsb().BeginUpdate(info)) + iAddress = info.iAddress; + } + return iAddress; + } + +void CDsbSurface::RunL() + { + iDsb.SurfaceReady(); + } + +void CDsbSurface::DoCancel() + { + //empty + } + +NONSHARABLE_CLASS(CDsaB) : public CDsaBase, + public MDsbObs + { + public: + CDsaB(RWsSession& aSession, TInt aFlags); + private: + ~CDsaB(); + TUint8* LockSurface(); + void UnlockHWSurfaceRequestComplete(); + void UnlockHwSurface(); + void CreateSurfaceL(); + void Wipe(TInt aLength); + void RecreateL(); + void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); + CDirectScreenBitmap& Dsb(); + void SurfaceReady(); + TInt ExternalUpdate(); + private: + CDsbSurface* iSurface1; + CDsbSurface* iSurface2; + CDirectScreenBitmap* iDsb; + TInt iType; + }; + +CDsaB::CDsaB(RWsSession& aSession, TInt aFlags) : CDsaBase(aSession), iType(aFlags) + { + } + + + +void CDsaB::UnlockHWSurfaceRequestComplete() + { + iSurface1->Complete(); + if(iSurface2 != NULL) + iSurface2->Complete(); + } + +void CDsaB::CreateSurfaceL() + { + __ASSERT_ALWAYS(SwSize() == HwRect().Size(), PANIC(KErrNotSupported)); + } + +void CDsaB::Wipe(TInt aLength) //dont call in drawing + { + TUint8* addr = LockSurface(); + if(addr != NULL) + { + Mem::FillZ(addr, aLength); + UnlockHwSurface(); + } + } + + +void CDsaB::UnlockHwSurface() + { + EpocSdlEnv::Request(CDsa::ERequestUpdate); + } + +TUint8* CDsaB::LockSurface() + { + TUint8* addr = iSurface1->Address(); + if(addr == NULL && iSurface2 != NULL) + addr = iSurface2->Address(); + SetUpdating(addr == NULL); + return addr; + } + +void CDsaB::SurfaceReady() + { + SetUpdating(EFalse); + } + +CDirectScreenBitmap& CDsaB::Dsb() + { + return *iDsb; + } + +void CDsaB::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) + { + if(iDsb == NULL) + iDsb = CDirectScreenBitmap::NewL(); + CDsaBase::ConstructL(aWindow, aDevice); + if(iSurface1 == NULL) + iSurface1 = new (ELeave) CDsbSurface(*this); + if(iSurface2 == NULL && iType & CDirectScreenBitmap::EDoubleBuffer) + iSurface2 = new (ELeave) CDsbSurface(*this); + } + +CDsaB::~CDsaB() + { + delete iSurface1; + delete iSurface2; + delete iDsb; + } + +void CDsaB::RecreateL() + { + iDsb->Close(); + iDsb->Create(HwRect(), CDirectScreenBitmap::TSettingsFlags(iType)); + } + +TInt CDsaB::ExternalUpdate() + { + if(LockSurface()) + { + UnlockHWSurfaceRequestComplete(); + return KErrNone; + } + return KErrNotReady; + } + + +///////////////////////////////////////////////////////////////////////////////////////////////////// + + + +CDsa* CDsa::CreateL(RWsSession& aSession) + { + if(EpocSdlEnv::Flags(CSDL::EDrawModeDSB)) + { + TInt flags = CDirectScreenBitmap::ENone; + if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBDoubleBuffer)) + flags |= CDirectScreenBitmap::EDoubleBuffer; + if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBIncrementalUpdate)) + flags |= CDirectScreenBitmap::EIncrementalUpdate; + return new (ELeave) CDsaB(aSession, flags); + } + else if(EpocSdlEnv::Flags(CSDL::EDrawModeGdi)) + { + return new (ELeave) CBitmapSurface(aSession); + } + else + { + return new (ELeave) CBitmapSurface(aSession); + } + } + + +void CDsa::RecreateL() + { + } + +void CDsa::Free() + { + } + +TSize CDsa::WindowSize() const + { + TSize size = iSwSize; + if(iStateFlags & EOrientation90) + { + const TInt tmp = size.iWidth; + size.iWidth = size.iHeight; + size.iHeight = tmp; + } + return size; + } + +void CDsa::SetSuspend() + { + iStateFlags |= ESdlThreadSuspend; + } + + +void CDsa::SetUpdating(TBool aUpdate) + { + if(aUpdate) + iStateFlags |= EUpdating; + else + iStateFlags &= ~EUpdating; + } + + +TBool CDsa::Stopped() const + { + return (iStateFlags & ESdlThreadExplicitStop); + } + +void CDsa::SetOrientation(CSDL::TOrientationMode aOrientation) + { + TInt flags = 0; + switch(aOrientation) + { + case CSDL::EOrientation90: + flags = EOrientation90; + break; + case CSDL::EOrientation180: + flags = EOrientation180; + break; + case CSDL::EOrientation270: + flags = EOrientation90 | EOrientation180; + break; + case CSDL::EOrientation0: + flags = 0; + break; + } + if(flags != (iStateFlags & EOrientationFlags)) + { + iStateFlags |= EOrientationChanged; + iNewFlags = flags; //cannot be set during drawing... + } + } + +CDsa::~CDsa() + { + iOverlays.Close(); + User::Free(iLut256); + } + +void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& /*aDevice*/) + { + if(iLut256 == NULL) + iLut256 = (TUint32*) User::AllocL(256 * sizeof(TUint32)); + iTargetMode = aWindow.DisplayMode(); + iTargetBpp = BytesPerPixel(DisplayMode()); + iScreenRect = TRect(aWindow.Position(), aWindow.Size()); + SetTargetRect(); + } + +void CDsa::DrawOverlays() + { + const TInt last = iOverlays.Count() - 1; + for(TInt i = last; i >= 0 ; i--) + iOverlays[i].iOverlay->Draw(Gc(), HwRect(), SwSize()); + } + +TInt CDsa::AppendOverlay(MOverlay& aOverlay, TInt aPriority) + { + TInt i; + for(i = 0; i < iOverlays.Count() && iOverlays[i].iPriority < aPriority; i++) + {} + const TOverlay overlay = {&aOverlay, aPriority}; + return iOverlays.Insert(overlay, i); + } + +TInt CDsa::RemoveOverlay(MOverlay& aOverlay) + { + for(TInt i = 0; i < iOverlays.Count(); i++) + { + if(iOverlays[i].iOverlay == &aOverlay) + { + iOverlays.Remove(i); + return KErrNone; + } + } + return KErrNotFound; + } + +void CDsa::LockPalette(TBool aLock) + { + if(aLock) + iStateFlags |= EPaletteLocked; + else + iStateFlags &= ~EPaletteLocked; + } +TInt CDsa::SetPalette(TInt aFirst, TInt aCount, TUint32* aPalette) + { + if(iLut256 == NULL) + return KErrNotFound; + const TInt count = aCount - aFirst; + if(count > 256) + return KErrArgument; + if(iStateFlags & EPaletteLocked) + return KErrNone; + for(TInt i = aFirst; i < count; i++) //not so busy here:-) + { + iLut256[i] = aPalette[i]; + } + return KErrNone; + } + + + + + +CDsa::CDsa(RWsSession& aSession) : + iSession(aSession), + iStateFlags(0) + { +// CActiveScheduler::Add(this); + iCFTable[0] = CopyMem; + iCFTable[1] = CopyMemFlipReversed; + iCFTable[2] = CopyMemReversed; + iCFTable[3] = CopyMemFlip; + + iCFTable[4] = Copy256; + iCFTable[5] = Copy256FlipReversed; + iCFTable[6] = Copy256Reversed; + iCFTable[7] = Copy256Flip; + + + iCFTable[8] = CopySlow; + iCFTable[9] = CopySlowFlipReversed; + iCFTable[10] = CopySlowReversed; + iCFTable[11] = CopySlowFlip; + } + +RWsSession& CDsa::Session() + { + return iSession; + } + +TInt CDsa::RedrawRequest() + { + if(!(iStateFlags & (EUpdating) && (iStateFlags & ERunning))) + { + return ExternalUpdate(); + } + return KErrNotReady; + } + +TUint8* CDsa::LockHwSurface() + { + if((iStateFlags & EUpdating) == 0) //else frame is skipped + { + return LockSurface(); + } + return NULL; + } + +/* +void CDsa::RunL() + { + iStateFlags &= ~EUpdating; + } + + +void CDsa::DoCancel() + { + iStateFlags &= ~EUpdating; + //nothing can do, just wait? + } +*/ + + +TInt CDsa::AllocSurface(TBool aHwSurface, const TSize& aSize, TDisplayMode aMode) + { + if(aHwSurface && aMode != DisplayMode()) + return KErrArgument; + + iSourceMode = aMode; + + iSourceBpp = BytesPerPixel(aMode); + + const TSize size = WindowSize(); + if(aSize.iWidth > size.iWidth) + return KErrTooBig; + if(aSize.iHeight > size.iHeight) + return KErrTooBig; + + TRAPD(err, CreateSurfaceL()); + if(err != KErrNone) + return err; + + SetCopyFunction(); + + return KErrNone; + } + + +void CDsa::CreateZoomerL(const TSize& aSize) + { + iSwSize = aSize; + iStateFlags |= EResizeRequest; + CreateSurfaceL(); + SetTargetRect(); + } + + +/* +void SaveBmp(const TDesC& aName, const TAny* aData, TInt aLength, const TSize& aSz, TDisplayMode aMode) + { + CFbsBitmap* s = new CFbsBitmap(); + s->Create(aSz, aMode); + s->LockHeap(); + TUint32* addr = s->DataAddress(); + Mem::Copy(addr, aData, aLength); + s->UnlockHeap(); + s->Save(aName); + s->Reset(); + delete s; + } + +void SaveBmp(const TDesC& aName, const TUint32* aData, const TSize& aSz) + { + CFbsBitmap* s = new CFbsBitmap(); + s->Create(aSz, EColor64K); + TBitmapUtil bmp(s); + bmp.Begin(TPoint(0, 0)); + for(TInt j = 0; j < aSz.iHeight; j++) + { + bmp.SetPos(TPoint(0, j)); + for(TInt i = 0; i < aSz.iWidth; i++) + { + bmp.SetPixel(*aData); + aData++; + bmp.IncXPos(); + } + } + bmp.End(); + s->Save(aName); + s->Reset(); + delete s; + } + +TBuf<16> FooName(TInt aFoo) + { + TBuf<16> b; + b.Format(_L("C:\\pic%d.mbm"), aFoo); + return b; + } + +*/ + + +void CDsa::ClipCopy(TUint8* aTarget, + const TUint8* aSource, + const TRect& aUpdateRect, + const TRect& aSourceRect) const + { + const TDsa dsa(*this); + switch(iSourceBpp) + { + case 1: + ::ClipCopy(dsa, aTarget, aSource, aUpdateRect, aSourceRect); + break; + case 2: + ::ClipCopy(dsa, aTarget, aSource, aUpdateRect, aSourceRect); + break; + case 4: + ::ClipCopy(dsa, aTarget, aSource, aUpdateRect, aSourceRect); + break; + } + } + + +void CDsa::Wipe() //dont call in drawing + { + if(IsDsaAvailable()) + Wipe(iTargetBpp * SwSize().iWidth * SwSize().iHeight); + } + +void CDsa::SetCopyFunction() + { + //calculate offset to correct function in iCFTable according to given parameters + TInt function = 0; + const TInt KCopyFunctions = 4; + const TInt KOffsetToNative = 0; + const TInt KOffsetTo256 = KOffsetToNative + KCopyFunctions; + const TInt KOffsetToOtherModes = KOffsetTo256 + KCopyFunctions; + const TInt KOffsetTo90Functions = 1; + const TInt KOffsetTo180Functions = 2; + + if(iSourceMode == DisplayMode()) + function = KOffsetToNative; //0 + else if(iSourceMode == EColor256) + function = KOffsetTo256; //4 + else + function = KOffsetToOtherModes; //8 + + if(iStateFlags & EOrientation90) + function += KOffsetTo90Functions; // + 1 + if(iStateFlags & EOrientation180) + function += KOffsetTo180Functions; //+ 2 + + iCopyFunction = iCFTable[function]; + + Wipe(); + } + +inline void Rotate(TRect& aRect) + { + const TInt dx = aRect.iBr.iX - aRect.iTl.iX; + const TInt dy = aRect.iBr.iY - aRect.iTl.iY; + + aRect.iBr.iX = aRect.iTl.iX + dy; + aRect.iBr.iY = aRect.iTl.iY + dx; + + const TInt tmp = aRect.iTl.iX; + aRect.iTl.iX = aRect.iTl.iY; + aRect.iTl.iY = tmp; + } + +/* +int bar = 0; +*/ + +TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect) + { + + if(iStateFlags & EOrientationChanged) + { + iStateFlags &= ~EOrientationFlags; + iStateFlags |= iNewFlags; + SetCopyFunction(); + iStateFlags &= ~EOrientationChanged; + EpocSdlEnv::WaitDeviceChange(); + return EFalse; //skip this frame as data is may be changed + } + + if(iTargetAddr == NULL) + { + iTargetAddr = LockHwSurface(); + } + + TUint8* target = iTargetAddr; + if(target == NULL) + return EFalse; + + + TRect targetRect = TRect(TPoint(0, 0), SwSize()); + + TRect sourceRect = aRect; + TRect updateRect = aUpdateRect; + +// TPoint move(0, 0); + + + if(iStateFlags & EOrientation90) + { + Rotate(sourceRect); + Rotate(updateRect); + } + + if(iSourceMode != DisplayMode() || targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0)) + { + sourceRect.Intersection(targetRect); //so source always smaller or equal than target + //updateRect.Intersection(targetRect); + ClipCopy(target, aBits, updateRect, sourceRect); + } + else + { + const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored + Mem::Copy(target, aBits, byteCount); + } + + return ETrue; + } + + +void CDsa::UpdateSwSurface() + { + iTargetAddr = NULL; + UnlockHwSurface(); //could be faster if does not use AO, but only check status before redraw, then no context switch needed + } + + + + +void CDsa::DoStop() + { + if(IsDsaAvailable()) + iStateFlags |= ESdlThreadExplicitStop; + Stop(); + } + + +void CDsa::Stop() + { + iStateFlags &= ~ERunning; + } + +void CDsa::Start() + { + iStateFlags |= ERunning; + + iStateFlags &= ~ESdlThreadExplicitStop; + + if(iStateFlags & ESdlThreadSuspend) + { + EpocSdlEnv::Resume(); + iStateFlags &= ~ ESdlThreadSuspend; + } + EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowReserved); + } + + +TBool CDsa::Blitter(CFbsBitmap& aBmp) + { + return iBlitter && iBlitter->BitBlt(Gc(), aBmp, HwRect(), SwSize()); + } + +void CDsa::SetBlitter(MBlitter* aBlitter) + { + iBlitter = aBlitter; + } + + +TPoint CDsa::WindowCoordinates(const TPoint& aPoint) const + { + TPoint pos = aPoint - iScreenRect.iTl; + const TSize asz = iScreenRect.Size(); + if(iStateFlags & EOrientation180) + { + pos.iX = asz.iWidth - pos.iX; + pos.iY = asz.iHeight - pos.iY; + } + if(iStateFlags & EOrientation90) + { + pos.iX = aPoint.iY; + pos.iY = aPoint.iX; + } + pos.iX <<= 16; + pos.iY <<= 16; + pos.iX /= asz.iWidth; + pos.iY /= asz.iHeight; + pos.iX *= iSwSize.iWidth; + pos.iY *= iSwSize.iHeight; + pos.iX >>= 16; + pos.iY >>= 16; + return pos; + } + +void CDsa::SetTargetRect() + { + iTargetRect = iScreenRect; + if(iStateFlags & EResizeRequest && EpocSdlEnv::Flags(CSDL::EAllowImageResizeKeepRatio)) + { + const TSize asz = iScreenRect.Size(); + const TSize sz = iSwSize; + + TRect rect; + + const TInt dh = (sz.iHeight << 16) / sz.iWidth; + + if((asz.iWidth * dh ) >> 16 <= asz.iHeight) + { + rect.SetRect(TPoint(0, 0), TSize(asz.iWidth, (asz.iWidth * dh) >> 16)); + } + else + { + const TInt dw = (sz.iWidth << 16) / sz.iHeight; + rect.SetRect(TPoint(0, 0), TSize((asz.iHeight * dw) >> 16, asz.iHeight)); + } + rect.Move((asz.iWidth - rect.Size().iWidth) >> 1, (asz.iHeight - rect.Size().iHeight) >> 1); + + iTargetRect = rect; + iTargetRect.Move(iScreenRect.iTl); + + } + if(!(iStateFlags & EResizeRequest)) + iSwSize = iScreenRect.Size(); + + } + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + TUint32* target = aTarget; + const TUint32* endt = target + aBytes; + const TUint8* source = aSource; + while(target < endt) + { + *target++ = aDsa.iLut256[*source++]; + } + } + +void CDsa::Copy256Reversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + const TUint32* target = aTarget; + TUint32* endt = aTarget + aBytes; + const TUint8* source = aSource; + while(target < endt) + { + *(--endt) = aDsa.iLut256[*source++]; + } + } + +void CDsa::Copy256Flip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + TUint32* target = aTarget; + const TUint32* endt = target + aBytes; + const TUint8* column = aSource; + + while(target < endt) + { + *target++ = aDsa.iLut256[*column]; + column += aLineLen; + } + } + +void CDsa::Copy256FlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + const TUint32* target = aTarget; + TUint32* endt = aTarget + aBytes; + const TUint8* column = aSource; + + while(target < endt) + { + *(--endt) = aDsa.iLut256[*column]; + column += aLineLen; + } + } + +void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + const TUint32* src = reinterpret_cast(aSource); + Mem::Copy(aTarget, src, aBytes << 2); + } + +void CDsa::CopyMemFlip(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + TUint32* target = aTarget; + const TUint32* endt = target + aBytes; + const TUint32* column = reinterpret_cast(aSource); + + while(target < endt) + { + *target++ = *column; + column += aLineLen; + } + } + +void CDsa::CopyMemReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + const TUint32* target = aTarget; + TUint32* endt = aTarget + aBytes; + const TUint32* source = reinterpret_cast(aSource); + while(target < endt) + { + *(--endt) = *source++; + } + } + + +void CDsa::CopyMemFlipReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + const TUint32* target = aTarget; + TUint32* endt = aTarget + aBytes; + const TUint32* column = reinterpret_cast(aSource); + + while(target < endt) + { + *(--endt) = *column; + column += aLineLen; + } + } + +/* + +LOCAL_C TRgb rgb16MA(TInt aValue) + { + return TRgb::Color16MA(aValue); + } +*/ +NONSHARABLE_CLASS(MRgbCopy) + { + public: + virtual void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) = 0; + virtual void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) = 0; + }; + +template +NONSHARABLE_CLASS(TRgbCopy) : public MRgbCopy + { + public: + TRgbCopy(TDisplayMode aMode); + void* operator new(TUint aBytes, TAny* aMem); + void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed); + void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed); + static TUint32 Gray256(const TUint8& aPixel); + static TUint32 Color256(const TUint8& aPixel); + static TUint32 Color4K(const TUint16& aPixel); + static TUint32 Color64K(const TUint16& aPixel); + static TUint32 Color16M(const TUint32& aPixel); + static TUint32 Color16MU(const TUint32& aPixel); + static TUint32 Color16MA(const TUint32& aPixel); + private: + typedef TUint32 (*TRgbFunc) (const T& aValue); + TRgbFunc iFunc; + }; + + +template +void* TRgbCopy::operator new(TUint /*aBytes*/, TAny* aMem) + { + return aMem; + } + +template +TRgbCopy::TRgbCopy(TDisplayMode aMode) + { + switch(aMode) + { + case EGray256 : iFunc = (TRgbFunc) Gray256; break; + case EColor256 : iFunc = (TRgbFunc) Color256; break; + case EColor4K : iFunc = (TRgbFunc) Color4K; break; + case EColor64K : iFunc = (TRgbFunc) Color64K; break; + case EColor16M : iFunc = (TRgbFunc) Color16M; break; + case EColor16MU : iFunc = (TRgbFunc) Color16MU; break; + case EColor16MA : iFunc = (TRgbFunc) Color16MA; break; + default: + PANIC(KErrNotSupported); + } + } + +template +void TRgbCopy::Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) + { + const T* source = reinterpret_cast(aSource); + TUint32* target = aTarget; + TUint32* endt = target + aBytes; + + if(aReversed) + { + while(target < endt) + { + const T value = *source++; + *(--endt) = iFunc(value);//iFunc(value).Value(); + } + } + else + { + while(target < endt) + { + const T value = *source++; + *target++ = iFunc(value);//iFunc(value).Value(); + } + } + } + +template +void TRgbCopy::FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) + { + const T* column = reinterpret_cast(aSource); + TUint32* target = aTarget; + TUint32* endt = target + aBytes; + + if(aReversed) + { + while(target < endt) + { + *(--endt) = iFunc(*column); + column += aLineLen; + } + } + else + { + while(target < endt) + { + *target++ = iFunc(*column); + column += aLineLen; + } + } + } + +template TUint32 TRgbCopy::Gray256(const TUint8& aPixel) + { + const TUint32 px = aPixel << 16 | aPixel << 8 | aPixel; + return px; + } + +template TUint32 TRgbCopy::Color256(const TUint8& aPixel) + { + return TRgb::Color256(aPixel).Value(); + } + +template TUint32 TRgbCopy::Color4K(const TUint16& aPixel) + { + TUint32 col = (aPixel & 0xF00) << 12; + col |= (aPixel & 0xF00) << 8; + + col |= (aPixel & 0x0F0) << 8; + col |= (aPixel & 0x0F0); + + col |= (aPixel & 0x00F) << 4; + col |= (aPixel & 0x00F); + + return col; + } + +template TUint32 TRgbCopy::Color64K(const TUint16& aPixel) + { + TUint32 col = (aPixel & 0xF800)<< 8; + col |= (aPixel & 0xE000) << 3; + + col |= (aPixel & 0x07E0) << 5; + col |= (aPixel & 0xC0) >> 1; + + col |= (aPixel & 0x07E0) << 3; + col |= (aPixel & 0x1C) >> 2; + + return col; + } + +template TUint32 TRgbCopy::Color16M(const TUint32& aPixel) + { + return TRgb::Color16M(aPixel).Value(); + } + +template TUint32 TRgbCopy::Color16MU(const TUint32& aPixel) + { + return TRgb::Color16MU(aPixel).Value(); + } + +template TUint32 TRgbCopy::Color16MA(const TUint32& aPixel) + { + return TRgb::Color16MA(aPixel).Value(); + } + +typedef TUint64 TStackMem; + +LOCAL_C MRgbCopy* GetCopy(TAny* mem, TDisplayMode aMode) + { + if(aMode == EColor256 || aMode == EGray256) + { + return new (mem) TRgbCopy(aMode); + } + if(aMode == EColor4K || aMode == EColor64K) + { + return new (mem) TRgbCopy(aMode); + } + if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA) + { + return new (mem) TRgbCopy(aMode); + } + PANIC(KErrNotSupported); + return NULL; + } + + +void CDsa::CopySlowFlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + TStackMem mem = 0; + GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, ETrue); + } + +void CDsa::CopySlowFlip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + TStackMem mem = 0; + GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, EFalse); + } + +void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + TStackMem mem = 0; + GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, EFalse); + } + +void CDsa::CopySlowReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + TStackMem mem = 0; + GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, ETrue); + } + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////7 diff --git a/src/video/symbian/EKA2/dsa_new.cpp b/src/video/symbian/EKA2/dsa_new.cpp new file mode 100644 index 000000000..638fbe8c9 --- /dev/null +++ b/src/video/symbian/EKA2/dsa_new.cpp @@ -0,0 +1,1443 @@ +#include "dsa.h" +#include "sdlepocapi.h" +#include + + +LOCAL_C TInt BytesPerPixel(TDisplayMode aMode) + { + return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1; + } + + +NONSHARABLE_CLASS(TDsa) + { + public: + inline TDsa(const CDsa& aDsa); + inline TBool IsFlip() const; + inline TBool IsTurn() const; + inline const TSize& SwSize() const; + inline void Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const; + private: + const CDsa& iDsa; + }; + + +inline TDsa::TDsa(const CDsa& aDsa) : iDsa(aDsa) + { + } + +inline TBool TDsa::IsTurn() const + { + return iDsa.iStateFlags & CDsa::EOrientation90; + } + +inline TBool TDsa::IsFlip() const + { + return iDsa.iStateFlags & CDsa::EOrientation180; + } + +inline const TSize& TDsa::SwSize() const + { + return iDsa.SwSize(); + } + +inline void TDsa::Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const + { + iDsa.iCopyFunction(iDsa, aTarget, aSrc, aBytes, aHeight); + } + +template +void ClipCopy(const TDsa& iDsa, TUint8* aTarget, + const TUint8* aSource, + const TRect& aUpdateRect, + const TRect& aSourceRect) + { + const S* source = reinterpret_cast(aSource); + const TInt lineWidth = aSourceRect.Width(); + + source += (aUpdateRect.iTl.iY * lineWidth); + const TInt sourceStartOffset = aUpdateRect.iTl.iX; + source += sourceStartOffset; + + T* targetPtr = reinterpret_cast(aTarget); + + const TInt scanLineWidth = iDsa.SwSize().iWidth; + + targetPtr += (aSourceRect.iTl.iY + aUpdateRect.iTl.iY ) * scanLineWidth; + const TInt targetStartOffset = (aUpdateRect.iTl.iX + aSourceRect.iTl.iX); + + targetPtr += targetStartOffset; + + + const TInt height = aUpdateRect.Height(); + + const TInt lineMove = iDsa.IsTurn() ? 1 : lineWidth; + const TInt copyLen = aUpdateRect.Width(); + + + if(iDsa.IsFlip()) + { + + targetPtr += scanLineWidth * (height - 1); + + for(TInt i = 0; i < height; i++) //source is always smaller + { + iDsa.Copy(reinterpret_cast(targetPtr), reinterpret_cast(source), copyLen, height); + source += lineMove; + targetPtr -= scanLineWidth; + } + } + else + { + + + for(TInt i = 0; i < height; i++) //source is always smaller + { + iDsa.Copy(reinterpret_cast(targetPtr), reinterpret_cast(source), copyLen, height); + source += lineMove; + targetPtr += scanLineWidth; // >> 2; + } + } + + } + + + +NONSHARABLE_CLASS(CDsaA) : public CDsa + { + public: + CDsaA(RWsSession& aSession); + private: + ~CDsaA(); + TUint8* LockSurface(); + void UnlockHWSurfaceRequestComplete(); + void UnlockHwSurface(); + void CreateSurfaceL(); + void Wipe(TInt aLength); + void Free(); + void Update(CFbsBitmap& aBmp); + void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); + TInt ExternalUpdate(); + // void ExternalUpdate(); + protected: + CFbsBitmap* iBmp; + CFbsBitmap* iCopyBmp; + }; + + +CDsaA::CDsaA(RWsSession& aSession) : CDsa(aSession) + { + } + + +void CDsaA::Free() + { + delete iBmp; + iBmp = NULL; + } + +CDsaA::~CDsaA() + { + __ASSERT_DEBUG(iBmp == NULL, PANIC(KErrNotReady)); + delete iCopyBmp; + } + +TUint8* CDsaA::LockSurface() + { + iBmp->LockHeap(); + return reinterpret_cast(iBmp->DataAddress()); + } + +void CDsaA::UnlockHWSurfaceRequestComplete() + { + PANIC(KErrNotSupported); + } + +void CDsaA::UnlockHwSurface() + { + iBmp->UnlockHeap(); + SetUpdating(EFalse); + Update(*iBmp); + } + +void CDsaA::Update(CFbsBitmap& aBmp) + { + if(!Blitter(aBmp)) + { + if(SwSize() == HwRect().Size()) + Dsa().Gc()->BitBlt(HwRect().iTl, &aBmp); + else + Dsa().Gc()->DrawBitmap(HwRect(), &aBmp); + } + DrawOverlays(); + Dsa().ScreenDevice()->Update(); + } +void CDsaA::CreateSurfaceL() + { + delete iBmp; + iBmp = NULL; + iBmp = new (ELeave) CFbsBitmap(); + User::LeaveIfError(iBmp->Create(SwSize(), DisplayMode())); + } + +void CDsaA::Wipe(TInt aLength) //dont call in drawing + { + iBmp->LockHeap(); + Mem::FillZ(iBmp->DataAddress(), aLength); + iBmp->UnlockHeap(); + } + + + +TInt CDsaA::ExternalUpdate() + { + if(iCopyBmp->Handle() == 0) + { + const TInt err = iCopyBmp->Duplicate(iBmp->Handle()); + if(err != KErrNone) + return err; + } + Update(*iCopyBmp); + return KErrNone; + } + +void CDsaA::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) + { + iCopyBmp = new (ELeave) CFbsBitmap(); + CDsa::ConstructL(aWindow, aDevice); + } + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +NONSHARABLE_CLASS(MDsbObs) + { + public: + virtual void SurfaceReady() = 0; + virtual CDirectScreenBitmap& Dsb() = 0; + }; + +NONSHARABLE_CLASS(CDsbSurface) : public CActive + { + public: + CDsbSurface(MDsbObs& aDsb); + TUint8* Address(); + void Complete(); + ~CDsbSurface(); + private: + void RunL(); + void DoCancel(); + private: + MDsbObs& iDsb; + TUint8* iAddress; + }; + +CDsbSurface::CDsbSurface(MDsbObs& aDsb) : CActive(CActive::EPriorityHigh) , iDsb(aDsb) + { + CActiveScheduler::Add(this); + } + +CDsbSurface::~CDsbSurface() + { + Cancel(); + } + +void CDsbSurface::Complete() + { + if(iAddress != NULL && !IsActive()) + { + iAddress = NULL; + SetActive(); + iDsb.Dsb().EndUpdate(iStatus); + } + } + +TUint8* CDsbSurface::Address() + { + if(iAddress == NULL && !IsActive()) + { + TAcceleratedBitmapInfo info; + if(KErrNone == iDsb.Dsb().BeginUpdate(info)) + iAddress = info.iAddress; + } + return iAddress; + } + +void CDsbSurface::RunL() + { + iDsb.SurfaceReady(); + } + +void CDsbSurface::DoCancel() + { + //empty + } + +NONSHARABLE_CLASS(CDsaB) : public CDsa, public MDsbObs + { + public: + CDsaB(RWsSession& aSession, TInt aFlags); + private: + ~CDsaB(); + TUint8* LockSurface(); + void UnlockHWSurfaceRequestComplete(); + void UnlockHwSurface(); + void CreateSurfaceL(); + void Wipe(TInt aLength); + void RecreateL(); + void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); + CDirectScreenBitmap& Dsb(); + void SurfaceReady(); + TInt ExternalUpdate(); + private: + CDsbSurface* iSurface1; + CDsbSurface* iSurface2; + CDirectScreenBitmap* iDsb; + TInt iType; + }; + +CDsaB::CDsaB(RWsSession& aSession, TInt aFlags) : CDsa(aSession), iType(aFlags) + { + } + + + +void CDsaB::UnlockHWSurfaceRequestComplete() + { + iSurface1->Complete(); + if(iSurface2 != NULL) + iSurface2->Complete(); + } + +void CDsaB::CreateSurfaceL() + { + __ASSERT_ALWAYS(SwSize() == HwRect().Size(), PANIC(KErrNotSupported)); + } + +void CDsaB::Wipe(TInt aLength) //dont call in drawing + { + TUint8* addr = LockSurface(); + if(addr != NULL) + { + Mem::FillZ(addr, aLength); + UnlockHwSurface(); + } + } + + +void CDsaB::UnlockHwSurface() + { + EpocSdlEnv::Request(CDsa::ERequestUpdate); + } + +TUint8* CDsaB::LockSurface() + { + TUint8* addr = iSurface1->Address(); + if(addr == NULL && iSurface2 != NULL) + addr = iSurface2->Address(); + SetUpdating(addr == NULL); + return addr; + } + +void CDsaB::SurfaceReady() + { + SetUpdating(EFalse); + } + +CDirectScreenBitmap& CDsaB::Dsb() + { + return *iDsb; + } + +void CDsaB::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) + { + if(iDsb == NULL) + iDsb = CDirectScreenBitmap::NewL(); + CDsa::ConstructL(aWindow, aDevice); + if(iSurface1 == NULL) + iSurface1 = new (ELeave) CDsbSurface(*this); + if(iSurface2 == NULL && iType & CDirectScreenBitmap::EDoubleBuffer) + iSurface2 = new (ELeave) CDsbSurface(*this); + } + +CDsaB::~CDsaB() + { + delete iSurface1; + delete iSurface2; + delete iDsb; + } + +void CDsaB::RecreateL() + { + iDsb->Close(); + iDsb->Create(HwRect(), CDirectScreenBitmap::TSettingsFlags(iType)); + } + +TInt CDsaB::ExternalUpdate() + { + if(LockSurface()) + { + UnlockHWSurfaceRequestComplete(); + return KErrNone; + } + return KErrNotReady; + } + + +///////////////////////////////////////////////////////////////////////////////////////////////////// + + +CDsa* CDsa::CreateL(RWsSession& aSession) + { + if(EpocSdlEnv::Flags(CSDL::EDrawModeDSB)) + { + TInt flags = CDirectScreenBitmap::ENone; + if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBDoubleBuffer)) + flags |= CDirectScreenBitmap::EDoubleBuffer; + if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBIncrentalUpdate)) + flags |= CDirectScreenBitmap::EIncrementalUpdate; + return new (ELeave) CDsaB(aSession, flags); + } + else + return new (ELeave) CDsaA(aSession); + } + + +void CDsa::RecreateL() + { + } + +void CDsa::Free() + { + } + +TSize CDsa::WindowSize() const + { + TSize size = iSwSize; + if(iStateFlags & EOrientation90) + { + const TInt tmp = size.iWidth; + size.iWidth = size.iHeight; + size.iHeight = tmp; + } + return size; + } + +void CDsa::SetSuspend() + { + iStateFlags |= ESdlThreadSuspend; + } + +void CDsa::ReleaseStop() + { + iStateFlags &= ~ESdlThreadExplicitStop; + } + + +TBool CDsa::Stopped() const + { + return (iStateFlags & ESdlThreadExplicitStop); + } + +void CDsa::SetOrientation(CSDL::TOrientationMode aOrientation) + { + TInt flags = 0; + switch(aOrientation) + { + case CSDL::EOrientation90: + flags = EOrientation90; + break; + case CSDL::EOrientation180: + flags = EOrientation180; + break; + case CSDL::EOrientation270: + flags = EOrientation90 | EOrientation180; + break; + case CSDL::EOrientation0: + flags = 0; + break; + } + if(flags != (iStateFlags & EOrientationFlags)) + { + iStateFlags |= EOrientationChanged; + iNewFlags = flags; //cannot be set during drawing... + } + } + +CDsa::~CDsa() + { + if(iDsa != NULL) + { + iDsa->Cancel(); + } + iOverlays.Close(); + delete iDsa; + User::Free(iLut256); + } + +void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) + { + if(iDsa != NULL) + { + iDsa->Cancel(); + delete iDsa; + iDsa = NULL; + } + + iDsa = CDirectScreenAccess::NewL( + iSession, + aDevice, + aWindow, + *this); + + if(iLut256 == NULL) + iLut256 = (TUint32*) User::AllocL(256 * sizeof(TUint32)); + iTargetMode = aWindow.DisplayMode(); + iTargetBpp = BytesPerPixel(DisplayMode()); + iScreenRect = TRect(aWindow.Position(), aWindow.Size()); + SetTargetRect(); + RestartL(); + } + +void CDsa::DrawOverlays() + { + const TInt last = iOverlays.Count() - 1; + for(TInt i = last; i >= 0 ; i--) + iOverlays[i].iOverlay->Draw(*iDsa->Gc(), HwRect(), SwSize()); + } + +TInt CDsa::AppendOverlay(MOverlay& aOverlay, TInt aPriority) + { + TInt i; + for(i = 0; i < iOverlays.Count() && iOverlays[i].iPriority < aPriority; i++) + {} + const TOverlay overlay = {&aOverlay, aPriority}; + return iOverlays.Insert(overlay, i); + } + +TInt CDsa::RemoveOverlay(MOverlay& aOverlay) + { + for(TInt i = 0; i < iOverlays.Count(); i++) + { + if(iOverlays[i].iOverlay == &aOverlay) + { + iOverlays.Remove(i); + return KErrNone; + } + } + return KErrNotFound; + } + +void CDsa::LockPalette(TBool aLock) + { + if(aLock) + iStateFlags |= EPaletteLocked; + else + iStateFlags &= ~EPaletteLocked; + } +TInt CDsa::SetPalette(TInt aFirst, TInt aCount, TUint32* aPalette) + { + if(iLut256 == NULL) + return KErrNotFound; + const TInt count = aCount - aFirst; + if(count > 256) + return KErrArgument; + if(iStateFlags & EPaletteLocked) + return KErrNone; + for(TInt i = aFirst; i < count; i++) //not so busy here:-) + { + iLut256[i] = aPalette[i]; + } + return KErrNone; + } + + + +void CDsa::RestartL() + { + //const TBool active = iDsa->IsActive(); + + //if(!active) + + iDsa->StartL(); + + const RRegion* r = iDsa->DrawingRegion(); + const TRect rect = r->BoundingRect(); + iDsa->Gc()->SetClippingRegion(r); + + if(rect != iScreenRect) + { + // iDsa->Cancel(); + return ; + } + + + + //iScreenRect = rect; //to ensure properly set, albeit may not(?) match to value SDL has - therefore may has to clip + //targetrect shall no change + SetTargetRect(); + RecreateL(); + + iStateFlags |= ERunning; + + ReleaseStop(); + if(iStateFlags & ESdlThreadSuspend) + { + EpocSdlEnv::Resume(); + iStateFlags &= ~ ESdlThreadSuspend; + } + EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowReserved); + } + +CDsa::CDsa(RWsSession& aSession) : + iSession(aSession), + iStateFlags(0) + { +// CActiveScheduler::Add(this); + iCFTable[0] = CopyMem; + iCFTable[1] = CopyMemFlipReversed; + iCFTable[2] = CopyMemReversed; + iCFTable[3] = CopyMemFlip; + + iCFTable[4] = Copy256; + iCFTable[5] = Copy256FlipReversed; + iCFTable[6] = Copy256Reversed; + iCFTable[7] = Copy256Flip; + + + iCFTable[8] = CopySlow; + iCFTable[9] = CopySlowFlipReversed; + iCFTable[10] = CopySlowReversed; + iCFTable[11] = CopySlowFlip; + } + +RWsSession& CDsa::Session() + { + return iSession; + } + +TInt CDsa::RedrawRequest() + { + if(!(iStateFlags & (EUpdating) && (iStateFlags & ERunning))) + { + return ExternalUpdate(); + } + return KErrNotReady; + } + +TUint8* CDsa::LockHwSurface() + { + if((iStateFlags & EUpdating) == 0) //else frame is skipped + { + return LockSurface(); + } + return NULL; + } + +/* +void CDsa::RunL() + { + iStateFlags &= ~EUpdating; + } + + +void CDsa::DoCancel() + { + iStateFlags &= ~EUpdating; + //nothing can do, just wait? + } +*/ + + +TInt CDsa::AllocSurface(TBool aHwSurface, const TSize& aSize, TDisplayMode aMode) + { + if(aHwSurface && aMode != DisplayMode()) + return KErrArgument; + + iSourceMode = aMode; + + iSourceBpp = BytesPerPixel(aMode); + + const TSize size = WindowSize(); + if(aSize.iWidth > size.iWidth) + return KErrTooBig; + if(aSize.iHeight > size.iHeight) + return KErrTooBig; + + TRAPD(err, CreateSurfaceL()); + if(err != KErrNone) + return err; + + SetCopyFunction(); + + return KErrNone; + } + + +void CDsa::CreateZoomerL(const TSize& aSize) + { + iSwSize = aSize; + iStateFlags |= EResizeRequest; + CreateSurfaceL(); + SetTargetRect(); + } + + +/* +void SaveBmp(const TDesC& aName, const TAny* aData, TInt aLength, const TSize& aSz, TDisplayMode aMode) + { + CFbsBitmap* s = new CFbsBitmap(); + s->Create(aSz, aMode); + s->LockHeap(); + TUint32* addr = s->DataAddress(); + Mem::Copy(addr, aData, aLength); + s->UnlockHeap(); + s->Save(aName); + s->Reset(); + delete s; + } + +void SaveBmp(const TDesC& aName, const TUint32* aData, const TSize& aSz) + { + CFbsBitmap* s = new CFbsBitmap(); + s->Create(aSz, EColor64K); + TBitmapUtil bmp(s); + bmp.Begin(TPoint(0, 0)); + for(TInt j = 0; j < aSz.iHeight; j++) + { + bmp.SetPos(TPoint(0, j)); + for(TInt i = 0; i < aSz.iWidth; i++) + { + bmp.SetPixel(*aData); + aData++; + bmp.IncXPos(); + } + } + bmp.End(); + s->Save(aName); + s->Reset(); + delete s; + } + +TBuf<16> FooName(TInt aFoo) + { + TBuf<16> b; + b.Format(_L("C:\\pic%d.mbm"), aFoo); + return b; + } + +void ClipCopy(TUint8* aTarget, const TUint8* aSource, const TRect& aRect, const TPoint& aTargetPos) + { + const TInt iSourceBpp = 1; + const TInt iTargetBpp = 4; + const TInt iScanLineWidth = 800; + + TUint8* target = aTarget; + const TUint8* source = aSource; + const TInt lineWidth = aRect.Width(); + source += iSourceBpp * (aRect.iTl.iY * lineWidth); + const TInt sourceStartOffset = iSourceBpp * aRect.iTl.iX; + source += sourceStartOffset; + target += iTargetBpp * ((aTargetPos.iY + aRect.iTl.iY ) * lineWidth); + const TInt targetStartOffset = iTargetBpp * (aRect.iTl.iX + aTargetPos.iX); + target += targetStartOffset; + TUint32* targetPtr = reinterpret_cast(target); + const TInt targetWidth = iScanLineWidth >> 2; + const TInt height = aRect.Height(); + } +*/ +/* +void CDsa::ClipCopy(TUint8* aTarget, + const TUint8* aSource, + const TRect& aUpdateRect, + const TRect& aSourceRect) const + { + //TUint8* target = aTarget; + const TUint32* source = (const TUint32*) aSource; + const TInt lineWidth = aSourceRect.Width(); + + source += (aUpdateRect.iTl.iY * lineWidth); + const TInt sourceStartOffset = aUpdateRect.iTl.iX; + source += sourceStartOffset; + + TUint32* targetPtr = reinterpret_cast(aTarget); + + targetPtr += (aSourceRect.iTl.iY + aUpdateRect.iTl.iY ) * SwSize().iWidth; + const TInt targetStartOffset = (aUpdateRect.iTl.iX + aSourceRect.iTl.iX); + + targetPtr += targetStartOffset; + +// TUint32* targetPtr = reinterpret_cast(target); + + const TInt targetWidth32 = SwSize().iWidth; + + const TInt height = aUpdateRect.Height(); + + const TInt lineMove = iStateFlags & EOrientation90 ? 1 : lineWidth; + const TInt copyLen = aUpdateRect.Width(); + + + if(iStateFlags & EOrientation180) + { + + targetPtr += targetWidth32 * (height - 1); + + for(TInt i = 0; i < height; i++) //source is always smaller + { + iCopyFunction(*this, targetPtr, (TUint8*)source, copyLen, height); + source += lineMove; + targetPtr -= targetWidth32; + } + } + else + { + + + for(TInt i = 0; i < height; i++) //source is always smaller + { + iCopyFunction(*this, targetPtr, (TUint8*)source, copyLen, height); + source += lineMove; + targetPtr += targetWidth32; // >> 2; + } + } + + } + +*/ + +void CDsa::ClipCopy(TUint8* aTarget, const TUint8* aSource, const TRect& aRect, const TPoint& aTargetPos) const + { + TUint8* target = aTarget; + const TUint8* source = aSource; + const TInt lineWidth = aRect.Width(); + source += iSourceBpp * (aRect.iTl.iY * lineWidth); + TInt sourceStartOffset = iSourceBpp * aRect.iTl.iX; + source += sourceStartOffset; + target += iTargetBpp * ((aTargetPos.iY + aRect.iTl.iY ) * lineWidth); + TInt targetStartOffset = iTargetBpp * (aRect.iTl.iX + aTargetPos.iX); + target += targetStartOffset; + TUint32* targetPtr = reinterpret_cast(target); + const TInt targetWidth = iScanLineWidth >> 2; + const TInt height = aRect.Height(); + + TInt lineMove = iStateFlags & EOrientation90 ? 1 : lineWidth; + + if(iStateFlags & EOrientation180) + { + + targetPtr += targetWidth * (height - 1); + + for(TInt i = 0; i < height; i++) //source is always smaller + { + iCopyFunction(*this, targetPtr, source, lineWidth, height); + source += lineMove; + targetPtr -= targetWidth; + } + } + else + { + + + for(TInt i = 0; i < height; i++) //source is always smaller + { + iCopyFunction(*this, targetPtr, source, lineWidth, height); + source += lineMove; + targetPtr += targetWidth; + } + } + + } + + + + /* +void CDsa::ClipCopy(TUint8* aTarget, + const TUint8* aSource, + const TRect& aUpdateRect, + const TRect& aSourceRect) const + { + const TDsa dsa(*this); + switch(iSourceBpp) + { + case 1: + ::ClipCopy(dsa, aTarget, aSource, aUpdateRect, aSourceRect); + break; + case 2: + ::ClipCopy(dsa, aTarget, aSource, aUpdateRect, aSourceRect); + break; + case 4: + ::ClipCopy(dsa, aTarget, aSource, aUpdateRect, aSourceRect); + break; + } + } + + +*/ + + + +void CDsa::Wipe() //dont call in drawing + { + if(IsDsaAvailable()) + Wipe(iTargetBpp * SwSize().iWidth * SwSize().iHeight); + } + +void CDsa::SetCopyFunction() + { + //calculate offset to correct function in iCFTable according to given parameters + TInt function = 0; + const TInt KCopyFunctions = 4; + const TInt KOffsetToNative = 0; + const TInt KOffsetTo256 = KOffsetToNative + KCopyFunctions; + const TInt KOffsetToOtherModes = KOffsetTo256 + KCopyFunctions; + const TInt KOffsetTo90Functions = 1; + const TInt KOffsetTo180Functions = 2; + + if(iSourceMode == DisplayMode()) + function = KOffsetToNative; //0 + else if(iSourceMode == EColor256) + function = KOffsetTo256; //4 + else + function = KOffsetToOtherModes; //8 + + if(iStateFlags & EOrientation90) + function += KOffsetTo90Functions; // + 1 + if(iStateFlags & EOrientation180) + function += KOffsetTo180Functions; //+ 2 + + iCopyFunction = iCFTable[function]; + + Wipe(); + } + +inline void Rotate(TRect& aRect) + { + const TInt dx = aRect.iBr.iX - aRect.iTl.iX; + const TInt dy = aRect.iBr.iY - aRect.iTl.iY; + + aRect.iBr.iX = aRect.iTl.iX + dy; + aRect.iBr.iY = aRect.iTl.iY + dx; + + const TInt tmp = aRect.iTl.iX; + aRect.iTl.iX = aRect.iTl.iY; + aRect.iTl.iY = tmp; + } + +/* +int bar = 0; +*/ +/* +TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect) + { + + if(iStateFlags & EOrientationChanged) + { + iStateFlags &= ~EOrientationFlags; + iStateFlags |= iNewFlags; + SetCopyFunction(); + iStateFlags &= ~EOrientationChanged; + EpocSdlEnv::WaitDeviceChange(); + return EFalse; //skip this frame as data is may be changed + } + + if(iTargetAddr == NULL) + { + iTargetAddr = LockHwSurface(); + } + + TUint8* target = iTargetAddr; + if(target == NULL) + return EFalse; + + + TRect targetRect = TRect(TPoint(0, 0), SwSize()); + + TRect sourceRect = aRect; + TRect updateRect = aUpdateRect; + +// TPoint move(0, 0); + + + if(iStateFlags & EOrientation90) + { + Rotate(sourceRect); + Rotate(updateRect); + } + + if(iSourceMode != DisplayMode() || targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0)) + { + sourceRect.Intersection(targetRect); //so source always smaller or equal than target + //updateRect.Intersection(targetRect); + ClipCopy(target, aBits, updateRect, sourceRect); + } + else + { + const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored + Mem::Copy(target, aBits, byteCount); + } + + return ETrue; + } + */ + +TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect) + { + + if(iStateFlags & EOrientationChanged) + { + iStateFlags &= ~EOrientationFlags; + iStateFlags |= iNewFlags; + SetCopyFunction(); + iStateFlags &= ~EOrientationChanged; + EpocSdlEnv::WaitDeviceChange(); + return EFalse; //skip this frame as data is may be changed + } + + if(iTargetAddr == NULL) + { + iTargetAddr = LockHwSurface(); + } + TUint8* target = iTargetAddr; + if(target == NULL) + return EFalse; + + + TRect targetRect = Rect(); + TRect sourceRect = aRect; + TRect updateRect = aUpdateRect; + + if(iStateFlags & EOrientation90) + { + Rotate(sourceRect); + Rotate(updateRect); + } + + if(iSourceMode != DisplayMode() || targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0)) + { + sourceRect.Intersection(targetRect); //so source always smaller or equal than target + updateRect.Intersection(targetRect); + ClipCopy(target, aBits, updateRect, sourceRect.iTl); + } + else + { + const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored + Mem::Copy(target, aBits, byteCount); + } + + return ETrue; + } +void CDsa::UpdateSwSurface() + { + iTargetAddr = NULL; + UnlockHwSurface(); //could be faster if does not use AO, but only check status before redraw, then no context switch needed + } + + +void CDsa::Resume() + { + if(Stopped()) + Restart(RDirectScreenAccess::ETerminateRegion); + } + +void CDsa::DoStop() + { + if(IsDsaAvailable()) + iStateFlags |= ESdlThreadExplicitStop; + Stop(); + } + +void CDsa::Stop() + { + iStateFlags &= ~ERunning; +// Cancel(); //can be called only from main! + iDsa->Cancel(); + } + +void CDsa::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/) + { +// iStateFlags |= EChangeNotify; + Stop(); + } + +void CDsa::Restart(RDirectScreenAccess::TTerminationReasons aReason) + { + if(aReason == RDirectScreenAccess::ETerminateRegion) //auto restart + { + TRAPD(err, RestartL()); + PANIC_IF_ERROR(err); + } + } + +void CDsa::SetBlitter(MBlitter* aBlitter) + { + iBlitter = aBlitter; + } + + +TPoint CDsa::WindowCoordinates(const TPoint& aPoint) const + { + TPoint pos = aPoint - iScreenRect.iTl; + const TSize asz = iScreenRect.Size(); + if(iStateFlags & EOrientation180) + { + pos.iX = asz.iWidth - pos.iX; + pos.iY = asz.iHeight - pos.iY; + } + if(iStateFlags & EOrientation90) + { + pos.iX = aPoint.iY; + pos.iY = aPoint.iX; + } + pos.iX <<= 16; + pos.iY <<= 16; + pos.iX /= asz.iWidth; + pos.iY /= asz.iHeight; + pos.iX *= iSwSize.iWidth; + pos.iY *= iSwSize.iHeight; + pos.iX >>= 16; + pos.iY >>= 16; + return pos; + } + +void CDsa::SetTargetRect() + { + iTargetRect = iScreenRect; + if(iStateFlags & EResizeRequest && EpocSdlEnv::Flags(CSDL::EAllowImageResizeKeepRatio)) + { + const TSize asz = iScreenRect.Size(); + const TSize sz = iSwSize; + + TRect rect; + + const TInt dh = (sz.iHeight << 16) / sz.iWidth; + + if((asz.iWidth * dh ) >> 16 <= asz.iHeight) + { + rect.SetRect(TPoint(0, 0), TSize(asz.iWidth, (asz.iWidth * dh) >> 16)); + } + else + { + const TInt dw = (sz.iWidth << 16) / sz.iHeight; + rect.SetRect(TPoint(0, 0), TSize((asz.iHeight * dw) >> 16, asz.iHeight)); + } + rect.Move((asz.iWidth - rect.Size().iWidth) >> 1, (asz.iHeight - rect.Size().iHeight) >> 1); + + iTargetRect = rect; + iTargetRect.Move(iScreenRect.iTl); + + } + if(!(iStateFlags & EResizeRequest)) + iSwSize = iScreenRect.Size(); +// iScanLineWidth = /*iTargetBpp **/ SwSize().iWidth; + } + +/*) +TBool CDsa::ChangeTrigger() + { + const TBool change = iStateFlags & EChangeNotify; + iStateFlags &= ~EChangeNotify; + return change; + } +*/ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + TUint32* target = aTarget; + const TUint32* endt = target + aBytes; + const TUint8* source = aSource; + while(target < endt) + { + *target++ = aDsa.iLut256[*source++]; + } + } + +void CDsa::Copy256Reversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + const TUint32* target = aTarget; + TUint32* endt = aTarget + aBytes; + const TUint8* source = aSource; + while(target < endt) + { + *(--endt) = aDsa.iLut256[*source++]; + } + } + +void CDsa::Copy256Flip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + TUint32* target = aTarget; + const TUint32* endt = target + aBytes; + const TUint8* column = aSource; + + while(target < endt) + { + *target++ = aDsa.iLut256[*column]; + column += aLineLen; + } + } + +void CDsa::Copy256FlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + const TUint32* target = aTarget; + TUint32* endt = aTarget + aBytes; + const TUint8* column = aSource; + + while(target < endt) + { + *(--endt) = aDsa.iLut256[*column]; + column += aLineLen; + } + } + +void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + const TUint32* src = reinterpret_cast(aSource); + Mem::Copy(aTarget, src, aBytes << 2); + } + +void CDsa::CopyMemFlip(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + TUint32* target = aTarget; + const TUint32* endt = target + aBytes; + const TUint32* column = reinterpret_cast(aSource); + + while(target < endt) + { + *target++ = *column; + column += aLineLen; + } + } + +void CDsa::CopyMemReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + const TUint32* target = aTarget; + TUint32* endt = aTarget + aBytes; + const TUint32* source = reinterpret_cast(aSource); + while(target < endt) + { + *(--endt) = *source++; + } + } + + +void CDsa::CopyMemFlipReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + const TUint32* target = aTarget; + TUint32* endt = aTarget + aBytes; + const TUint32* column = reinterpret_cast(aSource); + + while(target < endt) + { + *(--endt) = *column; + column += aLineLen; + } + } + +/* + +LOCAL_C TRgb rgb16MA(TInt aValue) + { + return TRgb::Color16MA(aValue); + } +*/ +NONSHARABLE_CLASS(MRgbCopy) + { + public: + virtual void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) = 0; + virtual void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) = 0; + }; + +template +NONSHARABLE_CLASS(TRgbCopy) : public MRgbCopy + { + public: + TRgbCopy(TDisplayMode aMode); + void* operator new(TUint aBytes, TAny* aMem); + void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed); + void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed); + static TUint32 Gray256(const TUint8& aPixel); + static TUint32 Color256(const TUint8& aPixel); + static TUint32 Color4K(const TUint16& aPixel); + static TUint32 Color64K(const TUint16& aPixel); + static TUint32 Color16M(const TUint32& aPixel); + static TUint32 Color16MU(const TUint32& aPixel); + static TUint32 Color16MA(const TUint32& aPixel); + private: + typedef TUint32 (*TRgbFunc) (const T& aValue); + TRgbFunc iFunc; + }; + + +template +void* TRgbCopy::operator new(TUint /*aBytes*/, TAny* aMem) + { + return aMem; + } + +template +TRgbCopy::TRgbCopy(TDisplayMode aMode) + { + switch(aMode) + { + case EGray256 : iFunc = (TRgbFunc) Gray256; break; + case EColor256 : iFunc = (TRgbFunc) Color256; break; + case EColor4K : iFunc = (TRgbFunc) Color4K; break; + case EColor64K : iFunc = (TRgbFunc) Color64K; break; + case EColor16M : iFunc = (TRgbFunc) Color16M; break; + case EColor16MU : iFunc = (TRgbFunc) Color16MU; break; + case EColor16MA : iFunc = (TRgbFunc) Color16MA; break; + default: + PANIC(KErrNotSupported); + } + } + +template +void TRgbCopy::Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) + { + const T* source = reinterpret_cast(aSource); + TUint32* target = aTarget; + TUint32* endt = target + aBytes; + + if(aReversed) + { + while(target < endt) + { + const T value = *source++; + *(--endt) = iFunc(value);//iFunc(value).Value(); + } + } + else + { + while(target < endt) + { + const T value = *source++; + *target++ = iFunc(value);//iFunc(value).Value(); + } + } + } + +template +void TRgbCopy::FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) + { + const T* column = reinterpret_cast(aSource); + TUint32* target = aTarget; + TUint32* endt = target + aBytes; + + if(aReversed) + { + while(target < endt) + { + *(--endt) = iFunc(*column); + column += aLineLen; + } + } + else + { + while(target < endt) + { + *target++ = iFunc(*column); + column += aLineLen; + } + } + } + +template TUint32 TRgbCopy::Gray256(const TUint8& aPixel) + { + const TUint32 px = aPixel << 16 | aPixel << 8 | aPixel; + return px; + } + +template TUint32 TRgbCopy::Color256(const TUint8& aPixel) + { + return TRgb::Color256(aPixel).Value(); + } + +template TUint32 TRgbCopy::Color4K(const TUint16& aPixel) + { + TUint32 col = (aPixel & 0xF00) << 12; + col |= (aPixel & 0xF00) << 8; + + col |= (aPixel & 0x0F0) << 8; + col |= (aPixel & 0x0F0); + + col |= (aPixel & 0x00F) << 4; + col |= (aPixel & 0x00F); + + return col; + } + +template TUint32 TRgbCopy::Color64K(const TUint16& aPixel) + { + TUint32 col = (aPixel & 0xF800)<< 8; + col |= (aPixel & 0xE000) << 3; + + col |= (aPixel & 0x07E0) << 5; + col |= (aPixel & 0xC0) >> 1; + + col |= (aPixel & 0x07E0) << 3; + col |= (aPixel & 0x1C) >> 2; + + return col; + } + +template TUint32 TRgbCopy::Color16M(const TUint32& aPixel) + { + return TRgb::Color16M(aPixel).Value(); + } + +template TUint32 TRgbCopy::Color16MU(const TUint32& aPixel) + { + return TRgb::Color16MU(aPixel).Value(); + } + +template TUint32 TRgbCopy::Color16MA(const TUint32& aPixel) + { + return TRgb::Color16MA(aPixel).Value(); + } + +typedef TUint64 TStackMem; + +LOCAL_C MRgbCopy* GetCopy(TAny* mem, TDisplayMode aMode) + { + if(aMode == EColor256 || aMode == EGray256) + { + return new (mem) TRgbCopy(aMode); + } + if(aMode == EColor4K || aMode == EColor64K) + { + return new (mem) TRgbCopy(aMode); + } + if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA) + { + return new (mem) TRgbCopy(aMode); + } + PANIC(KErrNotSupported); + return NULL; + } + + +void CDsa::CopySlowFlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + TStackMem mem = 0; + GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, ETrue); + } + +void CDsa::CopySlowFlip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + TStackMem mem = 0; + GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, EFalse); + } + +void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + TStackMem mem = 0; + GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, EFalse); + } + +void CDsa::CopySlowReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + TStackMem mem = 0; + GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, ETrue); + } + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////7 diff --git a/src/video/symbian/EKA2/dsa_old.cpp b/src/video/symbian/EKA2/dsa_old.cpp new file mode 100644 index 000000000..7e32de2cf --- /dev/null +++ b/src/video/symbian/EKA2/dsa_old.cpp @@ -0,0 +1,1075 @@ +#include "dsa.h" +#include "sdlepocapi.h" +#include + +LOCAL_C TInt BytesPerPixel(TDisplayMode aMode) + { + return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1; + } + + +//////////////////////////////////////////////////////////////////////////////////////////////// + +NONSHARABLE_CLASS(CDsaA) : public CDsa + { + public: + CDsaA(RWsSession& aSession); + private: + ~CDsaA(); + TUint8* LockSurface(); + void UnlockHWSurfaceRequestComplete(); + void UnlockHwSurface(); + void CreateSurfaceL(); + void Wipe(TInt aLength); + void RecreateL(); + void Free(); + TInt ExternalUpdate() {return 0;} + private: + CFbsBitmap* iBmp; + }; + + +CDsaA::CDsaA(RWsSession& aSession) : CDsa(aSession) + { + } + +void CDsaA::Free() + { + delete iBmp; + iBmp = NULL; + } + +CDsaA::~CDsaA() + { + __ASSERT_DEBUG(iBmp == NULL, PANIC(KErrNotReady)); + } + +TUint8* CDsaA::LockSurface() + { + iBmp->LockHeap(); + return reinterpret_cast(iBmp->DataAddress()); + } + +void CDsaA::UnlockHWSurfaceRequestComplete() + { + PANIC(KErrNotSupported); + } + +void CDsaA::UnlockHwSurface() + { + iBmp->UnlockHeap(); + SetUpdating(EFalse); + Dsa().Gc()->BitBlt(HwRect().iTl, iBmp); + Dsa().ScreenDevice()->Update(); + } + +void CDsaA::CreateSurfaceL() + { + delete iBmp; + iBmp = NULL; + iBmp = new (ELeave) CFbsBitmap(); + User::LeaveIfError(iBmp->Create(HwRect().Size(), DisplayMode())); + } + +void CDsaA::Wipe(TInt aLength) //dont call in drawing + { + iBmp->LockHeap(); + Mem::FillZ(iBmp->DataAddress(), aLength); + iBmp->UnlockHeap(); + } + +void CDsaA::RecreateL() + { + } + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +NONSHARABLE_CLASS(MDsbObs) + { + public: + virtual void SurfaceReady() = 0; + virtual CDirectScreenBitmap& Dsb() = 0; + }; + +NONSHARABLE_CLASS(CDsbSurface) : public CActive + { + public: + CDsbSurface(MDsbObs& aDsb); + TUint8* Address(); + void Complete(); + ~CDsbSurface(); + private: + void RunL(); + void DoCancel(); + private: + MDsbObs& iDsb; + TUint8* iAddress; + }; + +CDsbSurface::CDsbSurface(MDsbObs& aDsb) : CActive(CActive::EPriorityHigh) , iDsb(aDsb) + { + CActiveScheduler::Add(this); + } + +CDsbSurface::~CDsbSurface() + { + Cancel(); + } + +void CDsbSurface::Complete() + { + if(iAddress != NULL && !IsActive()) + { + iAddress = NULL; + SetActive(); + iDsb.Dsb().EndUpdate(iStatus); + } + } + +TUint8* CDsbSurface::Address() + { + if(iAddress == NULL && !IsActive()) + { + TAcceleratedBitmapInfo info; + if(KErrNone == iDsb.Dsb().BeginUpdate(info)) + iAddress = info.iAddress; + } + return iAddress; + } + +void CDsbSurface::RunL() + { + iDsb.SurfaceReady(); + } + +void CDsbSurface::DoCancel() + { + //empty + } + +NONSHARABLE_CLASS(CDsaB) : public CDsa, public MDsbObs + { + public: + CDsaB(RWsSession& aSession); + private: + ~CDsaB(); + TUint8* LockSurface(); + void UnlockHWSurfaceRequestComplete(); + void UnlockHwSurface(); + void CreateSurfaceL(); + void Wipe(TInt aLength); + void RecreateL(); + void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice); + void Free(); + CDirectScreenBitmap& Dsb(); + void SurfaceReady(); + TInt ExternalUpdate() {return 0;} + private: + CDsbSurface* iSurface1; + CDsbSurface* iSurface2; + CDirectScreenBitmap* iDsb; + }; + +CDsaB::CDsaB(RWsSession& aSession) : CDsa(aSession) + { + } + +void CDsaB::Free() + { + } + +void CDsaB::UnlockHWSurfaceRequestComplete() + { + iSurface1->Complete(); + iSurface2->Complete(); + } + +void CDsaB::CreateSurfaceL() + { + } + +void CDsaB::Wipe(TInt aLength) //dont call in drawing + { + TUint8* addr = LockSurface(); + if(addr != NULL) + { + Mem::FillZ(addr, aLength); + UnlockHwSurface(); + } + } + +void CDsaB::UnlockHwSurface() + { + EpocSdlEnv::Request(CDsa::ERequestUpdate); + } + +TUint8* CDsaB::LockSurface() + { + TUint8* addr = iSurface1->Address(); + if(addr == NULL) + addr = iSurface2->Address(); + SetUpdating(addr == NULL); + return addr; + } + +void CDsaB::SurfaceReady() + { + SetUpdating(EFalse); + } + +CDirectScreenBitmap& CDsaB::Dsb() + { + return *iDsb; + } + +void CDsaB::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) + { + if(iDsb == NULL) + iDsb = CDirectScreenBitmap::NewL(); + CDsa::ConstructL(aWindow, aDevice); + iSurface1 = new (ELeave) CDsbSurface(*this); + iSurface2 = new (ELeave) CDsbSurface(*this); + } + +CDsaB::~CDsaB() + { + delete iSurface1; + delete iSurface2; + delete iDsb; + } + +void CDsaB::RecreateL() + { + iDsb->Close(); + iDsb->Create(HwRect(), CDirectScreenBitmap::EDoubleBuffer); + } + +///////////////////////////////////////////////////////////////////////////////////////////////////// + + +TSize CDsa::WindowSize() const + { + TSize size = HwRect().Size(); + if(iStateFlags & EOrientation90) + { + const TInt tmp = size.iWidth; + size.iWidth = size.iHeight; + size.iHeight = tmp; + } + return size; + } + +void CDsa::SetSuspend() + { + iStateFlags |= ESdlThreadSuspend; + } + +void CDsa::ReleaseStop() + { + iStateFlags &= ~ESdlThreadExplicitStop; + } + + +TBool CDsa::Stopped() const + { + return (iStateFlags & ESdlThreadExplicitStop); + } + +void CDsa::SetOrientation(CSDL::TOrientationMode aOrientation) + { + TInt flags = 0; + switch(aOrientation) + { + case CSDL::EOrientation90: + flags = EOrientation90; + break; + case CSDL::EOrientation180: + flags = EOrientation180; + break; + case CSDL::EOrientation270: + flags = EOrientation90 | EOrientation180; + break; + case CSDL::EOrientation0: + flags = 0; + break; + } + if(flags != (iStateFlags & EOrientationFlags)) + { + iStateFlags |= EOrientationChanged; + iNewFlags = flags; //cannot be set during drawing... + } + } + +CDsa::~CDsa() + { + if(iDsa != NULL) + { + iDsa->Cancel(); + } + delete iDsa; + User::Free(iLut256); + } + +void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice) + { + if(iDsa != NULL) + { + iDsa->Cancel(); + delete iDsa; + iDsa = NULL; + } + + + iDsa = CDirectScreenAccess::NewL( + iSession, + aDevice, + aWindow, + *this); + + if(iLut256 == NULL) + iLut256 = (TUint32*) User::AllocL(256 * sizeof(TUint32)); + iTargetMode = aWindow.DisplayMode(); + iTargetBpp = BytesPerPixel(DisplayMode()); + iTargetRect = TRect(aWindow.Position(), aWindow.Size()); + RestartL(); + } + +void CDsa::LockPalette(TBool aLock) + { + if(aLock) + iStateFlags |= EPaletteLocked; + else + iStateFlags &= ~EPaletteLocked; + } +TInt CDsa::SetPalette(TInt aFirst, TInt aCount, TUint32* aPalette) + { + if(iLut256 == NULL) + return KErrNotFound; + const TInt count = aCount - aFirst; + if(count > 256) + return KErrArgument; + if(iStateFlags & EPaletteLocked) + return KErrNone; + for(TInt i = aFirst; i < count; i++) //not so busy here:-) + { + iLut256[i] = aPalette[i]; + } + return KErrNone; + } + + + + +void CDsa::RestartL() + { + //const TBool active = iDsa->IsActive(); + + //if(!active) + iDsa->StartL(); + + RRegion* r = iDsa->DrawingRegion(); + iDsa->Gc()->SetClippingRegion(r); + TRect rect = r->BoundingRect(); + + if(rect.IsEmpty()) + { + return; + } + + iScreenRect = rect; //to ensure properly set, albeit may not(?) match to value SDL has - therefore may has to clip + + RecreateL(); + + iStateFlags |= ERunning; +// iScanLineWidth = iTargetBpp * HwRect().Width(); + ReleaseStop(); + if(iStateFlags & ESdlThreadSuspend) + { + EpocSdlEnv::Resume(); + iStateFlags &= ~ ESdlThreadSuspend; + } + } + +CDsa::CDsa(RWsSession& aSession) : + iSession(aSession), + iStateFlags(0) + { +// CActiveScheduler::Add(this); + iCFTable[0] = CopyMem; + iCFTable[1] = CopyMemFlipReversed; + iCFTable[2] = CopyMemReversed; + iCFTable[3] = CopyMemFlip; + + iCFTable[4] = Copy256; + iCFTable[5] = Copy256FlipReversed; + iCFTable[6] = Copy256Reversed; + iCFTable[7] = Copy256Flip; + + + iCFTable[8] = CopySlow; + iCFTable[9] = CopySlowFlipReversed; + iCFTable[10] = CopySlowReversed; + iCFTable[11] = CopySlowFlip; + } + +RWsSession& CDsa::Session() + { + return iSession; + } + + + +TUint8* CDsa::LockHwSurface() + { + if((iStateFlags & EUpdating) == 0) //else frame is skipped + { + return LockSurface(); + } + return NULL; + } + +/* +void CDsa::RunL() + { + iStateFlags &= ~EUpdating; + } + + +void CDsa::DoCancel() + { + iStateFlags &= ~EUpdating; + //nothing can do, just wait? + } +*/ + +TInt CDsa::AllocSurface(TBool aHwSurface, const TSize& aSize, TDisplayMode aMode) + { + if(aHwSurface && aMode != DisplayMode()) + return KErrArgument; + + iSourceMode = aMode; + + iSourceBpp = BytesPerPixel(aMode); + + const TSize size = WindowSize(); + if(aSize.iWidth > size.iWidth) + return KErrTooBig; + if(aSize.iHeight > size.iHeight) + return KErrTooBig; + + TRAPD(err, CreateSurfaceL()); + if(err != KErrNone) + return err; + + + SetCopyFunction(); + + EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowReserved); + + return KErrNone; + } + + +/* +void SaveBmp(const TDesC& aName, const TAny* aData, TInt aLength, const TSize& aSz, TDisplayMode aMode) + { + CFbsBitmap* s = new CFbsBitmap(); + s->Create(aSz, aMode); + s->LockHeap(); + TUint32* addr = s->DataAddress(); + Mem::Copy(addr, aData, aLength); + s->UnlockHeap(); + s->Save(aName); + s->Reset(); + delete s; + } + +void SaveBmp(const TDesC& aName, const TUint32* aData, const TSize& aSz) + { + CFbsBitmap* s = new CFbsBitmap(); + s->Create(aSz, EColor64K); + TBitmapUtil bmp(s); + bmp.Begin(TPoint(0, 0)); + for(TInt j = 0; j < aSz.iHeight; j++) + { + bmp.SetPos(TPoint(0, j)); + for(TInt i = 0; i < aSz.iWidth; i++) + { + bmp.SetPixel(*aData); + aData++; + bmp.IncXPos(); + } + } + bmp.End(); + s->Save(aName); + s->Reset(); + delete s; + } + +TBuf<16> FooName(TInt aFoo) + { + TBuf<16> b; + b.Format(_L("C:\\pic%d.mbm"), aFoo); + return b; + } +*/ +void CDsa::ClipCopy(TUint8* aTarget, const TUint8* aSource, const TRect& aRect, const TRect& aTargetPos) const + { + TUint8* target = aTarget; + const TUint8* source = aSource; + const TInt lineWidth = aRect.Width(); + source += iSourceBpp * (aRect.iTl.iY * lineWidth); + TInt sourceStartOffset = iSourceBpp * aRect.iTl.iX; + source += sourceStartOffset; + target += iTargetBpp * ((aTargetPos.iTl.iY + aRect.iTl.iY ) * lineWidth); + TInt targetStartOffset = iTargetBpp * (aRect.iTl.iX + aTargetPos.iTl.iX); + target += targetStartOffset; + TUint32* targetPtr = reinterpret_cast(target); + const TInt targetWidth = HwRect().Size().iWidth; + const TInt height = aRect.Height(); + + TInt lineMove = iStateFlags & EOrientation90 ? 1 : lineWidth; + + if(iStateFlags & EOrientation180) + { + + targetPtr += targetWidth * (height - 1); + + for(TInt i = 0; i < height; i++) //source is always smaller + { + iCopyFunction(*this, targetPtr, source, lineWidth, height); + source += lineMove; + targetPtr -= targetWidth; + } + } + else + { + + + for(TInt i = 0; i < height; i++) //source is always smaller + { + iCopyFunction(*this, targetPtr, source, lineWidth, height); + source += lineMove; + targetPtr += targetWidth; + } + } + + } + + + + +void CDsa::Wipe() //dont call in drawing + { + if(IsDsaAvailable()) + Wipe(iTargetBpp * iScreenRect.Width() * iScreenRect.Height()); + } + +void CDsa::SetCopyFunction() + { + //calculate offset to correct function in iCFTable according to given parameters + TInt function = 0; + const TInt KCopyFunctions = 4; + const TInt KOffsetToNative = 0; + const TInt KOffsetTo256 = KOffsetToNative + KCopyFunctions; + const TInt KOffsetToOtherModes = KOffsetTo256 + KCopyFunctions; + const TInt KOffsetTo90Functions = 1; + const TInt KOffsetTo180Functions = 2; + + if(iSourceMode == DisplayMode()) + function = KOffsetToNative; //0 + else if(iSourceMode == EColor256) + function = KOffsetTo256; //4 + else + function = KOffsetToOtherModes; //8 + + if(iStateFlags & EOrientation90) + function += KOffsetTo90Functions; // + 1 + if(iStateFlags & EOrientation180) + function += KOffsetTo180Functions; //+ 2 + + iCopyFunction = iCFTable[function]; + + Wipe(); + } + +inline void Rotate(TRect& aRect) + { + const TInt dx = aRect.iBr.iX - aRect.iTl.iX; + const TInt dy = aRect.iBr.iY - aRect.iTl.iY; + + aRect.iBr.iX = aRect.iTl.iX + dy; + aRect.iBr.iY = aRect.iTl.iY + dx; + + const TInt tmp = aRect.iTl.iX; + aRect.iTl.iX = aRect.iTl.iY; + aRect.iTl.iY = tmp; + } + +/* +int bar = 0; +*/ +TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect) + { + + if(iStateFlags & EOrientationChanged) + { + iStateFlags &= ~EOrientationFlags; + iStateFlags |= iNewFlags; + SetCopyFunction(); + iStateFlags &= ~EOrientationChanged; + EpocSdlEnv::WaitDeviceChange(); + return EFalse; //skip this frame as data is may be changed + } + + if(iTargetAddr == NULL) + { + iTargetAddr = LockHwSurface(); + } + TUint8* target = iTargetAddr; + if(target == NULL) + return EFalse; + + + TRect targetRect = HwRect(); + TRect sourceRect = aRect; + TRect updateRect = aUpdateRect; + + if(iStateFlags & EOrientation90) + { + Rotate(sourceRect); + Rotate(updateRect); + } + + if(iSourceMode != DisplayMode() || targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0)) + { + sourceRect.Intersection(targetRect); //so source always smaller or equal than target + updateRect.Intersection(targetRect); + ClipCopy(target, aBits, updateRect, sourceRect); + } + else + { + const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored + Mem::Copy(target, aBits, byteCount); + } + + return ETrue; + } + +CDsa* CDsa::CreateL(RWsSession& aSession) + { + if(EpocSdlEnv::Flags(CSDL::EDrawModeDSB)) + { + TInt flags = CDirectScreenBitmap::ENone; + if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBDoubleBuffer)) + flags |= CDirectScreenBitmap::EDoubleBuffer; + if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBIncrentalUpdate)) + flags |= CDirectScreenBitmap::EIncrementalUpdate; + return new (ELeave) CDsaB(aSession); + } + else + return new (ELeave) CDsaA(aSession); + } + +void CDsa::CreateZoomerL(const TSize& aSize) + { + iSwSize = aSize; + iStateFlags |= EResizeRequest; + CreateSurfaceL(); + SetTargetRect(); + } + +TPoint CDsa::WindowCoordinates(const TPoint& aPoint) const + { + TPoint pos = aPoint - iScreenRect.iTl; + const TSize asz = iScreenRect.Size(); + if(iStateFlags & EOrientation180) + { + pos.iX = asz.iWidth - pos.iX; + pos.iY = asz.iHeight - pos.iY; + } + if(iStateFlags & EOrientation90) + { + pos.iX = aPoint.iY; + pos.iY = aPoint.iX; + } + pos.iX <<= 16; + pos.iY <<= 16; + pos.iX /= asz.iWidth; + pos.iY /= asz.iHeight; + pos.iX *= iSwSize.iWidth; + pos.iY *= iSwSize.iHeight; + pos.iX >>= 16; + pos.iY >>= 16; + return pos; + } + +void CDsa::SetTargetRect() + { + iTargetRect = iScreenRect; + if(iStateFlags & EResizeRequest && EpocSdlEnv::Flags(CSDL::EAllowImageResizeKeepRatio)) + { + const TSize asz = iScreenRect.Size(); + const TSize sz = iSwSize; + + TRect rect; + + const TInt dh = (sz.iHeight << 16) / sz.iWidth; + + if((asz.iWidth * dh ) >> 16 <= asz.iHeight) + { + rect.SetRect(TPoint(0, 0), TSize(asz.iWidth, (asz.iWidth * dh) >> 16)); + } + else + { + const TInt dw = (sz.iWidth << 16) / sz.iHeight; + rect.SetRect(TPoint(0, 0), TSize((asz.iHeight * dw) >> 16, asz.iHeight)); + } + rect.Move((asz.iWidth - rect.Size().iWidth) >> 1, (asz.iHeight - rect.Size().iHeight) >> 1); + + iTargetRect = rect; + iTargetRect.Move(iScreenRect.iTl); + + } + if(!(iStateFlags & EResizeRequest)) + iSwSize = iScreenRect.Size(); +// iScanLineWidth = /*iTargetBpp **/ SwSize().iWidth; + } + +void CDsa::RecreateL() + { + } + +void CDsa::Free() + { + } + +void CDsa::UpdateSwSurface() + { + iTargetAddr = NULL; + UnlockHwSurface(); //could be faster if does not use AO, but only check status before redraw, then no context switch needed + } + +void CDsa::SetBlitter(MBlitter* aBlitter) + { + iBlitter = aBlitter; + } + +void CDsa::DrawOverlays() + { + const TInt last = iOverlays.Count() - 1; + for(TInt i = last; i >= 0 ; i--) + iOverlays[i].iOverlay->Draw(*iDsa->Gc(), HwRect(), SwSize()); + } + +TInt CDsa::AppendOverlay(MOverlay& aOverlay, TInt aPriority) + { + TInt i; + for(i = 0; i < iOverlays.Count() && iOverlays[i].iPriority < aPriority; i++) + {} + const TOverlay overlay = {&aOverlay, aPriority}; + return iOverlays.Insert(overlay, i); + } + +TInt CDsa::RemoveOverlay(MOverlay& aOverlay) + { + for(TInt i = 0; i < iOverlays.Count(); i++) + { + if(iOverlays[i].iOverlay == &aOverlay) + { + iOverlays.Remove(i); + return KErrNone; + } + } + return KErrNotFound; + } + +TInt CDsa::RedrawRequest() + { + if(!(iStateFlags & (EUpdating) && (iStateFlags & ERunning))) + { + return ExternalUpdate(); + } + return KErrNotReady; + } + + +void CDsa::Resume() + { + if(Stopped()) + Restart(RDirectScreenAccess::ETerminateRegion); + } + +void CDsa::DoStop() + { + if(IsDsaAvailable()) + iStateFlags |= ESdlThreadExplicitStop; + Stop(); + } + +void CDsa::Stop() + { + iStateFlags &= ~ERunning; +// Cancel(); //can be called only from main! + iDsa->Cancel(); + } + +void CDsa::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/) + { +// iStateFlags |= EChangeNotify; + Stop(); + } + +void CDsa::Restart(RDirectScreenAccess::TTerminationReasons aReason) + { + if(aReason == RDirectScreenAccess::ETerminateRegion) //auto restart + { + TRAPD(err, RestartL()); + PANIC_IF_ERROR(err); + } + } +/*) +TBool CDsa::ChangeTrigger() + { + const TBool change = iStateFlags & EChangeNotify; + iStateFlags &= ~EChangeNotify; + return change; + } +*/ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + TUint32* target = aTarget; + const TUint32* endt = target + aBytes; + const TUint8* source = aSource; + while(target < endt) + { + *target++ = aDsa.iLut256[*source++]; + } + } + +void CDsa::Copy256Reversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + const TUint32* target = aTarget; + TUint32* endt = aTarget + aBytes; + const TUint8* source = aSource; + while(target < endt) + { + *(--endt) = aDsa.iLut256[*source++]; + } + } + +void CDsa::Copy256Flip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + TUint32* target = aTarget; + const TUint32* endt = target + aBytes; + const TUint8* column = aSource; + + while(target < endt) + { + *target++ = aDsa.iLut256[*column]; + column += aLineLen; + } + } + +void CDsa::Copy256FlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + const TUint32* target = aTarget; + TUint32* endt = aTarget + aBytes; + const TUint8* column = aSource; + + while(target < endt) + { + *(--endt) = aDsa.iLut256[*column]; + column += aLineLen; + } + } + +void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + Mem::Copy(aTarget, aSource, aBytes); + } + +void CDsa::CopyMemFlip(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + TUint32* target = aTarget; + const TUint32* endt = target + aBytes; + const TUint32* column = reinterpret_cast(aSource); + + while(target < endt) + { + *target++ = *column; + column += aLineLen; + } + } + +void CDsa::CopyMemReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + const TUint32* target = aTarget; + TUint32* endt = aTarget + aBytes; + const TUint32* source = reinterpret_cast(aSource); + while(target < endt) + { + *(--endt) = *source++; + } + } + + +void CDsa::CopyMemFlipReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + const TUint32* target = aTarget; + TUint32* endt = aTarget + aBytes; + const TUint32* column = reinterpret_cast(aSource); + + while(target < endt) + { + *(--endt) = *column; + column += aLineLen; + } + } + + +typedef TRgb (*TRgbFunc) (TInt aValue); + +LOCAL_C TRgb rgb16MA(TInt aValue) + { + return TRgb::Color16MA(aValue); + } + +NONSHARABLE_CLASS(MRgbCopy) + { + public: + virtual void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) = 0; + virtual void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) = 0; + }; +template +NONSHARABLE_CLASS(TRgbCopy) : public MRgbCopy + { + public: + TRgbCopy(TDisplayMode aMode); + void* operator new(TUint aBytes, TAny* aMem); + void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed); + void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed); + private: + TRgbFunc iFunc; + }; + +template +void* TRgbCopy::operator new(TUint /*aBytes*/, TAny* aMem) + { + return aMem; + } + +template +TRgbCopy::TRgbCopy(TDisplayMode aMode) + { + switch(aMode) + { + case EGray256 : iFunc = TRgb::Gray256; break; + case EColor256 : iFunc = TRgb::Color256; break; + case EColor4K : iFunc = TRgb::Color4K; break; + case EColor64K : iFunc = TRgb::Color64K; break; + case EColor16M : iFunc = TRgb::Color16M; break; + case EColor16MU : iFunc = TRgb::Color16MU; break; + case EColor16MA : iFunc = rgb16MA; break; + default: + PANIC(KErrNotSupported); + } + } + +template +void TRgbCopy::Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) + { + const T* source = reinterpret_cast(aSource); + TUint32* target = aTarget; + TUint32* endt = target + aBytes; + + if(aReversed) + { + while(target < endt) + { + TUint32 value = *source++; + *(--endt) = iFunc(value).Value(); + } + } + else + { + while(target < endt) + { + TUint32 value = *source++; + *target++ = iFunc(value).Value(); + } + } + } + +template +void TRgbCopy::FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) + { + const T* column = reinterpret_cast(aSource); + TUint32* target = aTarget; + TUint32* endt = target + aBytes; + + if(aReversed) + { + while(target < endt) + { + *(--endt) = iFunc(*column).Value(); + column += aLineLen; + } + } + else + { + while(target < endt) + { + *target++ = iFunc(*column).Value(); + column += aLineLen; + } + } + } + + +typedef TUint64 TStackMem; + +LOCAL_C MRgbCopy* GetCopy(TAny* mem, TDisplayMode aMode) + { + if(aMode == EColor256 || aMode == EGray256) + { + return new (mem) TRgbCopy(aMode); + } + if(aMode == EColor4K || aMode == EColor64K) + { + return new (mem) TRgbCopy(aMode); + } + if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA) + { + return new (mem) TRgbCopy(aMode); + } + PANIC(KErrNotSupported); + return NULL; + } + + +void CDsa::CopySlowFlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + TStackMem mem = 0; + GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, ETrue); + } + +void CDsa::CopySlowFlip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen) + { + TStackMem mem = 0; + GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, EFalse); + } + +void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + TStackMem mem = 0; + GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, EFalse); + } + +void CDsa::CopySlowReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt) + { + TStackMem mem = 0; + GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, ETrue); + } \ No newline at end of file diff --git a/src/video/symbian/SDL_epocevents_c.h b/src/video/symbian/SDL_epocevents_c.h new file mode 100644 index 000000000..8dd76f6c9 --- /dev/null +++ b/src/video/symbian/SDL_epocevents_c.h @@ -0,0 +1,60 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* + SDL_epocevents_c.h + Handle the event stream, converting Epoc events into SDL events + + Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi) and Markus Mertama + +*/ + + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_aaevents_c.h,v 1.1.2.2 2000/03/16 15:20:39 hercules Exp $"; +#endif + +extern "C" { +#include "SDL_sysvideo.h" +//#include "SDL_epocvideo.h" +} + + + +#define MAX_SCANCODE 255 + +/* Variables and functions exported by SDL_sysevents.c to other parts + of the native video subsystem (SDL_sysvideo.c) +*/ + +/* Hidden "this" pointer for the video functions */ +#define _THIS SDL_VideoDevice *_this +#define Private _this->hidden + +extern "C" { +extern void EPOC_InitOSKeymap(_THIS); +extern void EPOC_PumpEvents(_THIS); +} + +extern TBool isCursorVisible; + From 9d68aabeb7f7110da1d585bd0061c5d6c2106761 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 25 Jun 2007 00:50:20 +0000 Subject: [PATCH 130/241] Added initial support for Nintendo DS, based on the work by Troy Davis (GPF) --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402376 --- Makefile.ds | 63 ++++ README | 9 +- README.NDS | 22 ++ docs.html | 3 + include/SDL_config_nds.h | 115 +++++++ include/SDL_stdinc.h | 2 + src/SDL.c | 2 + src/audio/SDL_audio.c | 11 +- src/audio/SDL_sysaudio.h | 3 + src/audio/nds/SDL_ndsaudio.c | 335 +++++++++++++++++++ src/audio/nds/SDL_ndsaudio.h | 40 +++ src/audio/nds/sound9.c | 61 ++++ src/audio/nds/soundcommon.h | 80 +++++ src/joystick/nds/SDL_sysjoystick.c | 150 +++++++++ src/timer/nds/SDL_systimer.c | 73 +++++ src/video/SDL_blit.h | 19 ++ src/video/SDL_sysvideo.h | 3 + src/video/SDL_video.c | 3 + src/video/nds/SDL_ndsevents.c | 83 +++++ src/video/nds/SDL_ndsevents_c.h | 51 +++ src/video/nds/SDL_ndsmouse.c | 34 ++ src/video/nds/SDL_ndsmouse_c.h | 26 ++ src/video/nds/SDL_ndsvideo.c | 500 +++++++++++++++++++++++++++++ src/video/nds/SDL_ndsvideo.h | 61 ++++ src/video/windib/SDL_dibvideo.c | 5 + 25 files changed, 1744 insertions(+), 10 deletions(-) create mode 100644 Makefile.ds create mode 100644 README.NDS create mode 100644 include/SDL_config_nds.h create mode 100644 src/audio/nds/SDL_ndsaudio.c create mode 100644 src/audio/nds/SDL_ndsaudio.h create mode 100644 src/audio/nds/sound9.c create mode 100644 src/audio/nds/soundcommon.h create mode 100644 src/joystick/nds/SDL_sysjoystick.c create mode 100644 src/timer/nds/SDL_systimer.c create mode 100644 src/video/nds/SDL_ndsevents.c create mode 100644 src/video/nds/SDL_ndsevents_c.h create mode 100644 src/video/nds/SDL_ndsmouse.c create mode 100644 src/video/nds/SDL_ndsmouse_c.h create mode 100644 src/video/nds/SDL_ndsvideo.c create mode 100644 src/video/nds/SDL_ndsvideo.h diff --git a/Makefile.ds b/Makefile.ds new file mode 100644 index 000000000..df3d14652 --- /dev/null +++ b/Makefile.ds @@ -0,0 +1,63 @@ +#LibSDL 1.2.12 +#DS porting by Troy Davis(GPF) + + +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPro) +endif +ifeq ($(strip $(DEVKITARM)),) +DEVKITARM := $(DEVKITPRO)/devkitARM +endif + + +SRCS = $(shell echo ./src/*.c ./src/audio/*.c ./src/cdrom/*.c ./src/cpuinfo/*.c ./src/events/*.c ./src/file/*.c ./src/stdlib/*.c ./src/thread/*.c ./src/timer/*.c ./src/video/*.c ./src/joystick/*.c ./src/joystick/nds/*.c ./src/cdrom/dummy/*.c ./src/thread/generic/*.c ./src/timer/nds/*.c ./src/loadso/dummy/*.c ./src/audio/dummy/*.c ./src/audio/nds/*.c ./src/video/dummy/*.c ./src/video/nds/*.c) + +OBJS = $(SRCS:.c=.o) + + +SUBDIRS= + +CC=arm-eabi-gcc +CXX=arm-eabi-g++ +LDSHARED=$(CXX) +AR=arm-eabi-ar rc +RANLIB=arm-eabi-ranlib + +CFLAGS = -mthumb -mthumb-interwork \ + -march=armv5te -mtune=arm946e-s \ + -O2 -Wall -Wwrite-strings -Wpointer-arith \ + -DARM9 -D__NDS__ -I$(DEVKITPRO)/libnds/include -Iinclude + +CXXFLAGS += $(CFLAGS) + +all: $(DEVKITPRO)/libnds/lib/libSDL.a + + +$(DEVKITPRO)/libnds/lib/libSDL.a: $(OBJS) + $(AR) $@ $(OBJS) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +clean: + find . -name "*.o" |xargs rm -f + find . -name "*.d" |xargs rm -f + -rm -f *.elf + -rm -f *.nds + -rm -f *.gba + -rm -f *.arm9 + -rm -f *.map + -rm -f *.img + -rm -Rf *.d + + +subdirs: $(patsubst %, _dir_%, $(SUBDIRS)) + +$(patsubst %, _dir_%, $(SUBDIRS)): + $(MAKE) -C $(patsubst _dir_%, %, $@) + +clean_subdirs: $(patsubst %, _clean_dir_%, $(SUBDIRS)) + +$(patsubst %, _clean_dir_%, $(SUBDIRS)): + $(MAKE) -C $(patsubst _clean_dir_%, %, $@) clean + +#include $(DEVKITARM)/ds_rules + diff --git a/README b/README index ef9a76825..7c0dd5890 100644 --- a/README +++ b/README @@ -12,10 +12,11 @@ This is the Simple DirectMedia Layer, a general API that provides low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D framebuffer across multiple platforms. -The current version supports Linux, Windows, Windows CE, BeOS, MacOS, -Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX. -The code contains support for Dreamcast, Atari, AIX, OSF/Tru64, -RISC OS, SymbianOS, and OS/2, but these are not officially supported. +The current version supports Linux, Windows CE/95/98/ME/XP/Vista, BeOS, +MacOS Classic, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, +and QNX. The code contains support for Dreamcast, Atari, AIX, OSF/Tru64, +RISC OS, SymbianOS, Nintendo DS, and OS/2, but these are not officially +supported. SDL is written in C, but works with C++ natively, and has bindings to several other languages, including Ada, C#, Eiffel, Erlang, Euphoria, diff --git a/README.NDS b/README.NDS new file mode 100644 index 000000000..e96a9eeec --- /dev/null +++ b/README.NDS @@ -0,0 +1,22 @@ +The SDL port to the Nintendo DS + +This port uses the devKitPro toolchain, available from: +http://www.devkitpro.org + +Precompiled tools for cross-compiling on Linux are available from: +http://www.libsdl.org/extras/nds/devkitPro-20070503-linux.tar.gz + +todo: +add ds console specific features/optimizations +mouse/keyboard support +dual screen support + +build with: +cp include/SDL_config_nds.h include/SDL_config.h +make -f Makefile.ds + +included is an arm9/arm7 template to allow for sound streaming support. + +Enjoy, fix the source and share :) +Troy Davis(GPF) +http://gpf.dcemu.co.uk/ diff --git a/docs.html b/docs.html index 8c55e52b0..e8469ad70 100644 --- a/docs.html +++ b/docs.html @@ -49,6 +49,9 @@ SDL 1.2.12 is a minor bug fix release.

Unofficial support for the S60/SymbianOS platform has been added.

+

+ Unofficial support for the Nintendo DS platform has been added. +

Unix Notes

diff --git a/include/SDL_config_nds.h b/include/SDL_config_nds.h new file mode 100644 index 000000000..20b789c85 --- /dev/null +++ b/include/SDL_config_nds.h @@ -0,0 +1,115 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifndef _SDL_config_nds_h +#define _SDL_config_nds_h + +#include "SDL_platform.h" + +/* This is a set of defines to configure the SDL features */ + +/* General platform specific identifiers */ +#include "SDL_platform.h" + +/* C datatypes */ +#define SDL_HAS_64BIT_TYPE 1 + +/* Endianness */ +#define SDL_BYTEORDER 1234 + +/* Useful headers */ +#define HAVE_ALLOCA_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_STRING_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_MATH_H 1 +#define HAVE_ICONV_H 1 +#define HAVE_SIGNAL_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRDUP 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_SSCANF 1 +#define HAVE_SNPRINTF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_SETJMP 1 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_NDS 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable the stub cdrom driver (src/cdrom/dummy/\*.c) */ +#define SDL_CDROM_DISABLED 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_NDS 1 + +/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */ +#define SDL_LOADSO_DISABLED 1 + +/* Enable the stub thread support (src/thread/generic/\*.c) */ +#define SDL_THREADS_DISABLED 1 + +/* Enable various timer systems */ +#define SDL_TIMER_NDS 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_NDS 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 + +#endif /* _SDL_config_nds_h */ diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index 21a86794a..dc90828d4 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -129,7 +129,9 @@ typedef enum { DUMMY_ENUM_VALUE } SDL_DUMMY_ENUM; +#ifndef __NDS__ SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int)); +#endif #include "begin_code.h" diff --git a/src/SDL.c b/src/SDL.c index 353d1a575..eec4e7e31 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -54,7 +54,9 @@ static SDL_version version = /* The initialized subsystems */ static Uint32 SDL_initialized = 0; +#if !SDL_TIMERS_DISABLED static Uint32 ticks_started = 0; +#endif #ifdef CHECK_LEAKS int surfaces_allocated = 0; diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 81e890aaf..2e736323f 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -101,6 +101,9 @@ static AudioBootStrap *bootstrap[] = { #if SDL_AUDIO_DRIVER_DC &DCAUD_bootstrap, #endif +#if SDL_AUDIO_DRIVER_NDS + &NDSAUD_bootstrap, +#endif #if SDL_AUDIO_DRIVER_MMEAUDIO &MMEAUDIO_bootstrap, #endif @@ -470,10 +473,7 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) return(-1); } -#if defined(__MACOS__) || (defined(__RISCOS__) && SDL_THREADS_DISABLED) - /* FIXME: Need to implement PPC interrupt asm for SDL_LockAudio() */ -#else -#if defined(__MINT__) && SDL_THREADS_DISABLED +#if SDL_THREADS_DISABLED /* Uses interrupt driven audio, without thread */ #else /* Create a semaphore for locking the sound buffers */ @@ -483,8 +483,7 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) SDL_CloseAudio(); return(-1); } -#endif /* __MINT__ */ -#endif /* __MACOS__ */ +#endif /* SDL_THREADS_DISABLED */ /* Calculate the silence and size of the audio specification */ SDL_CalculateAudioSpec(desired); diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index 0fdd3ae10..1fc920a32 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -165,6 +165,9 @@ extern AudioBootStrap DUMMYAUD_bootstrap; #if SDL_AUDIO_DRIVER_DC extern AudioBootStrap DCAUD_bootstrap; #endif +#if SDL_AUDIO_DRIVER_NDS +extern AudioBootStrap NDSAUD_bootstrap; +#endif #if SDL_AUDIO_DRIVER_MMEAUDIO extern AudioBootStrap MMEAUDIO_bootstrap; #endif diff --git a/src/audio/nds/SDL_ndsaudio.c b/src/audio/nds/SDL_ndsaudio.c new file mode 100644 index 000000000..b511ef744 --- /dev/null +++ b/src/audio/nds/SDL_ndsaudio.c @@ -0,0 +1,335 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* Allow access to a raw mixing buffer */ +#include +#include "SDL.h" +#include "SDL_endian.h" +#include "SDL_timer.h" +#include "SDL_audio.h" +#include "../SDL_audiomem.h" +#include "../SDL_audio_c.h" +#include "SDL_ndsaudio.h" +#include "soundcommon.h" + + +/* Audio driver functions */ +static int NDS_OpenAudio(_THIS, SDL_AudioSpec *spec); +static void NDS_WaitAudio(_THIS); +static void NDS_PlayAudio(_THIS); +static Uint8 *NDS_GetAudioBuf(_THIS); +static void NDS_CloseAudio(_THIS); + +/* Audio driver bootstrap functions */ + +u32 framecounter = 0,soundoffset = 0; +static SDL_AudioDevice *sdl_nds_audiodevice; + +//void SoundMixCallback(void *stream,u32 size) +//{ +// //printf("SoundMixCallback\n"); +// +// Uint8 *buffer; +// +// buffer = sdl_nds_audiodevice->hidden->mixbuf; +// memset(buffer, sdl_nds_audiodevice->spec.silence, size); +// +// if (!sdl_nds_audiodevice->paused){ +// +// +// //if (sdl_nds_audiodevice->convert.needed) { +// // int silence; +// +// // if (sdl_nds_audiodevice->convert.src_format == AUDIO_U8 ) { +// // silence = 0x80; +// // } else { +// // silence = 0; +// // } +// // memset(sdl_nds_audiodevice->convert.buf, silence, sdl_nds_audiodevice->convert.len); +// // sdl_nds_audiodevice->spec.callback(sdl_nds_audiodevice->spec.userdata, +// // (Uint8 *)sdl_nds_audiodevice->convert.buf,sdl_nds_audiodevice->convert.len); +// // SDL_ConvertAudio(&sdl_nds_audiodevice->convert); +// // memcpy(buffer, sdl_nds_audiodevice->convert.buf, sdl_nds_audiodevice->convert.len_cvt); +// //} else +// { +// sdl_nds_audiodevice->spec.callback(sdl_nds_audiodevice->spec.userdata, buffer, size); +// //memcpy((Sint16 *)stream,buffer, size); +// } +// +// } +// +// if(soundsystem->format == 8) +// { +// int i; +// s32 *buffer32 = (s32 *)buffer; +// s32 *stream32 = (s32 *)stream; +// for(i=0;i buffer 16bit +// //if (buffer[i] &0x80) +// //((Sint16*)stream)[i] = 0xff00 | buffer[i]; +// ((Sint16*)stream)[i] = (buffer[i] - 128) << 8; +// +// //else +// // ((Sint16*)stream)[i] = buffer[i]; +// } +// //register signed char *pSrc =buffer; +// //register short *pDest =stream; +// //int x; +// // for (x=size; x>0; x--) +// // { +// // register short temp = (((short)*pSrc)-128)<<8; +// // pSrc++; +// // *pDest++ = temp; +// // } +// +// //memcpy((Sint16 *)stream,buffer, size); +// } +//} + +void SoundMixCallback(void *stream,u32 len) +{ + SDL_AudioDevice *audio = (SDL_AudioDevice *)sdl_nds_audiodevice; + + /* Silence the buffer, since it's ours */ + SDL_memset(stream, audio->spec.silence, len); + + /* Only do soemthing if audio is enabled */ + if ( ! audio->enabled ) + return; + + if ( ! audio->paused ) { + if ( audio->convert.needed ) { + //fprintf(stderr,"converting audio\n"); + SDL_mutexP(audio->mixer_lock); + (*audio->spec.callback)(audio->spec.userdata, + (Uint8 *)audio->convert.buf,audio->convert.len); + SDL_mutexV(audio->mixer_lock); + SDL_ConvertAudio(&audio->convert); + SDL_memcpy(stream,audio->convert.buf,audio->convert.len_cvt); + } else { + SDL_mutexP(audio->mixer_lock); + (*audio->spec.callback)(audio->spec.userdata, + (Uint8 *)stream, len); + SDL_mutexV(audio->mixer_lock); + } + } + return; +} +void MixSound(void) +{ + int remain; + + if(soundsystem->format == 8) + { + if((soundsystem->soundcursor + soundsystem->numsamples) > soundsystem->buffersize) + { + SoundMixCallback(&soundsystem->mixbuffer[soundsystem->soundcursor],soundsystem->buffersize - soundsystem->soundcursor); + remain = soundsystem->numsamples - (soundsystem->buffersize - soundsystem->soundcursor); + SoundMixCallback(soundsystem->mixbuffer,remain); + } + else + { + SoundMixCallback(&soundsystem->mixbuffer[soundsystem->soundcursor],soundsystem->numsamples); + } + } + else + { + if((soundsystem->soundcursor + soundsystem->numsamples) > (soundsystem->buffersize >> 1)) + { + SoundMixCallback(&soundsystem->mixbuffer[soundsystem->soundcursor << 1],(soundsystem->buffersize >> 1) - soundsystem->soundcursor); + remain = soundsystem->numsamples - ((soundsystem->buffersize >> 1) - soundsystem->soundcursor); + SoundMixCallback(soundsystem->mixbuffer,remain); + } + else + { + SoundMixCallback(&soundsystem->mixbuffer[soundsystem->soundcursor << 1],soundsystem->numsamples); + } + } +} + +void InterruptHandler(void) +{ + framecounter++; +} +void FiFoHandler(void) +{ + u32 command; + while ( !(REG_IPC_FIFO_CR & (IPC_FIFO_RECV_EMPTY)) ) + { + command = REG_IPC_FIFO_RX; + + switch(command) + { + case FIFO_NONE: + break; + case UPDATEON_ARM9: + REG_IME = 0; + MixSound(); + REG_IME = 1; + SendCommandToArm7(MIXCOMPLETE_ONARM9); + break; + } + } +} + + + + + +static int Audio_Available(void) +{ + return(1); +} + +static void Audio_DeleteDevice(SDL_AudioDevice *device) +{ +} + +static SDL_AudioDevice *Audio_CreateDevice(int devindex) +{ + + SDL_AudioDevice *this; + + /* Initialize all variables that we clean on shutdown */ + this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice)); + if ( this ) { + SDL_memset(this, 0, (sizeof *this)); + this->hidden = (struct SDL_PrivateAudioData *) + SDL_malloc((sizeof *this->hidden)); + } + if ( (this == NULL) || (this->hidden == NULL) ) { + SDL_OutOfMemory(); + if ( this ) { + SDL_free(this); + } + return(0); + } + SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + + /* Set the function pointers */ + this->OpenAudio = NDS_OpenAudio; + this->WaitAudio = NDS_WaitAudio; + this->PlayAudio = NDS_PlayAudio; + this->GetAudioBuf = NDS_GetAudioBuf; + this->CloseAudio = NDS_CloseAudio; + + this->free = Audio_DeleteDevice; +//fprintf(stderr,"Audio_CreateDevice\n"); + return this; +} + +AudioBootStrap NDSAUD_bootstrap = { + "nds", "NDS audio", + Audio_Available, Audio_CreateDevice +}; + + +void static NDS_WaitAudio(_THIS) +{ + //printf("NDS_WaitAudio\n"); +} + +static void NDS_PlayAudio(_THIS) +{ + //printf("playing audio\n"); + if (this->paused) + return; + +} + +static Uint8 *NDS_GetAudioBuf(_THIS) +{ + return NULL;//(this->hidden->mixbuf); +} + +static void NDS_CloseAudio(_THIS) +{ +/* if ( this->hidden->mixbuf != NULL ) { + SDL_FreeAudioMem(this->hidden->mixbuf); + this->hidden->mixbuf = NULL; + }*/ +} + +static int NDS_OpenAudio(_THIS, SDL_AudioSpec *spec) +{ + //printf("NDS_OpenAudio\n"); + int format = 0; + //switch(spec->format&0xff) { + //case 8: spec->format = AUDIO_S8;format=8; break; + //case 16: spec->format = AUDIO_S16LSB;format=16; break; + //default: + // SDL_SetError("Unsupported audio format"); + // return(-1); + //} + switch (spec->format&~0x1000) { + case AUDIO_S8: + /* Signed 8-bit audio supported */ + format=8; + break; + case AUDIO_U8: + spec->format ^= 0x80;format=8; + break; + case AUDIO_U16: + /* Unsigned 16-bit audio unsupported, convert to S16 */ + spec->format ^=0x8000;format=16; + case AUDIO_S16: + /* Signed 16-bit audio supported */ + format=16; + break; + } + /* Update the fragment size as size in bytes */ + SDL_CalculateAudioSpec(spec); + + /* Allocate mixing buffer */ + //this->hidden->mixlen = spec->size; + //this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); + //if ( this->hidden->mixbuf == NULL ) { + // SDL_SetError("Out of Memory"); + // return(-1); + //} + + SDL_NDSAudio_mutex = 0; + sdl_nds_audiodevice=this; + + irqInit(); + irqSet(IRQ_VBLANK,&InterruptHandler); + irqSet(IRQ_FIFO_NOT_EMPTY,&FiFoHandler); + irqEnable(IRQ_FIFO_NOT_EMPTY); + + REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR | IPC_FIFO_RECV_IRQ; + + + + SoundSystemInit(spec->freq,spec->size,0,format); + SoundStartMixer(); + + + return(1); +} diff --git a/src/audio/nds/SDL_ndsaudio.h b/src/audio/nds/SDL_ndsaudio.h new file mode 100644 index 000000000..d4eb2a5bf --- /dev/null +++ b/src/audio/nds/SDL_ndsaudio.h @@ -0,0 +1,40 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#ifndef _SDL_lowaudio_h +#define _SDL_lowaudio_h + +#include "../SDL_sysaudio.h" + +/* Hidden "this" pointer for the audio functions */ +#define _THIS SDL_AudioDevice *this + +struct SDL_PrivateAudioData { + /* The file descriptor for the audio device */ + //Uint8 *mixbuf; + //Uint32 mixlen; +}; +unsigned short SDL_NDSAudio_mutex=0; + + +#endif /* _SDL_lowaudio_h */ diff --git a/src/audio/nds/sound9.c b/src/audio/nds/sound9.c new file mode 100644 index 000000000..0cf732562 --- /dev/null +++ b/src/audio/nds/sound9.c @@ -0,0 +1,61 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" +#include "SDL_stdinc.h" + +#include "soundcommon.h" + +void SoundSystemInit(u32 rate,u32 buffersize,u8 channel,u8 format) +{ + soundsystem->rate = rate; + + if(format == 8) + soundsystem->buffersize = buffersize; + else if(format == 16) + soundsystem->buffersize = buffersize * sizeof(short); + + soundsystem->mixbuffer = (s8*)SDL_malloc(soundsystem->buffersize); + //soundsystem->soundbuffer = soundsystem->mixbuffer; + soundsystem->format = format; + soundsystem->channel = channel; + soundsystem->prevtimer = 0; + soundsystem->soundcursor = 0; + soundsystem->numsamples = 0; + soundsystem->period = 0x1000000 / rate; + soundsystem->cmd = INIT; +} + +void SoundStartMixer(void) +{ + soundsystem->cmd |= MIX; +} + +void SendCommandToArm7(u32 command) +{ + while (REG_IPC_FIFO_CR & IPC_FIFO_SEND_FULL); + if (REG_IPC_FIFO_CR & IPC_FIFO_ERROR) + { + REG_IPC_FIFO_CR |= IPC_FIFO_SEND_CLEAR; + } + + REG_IPC_FIFO_TX = command; +} diff --git a/src/audio/nds/soundcommon.h b/src/audio/nds/soundcommon.h new file mode 100644 index 000000000..fa819412b --- /dev/null +++ b/src/audio/nds/soundcommon.h @@ -0,0 +1,80 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#ifndef __SOUNDCOMMON_H +#define __SOUNDCOMMON_H + +#include + +#define CLOCK (1 << 25) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + NONE = 0, + INIT = 1, + MIX = 2, + MIXING = 4, + STOP = 8 +}CommandType; + +typedef enum +{ + FIFO_NONE = 0, + UPDATEON_ARM9 = 1, + MIXCOMPLETE_ONARM9 = 2, +}FifoType; + +typedef struct +{ + s8 *mixbuffer;//,*soundbuffer; + u32 rate; + u32 buffersize; + u32 cmd; + u8 channel,format; + u32 soundcursor,numsamples; + s32 prevtimer; + s16 period; +}S_SoundSystem; + +#define soundsystem ((S_SoundSystem*)((u32)(IPC)+sizeof(TransferRegion))) + +#ifdef ARM9 +extern void SoundSystemInit(u32 rate,u32 buffersize,u8 channel,u8 format); +extern void SoundStartMixer(void); +extern void SendCommandToArm7(u32 command); +#else +extern void SoundVBlankIrq(void); +extern void SoundSwapAndMix(void); +extern void SoundSetTimer(int period); +extern void SoundFifoHandler(void); +extern void SendCommandToArm9(u32 command); +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/joystick/nds/SDL_sysjoystick.c b/src/joystick/nds/SDL_sysjoystick.c new file mode 100644 index 000000000..81c069368 --- /dev/null +++ b/src/joystick/nds/SDL_sysjoystick.c @@ -0,0 +1,150 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* This is the system specific header for the SDL joystick API */ +#include +//#include + +#include "SDL_error.h" +#include "SDL_events.h" +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +#include "../../video/nds/SDL_ndsevents_c.h" + +/* Function to scan the system for joysticks. + * This function should set SDL_numjoysticks to the number of available + * joysticks. Joystick 0 should be the system default joystick. + * It should return 0, or -1 on an unrecoverable fatal error. + */ +int SDL_SYS_JoystickInit(void) +{ + SDL_numjoysticks = 1; + //keysInit(); + + return(1); +} + +/* Function to get the device-dependent name of a joystick */ +const char *SDL_SYS_JoystickName(int index) +{ + if(!index) + return "NDS builtin joypad"; + SDL_SetError("No joystick available with that index"); + return (NULL); +} + +/* Function to open a joystick for use. + The joystick to open is specified by the index field of the joystick. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) +{ + joystick->nbuttons=8; + joystick->nhats=0; + joystick->nballs=0; + joystick->naxes=2; + return 0; +} + + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ + +int prevbutton=0; +int prevkey=0; + +int dc=0;int ldc=0; +u32 keysd,keysu=0; +void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ + //dc=keysd; + //if (dc) + //{ + //fprintf(stderr,"heartbeat= %d\n",REG_VCOUNT); + //swiWaitForVBlank(); + //scanKeys(); + //keysd = keysDown(); + //keysu = keysUp(); + //ldc=keysd; + + //} + /*if (prevkey && prevbutton) + { + scanKeys(); + } + */ + + //scanKeys(); + keysd = keysDown(); + keysu = keysUp(); + + + short ax=0,v=0,h=0; + if((keysd&KEY_UP)) {ax=1;v=-10;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=KEY_UP;}//fprintf(stderr,"KEY_UP\n");} + if((keysd&KEY_DOWN)) {ax=1;v=10;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=KEY_DOWN;}//fprintf(stderr,"KEY_DOWN\n");} + if((keysd&KEY_LEFT)) {ax=0;h=-10;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=KEY_LEFT;}//fprintf(stderr,"KEY_LEFT\n");} + if((keysd&KEY_RIGHT)) {ax=0;h=10;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=KEY_RIGHT;}//fprintf(stderr,"KEY_RIGHT\n");} + + if((keysu&KEY_UP)) {ax=1;v=0;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=0;}//fprintf(stderr,"KEY_UP\n");} + if((keysu&KEY_DOWN)) {ax=1;v=0;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=0;}//fprintf(stderr,"KEY_DOWN\n");} + if((keysu&KEY_LEFT)) {ax=0;h=0;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=0;}//fprintf(stderr,"KEY_LEFT\n");} + if((keysu&KEY_RIGHT)) {ax=0;h=0;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=0;}//fprintf(stderr,"KEY_RIGHT\n");} + + if((keysd&KEY_A)) {SDL_PrivateJoystickButton(joystick,0,SDL_PRESSED);prevbutton=KEY_A;} + if((keysd&KEY_B)) {SDL_PrivateJoystickButton(joystick,1,SDL_PRESSED);prevbutton=KEY_B;} + if((keysd&KEY_X)) {SDL_PrivateJoystickButton(joystick,2,SDL_PRESSED);prevbutton=KEY_X;} + if((keysd&KEY_Y)) {SDL_PrivateJoystickButton(joystick,3,SDL_PRESSED);prevbutton=KEY_Y;} + if((keysd&KEY_SELECT)) {SDL_PrivateJoystickButton(joystick,6,SDL_PRESSED);prevbutton=KEY_SELECT;} + if((keysd&KEY_START)) {SDL_PrivateJoystickButton(joystick,7,SDL_PRESSED);prevbutton=KEY_START;} + if((keysd&KEY_L)) {SDL_PrivateJoystickButton(joystick,4,SDL_PRESSED);prevbutton=KEY_L;} + if((keysd&KEY_R)) {SDL_PrivateJoystickButton(joystick,5,SDL_PRESSED);prevbutton=KEY_R;} + + if((keysu&KEY_A)) {SDL_PrivateJoystickButton(joystick,0,SDL_RELEASED);prevbutton=0;} + if((keysu&KEY_B)) {SDL_PrivateJoystickButton(joystick,1,SDL_RELEASED);prevbutton=0;} + if((keysu&KEY_X)) {SDL_PrivateJoystickButton(joystick,2,SDL_RELEASED);prevbutton=0;} + if((keysu&KEY_Y)) {SDL_PrivateJoystickButton(joystick,3,SDL_RELEASED);prevbutton=0;} + if((keysu&KEY_SELECT)) {SDL_PrivateJoystickButton(joystick,6,SDL_RELEASED);prevbutton=0;} + if((keysu&KEY_START)) {SDL_PrivateJoystickButton(joystick,7,SDL_RELEASED);prevbutton=0;} + if((keysu&KEY_L)) {SDL_PrivateJoystickButton(joystick,4,SDL_RELEASED);prevbutton=0;} + if((keysu&KEY_R)) {SDL_PrivateJoystickButton(joystick,5,SDL_RELEASED);prevbutton=0;} + + + +} + +/* Function to close a joystick after use */ +void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ +} + +/* Function to perform any system-specific joystick related cleanup */ +void SDL_SYS_JoystickQuit(void) +{ +} + diff --git a/src/timer/nds/SDL_systimer.c b/src/timer/nds/SDL_systimer.c new file mode 100644 index 000000000..b057623a4 --- /dev/null +++ b/src/timer/nds/SDL_systimer.c @@ -0,0 +1,73 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_thread.h" +#include "SDL_timer.h" +#include "SDL_error.h" +#include "../SDL_timer_c.h" + +#include + +#define timers2ms(tlow,thigh)(tlow | (thigh<<16)) >> 5 + + +void SDL_StartTicks(void) +{ + TIMER0_DATA=0; + TIMER1_DATA=0; + TIMER0_CR=TIMER_ENABLE|TIMER_DIV_1024; + TIMER1_CR=TIMER_ENABLE|TIMER_CASCADE; +} + +Uint32 SDL_GetTicks(void) +{ + return timers2ms(TIMER0_DATA, TIMER1_DATA); +} + +void SDL_Delay(Uint32 ms) +{ + Uint32 now; + now=timers2ms(TIMER0_DATA, TIMER1_DATA); + while((Uint32)timers2ms(TIMER0_DATA, TIMER1_DATA)>fmt->Rloss)<Rshift)| \ + ((g>>fmt->Gloss)<Gshift)| \ + ((b>>fmt->Bloss)<Bshift) | (1<<15); \ +} +#else #define PIXEL_FROM_RGB(Pixel, fmt, r, g, b) \ { \ Pixel = ((r>>fmt->Rloss)<Rshift)| \ ((g>>fmt->Gloss)<Gshift)| \ ((b>>fmt->Bloss)<Bshift); \ } +#endif // __NDS__ FIXME #define RGB565_FROM_RGB(Pixel, r, g, b) \ { \ Pixel = ((r>>3)<<11)|((g>>2)<<5)|(b>>3); \ @@ -321,6 +330,15 @@ do { \ } while(0) /* FIXME: this isn't correct, especially for Alpha (maximum != 255) */ +#ifdef __NDS__ // FIXME +#define PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a) \ +{ \ + Pixel = ((r>>fmt->Rloss)<Rshift)| \ + ((g>>fmt->Gloss)<Gshift)| \ + ((b>>fmt->Bloss)<Bshift)| \ + ((a>>fmt->Aloss)<Ashift) | (1<<15); \ +} +#else #define PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a) \ { \ Pixel = ((r>>fmt->Rloss)<Rshift)| \ @@ -328,6 +346,7 @@ do { \ ((b>>fmt->Bloss)<Bshift)| \ ((a>>fmt->Aloss)<Ashift); \ } +#endif // __NDS__ FIXME #define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a) \ { \ switch (bpp) { \ diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 80a579c35..403fe9b3b 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -392,6 +392,9 @@ extern VideoBootStrap PG_bootstrap; #if SDL_VIDEO_DRIVER_DC extern VideoBootStrap DC_bootstrap; #endif +#if SDL_VIDEO_DRIVER_NDS +extern VideoBootStrap NDS_bootstrap; +#endif #if SDL_VIDEO_DRIVER_RISCOS extern VideoBootStrap RISCOS_bootstrap; #endif diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 3329b85ac..aeb76ddf1 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -108,6 +108,9 @@ static VideoBootStrap *bootstrap[] = { #if SDL_VIDEO_DRIVER_DC &DC_bootstrap, #endif +#if SDL_VIDEO_DRIVER_NDS + &NDS_bootstrap, +#endif #if SDL_VIDEO_DRIVER_RISCOS &RISCOS_bootstrap, #endif diff --git a/src/video/nds/SDL_ndsevents.c b/src/video/nds/SDL_ndsevents.c new file mode 100644 index 000000000..17fb0b23b --- /dev/null +++ b/src/video/nds/SDL_ndsevents.c @@ -0,0 +1,83 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* Being a nds driver, there's no event stream. We just define stubs for + most of the API. */ +#include +#include "SDL.h" +#include "../../events/SDL_sysevents.h" +#include "../../events/SDL_events_c.h" +#include "SDL_ndsvideo.h" +#include "SDL_ndsevents_c.h" + +static SDLKey keymap[NDS_NUMKEYS]; +char keymem[NDS_NUMKEYS]; /* memorize states of buttons */ + +void NDS_PumpEvents(_THIS) +{ + scanKeys(); + int i; + SDL_keysym keysym; + keysym.mod=KMOD_NONE; + for(i=0;i +#include +#include "SDL.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_ndsvideo.h" +#include "SDL_ndsevents_c.h" +#include "SDL_ndsmouse_c.h" + +#define NDSVID_DRIVER_NAME "nds" + +/* Initialization/Query functions */ +static int NDS_VideoInit(_THIS, SDL_PixelFormat *vformat); +static SDL_Rect **NDS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); +static SDL_Surface *NDS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); +static int NDS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); +static void NDS_VideoQuit(_THIS); + +/* Hardware surface functions */ +static int NDS_AllocHWSurface(_THIS, SDL_Surface *surface); +static int NDS_LockHWSurface(_THIS, SDL_Surface *surface); +static int NDS_FlipHWSurface(_THIS, SDL_Surface *surface); +static void NDS_UnlockHWSurface(_THIS, SDL_Surface *surface); +static void NDS_FreeHWSurface(_THIS, SDL_Surface *surface); + +/* etc. */ +static void NDS_UpdateRects(_THIS, int numrects, SDL_Rect *rects); + +/* NDS driver bootstrap functions */ + +static int NDS_Available(void) +{ + return(1); +} + +static void NDS_DeleteDevice(SDL_VideoDevice *device) +{ + SDL_free(device->hidden); + SDL_free(device); +} + +void on_irq_vblank() +{ + // Disable interrupts + //REG_IME = 0; + scanKeys(); + + // VBLANK_INTR_WAIT_FLAGS |= IRQ_VBLANK; + // REG_IF |= IRQ_VBLANK; + //REG_IF = REG_IF; + + // Enable interrupts + //REG_IME = 1; +} + +static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) + { + return 0; + } + +static int CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst) +{ + if (src->flags & SDL_SRCALPHA) return false; + if (src->flags & SDL_SRCCOLORKEY) return false; + if (src->flags & SDL_HWPALETTE ) return false; + if (dst->flags & SDL_SRCALPHA) return false; + if (dst->flags & SDL_SRCCOLORKEY) return false; + if (dst->flags & SDL_HWPALETTE ) return false; + + if (src->format->BitsPerPixel != dst->format->BitsPerPixel) return false; + if (src->format->BytesPerPixel != dst->format->BytesPerPixel) return false; + + src->map->hw_blit = HWAccelBlit; + return true; +} + +static SDL_VideoDevice *NDS_CreateDevice(int devindex) +{ + SDL_VideoDevice *device=0; + + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); + if ( device ) { + SDL_memset(device, 0, (sizeof *device)); + device->hidden = (struct SDL_PrivateVideoData *) + SDL_malloc((sizeof *device->hidden)); + } + if ( (device == NULL) || (device->hidden == NULL) ) { + SDL_OutOfMemory(); + if ( device ) { + SDL_free(device); + } + return(0); + } + SDL_memset(device->hidden, 0, (sizeof *device->hidden)); + + /* Set the function pointers */ + device->VideoInit = NDS_VideoInit; + device->ListModes = NDS_ListModes; + device->SetVideoMode = NDS_SetVideoMode; + device->CreateYUVOverlay = NULL; + device->SetColors = NDS_SetColors; + device->UpdateRects = NDS_UpdateRects; + device->VideoQuit = NDS_VideoQuit; + device->AllocHWSurface = NDS_AllocHWSurface; + device->CheckHWBlit = CheckHWBlit; + device->FillHWRect = NULL; + device->SetHWColorKey = NULL; + device->SetHWAlpha = NULL; + device->LockHWSurface = NDS_LockHWSurface; + device->UnlockHWSurface = NDS_UnlockHWSurface; + device->FlipHWSurface = NDS_FlipHWSurface; + device->FreeHWSurface = NDS_FreeHWSurface; + device->SetCaption = NULL; + device->SetIcon = NULL; + device->IconifyWindow = NULL; + device->GrabInput = NULL; + device->GetWMInfo = NULL; + device->InitOSKeymap = NDS_InitOSKeymap; + device->PumpEvents = NDS_PumpEvents; + device->info.blit_hw=1; + + device->free = NDS_DeleteDevice; + return device; +} + +VideoBootStrap NDS_bootstrap = { + NDSVID_DRIVER_NAME, "SDL NDS video driver", + NDS_Available, NDS_CreateDevice +}; + + u16* frontBuffer;// = (u16*)(0x06000000); + u16* backBuffer;// = (u16*)(0x06000000 + 256 * 256 * 2); +int NDS_VideoInit(_THIS, SDL_PixelFormat *vformat) +{ + //printf("WARNING: You are using the SDL NDS video driver!\n"); + + /* Determine the screen depth (use default 8-bit depth) */ + /* we change this during the SDL_SetVideoMode implementation... */ + vformat->BitsPerPixel = 16; // mode 3 + vformat->BytesPerPixel = 2; + vformat->Rmask = 0x0000f800; + vformat->Gmask = 0x000007e0; + vformat->Bmask = 0x0000001f; + powerON(POWER_ALL); + irqInit(); + irqSet(IRQ_VBLANK, on_irq_vblank); + irqEnable(IRQ_VBLANK); + + //set the mode for 2 text layers and two extended background layers + //videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE); + videoSetMode(MODE_6_2D| DISPLAY_BG2_ACTIVE); + + //set the sub background up for text display (we could just print to one + //of the main display text backgrounds just as easily + videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE); //sub bg 0 will be used to print text + + //set the first two banks as background memory and the third as sub background memory + //D is not used..if you need a bigger background then you will need to map + //more vram banks consecutivly (VRAM A-D are all 0x20000 bytes in size) + //vramSetMainBanks(VRAM_A_MAIN_BG_0x6000000, VRAM_B_MAIN_BG_0x6020000,VRAM_C_SUB_BG , VRAM_D_LCD); + vramSetMainBanks(VRAM_A_MAIN_BG,VRAM_B_MAIN_BG,VRAM_C_MAIN_BG,VRAM_D_MAIN_BG); + //vramSetBankA(VRAM_A_MAIN_BG); + //vramSetBankB(VRAM_B_MAIN_BG); + //vramSetBankC(VRAM_C_MAIN_BG); + //vramSetBankD(VRAM_D_MAIN_BG); + //vramSetBankE(VRAM_E_MAIN_BG); + //vramSetBankF(VRAM_F_MAIN_BG); + //vramSetBankG(VRAM_G_MAIN_BG); + vramSetBankH(VRAM_H_SUB_BG); + vramSetBankI(VRAM_I_LCD); + + ////////////////set up text background for text///////////////////// + SUB_BG0_CR = BG_MAP_BASE(8); + + BG_PALETTE_SUB[255] = RGB15(31,31,31);//by default font will be rendered with color 255 + ///////////////set up our bitmap background/////////////////////// + + //BG3_CR = BG_BMP16_512x512; + + //these are rotation backgrounds so you must set the rotation attributes: + //these are fixed point numbers with the low 8 bits the fractional part + //this basicaly gives it a 1:1 translation in x and y so you get a nice flat bitmap + /* BG3_XDX = 1<<8; + BG3_XDY = 0; + BG3_YDX = 0; + BG3_YDY = 1<<8; + //our bitmap looks a bit better if we center it so scroll down (256 - 192) / 2 + BG3_CX = 0; + BG3_CY = 0; + */ + //consoleInit() is a lot more flexible but this gets you up and running quick + consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(8), (u16*)CHAR_BASE_BLOCK_SUB(0), 16); + + + frontBuffer =(u16*)(0x06000000); + //backBuffer =(u16*)(0x06000000 + 1024 * 512*2); + + //lcdSwap(); + /* We're done! */ + return(0); +} + +SDL_Rect **NDS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) +{ + return (SDL_Rect **) -1; +} + +SDL_Surface *NDS_SetVideoMode(_THIS, SDL_Surface *current, + int width, int height, int bpp, Uint32 flags) +{ + Uint32 Rmask, Gmask, Bmask, Amask; + + //if(width > 1024 || height > 512 || bpp > 16) + // return(NULL); + + if(bpp >8) { + bpp=16; + Rmask = 0x0000001F; + Gmask = 0x000003E0; + Bmask = 0x00007C00; + Amask = 0x00008000; + + videoSetMode(MODE_5_2D| DISPLAY_BG2_ACTIVE); + + vramSetMainBanks(VRAM_A_MAIN_BG,VRAM_B_MAIN_BG,VRAM_C_MAIN_BG,VRAM_D_MAIN_BG); + + BG2_CR = BG_BMP16_512x512; + BG2_XDX = ((width / 256) << 8) | (width % 256) ; + BG2_XDY = 0; + BG2_YDX = 0; + BG2_YDY = ((height / 192) << 8) | ((height % 192) + (height % 192) / 3) ; + BG2_CX = 0; + BG2_CY = 0; +// for (i=0;i<256*192;i++) +// frontBuffer[i] = RGB15(31,0,0)|BIT(15); + } + else + if(bpp <= 8) { + bpp=8; + Rmask = 0x00000000; + Gmask = 0x00000000; + Bmask = 0x00000000; + BG2_CR = BG_BMP8_1024x512; + BG2_XDX = ((width / 256) << 8) | (width % 256) ; + BG2_XDY = 0; + BG2_YDX = 0; + BG2_YDY = ((height / 192) << 8) | ((height % 192) + (height % 192) / 3) ; + + } + else + if(bpp < 15) bpp=15; + if(width<=256) width=256; + else + if(width<256) width=256; + if(height<=192) height=192; + else + if(height<192) height=192; + + if(bpp==8) + { + if(width<256) width=256; + if(height<192) height=192; + this->hidden->ndsmode=4; + } + + if(bpp==15) + { + if(width<256) this->hidden->ndsmode=5; + else this->hidden->ndsmode=3; + } + + this->hidden->buffer= frontBuffer;//NDS_VRAM_BASE; + + //NDS_DISPCNT = NDS_DISP_MODE(this->hidden->ndsmode)|NDS_DISP_BG2; + + //fprintf(stderr,"Setting mode %dx%d (ndsmode %d)\n", width, height,this->hidden->ndsmode); + + // FIXME: How do I tell that 15 bits mode is 555? + + SDL_memset(this->hidden->buffer, 0, 1024 * 512* ((this->hidden->ndsmode==4 || this->hidden->ndsmode==5) ? 2 : 1 ) * ((bpp+7) / 8)); + + /* Allocate the new pixel format for the screen */ + if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, Amask) ) { + this->hidden->buffer = NULL; + SDL_SetError("Couldn't allocate new pixel format for requested mode"); + return(NULL); + } + + /* Set up the new mode framebuffer */ + current->flags = flags | SDL_FULLSCREEN | SDL_HWSURFACE | (this->hidden->ndsmode > 0 ? SDL_DOUBLEBUF : 0); + this->hidden->w = current->w = width; + this->hidden->h = current->h = height; + current->pixels = frontBuffer; + + if (flags & SDL_DOUBLEBUF) { + this->hidden->secondbufferallocd=1; + backBuffer=(u16*)SDL_malloc(1024*512*2); + current->pixels = backBuffer; + } + if(bpp==8) + current->pitch =1024; + else + current->pitch =1024*2; + + /* We're done */ + return(current); +} + +static int NDS_AllocHWSurface(_THIS, SDL_Surface *surface) +{ + if(this->hidden->secondbufferallocd) { + //printf("double double buffer alloc\n"); + return -1; + } + //if(this->hidden->ndsmode==3) + //{ + // printf("no 2nd buffer in mode3\n"); + // return -1; + //} + //printf("second buffer\n"); + //this->hidden->secondbufferallocd=1; + //backBuffer=(u16*)malloc(1024*512*2); + //surface->pixels = backBuffer; + + return(0); +} +static void NDS_FreeHWSurface(_THIS, SDL_Surface *surface) +{ + //free(backBuffer); + this->hidden->secondbufferallocd=0; +} +int z=0; +/* We need to wait for vertical retrace on page flipped displays */ +static int NDS_LockHWSurface(_THIS, SDL_Surface *surface) +{ +/* + uint8* a = surface->pixels; + int i,j; + a += 5 * SCREEN_WIDTH + 5; + for( i = 0; i < 195; ++i) { + uint16* line = a + (SCREEN_WIDTH * i); + for( j = 0; j < 158; ++j) { + *line++ = RGB15(155,155,25); + } + } +*/ + //if (z <256) + // BG_PALETTE[z++]=RGB15(255-z,z,255-z); + + + return(0); +} + +static void NDS_UnlockHWSurface(_THIS, SDL_Surface *surface) +{ + return; +} + +static int NDS_FlipHWSurface(_THIS, SDL_Surface *surface) +{ + if(this->hidden->secondbufferallocd){ + while(DISP_Y!=192); + while(DISP_Y==192); + //printf("flip"); + + dmaCopyAsynch(backBuffer,frontBuffer,1024*512); + } + //printf("flip\n"); + //u16* temp = surface->pixels; + //surface->pixels = frontBuffer; + //frontBuffer = temp; + /* u8* vram=BG_GFX; + int x,y; + for(y = 0; y < 512; y++) + dmaCopy(&frontBuffer[y*rects->w], &vram[y*512],512); + //unsigned char buf; + + //printf("NDS_FlipHWSurface\n"); + //printf("ptr now: 0x%x\n",surface->pixels); + + while(DISP_Y!=192); + while(DISP_Y==192); + //swap + u16* temp = frontBuffer; + frontBuffer = backBuffer; + backBuffer = temp; + + //flip + //base is 16KB and screen size is 256x256x2 (128KB) + BG2_CR ^= BG_BMP_BASE( 512 / 16 ); */ +/* + if(surface->pixels == frontBuffer)//NDS_VRAM_BASE) + { + while(DISP_Y!=192); + while(DISP_Y==192); + //swap + u16* temp = backBuffer; + backBuffer = frontBuffer; + frontBuffer = temp; + + //flip + //base is 16KB and screen size is 256x256x2 (128KB) + BG3_CR ^= BG_BMP_BASE( 128 / 16 ); + } + else + { + + while(DISP_Y!=192); + while(DISP_Y==192); + //swap + u16* temp = frontBuffer; + frontBuffer = backBuffer; + backBuffer = temp; + + //flip + //base is 16KB and screen size is 256x256x2 (128KB) + BG3_CR ^= BG_BMP_BASE( 128 / 16 ); + + } + */ + //printf("ptr then: 0x%x\n",surface->pixels); + + //printf("setting dispcnt to 0x%x\n",NDS_DISPCNT = NDS_DISP_MODE(this->hidden->ndsmode)|NDS_DISP_BG2| buf); + return(0); +} + +static void NDS_UpdateRects(_THIS, int numrects, SDL_Rect *rects) +{ + //fprintf(stderr,"update\n"); + /* do nothing. */ + //dmaCopy(frontBuffer,BG_GFX,512*512); + /* + u8* vram=(u8*)BG_GFX; + int x,y; + for(y = 0; y < 512; y++) + dmaCopy(&frontBuffer[y*rects->w], &vram[y*512],512); + */ + +} + +int NDS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) +{ + //printf("SetColors\n"); + short r,g,b; + + if(this->hidden->ndsmode != 4) + { + printf("This is not a palettized mode\n"); + return -1; + } + + int i,j=firstcolor+ncolors; + for(i=firstcolor;i>3; + g=colors[i].g>>3; + b=colors[i].b>>3; + BG_PALETTE[i]=RGB15(r, g, b); + } + + return(0); +} + +/* Note: If we are terminated, this could be called in the middle of + another SDL video routine -- notably UpdateRects. +*/ +void NDS_VideoQuit(_THIS) +{ +} diff --git a/src/video/nds/SDL_ndsvideo.h b/src/video/nds/SDL_ndsvideo.h new file mode 100644 index 000000000..22c11e6bf --- /dev/null +++ b/src/video/nds/SDL_ndsvideo.h @@ -0,0 +1,61 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#ifndef _SDL_ndsvideo_h +#define _SDL_ndsvideo_h + +#include "SDL_mouse.h" +#include "../SDL_sysvideo.h" + +/* Hidden "this" pointer for the video functions */ +#define _THIS SDL_VideoDevice *this + + +/* Private display data */ + +struct SDL_PrivateVideoData { + int w, h; + void *buffer; + short ndsmode; + short secondbufferallocd; +}; + +/* +#define NDS_VIDC_BASE 0x4000000 +#define NDS_DISPCNT (*(volatile Uint32*)(NDS_VIDC_BASE)) +#define NDS_VIDC_SCANLINE (NDS_VIDC_BASE+6) +#define NDS_SCANLINE (*(volatile Uint8*)(NDS_VIDC_SCANLINE)) + +#define NDS_DISP_MODE(n) (n&7) +#define NDS_DISP_BG2 0x400 +#define NDS_DISP_FB 0x10 + +#define NDS_PAL_BASE 0x5000000 +#define NDS_BGPAL ((volatile Uint16*)(NDS_PAL_BASE)) +#define NDS_OBJPAL ((volatile Uint16*)(NDS_PAL_BASE+0x200)) + +#define NDS_VRAM_BASE 0x6000000 +#define NDS_VRAM_2NDBUF 0x600a000 +#define NDS_VRAM = ((volatile Uint16* )NDS_VRAM_BASE) +*/ +#endif /* _SDL_ndsvideo_h */ diff --git a/src/video/windib/SDL_dibvideo.c b/src/video/windib/SDL_dibvideo.c index b9974b4ff..5b99cbdf7 100644 --- a/src/video/windib/SDL_dibvideo.c +++ b/src/video/windib/SDL_dibvideo.c @@ -751,6 +751,11 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, /* Set video surface flags */ if ( bpp <= 8 ) { + if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { + hdc = GetDC(SDL_Window); + SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC); + ReleaseDC(SDL_Window, hdc); + } /* BitBlt() maps colors for us */ video->flags |= SDL_HWPALETTE; } From 0f38978e549eac59cec3a74c2a5c98baf4c02136 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 25 Jun 2007 14:58:22 +0000 Subject: [PATCH 131/241] Oops, 512x512 in 16 bit mode --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402377 --- src/video/nds/SDL_ndsvideo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/nds/SDL_ndsvideo.c b/src/video/nds/SDL_ndsvideo.c index 2673a98bd..1bdbb1adb 100644 --- a/src/video/nds/SDL_ndsvideo.c +++ b/src/video/nds/SDL_ndsvideo.c @@ -331,7 +331,7 @@ SDL_Surface *NDS_SetVideoMode(_THIS, SDL_Surface *current, if(bpp==8) current->pitch =1024; else - current->pitch =1024*2; + current->pitch =512*2; /* We're done */ return(current); From daddb897733dabb7deafd31ce3c978d5a0734781 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 25 Jun 2007 19:58:32 +0000 Subject: [PATCH 132/241] Significantly improved XIM support. Fixes Bugzilla #429. Selected notes from the patch's README: = FIXES = This patch fixes the above issues as follows. == X11 events == Moved XFilterEvent just after XNextEvent so that all events are passed to it. Also, XFilterEvent will receive masks indicated by IM through XNFilterEvents IC value as well as masks surpplied by SDL. X11_KeyRepeat is called between XNextEvent and XFilterEvent, after testing an event is a KeyRelease. I'm not 100% comfortable to do so, but I couldn't find a better timing to call it, and use of the function is inevitable. == Xutf8LookupString == Used a longer buffer to receive UTF-8 string. If it is insufficient, a dynamic storage of the requested size will be allocated. The initial size of the buffer is set to 32, because the Japanese text converted from the most widely used benchmark key sequence for Japanese IM, "WATASHINONAMAEHANAKANODESU." has ten Japanese characters in it, that occupies 30 bytes when encoded in UTF-8. == SDL_keysym.unicode == On Windows version of SDL implementation, SDL_keysym.unicode stores UTF-16 encoded unicode characters, one UTF-16 encoding unit per an SDL event. A Unicode supplementary characters are sent to an application as two events. (One with a high surrogate and another with a low surrogate.) The behavior seems reasonable since it is upward compatible with existing handling of BMP characters. I wrote a UTF-8 to UTF-16 conversion function for the purpose. It is designed with the execution speed in mind, having a minimum set of features that my patch requires. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402378 --- src/video/x11/SDL_x11dyn.c | 4 + src/video/x11/SDL_x11dyn.h | 1 + src/video/x11/SDL_x11events.c | 328 ++++++++++++++++++++++++++++++---- src/video/x11/SDL_x11sym.h | 2 + src/video/x11/SDL_x11video.c | 125 ++++++++++++- 5 files changed, 423 insertions(+), 37 deletions(-) diff --git a/src/video/x11/SDL_x11dyn.c b/src/video/x11/SDL_x11dyn.c index e7f235d2f..883c2358c 100644 --- a/src/video/x11/SDL_x11dyn.c +++ b/src/video/x11/SDL_x11dyn.c @@ -98,6 +98,7 @@ static void X11_GetSym(const char *fnname, int *rc, void **fn) /* Annoying varargs entry point... */ #ifdef X_HAVE_UTF8_STRING XIC (*pXCreateIC)(XIM,...) = NULL; +char *(*pXGetICValues)(XIC, ...) = NULL; #endif /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */ @@ -127,6 +128,7 @@ void SDL_X11_UnloadSymbols(void) #ifdef X_HAVE_UTF8_STRING pXCreateIC = NULL; + pXGetICValues = NULL; #endif for (i = 0; i < SDL_TABLESIZE(x11libs); i++) { @@ -163,6 +165,7 @@ int SDL_X11_LoadSymbols(void) #ifdef X_HAVE_UTF8_STRING X11_GetSym("XCreateIC",&SDL_X11_HAVE_UTF8,(void **)&pXCreateIC); + X11_GetSym("XGetICValues",&SDL_X11_HAVE_UTF8,(void **)&pXGetICValues); #endif if (SDL_X11_HAVE_BASEXLIB) { /* all required symbols loaded. */ @@ -178,6 +181,7 @@ int SDL_X11_LoadSymbols(void) #endif #ifdef X_HAVE_UTF8_STRING pXCreateIC = XCreateIC; + pXGetICValues = XGetICValues; #endif #endif diff --git a/src/video/x11/SDL_x11dyn.h b/src/video/x11/SDL_x11dyn.h index dc1d17912..2e7e6ceaa 100644 --- a/src/video/x11/SDL_x11dyn.h +++ b/src/video/x11/SDL_x11dyn.h @@ -68,6 +68,7 @@ void SDL_X11_UnloadSymbols(void); /* That's really annoying...make this a function pointer no matter what. */ #ifdef X_HAVE_UTF8_STRING extern XIC (*pXCreateIC)(XIM,...); +extern char *(*pXGetICValues)(XIC, ...); #endif /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */ diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index f32279e44..1282cbb6c 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -176,6 +176,124 @@ Uint32 Utf8ToUcs4(const Uint8 *utf8) } return c; } + +/* Given a UTF-8 encoded string pointed to by utf8 of length length in + bytes, returns the corresponding UTF-16 encoded string in the + buffer pointed to by utf16. The maximum number of UTF-16 encoding + units (i.e., Unit16s) allowed in the buffer is specified in + utf16_max_length. The return value is the number of UTF-16 + encoding units placed in the output buffer pointed to by utf16. + + In case of an error, -1 is returned, leaving some unusable partial + results in the output buffer. + + The caller must estimate the size of utf16 buffer by itself before + calling this function. Insufficient output buffer is considered as + an error, and once an error occured, this function doesn't give any + clue how large the result will be. + + The error cases include following: + + - Invalid byte sequences were in the input UTF-8 bytes. The caller + has no way to know what point in the input buffer was the + errornous byte. + + - The input contained a character (a valid UTF-8 byte sequence) + whose scalar value exceeded the range that UTF-16 can represent + (i.e., characters whose Unicode scalar value above 0x110000). + + - The output buffer has no enough space to hold entire utf16 data. + + Please note: + + - '\0'-termination is not assumed both on the input UTF-8 string + and on the output UTF-16 string; any legal zero byte in the input + UTF-8 string will be converted to a 16-bit zero in output. As a + side effect, the last UTF-16 encoding unit stored in the output + buffer will have a non-zero value if the input UTF-8 was not + '\0'-terminated. + + - UTF-8 aliases are *not* considered as an error. They are + converted to UTF-16. For example, 0xC0 0xA0, 0xE0 0x80 0xA0, + and 0xF0 0x80 0x80 0xA0 are all mapped to a single UTF-16 + encoding unit 0x0020. + + - Three byte UTF-8 sequences whose value corresponds to a surrogate + code or other reserved scalar value are not considered as an + error either. They may cause an invalid UTF-16 data (e.g., those + containing unpaired surrogates). + +*/ + +static int Utf8ToUtf16(const Uint8 *utf8, const int utf8_length, Uint16 *utf16, const int utf16_max_length) { + + /* p moves over the output buffer. max_ptr points to the next to the last slot of the buffer. */ + Uint16 *p = utf16; + Uint16 const *const max_ptr = utf16 + utf16_max_length; + + /* end_of_input points to the last byte of input as opposed to the next to the last byte. */ + Uint8 const *const end_of_input = utf8 + utf8_length - 1; + + while (utf8 <= end_of_input) { + if (p >= max_ptr) { + /* No more output space. */ + return -1; + } + Uint8 const c = *utf8; + if (c < 0x80) { + /* One byte ASCII. */ + *p++ = c; + utf8 += 1; + } else if (c < 0xC0) { + /* Follower byte without preceeding leader bytes. */ + return -1; + } else if (c < 0xE0) { + /* Two byte sequence. We need one follower byte. */ + if (end_of_input - utf8 < 1 || (((utf8[1] ^ 0x80)) & 0xC0)) { + return -1; + } + *p++ = (Uint16)(0xCF80 + (c << 6) + utf8[1]); + utf8 += 2; + } else if (c < 0xF0) { + /* Three byte sequence. We need two follower byte. */ + if (end_of_input - utf8 < 2 || (((utf8[1] ^ 0x80) | (utf8[2] ^ 0x80)) & 0xC0)) { + return -1; + } + *p++ = (Uint16)(0xDF80 + (c << 12) + (utf8[1] << 6) + utf8[2]); + utf8 += 3; + } else if (c < 0xF8) { + int plane; + /* Four byte sequence. We need three follower bytes. */ + if (end_of_input - utf8 < 3 || (((utf8[1] ^ 0x80) | (utf8[2] ^0x80) | (utf8[3] ^ 0x80)) & 0xC0)) { + return -1; + } + plane = (-0xC8 + (c << 2) + (utf8[1] >> 4)); + if (plane == 0) { + /* This four byte sequence is an alias that + corresponds to a Unicode scalar value in BMP. + It fits in an UTF-16 encoding unit. */ + *p++ = (Uint16)(0xDF80 + (utf8[1] << 12) + (utf8[2] << 6) + utf8[3]); + } else if (plane <= 16) { + /* This is a legal four byte sequence that corresponds to a surrogate pair. */ + if (p + 1 >= max_ptr) { + /* No enough space on the output buffer for the pair. */ + return -1; + } + *p++ = (Uint16)(0xE5B8 + (c << 8) + (utf8[1] << 2) + (utf8[2] >> 4)); + *p++ = (Uint16)(0xDB80 + ((utf8[2] & 0x0F) << 6) + utf8[3]); + } else { + /* This four byte sequence is out of UTF-16 code space. */ + return -1; + } + utf8 += 4; + } else { + /* Longer sequence or unused byte. */ + return -1; + } + } + return p - utf16; +} + #endif /* Check to see if this is a repeated key. @@ -275,6 +393,24 @@ static int X11_DispatchEvent(_THIS) SDL_memset(&xevent, '\0', sizeof (XEvent)); /* valgrind fix. --ryan. */ XNextEvent(SDL_Display, &xevent); + /* Discard KeyRelease and KeyPress events generated by auto-repeat. + We need to do it before passing event to XFilterEvent. Otherwise, + KeyRelease aware IMs are confused... */ + if ( xevent.type == KeyRelease + && X11_KeyRepeat(SDL_Display, &xevent) ) { + return 0; + } + +#ifdef X_HAVE_UTF8_STRING + /* If we are translating with IM, we need to pass all events + to XFilterEvent, and discard those filtered events immediately. */ + if ( SDL_TranslateUNICODE + && SDL_IM != NULL + && XFilterEvent(&xevent, None) ) { + return 0; + } +#endif + posted = 0; switch (xevent.type) { @@ -358,6 +494,13 @@ printf("FocusOut!\n"); } break; + /* Some IM requires MappingNotify to be passed to + XRefreshKeyboardMapping by the app. */ + case MappingNotify: { + XRefreshKeyboardMapping(&xevent.xmapping); + } + break; + /* Generated upon EnterWindow and FocusIn */ case KeymapNotify: { #ifdef DEBUG_XEVENTS @@ -409,50 +552,168 @@ printf("KeymapNotify!\n"); /* Key press? */ case KeyPress: { - static SDL_keysym saved_keysym; SDL_keysym keysym; KeyCode keycode = xevent.xkey.keycode; #ifdef DEBUG_XEVENTS printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode); #endif - /* Get the translated SDL virtual keysym */ - if ( keycode ) { + /* If we're not doing translation, we're done! */ + if ( !SDL_TranslateUNICODE ) { + /* Get the translated SDL virtual keysym and put it on the queue.*/ keysym.scancode = keycode; keysym.sym = X11_TranslateKeycode(SDL_Display, keycode); keysym.mod = KMOD_NONE; keysym.unicode = 0; - } else { - keysym = saved_keysym; - } - - /* If we're not doing translation, we're done! */ - if ( !SDL_TranslateUNICODE ) { posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); break; } - if ( XFilterEvent(&xevent, None) ) { - if ( xevent.xkey.keycode ) { - posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); - } else { - /* Save event to be associated with IM text - In 1.3 we'll have a text event instead.. */ - saved_keysym = keysym; - } - break; - } - /* Look up the translated value for the key event */ #ifdef X_HAVE_UTF8_STRING if ( SDL_IC != NULL ) { - static Status state; + Status status; + KeySym xkeysym; + int i; /* A UTF-8 character can be at most 6 bytes */ - char keybuf[6]; - if ( Xutf8LookupString(SDL_IC, &xevent.xkey, - keybuf, sizeof(keybuf), - NULL, &state) ) { - keysym.unicode = Utf8ToUcs4((Uint8*)keybuf); + /* ... It's true, but Xutf8LookupString can + return more than one characters. Moreover, + the spec. put no upper bound, so we should + be ready for longer strings. */ + char keybuf[32]; + char *keydata = keybuf; + int count; + Uint16 utf16buf[32]; + Uint16 *utf16data = utf16buf; + int utf16size; + int utf16length; + + count = Xutf8LookupString(SDL_IC, &xevent.xkey, keydata, sizeof(keybuf), &xkeysym, &status); + if (XBufferOverflow == status) { + /* The IM has just generated somewhat long + string. We need a longer buffer in this + case. */ + keydata = SDL_malloc(count); + if ( keydata == NULL ) { + SDL_OutOfMemory(); + break; + } + count = Xutf8LookupString(SDL_IC, &xevent.xkey, keydata, count, &xkeysym, &status); + } + + switch (status) { + + case XBufferOverflow: { + /* Oops! We have allocated the bytes as + requested by Xutf8LookupString, so the + length of the buffer must be + sufficient. This case should never + happen! */ + SDL_SetError("Xutf8LookupString indicated a double buffer overflow!"); + break; + } + + case XLookupChars: + case XLookupBoth: { + if (0 == count) { + break; + } + + /* We got a converted string from IM. Make + sure to deliver all characters to the + application as SDL events. Note that + an SDL event can only carry one UTF-16 + encoding unit, and a surrogate pair is + delivered as two SDL events. I guess + this behaviour is probably _imported_ + from Windows or MacOS. To do so, we need + to convert the UTF-8 data into UTF-16 + data (not UCS4/UTF-32!). We need an + estimate of the number of UTF-16 encoding + units here. The worst case is pure ASCII + string. Assume so. */ + /* In 1.3 SDL may have a text event instead, that + carries the whole UTF-8 string with it. */ + utf16size = count * sizeof(Uint16); + if (utf16size > sizeof(utf16buf)) { + utf16data = (Uint16 *) SDL_malloc(utf16size); + if (utf16data == NULL) { + SDL_OutOfMemory(); + break; + } + } + utf16length = Utf8ToUtf16((Uint8 *)keydata, count, utf16data, utf16size); + if (utf16length < 0) { + /* The keydata contained an invalid byte + sequence. It should be a bug of the IM + or Xlib... */ + SDL_SetError("Oops! Xutf8LookupString returned an invalid UTF-8 sequence!"); + break; + } + + /* Deliver all UTF-16 encoding units. At + this moment, SDL event queue has a + fixed size (128 events), and an SDL + event can hold just one UTF-16 encoding + unit. So, if we receive more than 128 + UTF-16 encoding units from a commit, + exceeded characters will be lost. */ + for (i = 0; i < utf16length - 1; i++) { + keysym.scancode = 0; + keysym.sym = SDLK_UNKNOWN; + keysym.mod = KMOD_NONE; + keysym.unicode = utf16data[i]; + posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); + } + /* The keysym for the last character carries the + scancode and symbol that corresponds to the X11 + keycode. */ + if (utf16length > 0) { + keysym.scancode = keycode; + keysym.sym = (keycode ? X11_TranslateKeycode(SDL_Display, keycode) : 0); + keysym.mod = KMOD_NONE; + keysym.unicode = utf16data[utf16length - 1]; + posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); + } + break; + } + + case XLookupKeySym: { + /* I'm not sure whether it is possible that + a zero keycode makes XLookupKeySym + status. What I'm sure is that a + combination of a zero scan code and a non + zero sym makes SDL_PrivateKeyboard + strange state... So, just discard it. + If this doesn't work, I'm receiving bug + reports, and I can know under what + condition this case happens. */ + if (keycode) { + keysym.scancode = keycode; + keysym.sym = X11_TranslateKeycode(SDL_Display, keycode); + keysym.mod = KMOD_NONE; + keysym.unicode = 0; + posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); + } + break; + } + + case XLookupNone: { + /* IM has eaten the event. */ + break; + } + + default: + /* An unknown status from Xutf8LookupString. */ + SDL_SetError("Oops! Xutf8LookupStringreturned an unknown status"); + } + + /* Release dynamic buffers if allocated. */ + if (keydata != NULL && keybuf != keydata) { + SDL_free(keydata); + } + if (utf16data != NULL && utf16buf != utf16data) { + SDL_free(utf16data); } } else @@ -472,8 +733,9 @@ printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode); */ keysym.unicode = (Uint8)keybuf[0]; } + + posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); } - posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); } break; @@ -482,13 +744,17 @@ printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode); SDL_keysym keysym; KeyCode keycode = xevent.xkey.keycode; + if (keycode == 0) { + /* There should be no KeyRelease for keycode == 0, + since it is a notification from IM but a real + keystroke. */ + /* We need to emit some diagnostic message here. */ + break; + } + #ifdef DEBUG_XEVENTS printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode); #endif - /* Check to see if this is a repeated key */ - if ( X11_KeyRepeat(SDL_Display, &xevent) ) { - break; - } /* Get the translated SDL virtual keysym */ keysym.scancode = keycode; diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h index fe71cc0de..2d35e5e05 100644 --- a/src/video/x11/SDL_x11sym.h +++ b/src/video/x11/SDL_x11sym.h @@ -143,8 +143,10 @@ SDL_X11_SYM(int,Xutf8LookupString,(XIC a,XKeyPressedEvent* b,char* c,int d,KeySy SDL_X11_SYM(void,XDestroyIC,(XIC a),(a),) SDL_X11_SYM(void,XSetICFocus,(XIC a),(a),) SDL_X11_SYM(void,XUnsetICFocus,(XIC a),(a),) +/*SDL_X11_SYM(char*,XGetICValues,(XIC a, ...),return)*/ SDL_X11_SYM(XIM,XOpenIM,(Display* a,struct _XrmHashBucketRec* b,char* c,char* d),(a,b,c,d),return) SDL_X11_SYM(Status,XCloseIM,(XIM a),(a),return) +SDL_X11_SYM(char*,XSetLocaleModifiers,(_Xconst char* a),(a),return) #endif #ifndef NO_SHARED_MEMORY diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 63a2ad356..d801b3006 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -54,6 +54,10 @@ #include "SDL_x11gamma_c.h" #include "../blank_cursor.h" +#ifdef X_HAVE_UTF8_STRING +#include +#endif + /* Initialization/Query functions */ static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat); static SDL_Surface *X11_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); @@ -105,8 +109,10 @@ static SDL_VideoDevice *X11_CreateDevice(int devindex) SDL_memset(device, 0, (sizeof *device)); device->hidden = (struct SDL_PrivateVideoData *) SDL_malloc((sizeof *device->hidden)); + SDL_memset(device->hidden, 0, (sizeof *device->hidden)); device->gl_data = (struct SDL_PrivateGLData *) SDL_malloc((sizeof *device->gl_data)); + SDL_memset(device->gl_data, 0, (sizeof *device->gl_data)); } if ( (device == NULL) || (device->hidden == NULL) || (device->gl_data == NULL) ) { @@ -314,6 +320,7 @@ static void create_aux_windows(_THIS) char classname[1024]; XSetWindowAttributes xattr; XWMHints *hints; + unsigned long app_event_mask; int def_vis = (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen)); /* Look up some useful Atoms */ @@ -391,9 +398,9 @@ static void create_aux_windows(_THIS) XFree(hints); X11_SetCaptionNoLock(this, this->wm_title, this->wm_icon); - XSelectInput(SDL_Display, WMwindow, - FocusChangeMask | KeyPressMask | KeyReleaseMask - | PropertyChangeMask | StructureNotifyMask | KeymapStateMask); + app_event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask + | PropertyChangeMask | StructureNotifyMask | KeymapStateMask; + XSelectInput(SDL_Display, WMwindow, app_event_mask); /* Set the class hints so we can get an icon (AfterStep) */ get_classname(classname, sizeof(classname)); @@ -409,19 +416,111 @@ static void create_aux_windows(_THIS) } /* Setup the communication with the IM server */ - SDL_IM = NULL; - SDL_IC = NULL; + /* create_aux_windows may be called several times against the same + Display. We should reuse the SDL_IM if one has been opened for + the Display, so we should not simply reset SDL_IM here. */ #ifdef X_HAVE_UTF8_STRING if (SDL_X11_HAVE_UTF8) { + /* Discard obsolete resources if any. */ + if (SDL_IM != NULL && SDL_Display != XDisplayOfIM(SDL_IM)) { + /* Just a double check. I don't think this + code is ever executed. */ + SDL_SetError("display has changed while an IM is kept"); + if (SDL_IC) { + XUnsetICFocus(SDL_IC); + XDestroyIC(SDL_IC); + SDL_IC = NULL; + } + XCloseIM(SDL_IM); + SDL_IM = NULL; + } + + /* Open an input method. */ + if (SDL_IM == NULL) { + char *old_locale, *old_modifiers; + /* I'm not comfortable to do locale setup + here. However, we need C library locale + (and xlib modifiers) to be set based on the + user's preference to use XIM, and many + existing game programs doesn't take care of + users' locale preferences, so someone other + than the game program should do it. + Moreover, ones say that some game programs + heavily rely on the C locale behaviour, + e.g., strcol()'s, and we can't change the C + library locale. Given the situation, I + couldn't find better place to do the + job... */ + + /* Save the current (application program's) + locale settings. */ + old_locale = setlocale(LC_ALL, NULL); + old_modifiers = XSetLocaleModifiers(NULL); + if (old_locale == NULL || old_modifiers == NULL) { + /* The specs guarantee that the query + calls to above functions never + fail, so we should never come + here. */ + SDL_SetError("failed to retreive current locale settings"); + old_locale = NULL; + old_modifiers = NULL; + } else { + /* Save retreived values in our own + storage, since they may be + overwritten by the successive calls + to + setlocale/XSetLocaleModifiers. */ + char const *p; + p = old_locale; + old_locale = SDL_malloc(strlen(p) + 1); + strcpy(old_locale, p); + p = old_modifiers; + old_modifiers = SDL_malloc(strlen(p) + 1); + strcpy(old_modifiers, p); + } + + /* Fetch the user's preferences and open the + input method with them. */ + setlocale(LC_ALL, ""); + XSetLocaleModifiers(""); + SDL_IM = XOpenIM(SDL_Display, NULL, classname, classname); + + /* Restore the application's locale settings + so that we don't break the application's + expected behaviour. */ + if (old_locale != NULL && old_modifiers != NULL) { + /* We need to restore the C library + locale first, since the + interpretation of the X modifier + may depend on it. */ + setlocale(LC_ALL, old_locale); + SDL_free(old_locale); + XSetLocaleModifiers(old_modifiers); + SDL_free(old_modifiers); + } + } + + /* Create a new input context for the new window just created. */ SDL_IM = XOpenIM(SDL_Display, NULL, classname, classname); if (SDL_IM == NULL) { SDL_SetError("no input method could be opened"); } else { + if (SDL_IC != NULL) { + /* Discard the old IC before creating new one. */ + XUnsetICFocus(SDL_IC); + XDestroyIC(SDL_IC); + } + /* Theoretically we should check the current IM supports + PreeditNothing+StatusNothing style (i.e., root window method) + before creating the IC. However, it is the bottom line method, + and we supports any other options. If the IM didn't support + root window method, the following call fails, and SDL falls + back to pre-XIM keyboard handling. */ SDL_IC = pXCreateIC(SDL_IM, XNClientWindow, WMwindow, XNFocusWindow, WMwindow, - XNInputStyle, XIMPreeditNothing | XIMStatusNothing, + XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNResourceName, classname, XNResourceClass, classname, NULL); @@ -430,6 +529,19 @@ static void create_aux_windows(_THIS) SDL_SetError("no input context could be created"); XCloseIM(SDL_IM); SDL_IM = NULL; + } else { + /* We need to receive X events that an IM wants and to pass + them to the IM through XFilterEvent. The set of events may + vary depending on the IM implementation and the options + specified through various routes. Although unlikely, the + xlib specification allows IM to change the event requirement + with its own circumstances, it is safe to call SelectInput + whenever we re-create an IC. */ + unsigned long mask = 0; + char *ret = pXGetICValues(SDL_IC, XNFilterEvents, &mask, NULL); + &ic_event_mask, NULL); + XSelectInput(SDL_Display, WMwindow, app_event_mask | mask); + XSetICFocus(SDL_IC); } } } @@ -1350,6 +1462,7 @@ void X11_VideoQuit(_THIS) /* Close the connection with the IM server */ #ifdef X_HAVE_UTF8_STRING if (SDL_IC != NULL) { + XUnsetICFocus(SDL_IC); XDestroyIC(SDL_IC); SDL_IC = NULL; } From 9289f20b49f953519696102f615e135c03d35566 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 25 Jun 2007 20:08:55 +0000 Subject: [PATCH 133/241] Whoops, patched to compile. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402379 --- src/video/x11/SDL_x11video.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index d801b3006..884a0d66c 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -539,7 +539,6 @@ static void create_aux_windows(_THIS) whenever we re-create an IC. */ unsigned long mask = 0; char *ret = pXGetICValues(SDL_IC, XNFilterEvents, &mask, NULL); - &ic_event_mask, NULL); XSelectInput(SDL_Display, WMwindow, app_event_mask | mask); XSetICFocus(SDL_IC); } From 9797c48fd793753719a95023b1234a73aa32ba50 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 26 Jun 2007 00:57:09 +0000 Subject: [PATCH 134/241] Added some new XIM symbols to the dynamic X11 function list. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402380 --- src/video/x11/SDL_x11sym.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h index 2d35e5e05..9839fc9b3 100644 --- a/src/video/x11/SDL_x11sym.h +++ b/src/video/x11/SDL_x11sym.h @@ -147,6 +147,8 @@ SDL_X11_SYM(void,XUnsetICFocus,(XIC a),(a),) SDL_X11_SYM(XIM,XOpenIM,(Display* a,struct _XrmHashBucketRec* b,char* c,char* d),(a,b,c,d),return) SDL_X11_SYM(Status,XCloseIM,(XIM a),(a),return) SDL_X11_SYM(char*,XSetLocaleModifiers,(_Xconst char* a),(a),return) +SDL_X11_SYM(int,XRefreshKeyboardMapping,(XMappingEvent* a),(a),return) +SDL_X11_SYM(Display*,XDisplayOfIM,(XIM a),(a),return) #endif #ifndef NO_SHARED_MEMORY From 6848868c27aab82584abae5f73c0718d503eeeac Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 26 Jun 2007 20:02:40 +0000 Subject: [PATCH 135/241] windib target can now control screensaver with SDL_VIDEO_ALLOW_SCREENSAVER. Fixes Bugzilla #415. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402381 --- src/video/windib/SDL_dibevents.c | 9 +++++++-- src/video/windib/SDL_dibvideo.c | 5 +++++ src/video/windib/SDL_dibvideo.h | 2 ++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/video/windib/SDL_dibevents.c b/src/video/windib/SDL_dibevents.c index 1d18f86f0..254ba80f2 100644 --- a/src/video/windib/SDL_dibevents.c +++ b/src/video/windib/SDL_dibevents.c @@ -225,9 +225,14 @@ LRESULT DIB_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPar #if defined(SC_SCREENSAVE) && defined(SC_MONITORPOWER) case WM_SYSCOMMAND: { - if ((wParam&0xFFF0)==SC_SCREENSAVE || - (wParam&0xFFF0)==SC_MONITORPOWER) + const DWORD val = (DWORD) (wParam & 0xFFF0); + if ((val == SC_SCREENSAVE) || (val == SC_MONITORPOWER)) { + if (!this->hidden->allow_screensaver) { + /* Note that this doesn't stop anything on Vista + if the screensaver has a password. */ return(0); + } + } } /* Fall through to default processing */ #endif /* SC_SCREENSAVE && SC_MONITORPOWER */ diff --git a/src/video/windib/SDL_dibvideo.c b/src/video/windib/SDL_dibvideo.c index 5b99cbdf7..82b41d99a 100644 --- a/src/video/windib/SDL_dibvideo.c +++ b/src/video/windib/SDL_dibvideo.c @@ -282,6 +282,7 @@ static HPALETTE DIB_CreatePalette(int bpp) int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat) { + const char *env = NULL; #ifndef NO_CHANGEDISPLAYSETTINGS int i; DEVMODE settings; @@ -380,6 +381,10 @@ int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat) this->hidden->origRotation = -1; #endif + /* Allow environment override of screensaver disable. */ + env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER"); + this->hidden->allow_screensaver = ( (env && SDL_atoi(env)) ? 1 : 0 ); + /* We're done! */ return(0); } diff --git a/src/video/windib/SDL_dibvideo.h b/src/video/windib/SDL_dibvideo.h index b759bec86..695ef33c0 100644 --- a/src/video/windib/SDL_dibvideo.h +++ b/src/video/windib/SDL_dibvideo.h @@ -41,6 +41,8 @@ struct SDL_PrivateVideoData { HBITMAP screen_bmp; HPALETTE screen_pal; + int allow_screensaver; + #define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */ int SDL_nummodes[NUM_MODELISTS]; SDL_Rect **SDL_modelist[NUM_MODELISTS]; From d95716b5de811aa129b54796cacbaf64cb48b0f0 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 26 Jun 2007 20:04:15 +0000 Subject: [PATCH 136/241] Updated "What's New" docs. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402382 --- docs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs.html b/docs.html index e8469ad70..2fa2d713b 100644 --- a/docs.html +++ b/docs.html @@ -26,7 +26,7 @@ SDL 1.2.12 is a minor bug fix release. Added support for the PulseAudio sound server: http://www.pulseaudio.org/

- Added SDL_VIDEO_ALLOW_SCREENSAVER to override SDL's disabling of the screensaver on Mac OS X and X11. + Added SDL_VIDEO_ALLOW_SCREENSAVER to override SDL's disabling of the screensaver on Mac OS X, Windows, and X11.

Fixed buffer overrun crash when resampling audio rates. From 8915c4f95b18bdcab3b21012b0badc4782f6f71a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 27 Jun 2007 10:12:49 +0000 Subject: [PATCH 137/241] Removed textrels from hermes code. Partially fixes Bugzilla #418. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402383 --- src/hermes/mmx_main.asm | 4 +--- src/hermes/mmxp2_32.asm | 10 ++++----- src/hermes/x86_main.asm | 49 +---------------------------------------- src/hermes/x86p_16.asm | 17 +++++++------- src/hermes/x86p_32.asm | 40 ++++++++++++++++----------------- 5 files changed, 33 insertions(+), 87 deletions(-) diff --git a/src/hermes/mmx_main.asm b/src/hermes/mmx_main.asm index f79bb398d..c3886d6f0 100644 --- a/src/hermes/mmx_main.asm +++ b/src/hermes/mmx_main.asm @@ -12,7 +12,6 @@ BITS 32 %include "common.inc" SDL_FUNC _ConvertMMX -SDL_FUNC _mmxreturn SECTION .text @@ -51,9 +50,8 @@ _ConvertMMX: y_loop: mov ecx,[ebp+4] - jmp [ebp+32] + call [ebp+32] -_mmxreturn: add esi,[ebp+12] add edi,[ebp+28] diff --git a/src/hermes/mmxp2_32.asm b/src/hermes/mmxp2_32.asm index 8de8de482..89c76d0cb 100644 --- a/src/hermes/mmxp2_32.asm +++ b/src/hermes/mmxp2_32.asm @@ -28,8 +28,6 @@ SDL_FUNC _ConvertMMXpII32_16BGR565 SDL_FUNC _ConvertMMXpII32_16RGB555 SDL_FUNC _ConvertMMXpII32_16BGR555 -EXTERN _mmxreturn - ;; Macros for conversion routines %macro _push_immq_mask 1 @@ -121,7 +119,7 @@ _ConvertMMXpII32_24RGB888: dec ecx jnz .L3 .L4: - jmp _mmxreturn + return @@ -190,7 +188,7 @@ _ConvertMMXpII32_16RGB565: jnz .L3 .L4: - jmp _mmxreturn + retn _ConvertMMXpII32_16BGR565: @@ -260,7 +258,7 @@ _ConvertMMXpII32_16BGR565: jnz .L3 .L4: - jmp _mmxreturn + retn _ConvertMMXpII32_16BGR555: @@ -400,7 +398,7 @@ _convert_bgr555_cheat: jnz .L3 .L4: - jmp _mmxreturn + retn %ifidn __OUTPUT_FORMAT__,elf section .note.GNU-stack noalloc noexec nowrite progbits diff --git a/src/hermes/x86_main.asm b/src/hermes/x86_main.asm index fdc185dd7..e78bf8f7a 100644 --- a/src/hermes/x86_main.asm +++ b/src/hermes/x86_main.asm @@ -14,9 +14,6 @@ BITS 32 %include "common.inc" SDL_FUNC _ConvertX86 -SDL_FUNC _x86return - -SDL_FUNC _Hermes_X86_CPU SECTION .text @@ -55,9 +52,8 @@ _ConvertX86: y_loop: mov ecx,[ebp+4] - jmp [ebp+32] + call [ebp+32] -_x86return: add esi,[ebp+12] add edi,[ebp+28] @@ -74,49 +70,6 @@ endconvert: -;; Hermes_X86_CPU returns the CPUID flags in eax - -_Hermes_X86_CPU: - pushfd - pop eax - - mov ecx,eax - - xor eax,040000h - push eax - - popfd - pushfd - - pop eax - xor eax,ecx - jz .L1 ; Processor is 386 - - push ecx - popfd - - mov eax,ecx - xor eax,200000h - - push eax - popfd - pushfd - - pop eax - xor eax,ecx - je .L1 - - push ebx - - mov eax,1 - cpuid - mov eax,edx - - pop ebx - -.L1: - ret - %ifidn __OUTPUT_FORMAT__,elf section .note.GNU-stack noalloc noexec nowrite progbits %endif diff --git a/src/hermes/x86p_16.asm b/src/hermes/x86p_16.asm index 53363d2e7..e35c75de7 100644 --- a/src/hermes/x86p_16.asm +++ b/src/hermes/x86p_16.asm @@ -20,7 +20,6 @@ SDL_FUNC _ConvertX86p16_16BGR555 SDL_FUNC _ConvertX86p16_8RGB332 EXTERN _ConvertX86 -EXTERN _x86return SECTION .text @@ -49,7 +48,7 @@ _ConvertX86p16_16BGR565: dec ecx jnz .L1 .L2 - jmp _x86return + retn .L3 ; head mov eax,edi @@ -127,7 +126,7 @@ _ConvertX86p16_16BGR565: add edi,BYTE 2 .L7 - jmp _x86return + retn @@ -156,7 +155,7 @@ _ConvertX86p16_16RGB555: dec ecx jnz .L1 .L2 - jmp _x86return + retn .L3 ; head mov eax,edi @@ -235,7 +234,7 @@ _ConvertX86p16_16RGB555: jmp SHORT .L6 .L7 pop ebp - jmp _x86return + retn @@ -269,7 +268,7 @@ _ConvertX86p16_16BGR555: dec ecx jnz .L1 .L2 - jmp _x86return + retn .L3 ; head mov eax,edi @@ -353,7 +352,7 @@ _ConvertX86p16_16BGR555: add edi,BYTE 2 .L7 - jmp _x86return + retn @@ -386,7 +385,7 @@ _ConvertX86p16_8RGB332: dec ecx jnz .L1 .L2 - jmp _x86return + retn .L3 mov eax,edi and eax,BYTE 11b @@ -484,7 +483,7 @@ _ConvertX86p16_8RGB332: jnz .L6 .L7 pop ebp - jmp _x86return + retn %ifidn __OUTPUT_FORMAT__,elf section .note.GNU-stack noalloc noexec nowrite progbits diff --git a/src/hermes/x86p_32.asm b/src/hermes/x86p_32.asm index 1aaef410a..4446c1c2c 100644 --- a/src/hermes/x86p_32.asm +++ b/src/hermes/x86p_32.asm @@ -24,8 +24,6 @@ SDL_FUNC _ConvertX86p32_16RGB555 SDL_FUNC _ConvertX86p32_16BGR555 SDL_FUNC _ConvertX86p32_8RGB332 -EXTERN _x86return - SECTION .text ;; _Convert_* @@ -53,7 +51,7 @@ _ConvertX86p32_32BGR888: dec ecx jnz .L1 .L2 - jmp _x86return + retn .L3 ; save ebp push ebp @@ -113,7 +111,7 @@ _ConvertX86p32_32BGR888: jnz .L5 .L6 pop ebp - jmp _x86return + retn @@ -133,7 +131,7 @@ _ConvertX86p32_32RGBA888: dec ecx jnz .L1 .L2 - jmp _x86return + retn .L3 ; save ebp push ebp @@ -184,7 +182,7 @@ _ConvertX86p32_32RGBA888: jnz .L5 .L6 pop ebp - jmp _x86return + retn @@ -204,7 +202,7 @@ _ConvertX86p32_32BGRA888: dec ecx jnz .L1 .L2 - jmp _x86return + retn .L3 ; save ebp push ebp @@ -257,7 +255,7 @@ _ConvertX86p32_32BGRA888: jnz .L5 .L6 pop ebp - jmp _x86return + retn @@ -282,7 +280,7 @@ _ConvertX86p32_24RGB888: dec ecx jnz .L1 .L2 - jmp _x86return + retn .L3 ; head mov edx,edi @@ -354,7 +352,7 @@ _ConvertX86p32_24RGB888: jnz .L6 .L7 pop ebp - jmp _x86return + retn @@ -380,7 +378,7 @@ _ConvertX86p32_24BGR888: dec ecx jnz .L1 .L2 - jmp _x86return + retn .L3 ; head mov edx,edi @@ -455,7 +453,7 @@ _ConvertX86p32_24BGR888: .L7 pop ebp - jmp _x86return + retn @@ -484,7 +482,7 @@ _ConvertX86p32_16RGB565: jnz .L1 .L2: ; End of short loop - jmp _x86return + retn .L3 ; head @@ -570,7 +568,7 @@ _ConvertX86p32_16RGB565: add edi,BYTE 2 .L7: - jmp _x86return + retn @@ -599,7 +597,7 @@ _ConvertX86p32_16BGR565: dec ecx jnz .L1 .L2 - jmp _x86return + retn .L3 ; head mov ebx,edi @@ -684,7 +682,7 @@ _ConvertX86p32_16BGR565: add edi,BYTE 2 .L7 - jmp _x86return + retn @@ -713,7 +711,7 @@ _ConvertX86p32_16RGB555: dec ecx jnz .L1 .L2 - jmp _x86return + retn .L3 ; head mov ebx,edi @@ -795,7 +793,7 @@ _ConvertX86p32_16RGB555: add edi,BYTE 2 .L7 - jmp _x86return + retn @@ -825,7 +823,7 @@ _ConvertX86p32_16BGR555: dec ecx jnz .L1 .L2 - jmp _x86return + retn .L3 ; head mov ebx,edi @@ -910,7 +908,7 @@ _ConvertX86p32_16BGR555: add edi,BYTE 2 .L7 - jmp _x86return + retn @@ -1040,7 +1038,7 @@ _ConvertX86p32_8RGB332: jnz .L3 .L4: - jmp _x86return + retn %ifidn __OUTPUT_FORMAT__,elf section .note.GNU-stack noalloc noexec nowrite progbits From aa3a251d437460aa60ca0125a4c6b8427f0c5729 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 28 Jun 2007 05:35:50 +0000 Subject: [PATCH 138/241] Better fix for bug 419 --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402385 --- include/SDL_stdinc.h | 3 +-- src/stdlib/SDL_iconv.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index dc90828d4..421392d29 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -574,13 +574,12 @@ extern DECLSPEC int SDLCALL SDL_vsnprintf(char *text, size_t maxlen, const char #define SDL_iconv_t iconv_t #define SDL_iconv_open iconv_open #define SDL_iconv_close iconv_close -extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); #else typedef struct _SDL_iconv_t *SDL_iconv_t; extern DECLSPEC SDL_iconv_t SDLCALL SDL_iconv_open(const char *tocode, const char *fromcode); extern DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd); -extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); #endif +extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); /* This function converts a string between encodings in one pass, returning a string that must be freed with SDL_free() or NULL on error. */ diff --git a/src/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c index caa3eb1e5..1285f4916 100644 --- a/src/stdlib/SDL_iconv.c +++ b/src/stdlib/SDL_iconv.c @@ -31,7 +31,7 @@ #include size_t SDL_iconv(SDL_iconv_t cd, - char **inbuf, size_t *inbytesleft, + const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { size_t retCode = iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft); From cc3fe2e6390bec390f6553dddcaf817aaa65c36c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 28 Jun 2007 06:47:35 +0000 Subject: [PATCH 139/241] Okay, apparently the newer standard specifies char** for the inbuf parameter to iconv() (See http://lists.debian.org/debian-glibc/2004/05/msg00006.html) I'm casting in the general case, but I added a non-const codepath in case it matters on some platform. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402386 --- src/stdlib/SDL_iconv.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c index 1285f4916..245c4480c 100644 --- a/src/stdlib/SDL_iconv.c +++ b/src/stdlib/SDL_iconv.c @@ -34,7 +34,20 @@ size_t SDL_iconv(SDL_iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { - size_t retCode = iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft); + size_t retCode; +#ifdef ICONV_REALLY_MODIFIES_INBUF + if ( inbuf && *inbuf && inbytesleft ) { + char *tmp = SDL_stack_alloc(char, *inbytesleft); + char *ptr = tmp; + retCode = iconv(cd, &ptr, inbytesleft, outbuf, outbytesleft); + inbuf += (ptr - tmp); + SDL_stack_free(tmp); + } else { + retCode = iconv(cd, NULL, inbytesleft, outbuf, outbytesleft); + } +#else + retCode = iconv(cd, (char **)inbuf, inbytesleft, outbuf, outbytesleft); +#endif if ( retCode == (size_t)-1 ) { switch(errno) { case E2BIG: From 2fd06952d19e096073992e01f005e87727ad2e68 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 28 Jun 2007 06:53:09 +0000 Subject: [PATCH 140/241] Whoops, need to actually copy inbuf --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402387 --- src/stdlib/SDL_iconv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c index 245c4480c..326db9be3 100644 --- a/src/stdlib/SDL_iconv.c +++ b/src/stdlib/SDL_iconv.c @@ -39,6 +39,7 @@ size_t SDL_iconv(SDL_iconv_t cd, if ( inbuf && *inbuf && inbytesleft ) { char *tmp = SDL_stack_alloc(char, *inbytesleft); char *ptr = tmp; + SDL_memcpy(tmp, inbuf, *inbytesleft); retCode = iconv(cd, &ptr, inbytesleft, outbuf, outbytesleft); inbuf += (ptr - tmp); SDL_stack_free(tmp); From 9a001803a5bd25dbe3d2df2e9dd2144961db5ad5 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 28 Jun 2007 08:33:59 +0000 Subject: [PATCH 141/241] iconv() doesn't write to the data, just make compilers happy --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402389 --- src/stdlib/SDL_iconv.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c index 326db9be3..da9313364 100644 --- a/src/stdlib/SDL_iconv.c +++ b/src/stdlib/SDL_iconv.c @@ -28,6 +28,15 @@ #ifdef HAVE_ICONV +/* Depending on which standard the iconv() was implemented with, + iconv() may or may not use const char ** for the inbuf param. + If we get this wrong, it's just a warning, so no big deal. +*/ +#if defined(_XGP6) || \ + defined(__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) +#define ICONV_INBUF_NONCONST +#endif + #include size_t SDL_iconv(SDL_iconv_t cd, @@ -35,19 +44,10 @@ size_t SDL_iconv(SDL_iconv_t cd, char **outbuf, size_t *outbytesleft) { size_t retCode; -#ifdef ICONV_REALLY_MODIFIES_INBUF - if ( inbuf && *inbuf && inbytesleft ) { - char *tmp = SDL_stack_alloc(char, *inbytesleft); - char *ptr = tmp; - SDL_memcpy(tmp, inbuf, *inbytesleft); - retCode = iconv(cd, &ptr, inbytesleft, outbuf, outbytesleft); - inbuf += (ptr - tmp); - SDL_stack_free(tmp); - } else { - retCode = iconv(cd, NULL, inbytesleft, outbuf, outbytesleft); - } -#else +#ifdef ICONV_INBUF_NONCONST retCode = iconv(cd, (char **)inbuf, inbytesleft, outbuf, outbytesleft); +#else + retCode = iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft); #endif if ( retCode == (size_t)-1 ) { switch(errno) { From f6513ee758fb5d69f8e601e9094f964688be984c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 28 Jun 2007 19:29:26 +0000 Subject: [PATCH 142/241] Corrected mismerge of XIM patch, thanks Alissa! Fixes Bugzilla #429. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402391 --- src/video/x11/SDL_x11video.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 884a0d66c..8fb37d65d 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -502,7 +502,6 @@ static void create_aux_windows(_THIS) } /* Create a new input context for the new window just created. */ - SDL_IM = XOpenIM(SDL_Display, NULL, classname, classname); if (SDL_IM == NULL) { SDL_SetError("no input method could be opened"); } else { From b8cfbcff8f3923e5631cee41e65995649469b0ae Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 30 Jun 2007 03:47:50 +0000 Subject: [PATCH 143/241] Fixed 64-bit compile issues --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402393 --- src/video/fbcon/SDL_fb3dfx.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/video/fbcon/SDL_fb3dfx.c b/src/video/fbcon/SDL_fb3dfx.c index dca9f7339..91df7acff 100644 --- a/src/video/fbcon/SDL_fb3dfx.c +++ b/src/video/fbcon/SDL_fb3dfx.c @@ -52,7 +52,7 @@ static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key) static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) { int bpp; - char *dst_base; + Uint32 dst_base; Uint32 format; int dstX, dstY; @@ -65,7 +65,7 @@ static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) } /* Set the destination pixel format */ - dst_base = (char *)((char *)dst->pixels - mapped_mem); + dst_base = ((char *)dst->pixels - mapped_mem); bpp = dst->format->BitsPerPixel; format = dst->pitch | ((bpp+((bpp==8) ? 0 : 8)) << 13); @@ -75,7 +75,7 @@ static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) /* Execute the fill command */ tdfx_wait(6); - tdfx_out32(DSTBASE, (Uint32)dst_base); + tdfx_out32(DSTBASE, dst_base); tdfx_out32(DSTFORMAT, format); tdfx_out32(COLORFORE, color); tdfx_out32(COMMAND_2D, COMMAND_2D_FILLRECT); @@ -97,8 +97,8 @@ static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, int bpp; Uint32 src_format; Uint32 dst_format; - char *src_base; - char *dst_base; + Uint32 src_base; + Uint32 dst_base; int srcX, srcY; int dstX, dstY; Uint32 blitop; @@ -113,10 +113,10 @@ static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, } /* Set the source and destination pixel format */ - src_base = (char *)((char *)src->pixels - mapped_mem); + src_base = ((char *)src->pixels - mapped_mem); bpp = src->format->BitsPerPixel; src_format = src->pitch | ((bpp+((bpp==8) ? 0 : 8)) << 13); - dst_base = (char *)((char *)dst->pixels - mapped_mem); + dst_base = ((char *)dst->pixels - mapped_mem); bpp = dst->format->BitsPerPixel; dst_format = dst->pitch | ((bpp+((bpp==8) ? 0 : 8)) << 13); From a304f049b3db46bceb8c9664390952471c87baf9 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 30 Jun 2007 08:09:53 +0000 Subject: [PATCH 144/241] OpenGL is in the X11 directory on some systems. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402394 --- test/configure.in | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/test/configure.in b/test/configure.in index 057c11e26..4455bb9c0 100644 --- a/test/configure.in +++ b/test/configure.in @@ -68,6 +68,21 @@ AM_PATH_SDL($SDL_VERSION, CFLAGS="$CFLAGS $SDL_CFLAGS" LIBS="$LIBS $SDL_LIBS" +dnl Check for X11 path, needed for OpenGL on some systems +AC_PATH_X +if test x$have_x = xyes; then + if test x$ac_x_includes = xno || test x$ac_x_includes = x; then + : + else + CFLAGS="$CFLAGS -I$ac_x_includes" + fi + if test x$ac_x_libraries = xno || test x$ac_x_libraries = x; then + : + else + XPATH="-L$ac_x_libraries" + fi +fi + dnl Check for OpenGL AC_MSG_CHECKING(for OpenGL support) have_opengl=no @@ -80,7 +95,7 @@ have_opengl=yes AC_MSG_RESULT($have_opengl) if test x$have_opengl = xyes; then CFLAGS="$CFLAGS -DHAVE_OPENGL" - GLLIB="$SYS_GL_LIBS" + GLLIB="$XPATH $SYS_GL_LIBS" else GLLIB="" fi From 2ec93d3f0f2bbe3e22c69445c2c91cf8ceb67674 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 2 Jul 2007 02:45:52 +0000 Subject: [PATCH 145/241] Fixed assembly relocation problems, so we can check for NASM on Mac OS X. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402396 --- configure.in | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/configure.in b/configure.in index 0332be004..20c18e650 100644 --- a/configure.in +++ b/configure.in @@ -2503,10 +2503,7 @@ case "$host" in CheckDiskAudio CheckDummyAudio CheckDLOPEN - - # Temporarily disabled: - # ld: mmxp2_32.o has external relocation entries in non-writable section (__TEXT,__text) for symbols: _mmxreturn - #CheckNASM + CheckNASM # Set up files for the shared object loading library # (this needs to be done before the dynamic X11 check) From 30606315b49f96a10e808ed40c48fbe25b48a08b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 3 Jul 2007 09:05:51 +0000 Subject: [PATCH 146/241] Fixed bug #335 Use SetSystemPaletteUse() to get better access to the system palette. We can still do better palette matching in the case where we aren't using fullscreen mode or a hardware palette, but that can wait for another day. :) --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402398 --- src/video/wincommon/SDL_lowvideo.h | 3 + src/video/wincommon/SDL_sysevents.c | 25 ++-- src/video/windib/SDL_dibvideo.c | 186 ++++++++++++++++++++-------- src/video/windib/SDL_dibvideo.h | 2 + src/video/windx5/SDL_dx5video.c | 5 + 5 files changed, 158 insertions(+), 63 deletions(-) diff --git a/src/video/wincommon/SDL_lowvideo.h b/src/video/wincommon/SDL_lowvideo.h index f8ea258fa..96ea1459a 100644 --- a/src/video/wincommon/SDL_lowvideo.h +++ b/src/video/wincommon/SDL_lowvideo.h @@ -84,6 +84,9 @@ extern BOOL SDL_windowid; */ extern void WIN_FlushMessageQueue(); +/* Called by windows message loop when application is activated */ +extern void (*WIN_Activate)(_THIS, BOOL active, BOOL minimized); + /* Called by windows message loop when system palette is available */ extern void (*WIN_RealizePalette)(_THIS); diff --git a/src/video/wincommon/SDL_sysevents.c b/src/video/wincommon/SDL_sysevents.c index f5d4d1c33..1dc9bdb29 100644 --- a/src/video/wincommon/SDL_sysevents.c +++ b/src/video/wincommon/SDL_sysevents.c @@ -84,6 +84,7 @@ WORD *gamma_saved = NULL; /* Functions called by the message processing function */ LONG (*HandleMessage)(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)=NULL; +void (*WIN_Activate)(_THIS, BOOL active, BOOL iconic); void (*WIN_RealizePalette)(_THIS); void (*WIN_PaletteChanged)(_THIS, HWND window); void (*WIN_WinPAINT)(_THIS, HDC hdc); @@ -348,11 +349,12 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_ACTIVATE: { SDL_VideoDevice *this = current_video; - BOOL minimized; + BOOL active, minimized; Uint8 appstate; minimized = HIWORD(wParam); - if ( !minimized && (LOWORD(wParam) != WA_INACTIVE) ) { + active = (LOWORD(wParam) != WA_INACTIVE) && !minimized; + if ( active ) { /* Gain the following states */ appstate = SDL_APPACTIVE|SDL_APPINPUTFOCUS; if ( this->input_grab != SDL_GRAB_OFF ) { @@ -367,17 +369,14 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) } } #if defined(_WIN32_WCE) - if ( WINDIB_FULLSCREEN() ) - { - LoadAygshell(); - if( SHFullScreen ) - SHFullScreen(SDL_Window, SHFS_HIDESTARTICON|SHFS_HIDETASKBAR|SHFS_HIDESIPBUTTON); - else - ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE); - - } + if ( WINDIB_FULLSCREEN() ) { + LoadAygshell(); + if( SHFullScreen ) + SHFullScreen(SDL_Window, SHFS_HIDESTARTICON|SHFS_HIDETASKBAR|SHFS_HIDESIPBUTTON); + else + ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE); + } #endif - posted = SDL_PrivateAppActive(1, appstate); WIN_GetKeyboardState(); } else { @@ -401,12 +400,12 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) SHFullScreen(SDL_Window, SHFS_SHOWSTARTICON|SHFS_SHOWTASKBAR|SHFS_SHOWSIPBUTTON); else ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOW); - #endif } } posted = SDL_PrivateAppActive(0, appstate); } + WIN_Activate(this, active, minimized); return(0); } break; diff --git a/src/video/windib/SDL_dibvideo.c b/src/video/windib/SDL_dibvideo.c index 82b41d99a..285a83547 100644 --- a/src/video/windib/SDL_dibvideo.c +++ b/src/video/windib/SDL_dibvideo.c @@ -87,6 +87,9 @@ static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface); static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface); /* Windows message handling functions */ +static void DIB_GrabStaticColors(HWND window); +static void DIB_ReleaseStaticColors(HWND window); +static void DIB_Activate(_THIS, BOOL active, BOOL minimized); static void DIB_RealizePalette(_THIS); static void DIB_PaletteChanged(_THIS, HWND window); static void DIB_WinPAINT(_THIS, HDC hdc); @@ -176,6 +179,7 @@ static SDL_VideoDevice *DIB_CreateDevice(int devindex) device->PumpEvents = DIB_PumpEvents; /* Set up the windows message handling functions */ + WIN_Activate = DIB_Activate; WIN_RealizePalette = DIB_RealizePalette; WIN_PaletteChanged = DIB_PaletteChanged; WIN_WinPAINT = DIB_WinPAINT; @@ -248,36 +252,25 @@ static int DIB_AddMode(_THIS, int bpp, int w, int h) return(0); } -static HPALETTE DIB_CreatePalette(int bpp) +static void DIB_CreatePalette(_THIS, int bpp) { /* RJR: March 28, 2000 moved palette creation here from "DIB_VideoInit" */ - HPALETTE handle = NULL; - - if ( bpp <= 8 ) - { - LOGPALETTE *palette; - HDC hdc; - int ncolors; - int i; + LOGPALETTE *palette; + HDC hdc; + int ncolors; - ncolors = 1; - for ( i=0; ipalVersion = 0x300; - palette->palNumEntries = ncolors; - hdc = GetDC(SDL_Window); - GetSystemPaletteEntries(hdc, 0, ncolors, palette->palPalEntry); - ReleaseDC(SDL_Window, hdc); - handle = CreatePalette(palette); - SDL_free(palette); - } - - return handle; + ncolors = (1 << bpp); + palette = (LOGPALETTE *)SDL_malloc(sizeof(*palette)+ + ncolors*sizeof(PALETTEENTRY)); + palette->palVersion = 0x300; + palette->palNumEntries = ncolors; + hdc = GetDC(SDL_Window); + GetSystemPaletteEntries(hdc, 0, ncolors, palette->palPalEntry); + ReleaseDC(SDL_Window, hdc); + screen_pal = CreatePalette(palette); + screen_logpal = palette; } int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat) @@ -371,7 +364,7 @@ int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat) if ( vformat->BitsPerPixel <= 8 ) { /* RJR: March 28, 2000 moved palette creation to "DIB_CreatePalette" */ - screen_pal = DIB_CreatePalette(vformat->BitsPerPixel); + DIB_CreatePalette(this, vformat->BitsPerPixel); } /* Fill in some window manager capabilities */ @@ -645,16 +638,23 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, /* Reset the palette and create a new one if necessary */ if ( screen_pal != NULL ) { + if ( video->flags & SDL_HWPALETTE ) { + DIB_ReleaseStaticColors(SDL_Window); + } /* RJR: March 28, 2000 delete identity palette if switching from a palettized mode */ DeleteObject(screen_pal); screen_pal = NULL; } + if ( screen_logpal != NULL ) { + SDL_free(screen_logpal); + screen_logpal = NULL; + } if ( bpp <= 8 ) { /* RJR: March 28, 2000 create identity palette switching to a palettized mode */ - screen_pal = DIB_CreatePalette(bpp); + DIB_CreatePalette(this, bpp); } style = GetWindowLong(SDL_Window, GWL_STYLE); @@ -755,12 +755,7 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, this->UpdateRects = DIB_NormalUpdate; /* Set video surface flags */ - if ( bpp <= 8 ) { - if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { - hdc = GetDC(SDL_Window); - SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC); - ReleaseDC(SDL_Window, hdc); - } + if ( (flags & (SDL_FULLSCREEN|SDL_HWPALETTE)) != 0 ) { /* BitBlt() maps colors for us */ video->flags |= SDL_HWPALETTE; } @@ -885,6 +880,41 @@ static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) ReleaseDC(SDL_Window, hdc); } +static int FindPaletteIndex(LOGPALETTE *pal, BYTE r, BYTE g, BYTE b) +{ + PALETTEENTRY *entry; + int i; + int nentries = pal->palNumEntries; + + for ( i = 0; i < nentries; ++i ) { + entry = &pal->palPalEntry[i]; + if ( entry->peRed == r && entry->peGreen == g && entry->peBlue == b ) { + return i; + } + } + return -1; +} + +static BOOL CheckPaletteEntry(LOGPALETTE *pal, int index, BYTE r, BYTE g, BYTE b) +{ + PALETTEENTRY *entry; + BOOL moved = 0; + + entry = &pal->palPalEntry[index]; + if ( entry->peRed != r || entry->peGreen != g || entry->peBlue != b ) { + int found = FindPaletteIndex(pal, r, g, b); + if ( found >= 0 ) { + pal->palPalEntry[found] = *entry; + } + entry->peRed = r; + entry->peGreen = g; + entry->peBlue = b; + moved = 1; + } + entry->peFlags = 0; + + return moved; +} int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) { @@ -895,23 +925,37 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) HDC hdc; #endif int i; + int moved_entries = 0; /* Update the display palette */ hdc = GetDC(SDL_Window); if ( screen_pal ) { - PALETTEENTRY *entries; + PALETTEENTRY *entry; - entries = SDL_stack_alloc(PALETTEENTRY, ncolors); for ( i=0; ipalPalEntry[firstcolor+i]; + entry->peRed = colors[i].r; + entry->peGreen = colors[i].g; + entry->peBlue = colors[i].b; + entry->peFlags = PC_NOCOLLAPSE; } - SetPaletteEntries(screen_pal, firstcolor, ncolors, entries); + /* Check to make sure black and white are in position */ + if ( GetSystemPaletteUse(hdc) != SYSPAL_NOSTATIC256 ) { + moved_entries += CheckPaletteEntry(screen_logpal, 0, 0x00, 0x00, 0x00); + moved_entries += CheckPaletteEntry(screen_logpal, screen_logpal->palNumEntries-1, 0xff, 0xff, 0xff); + } + /* FIXME: + If we don't have full access to the palette, what we + really want to do is find the 236 most diverse colors + in the desired palette, set those entries (10-245) and + then map everything into the new system palette. + */ + + /* Copy the entries into the system palette */ + UnrealizeObject(screen_pal); + SetPaletteEntries(screen_pal, 0, screen_logpal->palNumEntries, screen_logpal->palPalEntry); SelectPalette(hdc, screen_pal, FALSE); RealizePalette(hdc); - SDL_stack_free(entries); } #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) @@ -928,8 +972,10 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) mdc = CreateCompatibleDC(hdc); SelectObject(mdc, screen_bmp); SetDIBColorTable(mdc, firstcolor, ncolors, pal); - BitBlt(hdc, 0, 0, this->screen->w, this->screen->h, - mdc, 0, 0, SRCCOPY); + if ( moved_entries || !(this->screen->flags & SDL_HWPALETTE) ) { + BitBlt(hdc, 0, 0, this->screen->w, this->screen->h, + mdc, 0, 0, SRCCOPY); + } DeleteDC(mdc); SDL_stack_free(pal); #endif @@ -1048,6 +1094,9 @@ void DIB_VideoQuit(_THIS) if ( SDL_Window ) { /* Delete the screen bitmap (also frees screen->pixels) */ if ( this->screen ) { + if ( this->screen->flags & SDL_HWPALETTE ) { + DIB_ReleaseStaticColors(SDL_Window); + } #ifndef NO_CHANGEDISPLAYSETTINGS if ( this->screen->flags & SDL_FULLSCREEN ) { ChangeDisplaySettings(NULL, 0); @@ -1059,6 +1108,14 @@ void DIB_VideoQuit(_THIS) } this->screen->pixels = NULL; } + if ( screen_pal != NULL ) { + DeleteObject(screen_pal); + screen_pal = NULL; + } + if ( screen_logpal != NULL ) { + SDL_free(screen_logpal); + screen_logpal = NULL; + } if ( screen_bmp ) { DeleteObject(screen_bmp); screen_bmp = NULL; @@ -1097,26 +1154,55 @@ void DIB_VideoQuit(_THIS) } /* Exported for the windows message loop only */ -static void DIB_FocusPalette(_THIS, int foreground) +static void DIB_GrabStaticColors(HWND window) +{ + HDC hdc; + + hdc = GetDC(window); + SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC256); + if ( GetSystemPaletteUse(hdc) != SYSPAL_NOSTATIC256 ) { + SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC); + } + ReleaseDC(window, hdc); +} +static void DIB_ReleaseStaticColors(HWND window) +{ + HDC hdc; + + hdc = GetDC(window); + SetSystemPaletteUse(hdc, SYSPAL_STATIC); + ReleaseDC(window, hdc); +} +static void DIB_Activate(_THIS, BOOL active, BOOL minimized) +{ + if ( screen_pal && (this->screen->flags & SDL_HWPALETTE) ) { + if ( !active ) { + DIB_ReleaseStaticColors(SDL_Window); + DIB_RealizePalette(this); + } else if ( !minimized ) { + DIB_GrabStaticColors(SDL_Window); + DIB_RealizePalette(this); + } + } +} +static void DIB_RealizePalette(_THIS) { if ( screen_pal != NULL ) { HDC hdc; hdc = GetDC(SDL_Window); + UnrealizeObject(screen_pal); SelectPalette(hdc, screen_pal, FALSE); - if ( RealizePalette(hdc) ) + if ( RealizePalette(hdc) ) { InvalidateRect(SDL_Window, NULL, FALSE); + } ReleaseDC(SDL_Window, hdc); } } -static void DIB_RealizePalette(_THIS) -{ - DIB_FocusPalette(this, 1); -} static void DIB_PaletteChanged(_THIS, HWND window) { if ( window != SDL_Window ) { - DIB_FocusPalette(this, 0); + DIB_RealizePalette(this); } } diff --git a/src/video/windib/SDL_dibvideo.h b/src/video/windib/SDL_dibvideo.h index 695ef33c0..efc6ebc8b 100644 --- a/src/video/windib/SDL_dibvideo.h +++ b/src/video/windib/SDL_dibvideo.h @@ -40,6 +40,7 @@ typedef enum struct SDL_PrivateVideoData { HBITMAP screen_bmp; HPALETTE screen_pal; + LOGPALETTE *screen_logpal; int allow_screensaver; @@ -58,6 +59,7 @@ struct SDL_PrivateVideoData { /* Old variable names */ #define screen_bmp (this->hidden->screen_bmp) #define screen_pal (this->hidden->screen_pal) +#define screen_logpal (this->hidden->screen_logpal) #define SDL_nummodes (this->hidden->SDL_nummodes) #define SDL_modelist (this->hidden->SDL_modelist) diff --git a/src/video/windx5/SDL_dx5video.c b/src/video/windx5/SDL_dx5video.c index e304bd5f9..aae58be62 100644 --- a/src/video/windx5/SDL_dx5video.c +++ b/src/video/windx5/SDL_dx5video.c @@ -427,6 +427,7 @@ static int DX5_AllocDDSurface(_THIS, SDL_Surface *surface, LPDIRECTDRAWSURFACE3 requested, Uint32 flag); /* Windows message handling functions */ +static void DX5_Activate(_THIS, BOOL active, BOOL minimized); static void DX5_RealizePalette(_THIS); static void DX5_PaletteChanged(_THIS, HWND window); static void DX5_WinPAINT(_THIS, HDC hdc); @@ -620,6 +621,7 @@ static SDL_VideoDevice *DX5_CreateDevice(int devindex) device->PumpEvents = DX5_PumpEvents; /* Set up the windows message handling functions */ + WIN_Activate = DX5_Activate; WIN_RealizePalette = DX5_RealizePalette; WIN_PaletteChanged = DX5_PaletteChanged; WIN_WinPAINT = DX5_WinPAINT; @@ -2421,6 +2423,9 @@ void DX5_VideoQuit(_THIS) } /* Exported for the windows message loop only */ +void DX5_Activate(_THIS, BOOL active, BOOL minimized) +{ +} void DX5_RealizePalette(_THIS) { if ( SDL_palette ) { From 6a44c15be5045602218713d0042e377bb0472828 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 3 Jul 2007 09:16:14 +0000 Subject: [PATCH 147/241] Added patch note for fixing bug 335 --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402399 --- docs.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs.html b/docs.html index 2fa2d713b..bfa664025 100644 --- a/docs.html +++ b/docs.html @@ -80,6 +80,9 @@ SDL 1.2.12 is a minor bug fix release.

Windows Notes

+

+ The GDI video driver makes better use of the palette in 8-bit modes. +

The windib driver now supports more mouse buttons with WM_XBUTTON events.

From 17349bcd158e5647543282db34ecff031829fb69 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 3 Jul 2007 09:22:57 +0000 Subject: [PATCH 148/241] Added some missing patch notes - Ryan, feel free to add them for your commits --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402400 --- docs.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs.html b/docs.html index bfa664025..5deb10373 100644 --- a/docs.html +++ b/docs.html @@ -57,6 +57,9 @@ SDL 1.2.12 is a minor bug fix release.

Unix Notes

+

+ Improved XIM support for asian character sets. +

The GFX_Display has been added to the X11 window information in SDL_syswm.h.

From 75823323edf9b94bad6f87ac4d643c4080af5994 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 3 Jul 2007 09:39:09 +0000 Subject: [PATCH 149/241] Fixed bug #398 You can use SetColors() before the video mode has been set. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402401 --- src/video/SDL_video.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index aeb76ddf1..86a3352c1 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1142,16 +1142,18 @@ static void SetPalette_logical(SDL_Surface *screen, SDL_Color *colors, ncolors * sizeof(*colors)); } - vidpal = SDL_VideoSurface->format->palette; - if ( (screen == SDL_ShadowSurface) && vidpal ) { - /* - * This is a shadow surface, and the physical - * framebuffer is also indexed. Propagate the - * changes to its logical palette so that - * updates are always identity blits - */ - SDL_memcpy(vidpal->colors + firstcolor, colors, - ncolors * sizeof(*colors)); + if ( current_video && SDL_VideoSurface ) { + vidpal = SDL_VideoSurface->format->palette; + if ( (screen == SDL_ShadowSurface) && vidpal ) { + /* + * This is a shadow surface, and the physical + * framebuffer is also indexed. Propagate the + * changes to its logical palette so that + * updates are always identity blits + */ + SDL_memcpy(vidpal->colors + firstcolor, colors, + ncolors * sizeof(*colors)); + } } SDL_FormatChanged(screen); } @@ -1244,13 +1246,13 @@ int SDL_SetPalette(SDL_Surface *screen, int which, int gotall; int palsize; - if ( ! current_video ) { + if ( !screen ) { return 0; } - if ( screen != SDL_PublicSurface ) { + if ( !current_video || screen != SDL_PublicSurface ) { /* only screens have physical palettes */ which &= ~SDL_PHYSPAL; - } else if( (screen->flags & SDL_HWPALETTE) != SDL_HWPALETTE ) { + } else if ( (screen->flags & SDL_HWPALETTE) != SDL_HWPALETTE ) { /* hardware palettes required for split colormaps */ which |= SDL_PHYSPAL | SDL_LOGPAL; } @@ -1283,16 +1285,14 @@ int SDL_SetPalette(SDL_Surface *screen, int which, * program's idea of what the screen looks like, but changes * its actual appearance. */ - if(!video) - return gotall; /* video not yet initialized */ - if(!video->physpal && !(which & SDL_LOGPAL) ) { + if ( !video->physpal && !(which & SDL_LOGPAL) ) { /* Lazy physical palette allocation */ int size; SDL_Palette *pp = SDL_malloc(sizeof(*pp)); if ( !pp ) { return 0; } - current_video->physpal = pp; + video->physpal = pp; pp->ncolors = pal->ncolors; size = pp->ncolors * sizeof(SDL_Color); pp->colors = SDL_malloc(size); From 84063eb26e5250feecc4f802aecdc4c4c2b8abf0 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 3 Jul 2007 09:53:26 +0000 Subject: [PATCH 150/241] Fixed yasm/nasm warning. Fixes Bugzilla #446. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402402 --- src/hermes/mmxp2_32.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hermes/mmxp2_32.asm b/src/hermes/mmxp2_32.asm index 89c76d0cb..d2d31ecdc 100644 --- a/src/hermes/mmxp2_32.asm +++ b/src/hermes/mmxp2_32.asm @@ -283,7 +283,7 @@ _convert_bgr555_cheat: mov edx,ecx ; Save ecx - and ecx,BYTE 0fffffff8h ; clear lower three bits + and ecx,DWORD 0fffffff8h ; clear lower three bits jnz .L_OK jmp near .L2 From 13be73d9999a7e746d71698826f488002c7523b5 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 4 Jul 2007 04:27:47 +0000 Subject: [PATCH 151/241] Fixed bug #349 Solaris doesn't support the LATIN1 character set alias. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402405 --- include/SDL_stdinc.h | 4 ++-- src/stdlib/SDL_iconv.c | 2 ++ test/testiconv.c | 10 +++++++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index 421392d29..9ea72f6c3 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -584,8 +584,8 @@ extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, siz string that must be freed with SDL_free() or NULL on error. */ extern DECLSPEC char * SDLCALL SDL_iconv_string(const char *tocode, const char *fromcode, const char *inbuf, size_t inbytesleft); -#define SDL_iconv_utf8_ascii(S) SDL_iconv_string("ASCII", "UTF-8", S, SDL_strlen(S)+1) -#define SDL_iconv_utf8_latin1(S) SDL_iconv_string("LATIN1", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ascii(S) SDL_iconv_string("646", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_latin1(S) SDL_iconv_string("8859-1", "UTF-8", S, SDL_strlen(S)+1) #define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2", "UTF-8", S, SDL_strlen(S)+1) #define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4", "UTF-8", S, SDL_strlen(S)+1) diff --git a/src/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c index da9313364..03d8d947e 100644 --- a/src/stdlib/SDL_iconv.c +++ b/src/stdlib/SDL_iconv.c @@ -107,9 +107,11 @@ static struct { const char *name; int format; } encodings[] = { + { "646", ENCODING_ASCII }, { "ASCII", ENCODING_ASCII }, { "US-ASCII", ENCODING_ASCII }, { "LATIN1", ENCODING_LATIN1 }, + { "8859-1", ENCODING_LATIN1 }, { "ISO-8859-1", ENCODING_LATIN1 }, { "UTF8", ENCODING_UTF8 }, { "UTF-8", ENCODING_UTF8 }, diff --git a/test/testiconv.c b/test/testiconv.c index 012de4542..53415d005 100644 --- a/test/testiconv.c +++ b/test/testiconv.c @@ -53,12 +53,16 @@ int main(int argc, char *argv[]) for ( i = 0; i < SDL_arraysize(formats); ++i ) { test[0] = SDL_iconv_string(formats[i], "UCS-4", ucs4, len); test[1] = SDL_iconv_string("UCS-4", formats[i], test[0], len); - if ( SDL_memcmp(test[1], ucs4, len) != 0 ) { + if ( !test[1] || SDL_memcmp(test[1], ucs4, len) != 0 ) { fprintf(stderr, "FAIL: %s\n", formats[i]); ++errors; } - SDL_free(test[0]); - SDL_free(test[1]); + if ( test[0] ) { + SDL_free(test[0]); + } + if ( test[1] ) { + SDL_free(test[1]); + } } test[0] = SDL_iconv_string("UTF-8", "UCS-4", ucs4, len); SDL_free(ucs4); From 6450125a74203c22094c97e9e310cb48d9a6863e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 4 Jul 2007 07:54:06 +0000 Subject: [PATCH 152/241] Fixed bug #447 Xlib uses the native locale, not latin1 ... the question is... what does the server use? :) --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402407 --- include/SDL_stdinc.h | 3 +-- src/stdlib/SDL_iconv.c | 26 ++++++++++++++++++++++++++ src/video/x11/SDL_x11wm.c | 16 ++++++++-------- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index 9ea72f6c3..f86eb04bb 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -584,8 +584,7 @@ extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, siz string that must be freed with SDL_free() or NULL on error. */ extern DECLSPEC char * SDLCALL SDL_iconv_string(const char *tocode, const char *fromcode, const char *inbuf, size_t inbytesleft); -#define SDL_iconv_utf8_ascii(S) SDL_iconv_string("646", "UTF-8", S, SDL_strlen(S)+1) -#define SDL_iconv_utf8_latin1(S) SDL_iconv_string("8859-1", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_locale(S) SDL_iconv_string("", "UTF-8", S, SDL_strlen(S)+1) #define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2", "UTF-8", S, SDL_strlen(S)+1) #define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4", "UTF-8", S, SDL_strlen(S)+1) diff --git a/src/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c index 03d8d947e..9eaabead4 100644 --- a/src/stdlib/SDL_iconv.c +++ b/src/stdlib/SDL_iconv.c @@ -772,6 +772,26 @@ int SDL_iconv_close(SDL_iconv_t cd) #endif /* !HAVE_ICONV */ +static const char *getlocale() +{ + const char *lang; + + lang = SDL_getenv("LC_ALL"); + if ( !lang ) { + lang = SDL_getenv("LC_CTYPE"); + } + if ( !lang ) { + lang = SDL_getenv("LC_MESSAGES"); + } + if ( !lang ) { + lang = SDL_getenv("LANG"); + } + if ( !lang || SDL_strcmp(lang, "C") == 0 ) { + lang = "ASCII"; + } + return lang; +} + char *SDL_iconv_string(const char *tocode, const char *fromcode, const char *inbuf, size_t inbytesleft) { SDL_iconv_t cd; @@ -781,6 +801,12 @@ char *SDL_iconv_string(const char *tocode, const char *fromcode, const char *inb size_t outbytesleft; size_t retCode = 0; + if ( !fromcode || !*fromcode ) { + fromcode = getlocale(); + } + if ( !tocode || !*tocode ) { + tocode = getlocale(); + } cd = SDL_iconv_open(tocode, fromcode); if ( cd == (SDL_iconv_t)-1 ) { return NULL; diff --git a/src/video/x11/SDL_x11wm.c b/src/video/x11/SDL_x11wm.c index ba78aac9d..f167e1207 100644 --- a/src/video/x11/SDL_x11wm.c +++ b/src/video/x11/SDL_x11wm.c @@ -257,13 +257,13 @@ void X11_SetCaptionNoLock(_THIS, const char *title, const char *icon) #endif if ( title != NULL ) { - char *title_latin1 = SDL_iconv_utf8_latin1((char *)title); - if ( !title_latin1 ) { + char *title_locale = SDL_iconv_utf8_locale(title); + if ( !title_locale ) { SDL_OutOfMemory(); return; } - status = XStringListToTextProperty(&title_latin1, 1, &titleprop); - SDL_free(title_latin1); + status = XStringListToTextProperty(&title_locale, 1, &titleprop); + SDL_free(title_locale); if ( status ) { XSetTextProperty(SDL_Display, WMwindow, &titleprop, XA_WM_NAME); XFree(titleprop.value); @@ -280,13 +280,13 @@ void X11_SetCaptionNoLock(_THIS, const char *title, const char *icon) #endif } if ( icon != NULL ) { - char *icon_latin1 = SDL_iconv_utf8_latin1((char *)icon); - if ( !icon_latin1 ) { + char *icon_locale = SDL_iconv_utf8_locale(icon); + if ( !icon_locale ) { SDL_OutOfMemory(); return; } - status = XStringListToTextProperty(&icon_latin1, 1, &iconprop); - SDL_free(icon_latin1); + status = XStringListToTextProperty(&icon_locale, 1, &iconprop); + SDL_free(icon_locale); if ( status ) { XSetTextProperty(SDL_Display, WMwindow, &iconprop, XA_WM_ICON_NAME); XFree(iconprop.value); From f4a253ef63cc52c1627dd2ec0467c72e816c1a19 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 4 Jul 2007 15:22:07 +0000 Subject: [PATCH 153/241] Fixed bug #450 --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402409 --- src/video/x11/SDL_x11events.c | 4 + test/testwin.c | 398 +++------------------------------- 2 files changed, 31 insertions(+), 371 deletions(-) diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 1282cbb6c..4c48a1805 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -722,6 +722,10 @@ printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode); static XComposeStatus state; char keybuf[32]; + keysym.scancode = keycode; + keysym.sym = X11_TranslateKeycode(SDL_Display, keycode); + keysym.mod = KMOD_NONE; + keysym.unicode = 0; if ( XLookupString(&xevent.xkey, keybuf, sizeof(keybuf), NULL, &state) ) { diff --git a/test/testwin.c b/test/testwin.c index 261ea9942..5b6deba14 100644 --- a/test/testwin.c +++ b/test/testwin.c @@ -1,377 +1,33 @@ +#include +#include "SDL/SDL.h" -/* Bring up a window and play with it */ -#include -#include -#include +#define WIDTH 480 +#define HEIGHT 480 +#define DEPTH 32 -#define BENCHMARK_SDL -#define NOTICE(X) printf("%s", X); - -#include "SDL.h" - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void quit(int rc) +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR +lpCmdLine, int nCmdShow) { - SDL_Quit(); - exit(rc); -} - -void DrawPict(SDL_Surface *screen, char *bmpfile, - int speedy, int flip, int nofade) -{ - SDL_Surface *picture; - SDL_Rect dest, update; - int i, centered; - int ncolors; - SDL_Color *colors, *cmap; - - /* Load the image into a surface */ - if ( bmpfile == NULL ) { - bmpfile = "sample.bmp"; /* Sample image */ - } -fprintf(stderr, "Loading picture: %s\n", bmpfile); - picture = SDL_LoadBMP(bmpfile); - if ( picture == NULL ) { - fprintf(stderr, "Couldn't load %s: %s\n", bmpfile, - SDL_GetError()); - return; - } - - /* Set the display colors -- on a hicolor display this is a no-op */ - if ( picture->format->palette ) { - ncolors = picture->format->palette->ncolors; - colors = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color)); - cmap = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color)); - memcpy(colors, picture->format->palette->colors, - ncolors*sizeof(SDL_Color)); - } else { - int r, g, b; - - /* Allocate 256 color palette */ - ncolors = 256; - colors = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color)); - cmap = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color)); - - /* Set a 3,3,2 color cube */ - for ( r=0; r<8; ++r ) { - for ( g=0; g<8; ++g ) { - for ( b=0; b<4; ++b ) { - i = ((r<<5)|(g<<2)|b); - colors[i].r = r<<5; - colors[i].g = g<<5; - colors[i].b = b<<6; - } - } - } - } -NOTICE("testwin: setting colors\n"); - if ( ! SDL_SetColors(screen, colors, 0, ncolors) && - (screen->format->palette != NULL) ) { - fprintf(stderr, -"Warning: Couldn't set all of the colors, but SDL will map the image\n" -" (colormap fading will suffer - try the -warp option)\n" - ); - } - - /* Set the screen to black (not really necessary) */ - if ( SDL_LockSurface(screen) == 0 ) { - Uint32 black; - Uint8 *pixels; - - black = SDL_MapRGB(screen->format, 0, 0, 0); - pixels = (Uint8 *)screen->pixels; - for ( i=0; ih; ++i ) { - memset(pixels, black, - screen->w*screen->format->BytesPerPixel); - pixels += screen->pitch; - } - SDL_UnlockSurface(screen); - SDL_UpdateRect(screen, 0, 0, 0, 0); - } - - /* Display the picture */ - if ( speedy ) { - SDL_Surface *displayfmt; - -fprintf(stderr, "Converting picture\n"); - displayfmt = SDL_DisplayFormat(picture); - if ( displayfmt == NULL ) { - fprintf(stderr, - "Couldn't convert image: %s\n", SDL_GetError()); - goto done; - } - SDL_FreeSurface(picture); - picture = displayfmt; - } - printf("(image surface located in %s memory)\n", - (picture->flags&SDL_HWSURFACE) ? "video" : "system"); - centered = (screen->w - picture->w)/2; - if ( centered < 0 ) { - centered = 0; - } - dest.y = (screen->h - picture->h)/2; - dest.w = picture->w; - dest.h = picture->h; -NOTICE("testwin: moving image\n"); - for ( i=0; i<=centered; ++i ) { - dest.x = i; - update = dest; - if ( SDL_BlitSurface(picture, NULL, screen, &update) < 0 ) { - fprintf(stderr, "Blit failed: %s\n", SDL_GetError()); - break; - } - if ( flip ) { - SDL_Flip(screen); - } else { - SDL_UpdateRects(screen, 1, &update); - } - } - -#ifdef SCREENSHOT - if ( SDL_SaveBMP(screen, "screen.bmp") < 0 ) - printf("Couldn't save screen: %s\n", SDL_GetError()); -#endif - -#ifndef BENCHMARK_SDL - /* Let it sit there for a while */ - SDL_Delay(5*1000); -#endif - /* Fade the colormap */ - if ( ! nofade ) { - int maxstep; - SDL_Color final; - SDL_Color palcolors[256]; - struct { - Sint16 r, g, b; - } cdist[256]; - -NOTICE("testwin: fading out...\n"); - memcpy(cmap, colors, ncolors*sizeof(SDL_Color)); - maxstep = 32-1; - final.r = 0xFF; - final.g = 0x00; - final.b = 0x00; - memcpy(palcolors, colors, ncolors*sizeof(SDL_Color)); - for ( i=0; i 1 ) { - if ( strcmp(argv[1], "-speedy") == 0 ) { - speedy = 1; - argv += 1; - argc -= 1; - } else - if ( strcmp(argv[1], "-nofade") == 0 ) { - nofade = 1; - argv += 1; - argc -= 1; - } else - if ( strcmp(argv[1], "-delay") == 0 ) { - if ( argv[2] ) { - delay = atoi(argv[2]); - argv += 2; - argc -= 2; - } else { - fprintf(stderr, - "The -delay option requires an argument\n"); - quit(1); - } - } else - if ( strcmp(argv[1], "-width") == 0 ) { - if ( argv[2] && ((w = atoi(argv[2])) > 0) ) { - argv += 2; - argc -= 2; - } else { - fprintf(stderr, - "The -width option requires an argument\n"); - quit(1); - } - } else - if ( strcmp(argv[1], "-height") == 0 ) { - if ( argv[2] && ((h = atoi(argv[2])) > 0) ) { - argv += 2; - argc -= 2; - } else { - fprintf(stderr, - "The -height option requires an argument\n"); - quit(1); - } - } else - if ( strcmp(argv[1], "-bpp") == 0 ) { - if ( argv[2] ) { - desired_bpp = atoi(argv[2]); - argv += 2; - argc -= 2; - } else { - fprintf(stderr, - "The -bpp option requires an argument\n"); - quit(1); - } - } else - if ( strcmp(argv[1], "-warp") == 0 ) { - video_flags |= SDL_HWPALETTE; - argv += 1; - argc -= 1; - } else - if ( strcmp(argv[1], "-hw") == 0 ) { - video_flags |= SDL_HWSURFACE; - argv += 1; - argc -= 1; - } else - if ( strcmp(argv[1], "-flip") == 0 ) { - video_flags |= SDL_DOUBLEBUF; - argv += 1; - argc -= 1; - } else - if ( strcmp(argv[1], "-fullscreen") == 0 ) { - video_flags |= SDL_FULLSCREEN; - argv += 1; - argc -= 1; - } else - break; - } - - /* Initialize the display */ - screen = SDL_SetVideoMode(w, h, desired_bpp, video_flags); - if ( screen == NULL ) { - fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n", - w, h, desired_bpp, SDL_GetError()); - quit(1); - } - printf("Set%s %dx%dx%d mode\n", - screen->flags & SDL_FULLSCREEN ? " fullscreen" : "", - screen->w, screen->h, screen->format->BitsPerPixel); - printf("(video surface located in %s memory)\n", - (screen->flags&SDL_HWSURFACE) ? "video" : "system"); - if ( screen->flags & SDL_DOUBLEBUF ) { - printf("Double-buffering enabled\n"); - flip = 1; - } - - /* Set the window manager title bar */ - SDL_WM_SetCaption("SDL test window", "testwin"); - - /* Do all the drawing work */ -#ifdef BENCHMARK_SDL - then = SDL_GetTicks(); - DrawPict(screen, argv[1], speedy, flip, nofade); - now = SDL_GetTicks(); - printf("Time: %d milliseconds\n", now-then); -#else - DrawPict(screen, argv[1], speedy, flip, nofade); -#endif - SDL_Delay(delay*1000); - SDL_Quit(); - return(0); + if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != -1) + { + SDL_Surface* w; + Uint32* r; + int x; + + w = SDL_SetVideoMode(WIDTH, HEIGHT, DEPTH, SDL_SWSURFACE | +SDL_FULLSCREEN); + + SDL_LockSurface(w); + r = w->pixels + w->pitch * HEIGHT / 2; + for (x = 0; x < WIDTH; ++x) r[x] = 0xFFFFFFFF; + SDL_UnlockSurface(w); + SDL_UpdateRect(w, 0, 0, 0, 0); + + SDL_Delay(1000); + SDL_Quit(); + } + + return 0; } From 2ada4fdd9b61f65c9137e76c288623e1e7bd4c48 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 4 Jul 2007 15:22:47 +0000 Subject: [PATCH 154/241] Oops, didn't mean to commit this... --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402410 --- test/testwin.c | 398 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 371 insertions(+), 27 deletions(-) diff --git a/test/testwin.c b/test/testwin.c index 5b6deba14..261ea9942 100644 --- a/test/testwin.c +++ b/test/testwin.c @@ -1,33 +1,377 @@ -#include -#include "SDL/SDL.h" +/* Bring up a window and play with it */ -#define WIDTH 480 -#define HEIGHT 480 -#define DEPTH 32 +#include +#include +#include +#define BENCHMARK_SDL -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR -lpCmdLine, int nCmdShow) +#define NOTICE(X) printf("%s", X); + +#include "SDL.h" + +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ +static void quit(int rc) { - if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != -1) - { - SDL_Surface* w; - Uint32* r; - int x; - - w = SDL_SetVideoMode(WIDTH, HEIGHT, DEPTH, SDL_SWSURFACE | -SDL_FULLSCREEN); - - SDL_LockSurface(w); - r = w->pixels + w->pitch * HEIGHT / 2; - for (x = 0; x < WIDTH; ++x) r[x] = 0xFFFFFFFF; - SDL_UnlockSurface(w); - SDL_UpdateRect(w, 0, 0, 0, 0); - - SDL_Delay(1000); - SDL_Quit(); - } - - return 0; + SDL_Quit(); + exit(rc); +} + +void DrawPict(SDL_Surface *screen, char *bmpfile, + int speedy, int flip, int nofade) +{ + SDL_Surface *picture; + SDL_Rect dest, update; + int i, centered; + int ncolors; + SDL_Color *colors, *cmap; + + /* Load the image into a surface */ + if ( bmpfile == NULL ) { + bmpfile = "sample.bmp"; /* Sample image */ + } +fprintf(stderr, "Loading picture: %s\n", bmpfile); + picture = SDL_LoadBMP(bmpfile); + if ( picture == NULL ) { + fprintf(stderr, "Couldn't load %s: %s\n", bmpfile, + SDL_GetError()); + return; + } + + /* Set the display colors -- on a hicolor display this is a no-op */ + if ( picture->format->palette ) { + ncolors = picture->format->palette->ncolors; + colors = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color)); + cmap = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color)); + memcpy(colors, picture->format->palette->colors, + ncolors*sizeof(SDL_Color)); + } else { + int r, g, b; + + /* Allocate 256 color palette */ + ncolors = 256; + colors = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color)); + cmap = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color)); + + /* Set a 3,3,2 color cube */ + for ( r=0; r<8; ++r ) { + for ( g=0; g<8; ++g ) { + for ( b=0; b<4; ++b ) { + i = ((r<<5)|(g<<2)|b); + colors[i].r = r<<5; + colors[i].g = g<<5; + colors[i].b = b<<6; + } + } + } + } +NOTICE("testwin: setting colors\n"); + if ( ! SDL_SetColors(screen, colors, 0, ncolors) && + (screen->format->palette != NULL) ) { + fprintf(stderr, +"Warning: Couldn't set all of the colors, but SDL will map the image\n" +" (colormap fading will suffer - try the -warp option)\n" + ); + } + + /* Set the screen to black (not really necessary) */ + if ( SDL_LockSurface(screen) == 0 ) { + Uint32 black; + Uint8 *pixels; + + black = SDL_MapRGB(screen->format, 0, 0, 0); + pixels = (Uint8 *)screen->pixels; + for ( i=0; ih; ++i ) { + memset(pixels, black, + screen->w*screen->format->BytesPerPixel); + pixels += screen->pitch; + } + SDL_UnlockSurface(screen); + SDL_UpdateRect(screen, 0, 0, 0, 0); + } + + /* Display the picture */ + if ( speedy ) { + SDL_Surface *displayfmt; + +fprintf(stderr, "Converting picture\n"); + displayfmt = SDL_DisplayFormat(picture); + if ( displayfmt == NULL ) { + fprintf(stderr, + "Couldn't convert image: %s\n", SDL_GetError()); + goto done; + } + SDL_FreeSurface(picture); + picture = displayfmt; + } + printf("(image surface located in %s memory)\n", + (picture->flags&SDL_HWSURFACE) ? "video" : "system"); + centered = (screen->w - picture->w)/2; + if ( centered < 0 ) { + centered = 0; + } + dest.y = (screen->h - picture->h)/2; + dest.w = picture->w; + dest.h = picture->h; +NOTICE("testwin: moving image\n"); + for ( i=0; i<=centered; ++i ) { + dest.x = i; + update = dest; + if ( SDL_BlitSurface(picture, NULL, screen, &update) < 0 ) { + fprintf(stderr, "Blit failed: %s\n", SDL_GetError()); + break; + } + if ( flip ) { + SDL_Flip(screen); + } else { + SDL_UpdateRects(screen, 1, &update); + } + } + +#ifdef SCREENSHOT + if ( SDL_SaveBMP(screen, "screen.bmp") < 0 ) + printf("Couldn't save screen: %s\n", SDL_GetError()); +#endif + +#ifndef BENCHMARK_SDL + /* Let it sit there for a while */ + SDL_Delay(5*1000); +#endif + /* Fade the colormap */ + if ( ! nofade ) { + int maxstep; + SDL_Color final; + SDL_Color palcolors[256]; + struct { + Sint16 r, g, b; + } cdist[256]; + +NOTICE("testwin: fading out...\n"); + memcpy(cmap, colors, ncolors*sizeof(SDL_Color)); + maxstep = 32-1; + final.r = 0xFF; + final.g = 0x00; + final.b = 0x00; + memcpy(palcolors, colors, ncolors*sizeof(SDL_Color)); + for ( i=0; i 1 ) { + if ( strcmp(argv[1], "-speedy") == 0 ) { + speedy = 1; + argv += 1; + argc -= 1; + } else + if ( strcmp(argv[1], "-nofade") == 0 ) { + nofade = 1; + argv += 1; + argc -= 1; + } else + if ( strcmp(argv[1], "-delay") == 0 ) { + if ( argv[2] ) { + delay = atoi(argv[2]); + argv += 2; + argc -= 2; + } else { + fprintf(stderr, + "The -delay option requires an argument\n"); + quit(1); + } + } else + if ( strcmp(argv[1], "-width") == 0 ) { + if ( argv[2] && ((w = atoi(argv[2])) > 0) ) { + argv += 2; + argc -= 2; + } else { + fprintf(stderr, + "The -width option requires an argument\n"); + quit(1); + } + } else + if ( strcmp(argv[1], "-height") == 0 ) { + if ( argv[2] && ((h = atoi(argv[2])) > 0) ) { + argv += 2; + argc -= 2; + } else { + fprintf(stderr, + "The -height option requires an argument\n"); + quit(1); + } + } else + if ( strcmp(argv[1], "-bpp") == 0 ) { + if ( argv[2] ) { + desired_bpp = atoi(argv[2]); + argv += 2; + argc -= 2; + } else { + fprintf(stderr, + "The -bpp option requires an argument\n"); + quit(1); + } + } else + if ( strcmp(argv[1], "-warp") == 0 ) { + video_flags |= SDL_HWPALETTE; + argv += 1; + argc -= 1; + } else + if ( strcmp(argv[1], "-hw") == 0 ) { + video_flags |= SDL_HWSURFACE; + argv += 1; + argc -= 1; + } else + if ( strcmp(argv[1], "-flip") == 0 ) { + video_flags |= SDL_DOUBLEBUF; + argv += 1; + argc -= 1; + } else + if ( strcmp(argv[1], "-fullscreen") == 0 ) { + video_flags |= SDL_FULLSCREEN; + argv += 1; + argc -= 1; + } else + break; + } + + /* Initialize the display */ + screen = SDL_SetVideoMode(w, h, desired_bpp, video_flags); + if ( screen == NULL ) { + fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n", + w, h, desired_bpp, SDL_GetError()); + quit(1); + } + printf("Set%s %dx%dx%d mode\n", + screen->flags & SDL_FULLSCREEN ? " fullscreen" : "", + screen->w, screen->h, screen->format->BitsPerPixel); + printf("(video surface located in %s memory)\n", + (screen->flags&SDL_HWSURFACE) ? "video" : "system"); + if ( screen->flags & SDL_DOUBLEBUF ) { + printf("Double-buffering enabled\n"); + flip = 1; + } + + /* Set the window manager title bar */ + SDL_WM_SetCaption("SDL test window", "testwin"); + + /* Do all the drawing work */ +#ifdef BENCHMARK_SDL + then = SDL_GetTicks(); + DrawPict(screen, argv[1], speedy, flip, nofade); + now = SDL_GetTicks(); + printf("Time: %d milliseconds\n", now-then); +#else + DrawPict(screen, argv[1], speedy, flip, nofade); +#endif + SDL_Delay(delay*1000); + SDL_Quit(); + return(0); } From 2a9137296f620018f0a49df04e34f47ed86cdedb Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 5 Jul 2007 02:24:36 +0000 Subject: [PATCH 155/241] Don't initialize the audio buffer passed to the application's audio callback, since they are expected to entirely fill it with data or silence. For legacy apps that might expect the buffer to already have silence and thus may not fill the buffer in the callback, there's an environment variable to expose the old behaviour. Fixes Bugzilla #416. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402411 --- src/audio/SDL_audio.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 2e736323f..e279aad80 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -117,6 +117,13 @@ static AudioBootStrap *bootstrap[] = { }; SDL_AudioDevice *current_audio = NULL; +/* + * If non-zero, use legacy behaviour (memset the callback buffer before call). + * Changed to NOT initializing the buffer before the callback in 1.2.12. + * Set environment SDL_AUDIO_MUST_INIT_BUFFERS=1 to get old behaviour. + */ +static int must_init_callback_buffer = 0; + /* Various local functions */ int SDL_AudioInit(const char *driver_name); void SDL_AudioQuit(void); @@ -190,7 +197,10 @@ int SDLCALL SDL_RunAudio(void *audiop) stream = audio->fake_stream; } } - SDL_memset(stream, silence, stream_len); + + if ( must_init_callback_buffer ) { + SDL_memset(stream, silence, stream_len); + } if ( ! audio->paused ) { SDL_mutexP(audio->mixer_lock); @@ -300,6 +310,9 @@ int SDL_AudioInit(const char *driver_name) { SDL_AudioDevice *audio; int i = 0, idx; + const char *envr = SDL_getenv("SDL_AUDIO_MUST_INIT_BUFFERS"); + + must_init_callback_buffer = ((envr != NULL) && (SDL_atoi(envr))); /* Check to make sure we don't overwrite 'current_audio' */ if ( current_audio != NULL ) { From 268bdb1cc1adc2a8a8a341571fbd61a24226d363 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 5 Jul 2007 02:44:54 +0000 Subject: [PATCH 156/241] Fixed our own test app. :) --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402413 --- test/loopwave.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/loopwave.c b/test/loopwave.c index e685aee65..e1df747a7 100644 --- a/test/loopwave.c +++ b/test/loopwave.c @@ -43,14 +43,14 @@ void SDLCALL fillerup(void *unused, Uint8 *stream, int len) /* Go! */ while ( waveleft <= len ) { - SDL_MixAudio(stream, waveptr, waveleft, SDL_MIX_MAXVOLUME); + SDL_memcpy(stream, waveptr, waveleft); stream += waveleft; len -= waveleft; waveptr = wave.sound; waveleft = wave.soundlen; wave.soundpos = 0; } - SDL_MixAudio(stream, waveptr, len, SDL_MIX_MAXVOLUME); + SDL_memcpy(stream, waveptr, len); wave.soundpos += len; } From 2e69a8f5504aba693f5b3de79a32f671fee9b764 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 5 Jul 2007 02:53:40 +0000 Subject: [PATCH 157/241] Added notes about audio callback behaviour. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402416 --- docs.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs.html b/docs.html index 5deb10373..25cb6fd9f 100644 --- a/docs.html +++ b/docs.html @@ -52,6 +52,10 @@ SDL 1.2.12 is a minor bug fix release.

Unofficial support for the Nintendo DS platform has been added.

+

+ Audio callbacks must now initialize the entire stream: applications must write silence to the stream if they can't supply data, and not mix against the buffer, as it may be random data. + Users may set SDL_AUDIO_MUST_INIT_BUFFERS to retain the old behaviour, but apps should not depend on this environment variable: just add a memset() at the start of your audio callback instead if you need it. +

Unix Notes

From 7834147dc621f96656f3a9d04122be270f9a6ac6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 5 Jul 2007 04:51:09 +0000 Subject: [PATCH 158/241] Minor updates to the Symbian/S60 port, plus project files that weren't previously imported. Fixes Bugzilla #433. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402418 --- README.Symbian | 17 ++++------------- include/SDL_config_symbian.h | 2 +- src/video/symbian/EKA2/dsa.cpp | 7 ++++--- symbian.zip | Bin 0 -> 378899 bytes 4 files changed, 9 insertions(+), 17 deletions(-) create mode 100644 symbian.zip diff --git a/README.Symbian b/README.Symbian index d1f2a4ae0..32d925a00 100644 --- a/README.Symbian +++ b/README.Symbian @@ -14,19 +14,10 @@ abld build That produces WINSCW and ARMV5 versions of sdl.dll runtime library and sdl.lib for development. - -Eaudiolib.lib and dll are generated as well, and must be delivered -along SDL as it uses it for audio. - -There are certain problems with GCC compiler when building for -target, it may compile or binaries are buggy - please use RVCT -compiler as it works and produces far more effient code. - -Its likely that SDL application should be integrated into S60 -work and behave well there. So there is CSDL class (sdlepocapi.h) -to make this easy. If you do porting from other system, then -implement a S60 application and use CSDL class, they you may -not need to modify original SDL code at all! +The sdlexe.dll/sdlexe.lib and sdlmain.lib are for easy SDL S60 +integration, please see http://www.mbnet.fi/~mertama/sdl.html +for further info. + diff --git a/include/SDL_config_symbian.h b/include/SDL_config_symbian.h index acb49abf0..003a49157 100644 --- a/include/SDL_config_symbian.h +++ b/include/SDL_config_symbian.h @@ -135,7 +135,7 @@ typedef unsigned long long uint64_t; #define HAVE_ATOF 1 #define HAVE_STRCMP 1 #define HAVE_STRNCMP 1 -#define HAVE__STRICMP 1 +//#define HAVE__STRICMP 1 #define HAVE__STRNICMP 1 #define HAVE_SSCANF 1 #define HAVE_STDARG_H 1 diff --git a/src/video/symbian/EKA2/dsa.cpp b/src/video/symbian/EKA2/dsa.cpp index 6702075b4..07b1ab413 100644 --- a/src/video/symbian/EKA2/dsa.cpp +++ b/src/video/symbian/EKA2/dsa.cpp @@ -12,7 +12,7 @@ LOCAL_C TInt BytesPerPixel(TDisplayMode aMode) template -class CBitmapSurface : public T +NONSHARABLE_CLASS(CBitmapSurface) : public T { public: CBitmapSurface(RWsSession& aSession); @@ -830,8 +830,9 @@ TInt CDsa::SetPalette(TInt aFirst, TInt aCount, TUint32* aPalette) CDsa::CDsa(RWsSession& aSession) : - iSession(aSession), - iStateFlags(0) + iStateFlags(0), + iSession(aSession) + { // CActiveScheduler::Add(this); iCFTable[0] = CopyMem; diff --git a/symbian.zip b/symbian.zip new file mode 100644 index 0000000000000000000000000000000000000000..b3686e926b04b810dffe7887fa76f93977c8dfc7 GIT binary patch literal 378899 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 vHKzn8tTu%^p_niu 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 AL;wH) literal 0 HcmV?d00001 From c27d0b332d160a6b6206aaa225bfd0bd95567a5b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 5 Jul 2007 04:53:36 +0000 Subject: [PATCH 159/241] Added Markus Mertama to the CREDITS file for the S60 port. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402419 --- CREDITS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CREDITS b/CREDITS index ffab8be51..7a21c12a8 100644 --- a/CREDITS +++ b/CREDITS @@ -40,6 +40,8 @@ Thanks to everyone who made this possible, including: * Hannu Viitala for the EPOC port +* Marcus Mertama for the S60 port. + * Peter Valchev for nagging me about the OpenBSD port until I got it right. :) * Kent B Mein, for a place to do the IRIX port From 12157bf17d45584cdacf45f7551e33cf1b6cc311 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 5 Jul 2007 06:34:51 +0000 Subject: [PATCH 160/241] Fixed bug #436 The install-lib target should depend on the libraries that are built. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402423 --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 81a18f65d..4cc6c2e5a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -90,7 +90,7 @@ install-hdrs: $(INSTALL) -m 644 $(srcdir)/include/$$file $(includedir)/SDL/$$file; \ done $(INSTALL) -m 644 include/SDL_config.h $(includedir)/SDL/SDL_config.h -install-lib: +install-lib: $(objects) $(objects)/$(TARGET) $(objects)/$(SDLMAIN_TARGET) $(SHELL) $(auxdir)/mkinstalldirs $(libdir) $(LIBTOOL) --mode=install $(INSTALL) $(objects)/$(TARGET) $(libdir)/$(TARGET) $(INSTALL) -m 644 $(objects)/$(SDLMAIN_TARGET) $(libdir)/$(SDLMAIN_TARGET) From 432dd128e4ec7d68cdfdff43660182d530e3ef39 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 5 Jul 2007 07:11:05 +0000 Subject: [PATCH 161/241] Fixed Windows build --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402425 --- src/video/wincommon/SDL_sysevents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/wincommon/SDL_sysevents.c b/src/video/wincommon/SDL_sysevents.c index 1dc9bdb29..ac538d390 100644 --- a/src/video/wincommon/SDL_sysevents.c +++ b/src/video/wincommon/SDL_sysevents.c @@ -815,7 +815,7 @@ int SDL_RegisterApp(char *name, Uint32 style, void *hInst) /* WinCE uses the UNICODE version */ SDL_Appname = SDL_iconv_utf8_ucs2(name); #else - SDL_Appname = SDL_iconv_utf8_latin1(name); + SDL_Appname = SDL_iconv_utf8_locale(name); #endif /* _WIN32_WCE */ SDL_Appstyle = style; SDL_Instance = hInst ? hInst : SDL_GetModuleHandle(); From 4722d6e917941fc8cf13d1e1ab5108ea9eed31d9 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 6 Jul 2007 07:45:33 +0000 Subject: [PATCH 162/241] Fixed bug #322 Need to resync the keyboard state every time we set a video mode, since the code in SDL_video.c is clearing the keyboard state. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402426 --- src/video/x11/SDL_x11video.c | 55 ++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 8fb37d65d..1e2c587e0 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -1078,33 +1078,6 @@ static int X11_CreateWindow(_THIS, SDL_Surface *screen, } } - /* Update the internal keyboard state */ - X11_SetKeyboardState(SDL_Display, NULL); - - /* When the window is first mapped, ignore non-modifier keys */ - { - Uint8 *keys = SDL_GetKeyState(NULL); - for ( i = 0; i < SDLK_LAST; ++i ) { - switch (i) { - case SDLK_NUMLOCK: - case SDLK_CAPSLOCK: - case SDLK_LCTRL: - case SDLK_RCTRL: - case SDLK_LSHIFT: - case SDLK_RSHIFT: - case SDLK_LALT: - case SDLK_RALT: - case SDLK_LMETA: - case SDLK_RMETA: - case SDLK_MODE: - break; - default: - keys[i] = SDL_RELEASED; - break; - } - } - } - /* Map them both and go fullscreen, if requested */ if ( ! SDL_windowid ) { XMapWindow(SDL_Display, SDL_Window); @@ -1185,6 +1158,34 @@ SDL_Surface *X11_SetVideoMode(_THIS, SDL_Surface *current, } } + /* Update the internal keyboard state */ + X11_SetKeyboardState(SDL_Display, NULL); + + /* When the window is first mapped, ignore non-modifier keys */ + if ( !current->w && !current->h ) { + Uint8 *keys = SDL_GetKeyState(NULL); + int i; + for ( i = 0; i < SDLK_LAST; ++i ) { + switch (i) { + case SDLK_NUMLOCK: + case SDLK_CAPSLOCK: + case SDLK_LCTRL: + case SDLK_RCTRL: + case SDLK_LSHIFT: + case SDLK_RSHIFT: + case SDLK_LALT: + case SDLK_RALT: + case SDLK_LMETA: + case SDLK_RMETA: + case SDLK_MODE: + break; + default: + keys[i] = SDL_RELEASED; + break; + } + } + } + /* Set up the new mode framebuffer */ if ( ((current->w != width) || (current->h != height)) || ((saved_flags&SDL_OPENGL) != (flags&SDL_OPENGL)) ) { From 79ce9cd629e2c2706e2db88cf28ec6fb67adca17 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 6 Jul 2007 09:15:43 +0000 Subject: [PATCH 163/241] Fixed bug #382 Added horizontal scrolling support: SDL_BUTTON_WHEELLEFT (6) and SDL_BUTTON_WHEELRIGHT (7) --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402427 --- WhatsNew | 2 ++ docs.html | 3 +++ include/SDL_mouse.h | 4 ++++ src/video/bwindow/SDL_sysevents.cc | 23 +++++++++++++++++------ src/video/quartz/SDL_QuartzEvents.m | 25 ++++++++++++++++++------- 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/WhatsNew b/WhatsNew index 8538e93ac..02cdc8bd5 100644 --- a/WhatsNew +++ b/WhatsNew @@ -7,6 +7,8 @@ Version 1.0: Added SDL_VIDEO_ALLOW_SCREENSAVER to override SDL's disabling of the screensaver on Mac OS X and X11. + Added SDL_BUTTON_WHEELLEFT (6) and SDL_BUTTON_WHEELRIGHT (7) + 1.2.10: If SDL_OpenAudio() is passed zero for the desired format fields, the following environment variables will be used diff --git a/docs.html b/docs.html index 25cb6fd9f..95df93587 100644 --- a/docs.html +++ b/docs.html @@ -28,6 +28,9 @@ SDL 1.2.12 is a minor bug fix release.

Added SDL_VIDEO_ALLOW_SCREENSAVER to override SDL's disabling of the screensaver on Mac OS X, Windows, and X11.

+

+ Added SDL_BUTTON_WHEELLEFT (6) and SDL_BUTTON_WHEELRIGHT (7) +

Fixed buffer overrun crash when resampling audio rates.

diff --git a/include/SDL_mouse.h b/include/SDL_mouse.h index c2364d859..cc01e50e1 100644 --- a/include/SDL_mouse.h +++ b/include/SDL_mouse.h @@ -115,6 +115,8 @@ extern DECLSPEC int SDLCALL SDL_ShowCursor(int toggle); Button 3: Right mouse button Button 4: Mouse wheel up (may also be a real button) Button 5: Mouse wheel down (may also be a real button) + Button 6: Mouse wheel left (may also be a real button) + Button 7: Mouse wheel right (may also be a real button) */ #define SDL_BUTTON(X) (1 << ((X)-1)) #define SDL_BUTTON_LEFT 1 @@ -122,6 +124,8 @@ extern DECLSPEC int SDLCALL SDL_ShowCursor(int toggle); #define SDL_BUTTON_RIGHT 3 #define SDL_BUTTON_WHEELUP 4 #define SDL_BUTTON_WHEELDOWN 5 +#define SDL_BUTTON_WHEELLEFT 6 +#define SDL_BUTTON_WHEELRIGHT 7 #define SDL_BUTTON_LMASK SDL_BUTTON(SDL_BUTTON_LEFT) #define SDL_BUTTON_MMASK SDL_BUTTON(SDL_BUTTON_MIDDLE) #define SDL_BUTTON_RMASK SDL_BUTTON(SDL_BUTTON_RIGHT) diff --git a/src/video/bwindow/SDL_sysevents.cc b/src/video/bwindow/SDL_sysevents.cc index 2a084682b..0746897fa 100644 --- a/src/video/bwindow/SDL_sysevents.cc +++ b/src/video/bwindow/SDL_sysevents.cc @@ -294,12 +294,23 @@ SDL_WarpMouse((int)center.x*2-1,(int)center.y*2-1); float x, y; x = y = 0; if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) { - if (x < 0 || y < 0) { - SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0); - SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0); - } else if (x > 0 || y > 0) { - SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0); - SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0); + if ( y ) { + if (y < 0) { + SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0); + SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0); + } else { + SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0); + SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0); + } + } + if ( x ) { + if (x < 0) { + SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELRIGHT, 0, 0); + SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELRIGHT, 0, 0); + } else { + SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELLEFT, 0, 0); + SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELLEFT, 0, 0); + } } } break; diff --git a/src/video/quartz/SDL_QuartzEvents.m b/src/video/quartz/SDL_QuartzEvents.m index 1647570b5..f531ea804 100644 --- a/src/video/quartz/SDL_QuartzEvents.m +++ b/src/video/quartz/SDL_QuartzEvents.m @@ -932,13 +932,24 @@ void QZ_PumpEvents (_THIS) Uint8 button; dy = [ event deltaY ]; dx = [ event deltaX ]; - if ( dy > 0.0 || dx > 0.0 ) /* Scroll up */ - button = SDL_BUTTON_WHEELUP; - else /* Scroll down */ - button = SDL_BUTTON_WHEELDOWN; - /* For now, wheel is sent as a quick down+up */ - SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); - SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); + if ( dy ) { + if ( dy > 0.0 ) /* Scroll up */ + button = SDL_BUTTON_WHEELUP; + else /* Scroll down */ + button = SDL_BUTTON_WHEELDOWN; + /* For now, wheel is sent as a quick down+up */ + SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); + SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); + } + if ( dx ) { + if ( dx > 0.0 ) /* Scroll left */ + button = SDL_BUTTON_WHEELLEFT; + else /* Scroll right */ + button = SDL_BUTTON_WHEELRIGHT; + /* For now, wheel is sent as a quick down+up */ + SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); + SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); + } } break; case NSKeyUp: From cf458d63c990e9a0de635b9cd4e798539f85ed7a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 6 Jul 2007 13:32:20 +0000 Subject: [PATCH 164/241] Ugh... actually changing what buttons are returned to the application. Maybe we should wait until SDL 1.3 for horizontal scrolling support? --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402429 --- src/video/wincommon/SDL_sysevents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/wincommon/SDL_sysevents.c b/src/video/wincommon/SDL_sysevents.c index ac538d390..d1cd058b1 100644 --- a/src/video/wincommon/SDL_sysevents.c +++ b/src/video/wincommon/SDL_sysevents.c @@ -520,12 +520,12 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) break; case WM_XBUTTONDOWN: xbuttonval = GET_XBUTTON_WPARAM(wParam); - button = SDL_BUTTON_WHEELDOWN + xbuttonval; + button = SDL_BUTTON_WHEELRIGHT + xbuttonval; state = SDL_PRESSED; break; case WM_XBUTTONUP: xbuttonval = GET_XBUTTON_WPARAM(wParam); - button = SDL_BUTTON_WHEELDOWN + xbuttonval; + button = SDL_BUTTON_WHEELRIGHT + xbuttonval; state = SDL_RELEASED; break; default: From e2d89e3012db8cd9a9cbb38d832f85540da7785b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 6 Jul 2007 13:39:03 +0000 Subject: [PATCH 165/241] Reverted mousewheel support in 1.2, since it breaks binary compatibility. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402430 --- WhatsNew | 2 -- docs.html | 3 --- include/SDL_mouse.h | 4 ---- src/video/bwindow/SDL_sysevents.cc | 23 ++++++----------------- src/video/quartz/SDL_QuartzEvents.m | 25 +++++++------------------ src/video/wincommon/SDL_sysevents.c | 4 ++-- 6 files changed, 15 insertions(+), 46 deletions(-) diff --git a/WhatsNew b/WhatsNew index 02cdc8bd5..8538e93ac 100644 --- a/WhatsNew +++ b/WhatsNew @@ -7,8 +7,6 @@ Version 1.0: Added SDL_VIDEO_ALLOW_SCREENSAVER to override SDL's disabling of the screensaver on Mac OS X and X11. - Added SDL_BUTTON_WHEELLEFT (6) and SDL_BUTTON_WHEELRIGHT (7) - 1.2.10: If SDL_OpenAudio() is passed zero for the desired format fields, the following environment variables will be used diff --git a/docs.html b/docs.html index 95df93587..25cb6fd9f 100644 --- a/docs.html +++ b/docs.html @@ -28,9 +28,6 @@ SDL 1.2.12 is a minor bug fix release.

Added SDL_VIDEO_ALLOW_SCREENSAVER to override SDL's disabling of the screensaver on Mac OS X, Windows, and X11.

-

- Added SDL_BUTTON_WHEELLEFT (6) and SDL_BUTTON_WHEELRIGHT (7) -

Fixed buffer overrun crash when resampling audio rates.

diff --git a/include/SDL_mouse.h b/include/SDL_mouse.h index cc01e50e1..c2364d859 100644 --- a/include/SDL_mouse.h +++ b/include/SDL_mouse.h @@ -115,8 +115,6 @@ extern DECLSPEC int SDLCALL SDL_ShowCursor(int toggle); Button 3: Right mouse button Button 4: Mouse wheel up (may also be a real button) Button 5: Mouse wheel down (may also be a real button) - Button 6: Mouse wheel left (may also be a real button) - Button 7: Mouse wheel right (may also be a real button) */ #define SDL_BUTTON(X) (1 << ((X)-1)) #define SDL_BUTTON_LEFT 1 @@ -124,8 +122,6 @@ extern DECLSPEC int SDLCALL SDL_ShowCursor(int toggle); #define SDL_BUTTON_RIGHT 3 #define SDL_BUTTON_WHEELUP 4 #define SDL_BUTTON_WHEELDOWN 5 -#define SDL_BUTTON_WHEELLEFT 6 -#define SDL_BUTTON_WHEELRIGHT 7 #define SDL_BUTTON_LMASK SDL_BUTTON(SDL_BUTTON_LEFT) #define SDL_BUTTON_MMASK SDL_BUTTON(SDL_BUTTON_MIDDLE) #define SDL_BUTTON_RMASK SDL_BUTTON(SDL_BUTTON_RIGHT) diff --git a/src/video/bwindow/SDL_sysevents.cc b/src/video/bwindow/SDL_sysevents.cc index 0746897fa..2a084682b 100644 --- a/src/video/bwindow/SDL_sysevents.cc +++ b/src/video/bwindow/SDL_sysevents.cc @@ -294,23 +294,12 @@ SDL_WarpMouse((int)center.x*2-1,(int)center.y*2-1); float x, y; x = y = 0; if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) { - if ( y ) { - if (y < 0) { - SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0); - SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0); - } else { - SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0); - SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0); - } - } - if ( x ) { - if (x < 0) { - SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELRIGHT, 0, 0); - SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELRIGHT, 0, 0); - } else { - SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELLEFT, 0, 0); - SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELLEFT, 0, 0); - } + if (x < 0 || y < 0) { + SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0); + SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0); + } else if (x > 0 || y > 0) { + SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0); + SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0); } } break; diff --git a/src/video/quartz/SDL_QuartzEvents.m b/src/video/quartz/SDL_QuartzEvents.m index f531ea804..1647570b5 100644 --- a/src/video/quartz/SDL_QuartzEvents.m +++ b/src/video/quartz/SDL_QuartzEvents.m @@ -932,24 +932,13 @@ void QZ_PumpEvents (_THIS) Uint8 button; dy = [ event deltaY ]; dx = [ event deltaX ]; - if ( dy ) { - if ( dy > 0.0 ) /* Scroll up */ - button = SDL_BUTTON_WHEELUP; - else /* Scroll down */ - button = SDL_BUTTON_WHEELDOWN; - /* For now, wheel is sent as a quick down+up */ - SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); - SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); - } - if ( dx ) { - if ( dx > 0.0 ) /* Scroll left */ - button = SDL_BUTTON_WHEELLEFT; - else /* Scroll right */ - button = SDL_BUTTON_WHEELRIGHT; - /* For now, wheel is sent as a quick down+up */ - SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); - SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); - } + if ( dy > 0.0 || dx > 0.0 ) /* Scroll up */ + button = SDL_BUTTON_WHEELUP; + else /* Scroll down */ + button = SDL_BUTTON_WHEELDOWN; + /* For now, wheel is sent as a quick down+up */ + SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); + SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); } break; case NSKeyUp: diff --git a/src/video/wincommon/SDL_sysevents.c b/src/video/wincommon/SDL_sysevents.c index d1cd058b1..ac538d390 100644 --- a/src/video/wincommon/SDL_sysevents.c +++ b/src/video/wincommon/SDL_sysevents.c @@ -520,12 +520,12 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) break; case WM_XBUTTONDOWN: xbuttonval = GET_XBUTTON_WPARAM(wParam); - button = SDL_BUTTON_WHEELRIGHT + xbuttonval; + button = SDL_BUTTON_WHEELDOWN + xbuttonval; state = SDL_PRESSED; break; case WM_XBUTTONUP: xbuttonval = GET_XBUTTON_WPARAM(wParam); - button = SDL_BUTTON_WHEELRIGHT + xbuttonval; + button = SDL_BUTTON_WHEELDOWN + xbuttonval; state = SDL_RELEASED; break; default: From 1ed61fec32eecf11766cab5eba49e1b887219b25 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 7 Jul 2007 19:20:28 +0000 Subject: [PATCH 166/241] Fixed bug #360 Fixed fullscreen video modes and improved the mouse grab code. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402433 --- src/video/bwindow/SDL_BView.h | 39 ++++++++++++-- src/video/bwindow/SDL_BWin.h | 28 ++++++++++ src/video/bwindow/SDL_sysevents.cc | 85 +++++++++++++++--------------- src/video/bwindow/SDL_sysmouse.cc | 17 +++--- src/video/bwindow/SDL_sysvideo.cc | 11 ++-- src/video/bwindow/SDL_sysyuv.cc | 8 ++- 6 files changed, 128 insertions(+), 60 deletions(-) diff --git a/src/video/bwindow/SDL_BView.h b/src/video/bwindow/SDL_BView.h index f78d17216..564d064ff 100644 --- a/src/video/bwindow/SDL_BView.h +++ b/src/video/bwindow/SDL_BView.h @@ -37,12 +37,26 @@ public: BView(frame, "SDL View", B_FOLLOW_ALL_SIDES, (B_WILL_DRAW|B_FRAME_EVENTS)) { image = NULL; + xoff = yoff = 0; SetViewColor(0,0,0,0); SetHighColor(0,0,0,0); } virtual ~SDL_BView() { SetBitmap(NULL); } + /* Set drawing offsets for fullscreen mode */ + virtual void SetXYOffset(int x, int y) { + xoff = x; + yoff = y; + } + virtual void GetXYOffset(int &x, int &y) { + x = xoff; + y = yoff; + } + virtual void GetXYOffset(float &x, float &y) { + x = (float)xoff; + y = (float)yoff; + } /* The view changed size. If it means we're in fullscreen, we * draw a nice black box in the entire view to get black borders. */ @@ -52,14 +66,14 @@ public: bounds.right = width; bounds.bottom = height; /* Fill the entire view with black */ -// FillRect(bounds, B_SOLID_HIGH); + FillRect(bounds, B_SOLID_HIGH); /* And if there's an image, redraw it. */ if( image ) { bounds = image->Bounds(); Draw(bounds); } } - + /* Drawing portion of this complete breakfast. :) */ virtual void SetBitmap(BBitmap *bitmap) { if ( image ) { @@ -69,17 +83,34 @@ public: } virtual void Draw(BRect updateRect) { if ( image ) { - DrawBitmap(image, updateRect, updateRect); + if(xoff || yoff) { + BRect dest; + dest.top = updateRect.top + yoff; + dest.left = updateRect.left + xoff; + dest.bottom = updateRect.bottom + yoff; + dest.right = updateRect.right + xoff; + DrawBitmap(image, updateRect, dest); + } else { + DrawBitmap(image, updateRect, updateRect); + } } } virtual void DrawAsync(BRect updateRect) { - if ( image ) { + if(xoff || yoff) { + BRect dest; + dest.top = updateRect.top + yoff; + dest.left = updateRect.left + xoff; + dest.bottom = updateRect.bottom + yoff; + dest.right = updateRect.right + xoff;; + DrawBitmapAsync(image, updateRect, dest); + } else { DrawBitmapAsync(image, updateRect, updateRect); } } private: BBitmap *image; + int xoff, yoff; }; #endif /* _SDL_BView_h */ diff --git a/src/video/bwindow/SDL_BWin.h b/src/video/bwindow/SDL_BWin.h index ea1783690..9bfa9d4df 100644 --- a/src/video/bwindow/SDL_BWin.h +++ b/src/video/bwindow/SDL_BWin.h @@ -149,6 +149,34 @@ public: virtual void SetBitmap(BBitmap *bitmap) { SDL_View->SetBitmap(bitmap); } + virtual void SetXYOffset(int x, int y) { +#if SDL_VIDEO_OPENGL + if ( the_view == SDL_GLView ) { + return; + } +#endif + SDL_View->SetXYOffset(x, y); + } + virtual void GetXYOffset(int &x, int &y) { +#if SDL_VIDEO_OPENGL + if ( the_view == SDL_GLView ) { + x = 0; + y = 0; + return; + } +#endif + SDL_View->GetXYOffset(x, y); + } + virtual void GetXYOffset(float &x, float &y) { +#if SDL_VIDEO_OPENGL + if ( the_view == SDL_GLView ) { + x = 0.0f; + y = 0.0f; + return; + } +#endif + SDL_View->GetXYOffset(x, y); + } virtual bool BeginDraw(void) { return(Lock()); } diff --git a/src/video/bwindow/SDL_sysevents.cc b/src/video/bwindow/SDL_sysevents.cc index 2a084682b..f011c57b2 100644 --- a/src/video/bwindow/SDL_sysevents.cc +++ b/src/video/bwindow/SDL_sysevents.cc @@ -166,62 +166,61 @@ void SDL_BWin::DispatchMessage(BMessage *msg, BHandler *target) BPoint where; int32 transit; if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) { + int x, y; -//BeSman: I need another method for cursor catching !!! -if(view->input_grab != SDL_GRAB_OFF) -{ - BPoint center; - center.x = (SDL_VideoSurface->w/2); - center.y = (SDL_VideoSurface->h/2); - BPoint delta = where - center; -if(delta.x > center.x) -SDL_WarpMouse((int)center.x*2,(int)where.y); + GetXYOffset(x, y); + x = (int)where.x - x; + y = (int)where.y - y; -if(delta.x < -center.x) -SDL_WarpMouse(0,(int)where.y); - -if(delta.y > center.y) -SDL_WarpMouse((int)where.x,(int)center.y*2); - -if(delta.y < -center.y) -SDL_WarpMouse((int)where.x,0); - - -if((delta.x-1 < -center.x)&&(delta.y-1 < -center.y)) -SDL_WarpMouse(1,1); - -if((delta.x-1 < -center.x)&&(delta.y+1 > center.y)) -SDL_WarpMouse(1,(int)center.y*2-1); - -if((delta.x+1 > center.x)&&(delta.y-1 < -center.y)) -SDL_WarpMouse((int)center.x*2-1,1); - -if((delta.x+1 > center.x)&&(delta.y+1 > center.y)) -SDL_WarpMouse((int)center.x*2-1,(int)center.y*2-1); - -} + //BeSman: I need another method for cursor catching !!! + if (view->input_grab != SDL_GRAB_OFF) + { + bool clipped = false; + if ( x < 0 ) { + x = 0; + clipped = true; + } else if ( x >= SDL_VideoSurface->w ) { + x = (SDL_VideoSurface->w-1); + clipped = true; + } + if ( y < 0 ) { + y = 0; + clipped = true; + } else if ( y >= SDL_VideoSurface->h ) { + y = (SDL_VideoSurface->h-1); + clipped = true; + } + if ( clipped ) { + BPoint edge; + GetXYOffset(edge.x, edge.y); + edge.x += x; + edge.y += y; + ConvertToScreen(&edge); + set_mouse_position((int)edge.x, (int)edge.y); + } + transit = B_INSIDE_VIEW; + } if (transit == B_EXITED_VIEW) { if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); - // be_app->SetCursor(B_HAND_CURSOR); + be_app->SetCursor(B_HAND_CURSOR); } } else { - - int x, y; - if ( ! (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { + if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); SDL_SetCursor(NULL); } - x = (int)where.x; - y = (int)where.y; if ( mouse_relative ) { - BPoint center; - center.x = (SDL_VideoSurface->w/2); - center.y = (SDL_VideoSurface->h/2); - x -= (int)center.x; - y -= (int)center.y; + int half_w = (SDL_VideoSurface->w/2); + int half_h = (SDL_VideoSurface->h/2); + x -= half_w; + y -= half_h; if ( x || y ) { + BPoint center; + GetXYOffset(center.x, center.y); + center.x += half_w; + center.y += half_h; ConvertToScreen(¢er); set_mouse_position((int)center.x, (int)center.y); SDL_PrivateMouseMotion(0, 1, x, y); diff --git a/src/video/bwindow/SDL_sysmouse.cc b/src/video/bwindow/SDL_sysmouse.cc index 093814f03..232186d52 100644 --- a/src/video/bwindow/SDL_sysmouse.cc +++ b/src/video/bwindow/SDL_sysmouse.cc @@ -128,15 +128,14 @@ void BE_FreeWMCursor(_THIS, WMcursor *cursor) /* Implementation by Christian Bauer */ void BE_WarpWMCursor(_THIS, Uint16 x, Uint16 y) { - if (_this->screen && (_this->screen->flags & SDL_FULLSCREEN)) { - SDL_PrivateMouseMotion(0, 0, x, y); - } else { - BPoint pt(x, y); - SDL_Win->Lock(); - SDL_Win->ConvertToScreen(&pt); - SDL_Win->Unlock(); - set_mouse_position((int32)pt.x, (int32)pt.y); - } + BPoint pt; + SDL_Win->GetXYOffset(pt.x, pt.y); + pt.x += x; + pt.y += y; + SDL_Win->Lock(); + SDL_Win->ConvertToScreen(&pt); + SDL_Win->Unlock(); + set_mouse_position((int32)pt.x, (int32)pt.y); } /* Check to see if we need to enter or leave mouse relative mode */ diff --git a/src/video/bwindow/SDL_sysvideo.cc b/src/video/bwindow/SDL_sysvideo.cc index 7ee02c3e0..59edec638 100644 --- a/src/video/bwindow/SDL_sysvideo.cc +++ b/src/video/bwindow/SDL_sysvideo.cc @@ -366,9 +366,8 @@ static bool BE_FindClosestFSMode(_THIS, int width, int height, int bpp, --i; /* We went too far */ } -/* BeSman::We dont want to use a Desktop resolution */ -// width = modes[i]->w; -// height = modes[i]->h; + width = modes[i]->w; + height = modes[i]->h; bscreen.GetModeList(&dmodes, &nmodes); for ( i = 0; i < nmodes; ++i ) { @@ -455,6 +454,12 @@ static int BE_SetFullScreen(_THIS, SDL_Surface *screen, int fullscreen) cx = (bounds.IntegerWidth() - width)/2; cy = (bounds.IntegerHeight() - height)/2; + if ( fullscreen ) { + /* Set offset for drawing */ + SDL_Win->SetXYOffset(cx, cy); + } else { + SDL_Win->SetXYOffset(0, 0); + } if ( ! needs_unlock || was_fullscreen ) { /* Center the window the first time */ SDL_Win->MoveTo(cx, cy); diff --git a/src/video/bwindow/SDL_sysyuv.cc b/src/video/bwindow/SDL_sysyuv.cc index 64213af70..557a120ed 100644 --- a/src/video/bwindow/SDL_sysyuv.cc +++ b/src/video/bwindow/SDL_sysyuv.cc @@ -274,7 +274,13 @@ int BE_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* src, SDL_Rect *d return 0; } BView * bview = overlay->hwdata->bview; - bview->MoveTo(dst->x,dst->y); + if (SDL_Win->IsFullScreen()) { + int left,top; + SDL_Win->GetXYOffset(left,top); + bview->MoveTo(left+dst->x,top+dst->y); + } else { + bview->MoveTo(dst->x,dst->y); + } bview->ResizeTo(dst->w,dst->h); bview->Flush(); if (overlay->hwdata->first_display) { From 69a0d935d9ca383d02ad79efe32f3605b1ee9daa Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 7 Jul 2007 19:22:27 +0000 Subject: [PATCH 167/241] Use GL direct updates when possible --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402434 --- src/video/bwindow/SDL_BWin.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/bwindow/SDL_BWin.h b/src/video/bwindow/SDL_BWin.h index 9bfa9d4df..952d5a248 100644 --- a/src/video/bwindow/SDL_BWin.h +++ b/src/video/bwindow/SDL_BWin.h @@ -113,6 +113,7 @@ public: SDL_GLView = new BGLView(Bounds(), "SDL GLView", B_FOLLOW_ALL_SIDES, (B_WILL_DRAW|B_FRAME_EVENTS), gl_flags); + SDL_GLView->EnableDirectMode(true); } if ( the_view != SDL_GLView ) { if ( the_view ) { From f5f620d18304c6b9dfd306d1e52cb523d42a5ddb Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 8 Jul 2007 01:35:50 +0000 Subject: [PATCH 168/241] Fixed compiler warning (gcc w/ -Wall) for unused variable, and checked for error return code too. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402435 --- src/video/x11/SDL_x11video.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 1e2c587e0..61a014496 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -538,8 +538,17 @@ static void create_aux_windows(_THIS) whenever we re-create an IC. */ unsigned long mask = 0; char *ret = pXGetICValues(SDL_IC, XNFilterEvents, &mask, NULL); - XSelectInput(SDL_Display, WMwindow, app_event_mask | mask); - XSetICFocus(SDL_IC); + if (ret != NULL) { + XUnsetICFocus(SDL_IC); + XDestroyIC(SDL_IC); + SDL_IC = NULL; + SDL_SetError("no input context could be created"); + XCloseIM(SDL_IM); + SDL_IM = NULL; + } else { + XSelectInput(SDL_Display, WMwindow, app_event_mask | mask); + XSetICFocus(SDL_IC); + } } } } From 2a5d0ac5c9993593c1ca7ea5c2afcfd722e6dd1e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 8 Jul 2007 01:36:16 +0000 Subject: [PATCH 169/241] Fixed compiler warning (gcc w/ -Wall) for using getpid() and kill() without their proper headers included. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402436 --- src/audio/arts/SDL_artsaudio.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/audio/arts/SDL_artsaudio.c b/src/audio/arts/SDL_artsaudio.c index 6581e97cb..204e582d2 100644 --- a/src/audio/arts/SDL_artsaudio.c +++ b/src/audio/arts/SDL_artsaudio.c @@ -23,6 +23,11 @@ /* Allow access to a raw mixing buffer */ +#ifdef HAVE_SIGNAL_H +#include +#endif +#include + #include "SDL_timer.h" #include "SDL_audio.h" #include "../SDL_audiomem.h" From f6d3643ebb012ae307db4f10c82ea91ef7a4ea23 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 8 Jul 2007 01:50:26 +0000 Subject: [PATCH 170/241] Clear the NOFRAME and RESIZABLE flags in the X11 target before setting their new values, so multiple calls to SetVideoMode() that toggle these will end up with the right data. Fixes Bugzilla #441. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402438 --- src/video/x11/SDL_x11video.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 61a014496..7fde77eb4 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -1203,6 +1203,9 @@ SDL_Surface *X11_SetVideoMode(_THIS, SDL_Surface *current, current->pitch = SDL_CalculatePitch(current); X11_ResizeImage(this, current, flags); } + + /* Clear these flags and set them only if they are in the new set. */ + current->flags &= ~(SDL_RESIZABLE|SDL_NOFRAME); current->flags |= (flags&(SDL_RESIZABLE|SDL_NOFRAME)); done: From 6a51107ae1d3b49879d445b99f6395089eb804d2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 8 Jul 2007 01:55:46 +0000 Subject: [PATCH 171/241] This looks like it might hit Bugzilla #441, too, so we'll play it safe. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402439 --- src/video/nanox/SDL_nxvideo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/video/nanox/SDL_nxvideo.c b/src/video/nanox/SDL_nxvideo.c index 12df7e2b6..89acb2a85 100644 --- a/src/video/nanox/SDL_nxvideo.c +++ b/src/video/nanox/SDL_nxvideo.c @@ -380,6 +380,9 @@ SDL_Surface * NX_SetVideoMode (_THIS, SDL_Surface * current, current -> pitch = SDL_CalculatePitch (current) ; NX_ResizeImage (this, current, flags) ; } + + /* Clear these flags and set them only if they are in the new set. */ + current -> flags &= ~(SDL_RESIZABLE|SDL_NOFRAME); current -> flags |= (flags & (SDL_RESIZABLE | SDL_NOFRAME)) ; done: From c0116871a66d9a4664769d9c62816d364ba0fd2a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 8 Jul 2007 04:07:36 +0000 Subject: [PATCH 172/241] Fixed typo... did somebody not compile this before submitting a patch? --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402440 --- src/video/directfb/SDL_DirectFB_yuv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/directfb/SDL_DirectFB_yuv.c b/src/video/directfb/SDL_DirectFB_yuv.c index ad0910e98..6366254ce 100644 --- a/src/video/directfb/SDL_DirectFB_yuv.c +++ b/src/video/directfb/SDL_DirectFB_yuv.c @@ -122,7 +122,7 @@ static DFBResult CreateYUVSurface(_THIS, struct private_yuvhwdata *hwdata, ret = layer->SetCooperativeLevel (layer, DLSCL_ADMINISTRATIVE); if (ret) { - SetDirectFBError("IDirectFBDisplayLayer::SetCooperativeLevel() failed", ret); + SetDirectFBerror("IDirectFBDisplayLayer::SetCooperativeLevel() failed", ret); layer->Release (layer); return ret; } From 89fa633402e1dc41e2bbd059c75b2a00df4b2fa1 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 8 Jul 2007 05:58:16 +0000 Subject: [PATCH 173/241] Fixed configure warning about datarootdir --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402441 --- Makefile.in | 59 +++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/Makefile.in b/Makefile.in index 4cc6c2e5a..dd281351c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -6,11 +6,12 @@ objects = build depend = build-deps prefix = @prefix@ exec_prefix = @exec_prefix@ -bindir = $(DESTDIR)@bindir@ -libdir = $(DESTDIR)@libdir@ -includedir = $(DESTDIR)@includedir@ -datadir = $(DESTDIR)@datadir@ -mandir = $(DESTDIR)@mandir@ +bindir = @bindir@ +libdir = @libdir@ +includedir = @includedir@ +datarootdir = @datarootdir@ +datadir = @datadir@ +mandir = @mandir@ auxdir = @ac_aux_dir@ distpath = $(srcdir)/.. distdir = SDL-@SDL_VERSION@ @@ -46,7 +47,7 @@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_RELEASE = @LT_RELEASE@ LT_REVISION = @LT_REVISION@ -LT_LDFLAGS = -no-undefined -rpath $(libdir) -release $(LT_RELEASE) -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) +LT_LDFLAGS = -no-undefined -rpath $(DESTDIR)$(libdir) -release $(LT_RELEASE) -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) all: $(srcdir)/configure Makefile $(objects) $(objects)/$(TARGET) $(objects)/$(SDLMAIN_TARGET) @@ -82,49 +83,49 @@ $(objects)/$(SDLMAIN_TARGET): $(SDLMAIN_OBJECTS) install: all install-bin install-hdrs install-lib install-data install-man install-bin: - $(SHELL) $(auxdir)/mkinstalldirs $(bindir) - $(INSTALL) -m 755 sdl-config $(bindir)/sdl-config + $(SHELL) $(auxdir)/mkinstalldirs $(DESTDIR)$(bindir) + $(INSTALL) -m 755 sdl-config $(DESTDIR)$(bindir)/sdl-config install-hdrs: - $(SHELL) $(auxdir)/mkinstalldirs $(includedir)/SDL + $(SHELL) $(auxdir)/mkinstalldirs $(DESTDIR)$(includedir)/SDL for file in $(HDRS); do \ - $(INSTALL) -m 644 $(srcdir)/include/$$file $(includedir)/SDL/$$file; \ + $(INSTALL) -m 644 $(srcdir)/include/$$file $(DESTDIR)$(includedir)/SDL/$$file; \ done - $(INSTALL) -m 644 include/SDL_config.h $(includedir)/SDL/SDL_config.h + $(INSTALL) -m 644 include/SDL_config.h $(DESTDIR)$(includedir)/SDL/SDL_config.h install-lib: $(objects) $(objects)/$(TARGET) $(objects)/$(SDLMAIN_TARGET) - $(SHELL) $(auxdir)/mkinstalldirs $(libdir) - $(LIBTOOL) --mode=install $(INSTALL) $(objects)/$(TARGET) $(libdir)/$(TARGET) - $(INSTALL) -m 644 $(objects)/$(SDLMAIN_TARGET) $(libdir)/$(SDLMAIN_TARGET) - $(RANLIB) $(libdir)/$(SDLMAIN_TARGET) + $(SHELL) $(auxdir)/mkinstalldirs $(DESTDIR)$(libdir) + $(LIBTOOL) --mode=install $(INSTALL) $(objects)/$(TARGET) $(DESTDIR)$(libdir)/$(TARGET) + $(INSTALL) -m 644 $(objects)/$(SDLMAIN_TARGET) $(DESTDIR)$(libdir)/$(SDLMAIN_TARGET) + $(RANLIB) $(DESTDIR)$(libdir)/$(SDLMAIN_TARGET) install-data: - $(SHELL) $(auxdir)/mkinstalldirs $(datadir)/aclocal - $(INSTALL) -m 644 $(srcdir)/sdl.m4 $(datadir)/aclocal/sdl.m4 - $(SHELL) $(auxdir)/mkinstalldirs $(libdir)/pkgconfig - $(INSTALL) -m 644 sdl.pc $(libdir)/pkgconfig + $(SHELL) $(auxdir)/mkinstalldirs $(DESTDIR)$(datadir)/aclocal + $(INSTALL) -m 644 $(srcdir)/sdl.m4 $(DESTDIR)$(datadir)/aclocal/sdl.m4 + $(SHELL) $(auxdir)/mkinstalldirs $(DESTDIR)$(libdir)/pkgconfig + $(INSTALL) -m 644 sdl.pc $(DESTDIR)$(libdir)/pkgconfig install-man: - $(SHELL) $(auxdir)/mkinstalldirs $(mandir)/man3 + $(SHELL) $(auxdir)/mkinstalldirs $(DESTDIR)$(mandir)/man3 for src in $(srcdir)/docs/man3/*.3; do \ file=`echo $$src | sed -e 's|^.*/||'`; \ - $(INSTALL) -m 644 $$src $(mandir)/man3/$$file; \ + $(INSTALL) -m 644 $$src $(DESTDIR)$(mandir)/man3/$$file; \ done uninstall: uninstall-bin uninstall-hdrs uninstall-lib uninstall-data uninstall-man uninstall-bin: - rm -f $(bindir)/sdl-config + rm -f $(DESTDIR)$(bindir)/sdl-config uninstall-hdrs: for file in $(HDRS); do \ - rm -f $(includedir)/SDL/$$file; \ + rm -f $(DESTDIR)$(includedir)/SDL/$$file; \ done - rm -f $(includedir)/SDL/SDL_config.h - -rmdir $(includedir)/SDL + rm -f $(DESTDIR)$(includedir)/SDL/SDL_config.h + -rmdir $(DESTDIR)$(includedir)/SDL uninstall-lib: - $(LIBTOOL) --mode=uninstall rm -f $(libdir)/$(TARGET) - rm -f $(libdir)/$(SDLMAIN_TARGET) + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$(TARGET) + rm -f $(DESTDIR)$(libdir)/$(SDLMAIN_TARGET) uninstall-data: - rm -f $(datadir)/aclocal/sdl.m4 + rm -f $(DESTDIR)$(datadir)/aclocal/sdl.m4 uninstall-man: for src in $(srcdir)/docs/man3/*.3; do \ file=`echo $$src | sed -e 's|^.*/||'`; \ - rm -f $(mandir)/man3/$$file; \ + rm -f $(DESTDIR)$(mandir)/man3/$$file; \ done clean: From d3ad0e277e9f1e8a19741a8be5944c5a2031ffff Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 8 Jul 2007 14:24:27 +0000 Subject: [PATCH 174/241] Fixed bug #451 SDL_memset4 copies a 32-bit value, not an 8-bit value. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402443 --- include/SDL_stdinc.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index f86eb04bb..891a9ac88 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -238,10 +238,7 @@ extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, extern DECLSPEC void * SDLCALL SDL_memset(void *dst, int c, size_t len); #endif -/* We can count on memset existing on Mac OS X and being well-tuned. */ -#if defined(__MACH__) && defined(__APPLE__) -#define SDL_memset4(dst, val, len) memset(dst, val, (len)*4) -#elif defined(__GNUC__) && defined(i386) +#if defined(__GNUC__) && defined(i386) #define SDL_memset4(dst, val, len) \ do { \ int u0, u1, u2; \ From bd653f815005e5623a124d7f3ce7afd304f62160 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 8 Jul 2007 20:38:36 +0000 Subject: [PATCH 175/241] Fixed bug #437 Some X servers advertise the DGA extension don't support DGA1 anymore. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402445 --- docs.html | 3 +++ src/video/dga/SDL_dgaevents.c | 3 --- src/video/x11/SDL_x11dga.c | 49 +++++++++++++++++++---------------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/docs.html b/docs.html index 25cb6fd9f..c26eca74b 100644 --- a/docs.html +++ b/docs.html @@ -61,6 +61,9 @@ SDL 1.2.12 is a minor bug fix release.

Unix Notes

+

+ Fixed detection of X11 DGA mouse support. +

Improved XIM support for asian character sets.

diff --git a/src/video/dga/SDL_dgaevents.c b/src/video/dga/SDL_dgaevents.c index eaf2c230e..11bd21efa 100644 --- a/src/video/dga/SDL_dgaevents.c +++ b/src/video/dga/SDL_dgaevents.c @@ -129,9 +129,6 @@ printf("KeyRelease (X11 keycode = 0x%X)\n", xkey.keycode); posted = SDL_PrivateKeyboard(SDL_RELEASED, &keysym); } break; - - break; - } return(posted); } diff --git a/src/video/x11/SDL_x11dga.c b/src/video/x11/SDL_x11dga.c index 96d9aa9b9..d68e7d93e 100644 --- a/src/video/x11/SDL_x11dga.c +++ b/src/video/x11/SDL_x11dga.c @@ -22,8 +22,7 @@ #include "SDL_config.h" /* This is currently only used to enable DGA mouse. - The new fullscreen code makes it very difficult to handle DGA dynamically. - There will be a completely separate DGA driver that is fullscreen-only. + There is a completely separate DGA driver that is fullscreen-only. */ #include "SDL_video.h" @@ -36,24 +35,33 @@ int dga_event, dga_error = -1; void X11_EnableDGAMouse(_THIS) { #if SDL_VIDEO_DRIVER_X11_DGAMOUSE - int dga_major, dga_minor; - int use_dgamouse; - const char *env_use_dgamouse; + static int use_dgamouse = -1; /* Check configuration to see if we should use DGA mouse */ - use_dgamouse = 1; - env_use_dgamouse = SDL_getenv("SDL_VIDEO_X11_DGAMOUSE"); - if ( env_use_dgamouse ) { - use_dgamouse = atoi(env_use_dgamouse); + if ( use_dgamouse < 0 ) { + int dga_major, dga_minor; + int dga_flags; + const char *env_use_dgamouse; + + use_dgamouse = 1; + env_use_dgamouse = SDL_getenv("SDL_VIDEO_X11_DGAMOUSE"); + if ( env_use_dgamouse ) { + use_dgamouse = SDL_atoi(env_use_dgamouse); + } + /* Check for buggy X servers */ + if ( use_dgamouse && BUGGY_XFREE86(==, 4000) ) { + use_dgamouse = 0; + } + if ( !use_dgamouse || !local_X11 || + !SDL_NAME(XF86DGAQueryExtension)(SDL_Display, &dga_event, &dga_error) || + !SDL_NAME(XF86DGAQueryVersion)(SDL_Display, &dga_major, &dga_minor) || + !SDL_NAME(XF86DGAQueryDirectVideo)(SDL_Display, SDL_Screen, &dga_flags) || + !(dga_flags & XF86DGADirectPresent) ) { + use_dgamouse = 0; + } } - /* Check for buggy X servers */ - if ( use_dgamouse && BUGGY_XFREE86(==, 4000) ) { - use_dgamouse = 0; - } - /* Only use DGA mouse if the cursor is not showing (in relative mode) */ - if ( use_dgamouse && local_X11 && !(using_dga & DGA_MOUSE) && - SDL_NAME(XF86DGAQueryExtension)(SDL_Display, &dga_event, &dga_error) && - SDL_NAME(XF86DGAQueryVersion)(SDL_Display, &dga_major, &dga_minor) ) { + + if ( use_dgamouse && !(using_dga & DGA_MOUSE) ) { if ( SDL_NAME(XF86DGADirectVideo)(SDL_Display, SDL_Screen, XF86DGADirectMouse) ) { using_dga |= DGA_MOUSE; } @@ -65,13 +73,8 @@ void X11_EnableDGAMouse(_THIS) void X11_CheckDGAMouse(_THIS) { #if SDL_VIDEO_DRIVER_X11_DGAMOUSE - int flags; - if ( using_dga & DGA_MOUSE ) { - SDL_NAME(XF86DGAQueryDirectVideo)(SDL_Display, SDL_Screen, &flags); - if ( ! (flags & XF86DGADirectMouse) ) { - SDL_NAME(XF86DGADirectVideo)(SDL_Display,SDL_Screen,XF86DGADirectMouse); - } + SDL_NAME(XF86DGADirectVideo)(SDL_Display,SDL_Screen,XF86DGADirectMouse); } #endif } From ee60355872b5ab2af607a35855c568270365ac6e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 8 Jul 2007 22:14:37 +0000 Subject: [PATCH 176/241] Merged FreeBSD joystick patch --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402446 --- src/joystick/bsd/SDL_sysjoystick.c | 61 ++++++++++++++++++------------ 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/src/joystick/bsd/SDL_sysjoystick.c b/src/joystick/bsd/SDL_sysjoystick.c index 0c7043aca..926899db6 100644 --- a/src/joystick/bsd/SDL_sysjoystick.c +++ b/src/joystick/bsd/SDL_sysjoystick.c @@ -123,6 +123,12 @@ struct joystick_hwdata { struct report_desc *repdesc; struct report inreport; int axis_map[JOYAXE_count]; /* map present JOYAXE_* to 0,1,..*/ + int x; + int y; + int xmin; + int ymin; + int xmax; + int ymax; }; static char *joynames[MAX_JOYS]; @@ -257,6 +263,12 @@ SDL_SYS_JoystickOpen(SDL_Joystick *joy) joy->hwdata = hw; hw->fd = fd; hw->path = strdup(path); + hw->x = 0; + hw->y = 0; + hw->xmin = 0xffff; + hw->ymin = 0xffff; + hw->xmax = 0; + hw->ymax = 0; if (! SDL_strncmp(path, "/dev/joy", 8)) { hw->type = BSDJOY_JOY; joy->naxes = 2; @@ -380,43 +392,42 @@ SDL_SYS_JoystickUpdate(SDL_Joystick *joy) #if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H struct joystick gameport; - static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0; if (joy->hwdata->type == BSDJOY_JOY) { if (read(joy->hwdata->fd, &gameport, sizeof gameport) != sizeof gameport) return; - if (abs(x - gameport.x) > 8) { - x = gameport.x; - if (x < xmin) { - xmin = x; + if (abs(joy->hwdata->x - gameport.x) > 8) { + joy->hwdata->x = gameport.x; + if (joy->hwdata->x < joy->hwdata->xmin) { + joy->hwdata->xmin = joy->hwdata->x; } - if (x > xmax) { - xmax = x; + if (joy->hwdata->x > joy->hwdata->xmax) { + joy->hwdata->xmax = joy->hwdata->x; } - if (xmin == xmax) { - xmin--; - xmax++; + if (joy->hwdata->xmin == joy->hwdata->xmax) { + joy->hwdata->xmin--; + joy->hwdata->xmax++; } - v = (Sint32)x; - v -= (xmax + xmin + 1)/2; - v *= 32768/((xmax - xmin + 1)/2); + v = (Sint32)joy->hwdata->x; + v -= (joy->hwdata->xmax + joy->hwdata->xmin + 1)/2; + v *= 32768/((joy->hwdata->xmax - joy->hwdata->xmin + 1)/2); SDL_PrivateJoystickAxis(joy, 0, v); } - if (abs(y - gameport.y) > 8) { - y = gameport.y; - if (y < ymin) { - ymin = y; + if (abs(joy->hwdata->y - gameport.y) > 8) { + joy->hwdata->y = gameport.y; + if (joy->hwdata->y < joy->hwdata->ymin) { + joy->hwdata->ymin = joy->hwdata->y; } - if (y > ymax) { - ymax = y; + if (joy->hwdata->y > joy->hwdata->ymax) { + joy->hwdata->ymax = joy->hwdata->y; } - if (ymin == ymax) { - ymin--; - ymax++; + if (joy->hwdata->ymin == joy->hwdata->ymax) { + joy->hwdata->ymin--; + joy->hwdata->ymax++; } - v = (Sint32)y; - v -= (ymax + ymin + 1)/2; - v *= 32768/((ymax - ymin + 1)/2); + v = (Sint32)joy->hwdata->y; + v -= (joy->hwdata->ymax + joy->hwdata->ymin + 1)/2; + v *= 32768/((joy->hwdata->ymax - joy->hwdata->ymin + 1)/2); SDL_PrivateJoystickAxis(joy, 1, v); } if (gameport.b1 != joy->buttons[0]) { From 619068cfc965b65f5c07f99a89ed9f4906519bc1 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 8 Jul 2007 22:58:33 +0000 Subject: [PATCH 177/241] Applied patch from OpenBSD ports package --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402447 --- src/video/x11/SDL_x11gl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/x11/SDL_x11gl.c b/src/video/x11/SDL_x11gl.c index 7e89d1707..dcf808097 100644 --- a/src/video/x11/SDL_x11gl.c +++ b/src/video/x11/SDL_x11gl.c @@ -33,6 +33,8 @@ #define DEFAULT_OPENGL "/usr/X11R6/lib/libGL.1.dylib" #elif defined(__QNXNTO__) #define DEFAULT_OPENGL "libGL.so.3" +#elif defined(__OpenBSD__) +#define DEFAULT_OPENGL "libGL.so.4.0" #else #define DEFAULT_OPENGL "libGL.so.1" #endif From 40849ebe5f5721a34b6501a46ec57791583ddd90 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 9 Jul 2007 00:25:31 +0000 Subject: [PATCH 178/241] Reverted patch in revision #3139, since it changes behaviour, which isn't good at this stage of 1.2. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402448 --- src/audio/SDL_audio.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index e279aad80..e0102ad00 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -117,13 +117,6 @@ static AudioBootStrap *bootstrap[] = { }; SDL_AudioDevice *current_audio = NULL; -/* - * If non-zero, use legacy behaviour (memset the callback buffer before call). - * Changed to NOT initializing the buffer before the callback in 1.2.12. - * Set environment SDL_AUDIO_MUST_INIT_BUFFERS=1 to get old behaviour. - */ -static int must_init_callback_buffer = 0; - /* Various local functions */ int SDL_AudioInit(const char *driver_name); void SDL_AudioQuit(void); @@ -198,9 +191,7 @@ int SDLCALL SDL_RunAudio(void *audiop) } } - if ( must_init_callback_buffer ) { - SDL_memset(stream, silence, stream_len); - } + SDL_memset(stream, silence, stream_len); if ( ! audio->paused ) { SDL_mutexP(audio->mixer_lock); @@ -310,9 +301,6 @@ int SDL_AudioInit(const char *driver_name) { SDL_AudioDevice *audio; int i = 0, idx; - const char *envr = SDL_getenv("SDL_AUDIO_MUST_INIT_BUFFERS"); - - must_init_callback_buffer = ((envr != NULL) && (SDL_atoi(envr))); /* Check to make sure we don't overwrite 'current_audio' */ if ( current_audio != NULL ) { From 31d16a05424502bb329682ee10cbf2a68ffa20a6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 9 Jul 2007 00:26:21 +0000 Subject: [PATCH 179/241] Removed note about initializing mixing buffers. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402449 --- docs.html | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs.html b/docs.html index c26eca74b..5bd2271bf 100644 --- a/docs.html +++ b/docs.html @@ -52,10 +52,6 @@ SDL 1.2.12 is a minor bug fix release.

Unofficial support for the Nintendo DS platform has been added.

-

- Audio callbacks must now initialize the entire stream: applications must write silence to the stream if they can't supply data, and not mix against the buffer, as it may be random data. - Users may set SDL_AUDIO_MUST_INIT_BUFFERS to retain the old behaviour, but apps should not depend on this environment variable: just add a memset() at the start of your audio callback instead if you need it. -

Unix Notes

From 4b89904edbc5c4da53dc7be3f6dfbbebf5def2de Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Jul 2007 04:01:46 +0000 Subject: [PATCH 180/241] Added read-ahead support for Win32 file IO --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402450 --- include/SDL_rwops.h | 11 ++++-- src/file/SDL_rwops.c | 82 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 76 insertions(+), 17 deletions(-) diff --git a/include/SDL_rwops.h b/include/SDL_rwops.h index d7e01d8fd..8c177017f 100644 --- a/include/SDL_rwops.h +++ b/include/SDL_rwops.h @@ -62,10 +62,15 @@ typedef struct SDL_RWops { Uint32 type; union { -#ifdef __WIN32__ +#if defined(__WIN32__) && !defined(__SYMBIAN32__) struct { - int append; - void* h; + int append; + void *h; + struct { + void *data; + int size; + int left; + } buffer; } win32io; #endif #ifdef HAVE_STDIO_H diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index c47f43862..6d0bf136e 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -43,6 +43,8 @@ #define INVALID_SET_FILE_POINTER 0xFFFFFFFF #endif +#define READAHEAD_BUFFER_SIZE 1024 + static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, const char *mode) { #ifndef _WIN32_WCE @@ -58,6 +60,14 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con context->hidden.win32io.h = INVALID_HANDLE_VALUE; /* mark this as unusable */ + context->hidden.win32io.buffer.data = (char *)SDL_malloc(READAHEAD_BUFFER_SIZE); + if (!context->hidden.win32io.buffer.data) { + SDL_OutOfMemory(); + return -1; + } + context->hidden.win32io.buffer.size = 0; + context->hidden.win32io.buffer.left = 0; + /* "r" = reading, file must exist */ /* "w" = writing, truncate existing, file may not exist */ /* "r+"= reading or writing, file must exist */ @@ -117,7 +127,13 @@ static int SDLCALL win32_file_seek(SDL_RWops *context, int offset, int whence) SDL_SetError("win32_file_seek: invalid context/file not opened"); return -1; } - + + /* FIXME: We may be able to satisfy the seek within buffered data */ + if (whence == RW_SEEK_CUR && context->hidden.win32io.buffer.left) { + offset -= context->hidden.win32io.buffer.left; + } + context->hidden.win32io.buffer.left = 0; + switch (whence) { case RW_SEEK_SET: win32whence = FILE_BEGIN; break; @@ -129,7 +145,7 @@ static int SDLCALL win32_file_seek(SDL_RWops *context, int offset, int whence) SDL_SetError("win32_file_seek: Unknown value for 'whence'"); return -1; } - + file_pos = SetFilePointer(context->hidden.win32io.h,offset,NULL,win32whence); if ( file_pos != INVALID_SET_FILE_POINTER ) @@ -140,21 +156,50 @@ static int SDLCALL win32_file_seek(SDL_RWops *context, int offset, int whence) } static int SDLCALL win32_file_read(SDL_RWops *context, void *ptr, int size, int maxnum) { + int total_need; + int total_read = 0; + int read_ahead; + DWORD byte_read; - int total_bytes; - DWORD byte_read,nread; + total_need = size*maxnum; - total_bytes = size*maxnum; - - if (!context || context->hidden.win32io.h == INVALID_HANDLE_VALUE || total_bytes<=0 || !size) + if (!context || context->hidden.win32io.h == INVALID_HANDLE_VALUE || total_need<=0 || !size) return 0; - - if (!ReadFile(context->hidden.win32io.h,ptr,total_bytes,&byte_read,NULL)) { - SDL_Error(SDL_EFREAD); - return 0; - } - nread = byte_read/size; - return nread; + + if (context->hidden.win32io.buffer.left > 0) { + void *data = (char *)context->hidden.win32io.buffer.data + + context->hidden.win32io.buffer.size - + context->hidden.win32io.buffer.left; + read_ahead = SDL_min(total_need, context->hidden.win32io.buffer.left); + SDL_memcpy(ptr, data, read_ahead); + context->hidden.win32io.buffer.left -= read_ahead; + + if (read_ahead == total_need) { + return maxnum; + } + ptr = (char *)ptr + read_ahead; + total_need -= read_ahead; + total_read += read_ahead; + } + + if (total_need < READAHEAD_BUFFER_SIZE) { + if (!ReadFile(context->hidden.win32io.h,context->hidden.win32io.buffer.data,READAHEAD_BUFFER_SIZE,&byte_read,NULL)) { + SDL_Error(SDL_EFREAD); + return 0; + } + read_ahead = SDL_min(total_need, byte_read); + SDL_memcpy(ptr, context->hidden.win32io.buffer.data, read_ahead); + context->hidden.win32io.buffer.size = byte_read; + context->hidden.win32io.buffer.left = byte_read-read_ahead; + total_read += read_ahead; + } else { + if (!ReadFile(context->hidden.win32io.h,ptr,total_need,&byte_read,NULL)) { + SDL_Error(SDL_EFREAD); + return 0; + } + total_read += byte_read; + } + return (total_read/size); } static int SDLCALL win32_file_write(SDL_RWops *context, const void *ptr, int size, int num) { @@ -167,6 +212,11 @@ static int SDLCALL win32_file_write(SDL_RWops *context, const void *ptr, int siz if (!context || context->hidden.win32io.h==INVALID_HANDLE_VALUE || total_bytes<=0 || !size) return 0; + if (context->hidden.win32io.buffer.left) { + SetFilePointer(context->hidden.win32io.h,-context->hidden.win32io.buffer.left,NULL,FILE_CURRENT); + context->hidden.win32io.buffer.left = 0; + } + /* if in append mode, we must go to the EOF before write */ if (context->hidden.win32io.append) { if ( SetFilePointer(context->hidden.win32io.h,0L,NULL,FILE_END) == INVALID_SET_FILE_POINTER ) { @@ -191,6 +241,10 @@ static int SDLCALL win32_file_close(SDL_RWops *context) CloseHandle(context->hidden.win32io.h); context->hidden.win32io.h = INVALID_HANDLE_VALUE; /* to be sure */ } + if (context->hidden.win32io.buffer.data) { + SDL_free(context->hidden.win32io.buffer.data); + context->hidden.win32io.buffer.data = NULL; + } SDL_FreeRW(context); } return(0); From d14434c6073593f2ef485cb9f0819f695f6805ec Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Jul 2007 04:31:31 +0000 Subject: [PATCH 181/241] Fixed signed/unsigned mismatch ... hmm, limited to 2 GB reads? Fix in SDL 1.3 --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402451 --- src/file/SDL_rwops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index 6d0bf136e..2a510ee53 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -187,7 +187,7 @@ static int SDLCALL win32_file_read(SDL_RWops *context, void *ptr, int size, int SDL_Error(SDL_EFREAD); return 0; } - read_ahead = SDL_min(total_need, byte_read); + read_ahead = SDL_min(total_need, (int)byte_read); SDL_memcpy(ptr, context->hidden.win32io.buffer.data, read_ahead); context->hidden.win32io.buffer.size = byte_read; context->hidden.win32io.buffer.left = byte_read-read_ahead; From 4011f1ea6f3634b971b7f529d186249459ccdda3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Jul 2007 04:41:50 +0000 Subject: [PATCH 182/241] Added patch-aj from NetBSD pkgsrc: chunk 1: avoid hardcoding nas paths; pkgsrc installs it somewhere else. This part could probably be done better. chunk 2: -L/usr/lib is unnecessary chunk 3: Better DragonFly support. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402452 --- configure.in | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/configure.in b/configure.in index 20c18e650..0ce9d86d3 100644 --- a/configure.in +++ b/configure.in @@ -578,10 +578,10 @@ AC_HELP_STRING([--enable-nas], [support the NAS audio API [[default=yes]]]), if test x$enable_audio = xyes -a x$enable_nas = xyes; then AC_MSG_CHECKING(for NAS audio support) have_nas=no - if test -r /usr/X11R6/include/audio/audiolib.h; then + if true; then have_nas=yes - NAS_CFLAGS="-I/usr/X11R6/include/" - NAS_LIBS="-L/usr/X11R6/lib -laudio -lXt" + NAS_CFLAGS="" + NAS_LIBS="-laudio -lXt" dnl On IRIX, the NAS includes are in a different directory, dnl and libnas must be explicitly linked in @@ -1761,7 +1761,7 @@ AC_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [[default=yes]]]) ;; *-*-netbsd*) pthread_cflags="-D_REENTRANT -D_THREAD_SAFE" - pthread_lib="-L/usr/lib -lpthread" + pthread_lib="-lpthread" ;; *-*-openbsd*) pthread_cflags="-D_REENTRANT" @@ -2104,8 +2104,13 @@ CheckUSBHID() #if defined(HAVE_USB_H) #include #endif + #ifdef __DragonFly__ + #include + #include + #else #include #include + #endif #if defined(HAVE_USBHID_H) #include #elif defined(HAVE_LIBUSB_H) From 7ec71685d6ff4cf8be34cfcad4a3b7d3eaa248b3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Jul 2007 04:47:08 +0000 Subject: [PATCH 183/241] Merged some patches from NetBSD pkgsrc: Added two patches for Solaris 8. The X11 implementation does not define the xEvent structure unless NEED_EVENTS is defined. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402454 --- src/video/dga/SDL_dgaevents.c | 2 ++ src/video/dga/SDL_dgavideo.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/video/dga/SDL_dgaevents.c b/src/video/dga/SDL_dgaevents.c index 11bd21efa..de43266cb 100644 --- a/src/video/dga/SDL_dgaevents.c +++ b/src/video/dga/SDL_dgaevents.c @@ -24,6 +24,8 @@ /* Handle the event stream, converting DGA events into SDL events */ #include +#define NEED_EVENTS +#define NEED_REPLIES #include #include "../Xext/extensions/xf86dga.h" diff --git a/src/video/dga/SDL_dgavideo.c b/src/video/dga/SDL_dgavideo.c index 331fcd260..bc831abf6 100644 --- a/src/video/dga/SDL_dgavideo.c +++ b/src/video/dga/SDL_dgavideo.c @@ -26,6 +26,8 @@ #include +#define NEED_EVENTS +#define NEED_REPLIES #include #include "../Xext/extensions/xf86dga.h" From 65c53ab18b7cfde1695b33d93915191e62c19949 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Jul 2007 04:49:00 +0000 Subject: [PATCH 184/241] I'm reverting this patch... I'm suspicious, since the X11 driver doesn't appear to need it. :) --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402455 --- src/video/dga/SDL_dgaevents.c | 2 -- src/video/dga/SDL_dgavideo.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/video/dga/SDL_dgaevents.c b/src/video/dga/SDL_dgaevents.c index de43266cb..11bd21efa 100644 --- a/src/video/dga/SDL_dgaevents.c +++ b/src/video/dga/SDL_dgaevents.c @@ -24,8 +24,6 @@ /* Handle the event stream, converting DGA events into SDL events */ #include -#define NEED_EVENTS -#define NEED_REPLIES #include #include "../Xext/extensions/xf86dga.h" diff --git a/src/video/dga/SDL_dgavideo.c b/src/video/dga/SDL_dgavideo.c index bc831abf6..331fcd260 100644 --- a/src/video/dga/SDL_dgavideo.c +++ b/src/video/dga/SDL_dgavideo.c @@ -26,8 +26,6 @@ #include -#define NEED_EVENTS -#define NEED_REPLIES #include #include "../Xext/extensions/xf86dga.h" From 86d88abf5927b5ef7cb890e02bb0a1ae17976f8a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Jul 2007 05:35:33 +0000 Subject: [PATCH 185/241] Fixed bug #453 That's silly, we included even though we know we have getpagesize() --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402459 --- src/video/Xext/Xxf86dga/XF86DGA.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/Xext/Xxf86dga/XF86DGA.c b/src/video/Xext/Xxf86dga/XF86DGA.c index 4e3d662ff..f91a135c3 100644 --- a/src/video/Xext/Xxf86dga/XF86DGA.c +++ b/src/video/Xext/Xxf86dga/XF86DGA.c @@ -18,7 +18,7 @@ Copyright (c) 1995,1996 The XFree86 Project, Inc #define HAS_MMAP_ANON #include #include -#include /* PAGE_SIZE */ +/*#include /* PAGE_SIZE */ #define HAS_SC_PAGESIZE /* _SC_PAGESIZE may be an enum for Linux */ #define HAS_GETPAGESIZE #endif /* linux */ From e9910211c8810c9bcc97aa74ef13391284f76a88 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Jul 2007 05:37:53 +0000 Subject: [PATCH 186/241] Added patch note for file I/O speedup --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402460 --- docs.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs.html b/docs.html index 5bd2271bf..8bf29222e 100644 --- a/docs.html +++ b/docs.html @@ -98,6 +98,9 @@ SDL 1.2.12 is a minor bug fix release.

Fixed joystick detection on Windows.

+

+ Improved performance with Win32 file I/O. +

Fixed HBITMAP leak in GAPI driver.

From 8b10fbc3a1f586c4aa123804efc6ef0ec70d3a52 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 10 Jul 2007 13:52:07 +0000 Subject: [PATCH 187/241] Added a '*/' for whiney compilers that don't like comments-in-comments. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402461 --- src/video/Xext/Xxf86dga/XF86DGA.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/Xext/Xxf86dga/XF86DGA.c b/src/video/Xext/Xxf86dga/XF86DGA.c index f91a135c3..346e9e7ed 100644 --- a/src/video/Xext/Xxf86dga/XF86DGA.c +++ b/src/video/Xext/Xxf86dga/XF86DGA.c @@ -18,7 +18,7 @@ Copyright (c) 1995,1996 The XFree86 Project, Inc #define HAS_MMAP_ANON #include #include -/*#include /* PAGE_SIZE */ +/*#include */ /* PAGE_SIZE */ #define HAS_SC_PAGESIZE /* _SC_PAGESIZE may be an enum for Linux */ #define HAS_GETPAGESIZE #endif /* linux */ From 9c48629d64955eee93c09c45c95545ccbdaca867 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Jul 2007 14:16:44 +0000 Subject: [PATCH 188/241] Backported the NAS detection from SDL 1.3, replacing the broken NetBSD patch --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402462 --- configure.in | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/configure.in b/configure.in index 0ce9d86d3..8545c56bb 100644 --- a/configure.in +++ b/configure.in @@ -576,12 +576,20 @@ CheckNAS() AC_HELP_STRING([--enable-nas], [support the NAS audio API [[default=yes]]]), , enable_nas=yes) if test x$enable_audio = xyes -a x$enable_nas = xyes; then + AC_CHECK_HEADER(audio/audiolib.h, have_nas_hdr=yes) + AC_CHECK_LIB(audio, AuOpenServer, have_nas_lib=yes) + AC_MSG_CHECKING(for NAS audio support) have_nas=no - if true; then + + if test x$have_nas_hdr = xyes -a x$have_nas_lib = xyes; then have_nas=yes - NAS_CFLAGS="" - NAS_LIBS="-laudio -lXt" + NAS_LIBS="-laudio" + + elif test -r /usr/X11R6/include/audio/audiolib.h; then + have_nas=yes + NAS_CFLAGS="-I/usr/X11R6/include/" + NAS_LIBS="-L/usr/X11R6/lib -laudio -lXt" dnl On IRIX, the NAS includes are in a different directory, dnl and libnas must be explicitly linked in @@ -590,7 +598,9 @@ AC_HELP_STRING([--enable-nas], [support the NAS audio API [[default=yes]]]), have_nas=yes NAS_LIBS="-lnas -lXt" fi + AC_MSG_RESULT($have_nas) + if test x$have_nas = xyes; then AC_DEFINE(SDL_AUDIO_DRIVER_NAS) SOURCES="$SOURCES $srcdir/src/audio/nas/*.c" From 9a699f8d1511ffd35ee84f28da809b118f1da5ef Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 10 Jul 2007 15:03:19 +0000 Subject: [PATCH 189/241] Don't leak the readahead buffer if win32 rwops file open fails. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402464 --- src/file/SDL_rwops.c | 19 ++++++++++++------- test/Makefile.in | 5 ++++- test/README | 1 + 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index 2a510ee53..c219b5570 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -59,12 +59,7 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con return -1; context->hidden.win32io.h = INVALID_HANDLE_VALUE; /* mark this as unusable */ - - context->hidden.win32io.buffer.data = (char *)SDL_malloc(READAHEAD_BUFFER_SIZE); - if (!context->hidden.win32io.buffer.data) { - SDL_OutOfMemory(); - return -1; - } + context->hidden.win32io.buffer.data = NULL; context->hidden.win32io.buffer.size = 0; context->hidden.win32io.buffer.left = 0; @@ -84,6 +79,12 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con if (!r_right && !w_right) /* inconsistent mode */ return -1; /* failed (invalid call)*/ + context->hidden.win32io.buffer.data = (char *)SDL_malloc(READAHEAD_BUFFER_SIZE); + if (!context->hidden.win32io.buffer.data) { + SDL_OutOfMemory(); + return -1; + } + #ifdef _WIN32_WCE { size_t size = SDL_strlen(filename)+1; @@ -92,6 +93,8 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con if ( MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, size) == 0 ) { SDL_SetError("Unable to convert filename to Unicode"); SDL_stack_free(filenameW); + SDL_free(context->hidden.win32io.buffer.data); + context->hidden.win32io.buffer.data = NULL; return -1; } h = CreateFile(filenameW, (w_right|r_right), (w_right)? 0 : FILE_SHARE_READ, @@ -111,11 +114,13 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con if (h==INVALID_HANDLE_VALUE) { SDL_SetError("Couldn't open %s",filename); + SDL_free(context->hidden.win32io.buffer.data); + context->hidden.win32io.buffer.data = NULL; return -2; /* failed (CreateFile) */ } context->hidden.win32io.h = h; context->hidden.win32io.append = a_mode; - + return 0; /* ok */ } static int SDLCALL win32_file_seek(SDL_RWops *context, int offset, int whence) diff --git a/test/Makefile.in b/test/Makefile.in index 7d5bb8b73..898ffb612 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -7,7 +7,7 @@ EXE = @EXE@ CFLAGS = @CFLAGS@ LIBS = @LIBS@ -TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) +TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testrwops$(EXE) testsem$(EXE) testsprite$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) all: $(TARGETS) @@ -77,6 +77,9 @@ testpalette$(EXE): $(srcdir)/testpalette.c testplatform$(EXE): $(srcdir)/testplatform.c $(CC) -o $@ $? $(CFLAGS) $(LIBS) +testrwops$(EXE): $(srcdir)/testrwops.c + $(CC) -o $@ $? $(CFLAGS) $(LIBS) @MATHLIB@ + testsem$(EXE): $(srcdir)/testsem.c $(CC) -o $@ $? $(CFLAGS) $(LIBS) diff --git a/test/README b/test/README index 9cf5659c7..55d35c762 100644 --- a/test/README +++ b/test/README @@ -24,6 +24,7 @@ These are test programs for the SDL library: testoverlay2 Tests the overlay flickering/scaling during playback. testpalette Tests palette color cycling testplatform Tests types, endianness and cpu capabilities + testrwops Stress-test file i/o API testsem Tests SDL's semaphore implementation testsprite Example of fast sprite movement on the screen testtimer Test the timer facilities From c64b5ebfd94993f61cb023ebf442e341e3b1c071 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 10 Jul 2007 15:04:49 +0000 Subject: [PATCH 190/241] Whoops, reverted changes that shouldn't have been committed with #3197. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402465 --- test/Makefile.in | 5 +---- test/README | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/test/Makefile.in b/test/Makefile.in index 898ffb612..7d5bb8b73 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -7,7 +7,7 @@ EXE = @EXE@ CFLAGS = @CFLAGS@ LIBS = @LIBS@ -TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testrwops$(EXE) testsem$(EXE) testsprite$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) +TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) all: $(TARGETS) @@ -77,9 +77,6 @@ testpalette$(EXE): $(srcdir)/testpalette.c testplatform$(EXE): $(srcdir)/testplatform.c $(CC) -o $@ $? $(CFLAGS) $(LIBS) -testrwops$(EXE): $(srcdir)/testrwops.c - $(CC) -o $@ $? $(CFLAGS) $(LIBS) @MATHLIB@ - testsem$(EXE): $(srcdir)/testsem.c $(CC) -o $@ $? $(CFLAGS) $(LIBS) diff --git a/test/README b/test/README index 55d35c762..9cf5659c7 100644 --- a/test/README +++ b/test/README @@ -24,7 +24,6 @@ These are test programs for the SDL library: testoverlay2 Tests the overlay flickering/scaling during playback. testpalette Tests palette color cycling testplatform Tests types, endianness and cpu capabilities - testrwops Stress-test file i/o API testsem Tests SDL's semaphore implementation testsprite Example of fast sprite movement on the screen testtimer Test the timer facilities From 5d9a9d6e7fb52d4316e08115d62b52397b916495 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Jul 2007 15:39:14 +0000 Subject: [PATCH 191/241] Sort of fixed NAS detection on NetBSD - requires that /usr/pkg be in your include/linker/library path --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402466 --- configure.in | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/configure.in b/configure.in index 8545c56bb..ec4091045 100644 --- a/configure.in +++ b/configure.in @@ -74,8 +74,8 @@ BUILD_CFLAGS="$CFLAGS $CPPFLAGS" EXTRA_CFLAGS="$INCLUDE $BASE_CFLAGS" BUILD_LDFLAGS="$LDFLAGS" EXTRA_LDFLAGS="$BASE_LDFLAGS" -# I can't remember why I added this. I'm sure it'll come to me... -#for path in /usr/local; do +## These are common directories to find software packages +#for path in /usr/freeware /usr/pkg /usr/X11R6 /usr/local; do # if test -d $path/include; then # EXTRA_CFLAGS="$EXTRA_CFLAGS -I$path/include" # fi @@ -576,29 +576,23 @@ CheckNAS() AC_HELP_STRING([--enable-nas], [support the NAS audio API [[default=yes]]]), , enable_nas=yes) if test x$enable_audio = xyes -a x$enable_nas = xyes; then - AC_CHECK_HEADER(audio/audiolib.h, have_nas_hdr=yes) - AC_CHECK_LIB(audio, AuOpenServer, have_nas_lib=yes) + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -lXt -lm" + AC_CHECK_HEADER(audio/audiolib.h, have_audio_hdr=yes) + AC_CHECK_LIB(audio, AuOpenServer, have_audio_lib=yes) + AC_CHECK_HEADER(nas/audiolib.h, have_nas_hdr=yes) + AC_CHECK_LIB(nas, AuOpenServer, have_nas_lib=yes) + LDFLAGS="$save_LDFLAGS" AC_MSG_CHECKING(for NAS audio support) have_nas=no - - if test x$have_nas_hdr = xyes -a x$have_nas_lib = xyes; then + if test x$have_audio_hdr = xyes -a x$have_audio_lib = xyes; then have_nas=yes - NAS_LIBS="-laudio" - - elif test -r /usr/X11R6/include/audio/audiolib.h; then - have_nas=yes - NAS_CFLAGS="-I/usr/X11R6/include/" - NAS_LIBS="-L/usr/X11R6/lib -laudio -lXt" - - dnl On IRIX, the NAS includes are in a different directory, - dnl and libnas must be explicitly linked in - - elif test -r /usr/freeware/include/nas/audiolib.h; then + NAS_LIBS="-laudio -lXt" + elif test x$have_nas_hdr = xyes -a x$have_nas_lib = xyes; then have_nas=yes NAS_LIBS="-lnas -lXt" - fi - + fi AC_MSG_RESULT($have_nas) if test x$have_nas = xyes; then @@ -2114,13 +2108,13 @@ CheckUSBHID() #if defined(HAVE_USB_H) #include #endif - #ifdef __DragonFly__ + #ifdef __DragonFly__ #include #include - #else + #else #include #include - #endif + #endif #if defined(HAVE_USBHID_H) #include #elif defined(HAVE_LIBUSB_H) From bfef64638896186e66c89a404d8cda1cb3accc94 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Jul 2007 16:01:46 +0000 Subject: [PATCH 192/241] Simplified Win32 file opening code --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402468 --- src/file/SDL_rwops.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index c219b5570..ed596264f 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -56,12 +56,7 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con int a_mode; if (!context) - return -1; - - context->hidden.win32io.h = INVALID_HANDLE_VALUE; /* mark this as unusable */ - context->hidden.win32io.buffer.data = NULL; - context->hidden.win32io.buffer.size = 0; - context->hidden.win32io.buffer.left = 0; + return -1; /* failed (invalid call) */ /* "r" = reading, file must exist */ /* "w" = writing, truncate existing, file may not exist */ @@ -77,13 +72,7 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con w_right = ( a_mode || SDL_strchr(mode,'+') || truncate ) ? GENERIC_WRITE : 0; if (!r_right && !w_right) /* inconsistent mode */ - return -1; /* failed (invalid call)*/ - - context->hidden.win32io.buffer.data = (char *)SDL_malloc(READAHEAD_BUFFER_SIZE); - if (!context->hidden.win32io.buffer.data) { - SDL_OutOfMemory(); - return -1; - } + return -1; /* failed (invalid call) */ #ifdef _WIN32_WCE { @@ -93,8 +82,6 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con if ( MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, size) == 0 ) { SDL_SetError("Unable to convert filename to Unicode"); SDL_stack_free(filenameW); - SDL_free(context->hidden.win32io.buffer.data); - context->hidden.win32io.buffer.data = NULL; return -1; } h = CreateFile(filenameW, (w_right|r_right), (w_right)? 0 : FILE_SHARE_READ, @@ -114,13 +101,20 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con if (h==INVALID_HANDLE_VALUE) { SDL_SetError("Couldn't open %s",filename); - SDL_free(context->hidden.win32io.buffer.data); - context->hidden.win32io.buffer.data = NULL; return -2; /* failed (CreateFile) */ } context->hidden.win32io.h = h; context->hidden.win32io.append = a_mode; + context->hidden.win32io.buffer.data = (char *)SDL_malloc(READAHEAD_BUFFER_SIZE); + if (!context->hidden.win32io.buffer.data) { + SDL_OutOfMemory(); + CloseHandle(context->hidden.win32io.h); + return -1; + } + context->hidden.win32io.buffer.size = 0; + context->hidden.win32io.buffer.left = 0; + return 0; /* ok */ } static int SDLCALL win32_file_seek(SDL_RWops *context, int offset, int whence) @@ -435,8 +429,7 @@ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode) rwops = SDL_AllocRW(); if (!rwops) return NULL; /* SDL_SetError already setup by SDL_AllocRW() */ - rwops->hidden.win32io.h = INVALID_HANDLE_VALUE; - if (win32_file_open(rwops,file,mode)) { + if (win32_file_open(rwops,file,mode) < 0) { SDL_FreeRW(rwops); return NULL; } From a37ebaa8e6d2a00b570e90ef4654ad62769afed2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 10 Jul 2007 18:56:08 +0000 Subject: [PATCH 193/241] Reverted most of r3200:3201: a malloc() failure would leave a zero-byte file if opening for write. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402470 --- src/file/SDL_rwops.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index ed596264f..fcf3867be 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -57,6 +57,11 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con if (!context) return -1; /* failed (invalid call) */ + + context->hidden.win32io.h = INVALID_HANDLE_VALUE; /* mark this as unusable */ + context->hidden.win32io.buffer.data = NULL; + context->hidden.win32io.buffer.size = 0; + context->hidden.win32io.buffer.left = 0; /* "r" = reading, file must exist */ /* "w" = writing, truncate existing, file may not exist */ @@ -74,6 +79,12 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con if (!r_right && !w_right) /* inconsistent mode */ return -1; /* failed (invalid call) */ + context->hidden.win32io.buffer.data = (char *)SDL_malloc(READAHEAD_BUFFER_SIZE); + if (!context->hidden.win32io.buffer.data) { + SDL_OutOfMemory(); + return -1; + } + #ifdef _WIN32_WCE { size_t size = SDL_strlen(filename)+1; @@ -82,6 +93,8 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con if ( MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, size) == 0 ) { SDL_SetError("Unable to convert filename to Unicode"); SDL_stack_free(filenameW); + SDL_free(context->hidden.win32io.buffer.data); + context->hidden.win32io.buffer.data = NULL; return -1; } h = CreateFile(filenameW, (w_right|r_right), (w_right)? 0 : FILE_SHARE_READ, @@ -101,20 +114,13 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con if (h==INVALID_HANDLE_VALUE) { SDL_SetError("Couldn't open %s",filename); + SDL_free(context->hidden.win32io.buffer.data); + context->hidden.win32io.buffer.data = NULL; return -2; /* failed (CreateFile) */ } context->hidden.win32io.h = h; context->hidden.win32io.append = a_mode; - context->hidden.win32io.buffer.data = (char *)SDL_malloc(READAHEAD_BUFFER_SIZE); - if (!context->hidden.win32io.buffer.data) { - SDL_OutOfMemory(); - CloseHandle(context->hidden.win32io.h); - return -1; - } - context->hidden.win32io.buffer.size = 0; - context->hidden.win32io.buffer.left = 0; - return 0; /* ok */ } static int SDLCALL win32_file_seek(SDL_RWops *context, int offset, int whence) From 3183821d0948a1524898b52e88d10099fe54c6da Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 10 Jul 2007 19:03:44 +0000 Subject: [PATCH 194/241] Set the error after freeing stuff, just in case one of those functions resets the error string. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402471 --- src/file/SDL_rwops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index fcf3867be..e463bf11c 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -91,10 +91,10 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con wchar_t *filenameW = SDL_stack_alloc(wchar_t, size); if ( MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, size) == 0 ) { - SDL_SetError("Unable to convert filename to Unicode"); SDL_stack_free(filenameW); SDL_free(context->hidden.win32io.buffer.data); context->hidden.win32io.buffer.data = NULL; + SDL_SetError("Unable to convert filename to Unicode"); return -1; } h = CreateFile(filenameW, (w_right|r_right), (w_right)? 0 : FILE_SHARE_READ, @@ -113,9 +113,9 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con #endif /* _WIN32_WCE */ if (h==INVALID_HANDLE_VALUE) { - SDL_SetError("Couldn't open %s",filename); SDL_free(context->hidden.win32io.buffer.data); context->hidden.win32io.buffer.data = NULL; + SDL_SetError("Couldn't open %s",filename); return -2; /* failed (CreateFile) */ } context->hidden.win32io.h = h; From 3530814620d9363f92305ee7e5ad260b37f9f713 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Jul 2007 20:15:31 +0000 Subject: [PATCH 195/241] Updated SVN checkout instructions --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402473 --- README.SVN | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.SVN b/README.SVN index bdab4ded3..eec5918a1 100644 --- a/README.SVN +++ b/README.SVN @@ -7,7 +7,7 @@ at the Subversion website ( http://subversion.tigris.org/ ) for more information on using svn, where you can also download software for MacOS, Windows, and Unix systems. - svn checkout svn://libsdl.org/trunk/SDL + svn checkout http://svn.libsdl.org/branches/SDL-1.2 If you are building SDL with an IDE, you will need to copy the file include/SDL_config.h.default to include/SDL_config.h before building. From 7cfdd8efb6d8981a81fffdf97417314e2c2a13e1 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 11 Jul 2007 05:43:39 +0000 Subject: [PATCH 196/241] I think this fixes bug #261 Make sure that you don't use a wgl function after the context is deleted. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402476 --- src/video/wincommon/SDL_wingl.c | 242 +++++++++++++++--------------- src/video/wincommon/SDL_wingl_c.h | 4 - 2 files changed, 122 insertions(+), 124 deletions(-) diff --git a/src/video/wincommon/SDL_wingl.c b/src/video/wincommon/SDL_wingl.c index c3ce470d8..235a11116 100644 --- a/src/video/wincommon/SDL_wingl.c +++ b/src/video/wincommon/SDL_wingl.c @@ -109,15 +109,16 @@ static int ExtensionSupported(const char *extension, const char *extensions) return 0; } -static void Init_WGL_ARB_extensions(_THIS) +static int ChoosePixelFormatARB(_THIS, const int *iAttribs, const FLOAT *fAttribs) { HWND hwnd; HDC hdc; HGLRC hglrc; - int pformat; const char * (WINAPI *wglGetExtensionsStringARB)(HDC) = 0; const char *extensions; - + int pformat = 0; + UINT matches = 0; + hwnd = CreateWindow(SDL_Appname, SDL_Appname, WS_POPUP | WS_DISABLED, 0, 0, 10, 10, NULL, NULL, SDL_Instance, NULL); @@ -125,8 +126,7 @@ static void Init_WGL_ARB_extensions(_THIS) hdc = GetDC(hwnd); - pformat = ChoosePixelFormat(hdc, &GL_pfd); - SetPixelFormat(hdc, pformat, &GL_pfd); + SetPixelFormat(hdc, ChoosePixelFormat(hdc, &GL_pfd), &GL_pfd); hglrc = this->gl_data->wglCreateContext(hdc); if ( hglrc ) { @@ -144,15 +144,12 @@ static void Init_WGL_ARB_extensions(_THIS) this->gl_data->WGL_ARB_pixel_format = 0; if( ExtensionSupported("WGL_ARB_pixel_format", extensions) ) { - this->gl_data->wglChoosePixelFormatARB = + BOOL (WINAPI *wglChoosePixelFormatARB)(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); + wglChoosePixelFormatARB = (BOOL (WINAPI *)(HDC, const int *, const FLOAT *, UINT, int *, UINT *)) this->gl_data->wglGetProcAddress("wglChoosePixelFormatARB"); - this->gl_data->wglGetPixelFormatAttribivARB = - (BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *)) - this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB"); - - if( (this->gl_data->wglChoosePixelFormatARB != NULL) && - (this->gl_data->wglGetPixelFormatAttribivARB != NULL) ) { + if( wglChoosePixelFormatARB && + wglChoosePixelFormatARB(hdc, iAttribs, fAttribs, 1, &pformat, &matches) && pformat ) { this->gl_data->WGL_ARB_pixel_format = 1; } } @@ -164,6 +161,8 @@ static void Init_WGL_ARB_extensions(_THIS) ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); WIN_FlushMessageQueue(); + + return pformat; } #endif /* SDL_VIDEO_OPENGL */ @@ -188,6 +187,105 @@ int WIN_GL_SetupWindow(_THIS) } } + /* Set up the pixel format descriptor with our needed format */ + SDL_memset(&GL_pfd, 0, sizeof(GL_pfd)); + GL_pfd.nSize = sizeof(GL_pfd); + GL_pfd.nVersion = 1; + GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL); + if ( this->gl_config.double_buffer ) { + GL_pfd.dwFlags |= PFD_DOUBLEBUFFER; + } + if ( this->gl_config.stereo ) { + GL_pfd.dwFlags |= PFD_STEREO; + } + GL_pfd.iPixelType = PFD_TYPE_RGBA; + GL_pfd.cColorBits = this->gl_config.buffer_size; + GL_pfd.cRedBits = this->gl_config.red_size; + GL_pfd.cGreenBits = this->gl_config.green_size; + GL_pfd.cBlueBits = this->gl_config.blue_size; + GL_pfd.cAlphaBits = this->gl_config.alpha_size; + GL_pfd.cAccumRedBits = this->gl_config.accum_red_size; + GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size; + GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size; + GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size; + GL_pfd.cAccumBits = + (GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits + + GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits); + GL_pfd.cDepthBits = this->gl_config.depth_size; + GL_pfd.cStencilBits = this->gl_config.stencil_size; + + /* setup WGL_ARB_pixel_format attribs */ + iAttr = &iAttribs[0]; + + *iAttr++ = WGL_DRAW_TO_WINDOW_ARB; + *iAttr++ = GL_TRUE; + *iAttr++ = WGL_ACCELERATION_ARB; + *iAttr++ = WGL_FULL_ACCELERATION_ARB; + *iAttr++ = WGL_RED_BITS_ARB; + *iAttr++ = this->gl_config.red_size; + *iAttr++ = WGL_GREEN_BITS_ARB; + *iAttr++ = this->gl_config.green_size; + *iAttr++ = WGL_BLUE_BITS_ARB; + *iAttr++ = this->gl_config.blue_size; + + if ( this->gl_config.alpha_size ) { + *iAttr++ = WGL_ALPHA_BITS_ARB; + *iAttr++ = this->gl_config.alpha_size; + } + + *iAttr++ = WGL_DOUBLE_BUFFER_ARB; + *iAttr++ = this->gl_config.double_buffer; + + *iAttr++ = WGL_DEPTH_BITS_ARB; + *iAttr++ = this->gl_config.depth_size; + + if ( this->gl_config.stencil_size ) { + *iAttr++ = WGL_STENCIL_BITS_ARB; + *iAttr++ = this->gl_config.stencil_size; + } + + if ( this->gl_config.accum_red_size ) { + *iAttr++ = WGL_ACCUM_RED_BITS_ARB; + *iAttr++ = this->gl_config.accum_red_size; + } + + if ( this->gl_config.accum_green_size ) { + *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB; + *iAttr++ = this->gl_config.accum_green_size; + } + + if ( this->gl_config.accum_blue_size ) { + *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB; + *iAttr++ = this->gl_config.accum_blue_size; + } + + if ( this->gl_config.accum_alpha_size ) { + *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB; + *iAttr++ = this->gl_config.accum_alpha_size; + } + + if ( this->gl_config.stereo ) { + *iAttr++ = WGL_STEREO_ARB; + *iAttr++ = GL_TRUE; + } + + if ( this->gl_config.multisamplebuffers ) { + *iAttr++ = WGL_SAMPLE_BUFFERS_ARB; + *iAttr++ = this->gl_config.multisamplebuffers; + } + + if ( this->gl_config.multisamplesamples ) { + *iAttr++ = WGL_SAMPLES_ARB; + *iAttr++ = this->gl_config.multisamplesamples; + } + + if ( this->gl_config.accelerated >= 0 ) { + *iAttr++ = WGL_ACCELERATION_ARB; + *iAttr++ = (this->gl_config.accelerated ? WGL_GENERIC_ACCELERATION_ARB : WGL_NO_ACCELERATION_ARB); + } + + *iAttr = 0; + for ( i=0; ; ++i ) { /* Get the window device context for our OpenGL drawing */ GL_hdc = GetDC(SDL_Window); @@ -196,114 +294,10 @@ int WIN_GL_SetupWindow(_THIS) return(-1); } - /* Set up the pixel format descriptor with our needed format */ - SDL_memset(&GL_pfd, 0, sizeof(GL_pfd)); - GL_pfd.nSize = sizeof(GL_pfd); - GL_pfd.nVersion = 1; - GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL); - if ( this->gl_config.double_buffer ) { - GL_pfd.dwFlags |= PFD_DOUBLEBUFFER; - } - if ( this->gl_config.stereo ) { - GL_pfd.dwFlags |= PFD_STEREO; - } - GL_pfd.iPixelType = PFD_TYPE_RGBA; - GL_pfd.cColorBits = this->gl_config.buffer_size; - GL_pfd.cRedBits = this->gl_config.red_size; - GL_pfd.cGreenBits = this->gl_config.green_size; - GL_pfd.cBlueBits = this->gl_config.blue_size; - GL_pfd.cAlphaBits = this->gl_config.alpha_size; - GL_pfd.cAccumRedBits = this->gl_config.accum_red_size; - GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size; - GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size; - GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size; - GL_pfd.cAccumBits = - (GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits + - GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits); - GL_pfd.cDepthBits = this->gl_config.depth_size; - GL_pfd.cStencilBits = this->gl_config.stencil_size; - - /* initialize WGL_ARB_pixel_format */ - Init_WGL_ARB_extensions(this); - - /* setup WGL_ARB_pixel_format attribs */ - iAttr = &iAttribs[0]; - - *iAttr++ = WGL_DRAW_TO_WINDOW_ARB; - *iAttr++ = GL_TRUE; - *iAttr++ = WGL_ACCELERATION_ARB; - *iAttr++ = WGL_FULL_ACCELERATION_ARB; - *iAttr++ = WGL_RED_BITS_ARB; - *iAttr++ = this->gl_config.red_size; - *iAttr++ = WGL_GREEN_BITS_ARB; - *iAttr++ = this->gl_config.green_size; - *iAttr++ = WGL_BLUE_BITS_ARB; - *iAttr++ = this->gl_config.blue_size; - - if ( this->gl_config.alpha_size ) { - *iAttr++ = WGL_ALPHA_BITS_ARB; - *iAttr++ = this->gl_config.alpha_size; - } - - *iAttr++ = WGL_DOUBLE_BUFFER_ARB; - *iAttr++ = this->gl_config.double_buffer; - - *iAttr++ = WGL_DEPTH_BITS_ARB; - *iAttr++ = this->gl_config.depth_size; - - if ( this->gl_config.stencil_size ) { - *iAttr++ = WGL_STENCIL_BITS_ARB; - *iAttr++ = this->gl_config.stencil_size; - } - - if ( this->gl_config.accum_red_size ) { - *iAttr++ = WGL_ACCUM_RED_BITS_ARB; - *iAttr++ = this->gl_config.accum_red_size; - } - - if ( this->gl_config.accum_green_size ) { - *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB; - *iAttr++ = this->gl_config.accum_green_size; - } - - if ( this->gl_config.accum_blue_size ) { - *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB; - *iAttr++ = this->gl_config.accum_blue_size; - } - - if ( this->gl_config.accum_alpha_size ) { - *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB; - *iAttr++ = this->gl_config.accum_alpha_size; - } - - if ( this->gl_config.stereo ) { - *iAttr++ = WGL_STEREO_ARB; - *iAttr++ = GL_TRUE; - } - - if ( this->gl_config.multisamplebuffers ) { - *iAttr++ = WGL_SAMPLE_BUFFERS_ARB; - *iAttr++ = this->gl_config.multisamplebuffers; - } - - if ( this->gl_config.multisamplesamples ) { - *iAttr++ = WGL_SAMPLES_ARB; - *iAttr++ = this->gl_config.multisamplesamples; - } - - if ( this->gl_config.accelerated >= 0 ) { - *iAttr++ = WGL_ACCELERATION_ARB; - *iAttr++ = (this->gl_config.accelerated ? WGL_GENERIC_ACCELERATION_ARB : WGL_NO_ACCELERATION_ARB); - } - - *iAttr = 0; - /* Choose and set the closest available pixel format */ - if ( !this->gl_data->WGL_ARB_pixel_format || - !this->gl_data->wglChoosePixelFormatARB(GL_hdc, iAttribs, fAttribs, 1, &pixel_format, &matching) || - !matching ) { + pixel_format = ChoosePixelFormatARB(this, iAttribs, fAttribs); + if ( !pixel_format ) { pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd); - this->gl_data->WGL_ARB_pixel_format = 0; } if ( !pixel_format ) { SDL_SetError("No matching GL pixel format available"); @@ -335,6 +329,15 @@ int WIN_GL_SetupWindow(_THIS) } gl_active = 1; + /* Get the wglGetPixelFormatAttribivARB pointer for the context */ + if ( this->gl_data->WGL_ARB_pixel_format ) { + this->gl_data->wglGetPixelFormatAttribivARB = + (BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *)) + this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB"); + } else { + this->gl_data->wglGetPixelFormatAttribivARB = NULL; + } + /* Vsync control under Windows. Checking glGetString here is * somewhat a documented and reliable hack - it was originally * as a feature added by mistake, but since so many people rely @@ -416,7 +419,7 @@ int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) return -1; } - if ( this->gl_data->WGL_ARB_pixel_format ) { + if ( this->gl_data->wglGetPixelFormatAttribivARB ) { int wgl_attrib; switch(attrib) { @@ -566,7 +569,6 @@ void WIN_GL_UnloadLibrary(_THIS) this->gl_data->wglCreateContext = NULL; this->gl_data->wglDeleteContext = NULL; this->gl_data->wglMakeCurrent = NULL; - this->gl_data->wglChoosePixelFormatARB = NULL; this->gl_data->wglGetPixelFormatAttribivARB = NULL; this->gl_data->wglSwapIntervalEXT = NULL; this->gl_data->wglGetSwapIntervalEXT = NULL; diff --git a/src/video/wincommon/SDL_wingl_c.h b/src/video/wincommon/SDL_wingl_c.h index 5a1fd2277..e800becd7 100644 --- a/src/video/wincommon/SDL_wingl_c.h +++ b/src/video/wincommon/SDL_wingl_c.h @@ -44,10 +44,6 @@ struct SDL_PrivateGLData { BOOL (WINAPI *wglMakeCurrent)(HDC hdc, HGLRC hglrc); - BOOL (WINAPI *wglChoosePixelFormatARB)(HDC hdc, const int *piAttribIList, - const FLOAT *pfAttribFList, - UINT nMaxFormats, int *piFormats, - UINT *nNumFormats); BOOL (WINAPI *wglGetPixelFormatAttribivARB)(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, From ec47c8fd5fce4da352d072763d5ff740563abdc4 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 11 Jul 2007 05:46:04 +0000 Subject: [PATCH 197/241] Removed unreferenced variable --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402477 --- src/video/wincommon/SDL_wingl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/wincommon/SDL_wingl.c b/src/video/wincommon/SDL_wingl.c index 235a11116..88ceffce7 100644 --- a/src/video/wincommon/SDL_wingl.c +++ b/src/video/wincommon/SDL_wingl.c @@ -172,7 +172,6 @@ int WIN_GL_SetupWindow(_THIS) int retval; #if SDL_VIDEO_OPENGL int i; - unsigned int matching; int iAttribs[64]; int *iAttr; float fAttribs[1] = { 0 }; From ef9a77972055fcbf469298c5f442b738cca9b3d7 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 11 Jul 2007 05:55:10 +0000 Subject: [PATCH 198/241] Fixed VC++ warnings --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402478 --- src/audio/SDL_audio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index e0102ad00..3e2316df2 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -437,7 +437,7 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) if ( desired->channels == 0 ) { env = SDL_getenv("SDL_AUDIO_CHANNELS"); if ( env ) { - desired->channels = SDL_atoi(env); + desired->channels = (Uint8)SDL_atoi(env); } } if ( desired->channels == 0 ) { @@ -457,7 +457,7 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) if ( desired->samples == 0 ) { env = SDL_getenv("SDL_AUDIO_SAMPLES"); if ( env ) { - desired->samples = SDL_atoi(env); + desired->samples = (Uint16)SDL_atoi(env); } } if ( desired->samples == 0 ) { From 0e32fcbe1dca4d1b62f2384ea25ce6a15a6d2c48 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 11 Jul 2007 06:26:22 +0000 Subject: [PATCH 199/241] GCC inline asm for MMX YUV processing no longer has textrels and now works when gcc wants to hog %%ebx for the PIC register. Fixes Bugzilla #418. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402479 --- src/video/SDL_yuv_mmx.c | 202 ++++++++++++++++++++++------------------ src/video/SDL_yuv_sw.c | 6 +- 2 files changed, 114 insertions(+), 94 deletions(-) diff --git a/src/video/SDL_yuv_mmx.c b/src/video/SDL_yuv_mmx.c index 4a9fb1d67..580d6ce16 100644 --- a/src/video/SDL_yuv_mmx.c +++ b/src/video/SDL_yuv_mmx.c @@ -21,36 +21,35 @@ */ #include "SDL_config.h" -#if 0 /* FIXME: This code needs to be rewritten to reference the static data using relocatable addresses (e.g. http://www.gentoo.org/proj/en/hardened/pic-fix-guide.xml or http://nasm.sourceforge.net/doc/html/nasmdoc8.html#section-8.2) This code currently breaks on systems with readonly text segments (hardened Linux / Intel Mac) */ -#if defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES +#if (__GNUC__ > 2) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES #include "SDL_stdinc.h" -#define ASM_ARRAY(x) x[] __asm__("_" #x) __attribute__((used)) - -static unsigned int ASM_ARRAY(MMX_0080w) = {0x00800080, 0x00800080}; -static unsigned int ASM_ARRAY(MMX_00FFw) = {0x00ff00ff, 0x00ff00ff}; -static unsigned int ASM_ARRAY(MMX_FF00w) = {0xff00ff00, 0xff00ff00}; +#include "mmx.h" -static unsigned short ASM_ARRAY(MMX_Ycoeff) = {0x004a, 0x004a, 0x004a, 0x004a}; +static mmx_t MMX_0080w = { .ud = {0x00800080, 0x00800080} }; +static mmx_t MMX_00FFw = { .ud = {0x00ff00ff, 0x00ff00ff} }; +static mmx_t MMX_FF00w = { .ud = {0xff00ff00, 0xff00ff00} }; -static unsigned short ASM_ARRAY(MMX_UbluRGB) = {0x0072, 0x0072, 0x0072, 0x0072}; -static unsigned short ASM_ARRAY(MMX_VredRGB) = {0x0059, 0x0059, 0x0059, 0x0059}; -static unsigned short ASM_ARRAY(MMX_UgrnRGB) = {0xffea, 0xffea, 0xffea, 0xffea}; -static unsigned short ASM_ARRAY(MMX_VgrnRGB) = {0xffd2, 0xffd2, 0xffd2, 0xffd2}; +static mmx_t MMX_Ycoeff = { .uw = {0x004a, 0x004a, 0x004a, 0x004a} }; -static unsigned short ASM_ARRAY(MMX_Ublu5x5) = {0x0081, 0x0081, 0x0081, 0x0081}; -static unsigned short ASM_ARRAY(MMX_Vred5x5) = {0x0066, 0x0066, 0x0066, 0x0066}; -static unsigned short ASM_ARRAY(MMX_Ugrn555) = {0xffe7, 0xffe7, 0xffe7, 0xffe7}; -static unsigned short ASM_ARRAY(MMX_Vgrn555) = {0xffcc, 0xffcc, 0xffcc, 0xffcc}; -static unsigned short ASM_ARRAY(MMX_Ugrn565) = {0xffe8, 0xffe8, 0xffe8, 0xffe8}; -static unsigned short ASM_ARRAY(MMX_Vgrn565) = {0xffcd, 0xffcd, 0xffcd, 0xffcd}; +static mmx_t MMX_UbluRGB = { .uw = {0x0072, 0x0072, 0x0072, 0x0072} }; +static mmx_t MMX_VredRGB = { .uw = {0x0059, 0x0059, 0x0059, 0x0059} }; +static mmx_t MMX_UgrnRGB = { .uw = {0xffea, 0xffea, 0xffea, 0xffea} }; +static mmx_t MMX_VgrnRGB = { .uw = {0xffd2, 0xffd2, 0xffd2, 0xffd2} }; -static unsigned short ASM_ARRAY(MMX_red555) = {0x7c00, 0x7c00, 0x7c00, 0x7c00}; -static unsigned short ASM_ARRAY(MMX_red565) = {0xf800, 0xf800, 0xf800, 0xf800}; -static unsigned short ASM_ARRAY(MMX_grn555) = {0x03e0, 0x03e0, 0x03e0, 0x03e0}; -static unsigned short ASM_ARRAY(MMX_grn565) = {0x07e0, 0x07e0, 0x07e0, 0x07e0}; -static unsigned short ASM_ARRAY(MMX_blu5x5) = {0x001f, 0x001f, 0x001f, 0x001f}; +static mmx_t MMX_Ublu5x5 = { .uw = {0x0081, 0x0081, 0x0081, 0x0081} }; +static mmx_t MMX_Vred5x5 = { .uw = {0x0066, 0x0066, 0x0066, 0x0066} }; +static mmx_t MMX_Ugrn555 = { .uw = {0xffe7, 0xffe7, 0xffe7, 0xffe7} }; +static mmx_t MMX_Vgrn555 = { .uw = {0xffcc, 0xffcc, 0xffcc, 0xffcc} }; +static mmx_t MMX_Ugrn565 = { .uw = {0xffe8, 0xffe8, 0xffe8, 0xffe8} }; +static mmx_t MMX_Vgrn565 = { .uw = {0xffcd, 0xffcd, 0xffcd, 0xffcd} }; + +static mmx_t MMX_red555 = { .uw = {0x7c00, 0x7c00, 0x7c00, 0x7c00} }; +static mmx_t MMX_red565 = { .uw = {0xf800, 0xf800, 0xf800, 0xf800} }; +static mmx_t MMX_grn555 = { .uw = {0x03e0, 0x03e0, 0x03e0, 0x03e0} }; +static mmx_t MMX_grn565 = { .uw = {0x07e0, 0x07e0, 0x07e0, 0x07e0} }; +static mmx_t MMX_blu5x5 = { .uw = {0x001f, 0x001f, 0x001f, 0x001f} }; /** This MMX assembler is my first assembler/MMX program ever. @@ -86,38 +85,42 @@ void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, unsigned char *cb, unsigned char *out, int rows, int cols, int mod ) { - Uint32 *row1; - Uint32 *row2; + Uint32 *row1; + Uint32 *row2; - unsigned char* y = lum +cols*rows; // Pointer to the end - int x=0; - row1 = (Uint32 *)out; // 32 bit target - row2 = (Uint32 *)out+cols+mod; // start of second row - mod = (mod+cols+mod)*4; // increment for row1 in byte + unsigned char* y = lum +cols*rows; // Pointer to the end + int x = 0; + row1 = (Uint32 *)out; // 32 bit target + row2 = (Uint32 *)out+cols+mod; // start of second row + mod = (mod+cols+mod)*4; // increment for row1 in byte - __asm__ __volatile__ ( -/* We don't really care about PIC - the code should be rewritten to use - relative addressing for the static tables, so right now we take the - COW hit on the pages this code resides. Big deal. - This spill is just to reduce register pressure in the PIC case. */ - "pushl %%ebx\n" - "movl %0, %%ebx\n" + __asm__ __volatile__ ( + // tap dance to workaround the inability to use %%ebx at will... + // move one thing to the stack... + "pushl $0\n" // save a slot on the stack. + "pushl %%ebx\n" // save %%ebx. + "movl %0, %%ebx\n" // put the thing in ebx. + "movl %%ebx, 4(%%esp)\n" // put the thing in the stack slot. + "popl %%ebx\n" // get back %%ebx (the PIC register). - ".align 8\n" + ".align 8\n" "1:\n" // create Cr (result in mm1) + "pushl %%ebx\n" + "movl 4(%%esp), %%ebx\n" "movd (%%ebx), %%mm1\n" // 0 0 0 0 v3 v2 v1 v0 + "popl %%ebx\n" "pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00 "movd (%2), %%mm2\n" // 0 0 0 0 l3 l2 l1 l0 "punpcklbw %%mm7,%%mm1\n" // 0 v3 0 v2 00 v1 00 v0 "punpckldq %%mm1,%%mm1\n" // 00 v1 00 v0 00 v1 00 v0 - "psubw _MMX_0080w,%%mm1\n" // mm1-128:r1 r1 r0 r0 r1 r1 r0 r0 + "psubw %9,%%mm1\n" // mm1-128:r1 r1 r0 r0 r1 r1 r0 r0 // create Cr_g (result in mm0) "movq %%mm1,%%mm0\n" // r1 r1 r0 r0 r1 r1 r0 r0 - "pmullw _MMX_VgrnRGB,%%mm0\n"// red*-46dec=0.7136*64 - "pmullw _MMX_VredRGB,%%mm1\n"// red*89dec=1.4013*64 + "pmullw %10,%%mm0\n" // red*-46dec=0.7136*64 + "pmullw %11,%%mm1\n" // red*89dec=1.4013*64 "psraw $6, %%mm0\n" // red=red/64 "psraw $6, %%mm1\n" // red=red/64 @@ -126,8 +129,8 @@ void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, "movq (%2,%4),%%mm3\n" // 0 0 0 0 L3 L2 L1 L0 "punpckldq %%mm3,%%mm2\n" // L3 L2 L1 L0 l3 l2 l1 l0 "movq %%mm2,%%mm4\n" // L3 L2 L1 L0 l3 l2 l1 l0 - "pand _MMX_FF00w,%%mm2\n" // L3 0 L1 0 l3 0 l1 0 - "pand _MMX_00FFw,%%mm4\n" // 0 L2 0 L0 0 l2 0 l0 + "pand %12,%%mm2\n" // L3 0 L1 0 l3 0 l1 0 + "pand %13,%%mm4\n" // 0 L2 0 L0 0 l2 0 l0 "psrlw $8,%%mm2\n" // 0 L3 0 L1 0 l3 0 l1 // create R (result in mm6) @@ -144,11 +147,11 @@ void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, "movd (%1), %%mm1\n" // 0 0 0 0 u3 u2 u1 u0 "punpcklbw %%mm7,%%mm1\n" // 0 u3 0 u2 00 u1 00 u0 "punpckldq %%mm1,%%mm1\n" // 00 u1 00 u0 00 u1 00 u0 - "psubw _MMX_0080w,%%mm1\n" // mm1-128:u1 u1 u0 u0 u1 u1 u0 u0 + "psubw %9,%%mm1\n" // mm1-128:u1 u1 u0 u0 u1 u1 u0 u0 // create Cb_g (result in mm5) "movq %%mm1,%%mm5\n" // u1 u1 u0 u0 u1 u1 u0 u0 - "pmullw _MMX_UgrnRGB,%%mm5\n" // blue*-109dec=1.7129*64 - "pmullw _MMX_UbluRGB,%%mm1\n" // blue*114dec=1.78125*64 + "pmullw %14,%%mm5\n" // blue*-109dec=1.7129*64 + "pmullw %15,%%mm1\n" // blue*114dec=1.78125*64 "psraw $6, %%mm5\n" // blue=red/64 "psraw $6, %%mm1\n" // blue=blue/64 @@ -213,7 +216,7 @@ void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, "addl $4,%2\n" // lum+4 "leal 16(%3),%3\n" // row1+16 "leal 16(%5),%5\n" // row2+16 - "addl $2, %%ebx\n" // cr+2 + "addl $2, (%%esp)\n" // cr+2 "addl $2, %1\n" // cb+2 "addl $4,%6\n" // x+4 @@ -226,11 +229,16 @@ void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, "movl $0, %6\n" // x=0 "cmpl %7, %2\n" "jl 1b\n" - "emms\n" - "popl %%ebx\n" + + "addl $4, %%esp\n" // get rid of the stack slot we reserved. + "emms\n" // reset MMX registers. : : "m" (cr), "r"(cb),"r"(lum), - "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod)); + "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod), + "m"(MMX_0080w),"m"(MMX_VgrnRGB),"m"(MMX_VredRGB), + "m"(MMX_FF00w),"m"(MMX_00FFw),"m"(MMX_UgrnRGB), + "m"(MMX_UbluRGB) + ); } void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, @@ -249,31 +257,40 @@ void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, __asm__ __volatile__( - "pushl %%ebx\n" - "movl %0, %%ebx\n" + // tap dance to workaround the inability to use %%ebx at will... + // move one thing to the stack... + "pushl $0\n" // save a slot on the stack. + "pushl %%ebx\n" // save %%ebx. + "movl %0, %%ebx\n" // put the thing in ebx. + "movl %%ebx, 4(%%esp)\n" // put the thing in the stack slot. + "popl %%ebx\n" // get back %%ebx (the PIC register). ".align 8\n" "1:\n" "movd (%1), %%mm0\n" // 4 Cb 0 0 0 0 u3 u2 u1 u0 "pxor %%mm7, %%mm7\n" - "movd (%%ebx), %%mm1\n" // 4 Cr 0 0 0 0 v3 v2 v1 v0 + "pushl %%ebx\n" + "movl 4(%%esp), %%ebx\n" + "movd (%%ebx), %%mm1\n" // 4 Cr 0 0 0 0 v3 v2 v1 v0 + "popl %%ebx\n" + "punpcklbw %%mm7, %%mm0\n" // 4 W cb 0 u3 0 u2 0 u1 0 u0 "punpcklbw %%mm7, %%mm1\n" // 4 W cr 0 v3 0 v2 0 v1 0 v0 - "psubw _MMX_0080w, %%mm0\n" - "psubw _MMX_0080w, %%mm1\n" + "psubw %9, %%mm0\n" + "psubw %9, %%mm1\n" "movq %%mm0, %%mm2\n" // Cb 0 u3 0 u2 0 u1 0 u0 "movq %%mm1, %%mm3\n" // Cr - "pmullw _MMX_Ugrn565, %%mm2\n" // Cb2green 0 R3 0 R2 0 R1 0 R0 + "pmullw %10, %%mm2\n" // Cb2green 0 R3 0 R2 0 R1 0 R0 "movq (%2), %%mm6\n" // L1 l7 L6 L5 L4 L3 L2 L1 L0 - "pmullw _MMX_Ublu5x5, %%mm0\n" // Cb2blue - "pand _MMX_00FFw, %%mm6\n" // L1 00 L6 00 L4 00 L2 00 L0 - "pmullw _MMX_Vgrn565, %%mm3\n" // Cr2green + "pmullw %11, %%mm0\n" // Cb2blue + "pand %12, %%mm6\n" // L1 00 L6 00 L4 00 L2 00 L0 + "pmullw %13, %%mm3\n" // Cr2green "movq (%2), %%mm7\n" // L2 - "pmullw _MMX_Vred5x5, %%mm1\n" // Cr2red + "pmullw %14, %%mm1\n" // Cr2red "psrlw $8, %%mm7\n" // L2 00 L7 00 L5 00 L3 00 L1 - "pmullw _MMX_Ycoeff, %%mm6\n" // lum1 + "pmullw %15, %%mm6\n" // lum1 "paddw %%mm3, %%mm2\n" // Cb2green + Cr2green == green - "pmullw _MMX_Ycoeff, %%mm7\n" // lum2 + "pmullw %15, %%mm7\n" // lum2 "movq %%mm6, %%mm4\n" // lum1 "paddw %%mm0, %%mm6\n" // lum1 +blue 00 B6 00 B4 00 B2 00 B0 @@ -291,11 +308,11 @@ void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, "punpcklbw %%mm4, %%mm4\n" "punpcklbw %%mm5, %%mm5\n" - "pand _MMX_red565, %%mm4\n" + "pand %16, %%mm4\n" "psllw $3, %%mm5\n" // GREEN 1 "punpcklbw %%mm6, %%mm6\n" - "pand _MMX_grn565, %%mm5\n" - "pand _MMX_red565, %%mm6\n" + "pand %17, %%mm5\n" + "pand %16, %%mm6\n" "por %%mm5, %%mm4\n" // "psrlw $11, %%mm6\n" // BLUE 1 "movq %%mm3, %%mm5\n" // lum2 @@ -309,23 +326,23 @@ void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, "packuswb %%mm3, %%mm3\n" "packuswb %%mm5, %%mm5\n" "packuswb %%mm7, %%mm7\n" - "pand _MMX_00FFw, %%mm6\n" // L3 + "pand %12, %%mm6\n" // L3 "punpcklbw %%mm3, %%mm3\n" "punpcklbw %%mm5, %%mm5\n" - "pmullw _MMX_Ycoeff, %%mm6\n" // lum3 + "pmullw %15, %%mm6\n" // lum3 "punpcklbw %%mm7, %%mm7\n" "psllw $3, %%mm5\n" // GREEN 2 - "pand _MMX_red565, %%mm7\n" - "pand _MMX_red565, %%mm3\n" + "pand %16, %%mm7\n" + "pand %16, %%mm3\n" "psrlw $11, %%mm7\n" // BLUE 2 - "pand _MMX_grn565, %%mm5\n" + "pand %17, %%mm5\n" "por %%mm7, %%mm3\n" "movq (%2,%4), %%mm7\n" // L4 load lum2 "por %%mm5, %%mm3\n" // "psrlw $8, %%mm7\n" // L4 "movq %%mm4, %%mm5\n" "punpcklwd %%mm3, %%mm4\n" - "pmullw _MMX_Ycoeff, %%mm7\n" // lum4 + "pmullw %15, %%mm7\n" // lum4 "punpckhwd %%mm3, %%mm5\n" "movq %%mm4, (%3)\n" // write row1 @@ -352,11 +369,11 @@ void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, "punpcklbw %%mm5, %%mm5\n" "punpcklbw %%mm6, %%mm6\n" "psllw $3, %%mm5\n" // GREEN 3 - "pand _MMX_red565, %%mm4\n" + "pand %16, %%mm4\n" "psraw $6, %%mm3\n" // psr 6 "psraw $6, %%mm0\n" - "pand _MMX_red565, %%mm6\n" // BLUE - "pand _MMX_grn565, %%mm5\n" + "pand %16, %%mm6\n" // BLUE + "pand %17, %%mm5\n" "psrlw $11, %%mm6\n" // BLUE 3 "por %%mm5, %%mm4\n" "psraw $6, %%mm7\n" @@ -367,11 +384,11 @@ void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, "punpcklbw %%mm3, %%mm3\n" "punpcklbw %%mm0, %%mm0\n" "punpcklbw %%mm7, %%mm7\n" - "pand _MMX_red565, %%mm3\n" - "pand _MMX_red565, %%mm7\n" // BLUE + "pand %16, %%mm3\n" + "pand %16, %%mm7\n" // BLUE "psllw $3, %%mm0\n" // GREEN 4 "psrlw $11, %%mm7\n" - "pand _MMX_grn565, %%mm0\n" + "pand %17, %%mm0\n" "por %%mm7, %%mm3\n" "por %%mm0, %%mm3\n" @@ -381,30 +398,33 @@ void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, "punpckhwd %%mm3, %%mm5\n" "movq %%mm4, (%5)\n" - "movq %%mm5, 8(%5)\n" + "movq %%mm5, 8(%5)\n" "addl $8, %6\n" "addl $8, %2\n" - "addl $4, %%ebx\n" + "addl $4, (%%esp)\n" "addl $4, %1\n" "cmpl %4, %6\n" "leal 16(%3), %3\n" - "leal 16(%5),%5\n" // row2+16 + "leal 16(%5),%5\n" // row2+16 "jl 1b\n" - "addl %4, %2\n" // lum += cols - "addl %8, %3\n" // row1+= mod - "addl %8, %5\n" // row2+= mod - "movl $0, %6\n" // x=0 - "cmpl %7, %2\n" - "jl 1b\n" + "addl %4, %2\n" // lum += cols + "addl %8, %3\n" // row1+= mod + "addl %8, %5\n" // row2+= mod + "movl $0, %6\n" // x=0 + "cmpl %7, %2\n" + "jl 1b\n" + "addl $4, %%esp\n" // get rid of the stack slot we reserved. "emms\n" - "popl %%ebx\n" : - :"m" (cr), "r"(cb),"r"(lum), - "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod)); + : "m" (cr), "r"(cb),"r"(lum), + "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod), + "m"(MMX_0080w),"m"(MMX_Ugrn565),"m"(MMX_Ublu5x5), + "m"(MMX_00FFw),"m"(MMX_Vgrn565),"m"(MMX_Vred5x5), + "m"(MMX_Ycoeff),"m"(MMX_red565),"m"(MMX_grn565)); } -#endif /* GCC i386 inline assembly */ -#endif /* 0 */ +#endif /* GCC3 i386 inline assembly */ + diff --git a/src/video/SDL_yuv_sw.c b/src/video/SDL_yuv_sw.c index c67d59296..66c2bb7dc 100644 --- a/src/video/SDL_yuv_sw.c +++ b/src/video/SDL_yuv_sw.c @@ -121,7 +121,7 @@ struct private_yuvhwdata { /* The colorspace conversion functions */ -#if 0 /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES*/ +#if (__GNUC__ > 2) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES extern void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, unsigned char *lum, unsigned char *cr, unsigned char *cb, unsigned char *out, @@ -1061,7 +1061,7 @@ SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_S case SDL_YV12_OVERLAY: case SDL_IYUV_OVERLAY: if ( display->format->BytesPerPixel == 2 ) { -#if 0 /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES*/ +#if (__GNUC__ > 2) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES /* inline assembly functions */ if ( SDL_HasMMX() && (Rmask == 0xF800) && (Gmask == 0x07E0) && @@ -1083,7 +1083,7 @@ SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_S swdata->Display2X = Color24DitherYV12Mod2X; } if ( display->format->BytesPerPixel == 4 ) { -#if 0 /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES*/ +#if (__GNUC__ > 2) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES /* inline assembly functions */ if ( SDL_HasMMX() && (Rmask == 0x00FF0000) && (Gmask == 0x0000FF00) && From fcba672095a4be05a6d2ced89bd3a83355659325 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 11 Jul 2007 07:21:39 +0000 Subject: [PATCH 200/241] Cleaned up tabs. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402480 --- src/video/SDL_yuv_mmx.c | 597 ++++++++++++++++++++-------------------- 1 file changed, 298 insertions(+), 299 deletions(-) diff --git a/src/video/SDL_yuv_mmx.c b/src/video/SDL_yuv_mmx.c index 580d6ce16..cd0fcbf52 100644 --- a/src/video/SDL_yuv_mmx.c +++ b/src/video/SDL_yuv_mmx.c @@ -95,149 +95,149 @@ void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, mod = (mod+cols+mod)*4; // increment for row1 in byte __asm__ __volatile__ ( - // tap dance to workaround the inability to use %%ebx at will... - // move one thing to the stack... - "pushl $0\n" // save a slot on the stack. - "pushl %%ebx\n" // save %%ebx. - "movl %0, %%ebx\n" // put the thing in ebx. - "movl %%ebx, 4(%%esp)\n" // put the thing in the stack slot. - "popl %%ebx\n" // get back %%ebx (the PIC register). + // tap dance to workaround the inability to use %%ebx at will... + // move one thing to the stack... + "pushl $0\n" // save a slot on the stack. + "pushl %%ebx\n" // save %%ebx. + "movl %0, %%ebx\n" // put the thing in ebx. + "movl %%ebx,4(%%esp)\n" // put the thing in the stack slot. + "popl %%ebx\n" // get back %%ebx (the PIC register). - ".align 8\n" - "1:\n" - - // create Cr (result in mm1) - "pushl %%ebx\n" - "movl 4(%%esp), %%ebx\n" - "movd (%%ebx), %%mm1\n" // 0 0 0 0 v3 v2 v1 v0 - "popl %%ebx\n" - "pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00 - "movd (%2), %%mm2\n" // 0 0 0 0 l3 l2 l1 l0 - "punpcklbw %%mm7,%%mm1\n" // 0 v3 0 v2 00 v1 00 v0 - "punpckldq %%mm1,%%mm1\n" // 00 v1 00 v0 00 v1 00 v0 - "psubw %9,%%mm1\n" // mm1-128:r1 r1 r0 r0 r1 r1 r0 r0 + ".align 8\n" + "1:\n" + + // create Cr (result in mm1) + "pushl %%ebx\n" + "movl 4(%%esp),%%ebx\n" + "movd (%%ebx),%%mm1\n" // 0 0 0 0 v3 v2 v1 v0 + "popl %%ebx\n" + "pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00 + "movd (%2), %%mm2\n" // 0 0 0 0 l3 l2 l1 l0 + "punpcklbw %%mm7,%%mm1\n" // 0 v3 0 v2 00 v1 00 v0 + "punpckldq %%mm1,%%mm1\n" // 00 v1 00 v0 00 v1 00 v0 + "psubw %9,%%mm1\n" // mm1-128:r1 r1 r0 r0 r1 r1 r0 r0 // create Cr_g (result in mm0) - "movq %%mm1,%%mm0\n" // r1 r1 r0 r0 r1 r1 r0 r0 - "pmullw %10,%%mm0\n" // red*-46dec=0.7136*64 - "pmullw %11,%%mm1\n" // red*89dec=1.4013*64 - "psraw $6, %%mm0\n" // red=red/64 - "psraw $6, %%mm1\n" // red=red/64 + "movq %%mm1,%%mm0\n" // r1 r1 r0 r0 r1 r1 r0 r0 + "pmullw %10,%%mm0\n" // red*-46dec=0.7136*64 + "pmullw %11,%%mm1\n" // red*89dec=1.4013*64 + "psraw $6, %%mm0\n" // red=red/64 + "psraw $6, %%mm1\n" // red=red/64 + + // create L1 L2 (result in mm2,mm4) + // L2=lum+cols + "movq (%2,%4),%%mm3\n" // 0 0 0 0 L3 L2 L1 L0 + "punpckldq %%mm3,%%mm2\n" // L3 L2 L1 L0 l3 l2 l1 l0 + "movq %%mm2,%%mm4\n" // L3 L2 L1 L0 l3 l2 l1 l0 + "pand %12,%%mm2\n" // L3 0 L1 0 l3 0 l1 0 + "pand %13,%%mm4\n" // 0 L2 0 L0 0 l2 0 l0 + "psrlw $8,%%mm2\n" // 0 L3 0 L1 0 l3 0 l1 + + // create R (result in mm6) + "movq %%mm2,%%mm5\n" // 0 L3 0 L1 0 l3 0 l1 + "movq %%mm4,%%mm6\n" // 0 L2 0 L0 0 l2 0 l0 + "paddsw %%mm1, %%mm5\n" // lum1+red:x R3 x R1 x r3 x r1 + "paddsw %%mm1, %%mm6\n" // lum1+red:x R2 x R0 x r2 x r0 + "packuswb %%mm5,%%mm5\n" // R3 R1 r3 r1 R3 R1 r3 r1 + "packuswb %%mm6,%%mm6\n" // R2 R0 r2 r0 R2 R0 r2 r0 + "pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00 + "punpcklbw %%mm5,%%mm6\n" // R3 R2 R1 R0 r3 r2 r1 r0 + + // create Cb (result in mm1) + "movd (%1), %%mm1\n" // 0 0 0 0 u3 u2 u1 u0 + "punpcklbw %%mm7,%%mm1\n" // 0 u3 0 u2 00 u1 00 u0 + "punpckldq %%mm1,%%mm1\n" // 00 u1 00 u0 00 u1 00 u0 + "psubw %9,%%mm1\n" // mm1-128:u1 u1 u0 u0 u1 u1 u0 u0 + // create Cb_g (result in mm5) + "movq %%mm1,%%mm5\n" // u1 u1 u0 u0 u1 u1 u0 u0 + "pmullw %14,%%mm5\n" // blue*-109dec=1.7129*64 + "pmullw %15,%%mm1\n" // blue*114dec=1.78125*64 + "psraw $6, %%mm5\n" // blue=red/64 + "psraw $6, %%mm1\n" // blue=blue/64 + + // create G (result in mm7) + "movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1 + "movq %%mm4,%%mm7\n" // 0 L2 0 L0 0 l2 0 l1 + "paddsw %%mm5, %%mm3\n" // lum1+Cb_g:x G3t x G1t x g3t x g1t + "paddsw %%mm5, %%mm7\n" // lum1+Cb_g:x G2t x G0t x g2t x g0t + "paddsw %%mm0, %%mm3\n" // lum1+Cr_g:x G3 x G1 x g3 x g1 + "paddsw %%mm0, %%mm7\n" // lum1+blue:x G2 x G0 x g2 x g0 + "packuswb %%mm3,%%mm3\n" // G3 G1 g3 g1 G3 G1 g3 g1 + "packuswb %%mm7,%%mm7\n" // G2 G0 g2 g0 G2 G0 g2 g0 + "punpcklbw %%mm3,%%mm7\n" // G3 G2 G1 G0 g3 g2 g1 g0 + + // create B (result in mm5) + "movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1 + "movq %%mm4,%%mm5\n" // 0 L2 0 L0 0 l2 0 l1 + "paddsw %%mm1, %%mm3\n" // lum1+blue:x B3 x B1 x b3 x b1 + "paddsw %%mm1, %%mm5\n" // lum1+blue:x B2 x B0 x b2 x b0 + "packuswb %%mm3,%%mm3\n" // B3 B1 b3 b1 B3 B1 b3 b1 + "packuswb %%mm5,%%mm5\n" // B2 B0 b2 b0 B2 B0 b2 b0 + "punpcklbw %%mm3,%%mm5\n" // B3 B2 B1 B0 b3 b2 b1 b0 + + // fill destination row1 (needed are mm6=Rr,mm7=Gg,mm5=Bb) + + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "pxor %%mm4,%%mm4\n" // 0 0 0 0 0 0 0 0 + "movq %%mm6,%%mm1\n" // R3 R2 R1 R0 r3 r2 r1 r0 + "movq %%mm5,%%mm3\n" // B3 B2 B1 B0 b3 b2 b1 b0 + // process lower lum + "punpcklbw %%mm4,%%mm1\n" // 0 r3 0 r2 0 r1 0 r0 + "punpcklbw %%mm4,%%mm3\n" // 0 b3 0 b2 0 b1 0 b0 + "movq %%mm1,%%mm2\n" // 0 r3 0 r2 0 r1 0 r0 + "movq %%mm3,%%mm0\n" // 0 b3 0 b2 0 b1 0 b0 + "punpcklwd %%mm1,%%mm3\n" // 0 r1 0 b1 0 r0 0 b0 + "punpckhwd %%mm2,%%mm0\n" // 0 r3 0 b3 0 r2 0 b2 + + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "movq %%mm7,%%mm1\n" // G3 G2 G1 G0 g3 g2 g1 g0 + "punpcklbw %%mm1,%%mm2\n" // g3 0 g2 0 g1 0 g0 0 + "punpcklwd %%mm4,%%mm2\n" // 0 0 g1 0 0 0 g0 0 + "por %%mm3, %%mm2\n" // 0 r1 g1 b1 0 r0 g0 b0 + "movq %%mm2,(%3)\n" // wrote out ! row1 + + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "punpcklbw %%mm1,%%mm4\n" // g3 0 g2 0 g1 0 g0 0 + "punpckhwd %%mm2,%%mm4\n" // 0 0 g3 0 0 0 g2 0 + "por %%mm0, %%mm4\n" // 0 r3 g3 b3 0 r2 g2 b2 + "movq %%mm4,8(%3)\n" // wrote out ! row1 - // create L1 L2 (result in mm2,mm4) - // L2=lum+cols - "movq (%2,%4),%%mm3\n" // 0 0 0 0 L3 L2 L1 L0 - "punpckldq %%mm3,%%mm2\n" // L3 L2 L1 L0 l3 l2 l1 l0 - "movq %%mm2,%%mm4\n" // L3 L2 L1 L0 l3 l2 l1 l0 - "pand %12,%%mm2\n" // L3 0 L1 0 l3 0 l1 0 - "pand %13,%%mm4\n" // 0 L2 0 L0 0 l2 0 l0 - "psrlw $8,%%mm2\n" // 0 L3 0 L1 0 l3 0 l1 - - // create R (result in mm6) - "movq %%mm2,%%mm5\n" // 0 L3 0 L1 0 l3 0 l1 - "movq %%mm4,%%mm6\n" // 0 L2 0 L0 0 l2 0 l0 - "paddsw %%mm1, %%mm5\n" // lum1+red:x R3 x R1 x r3 x r1 - "paddsw %%mm1, %%mm6\n" // lum1+red:x R2 x R0 x r2 x r0 - "packuswb %%mm5,%%mm5\n" // R3 R1 r3 r1 R3 R1 r3 r1 - "packuswb %%mm6,%%mm6\n" // R2 R0 r2 r0 R2 R0 r2 r0 - "pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00 - "punpcklbw %%mm5,%%mm6\n" // R3 R2 R1 R0 r3 r2 r1 r0 - - // create Cb (result in mm1) - "movd (%1), %%mm1\n" // 0 0 0 0 u3 u2 u1 u0 - "punpcklbw %%mm7,%%mm1\n" // 0 u3 0 u2 00 u1 00 u0 - "punpckldq %%mm1,%%mm1\n" // 00 u1 00 u0 00 u1 00 u0 - "psubw %9,%%mm1\n" // mm1-128:u1 u1 u0 u0 u1 u1 u0 u0 - // create Cb_g (result in mm5) - "movq %%mm1,%%mm5\n" // u1 u1 u0 u0 u1 u1 u0 u0 - "pmullw %14,%%mm5\n" // blue*-109dec=1.7129*64 - "pmullw %15,%%mm1\n" // blue*114dec=1.78125*64 - "psraw $6, %%mm5\n" // blue=red/64 - "psraw $6, %%mm1\n" // blue=blue/64 - - // create G (result in mm7) - "movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1 - "movq %%mm4,%%mm7\n" // 0 L2 0 L0 0 l2 0 l1 - "paddsw %%mm5, %%mm3\n" // lum1+Cb_g:x G3t x G1t x g3t x g1t - "paddsw %%mm5, %%mm7\n" // lum1+Cb_g:x G2t x G0t x g2t x g0t - "paddsw %%mm0, %%mm3\n" // lum1+Cr_g:x G3 x G1 x g3 x g1 - "paddsw %%mm0, %%mm7\n" // lum1+blue:x G2 x G0 x g2 x g0 - "packuswb %%mm3,%%mm3\n" // G3 G1 g3 g1 G3 G1 g3 g1 - "packuswb %%mm7,%%mm7\n" // G2 G0 g2 g0 G2 G0 g2 g0 - "punpcklbw %%mm3,%%mm7\n" // G3 G2 G1 G0 g3 g2 g1 g0 + // fill destination row2 (needed are mm6=Rr,mm7=Gg,mm5=Bb) + // this can be done "destructive" + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "punpckhbw %%mm2,%%mm6\n" // 0 R3 0 R2 0 R1 0 R0 + "punpckhbw %%mm1,%%mm5\n" // G3 B3 G2 B2 G1 B1 G0 B0 + "movq %%mm5,%%mm1\n" // G3 B3 G2 B2 G1 B1 G0 B0 + "punpcklwd %%mm6,%%mm1\n" // 0 R1 G1 B1 0 R0 G0 B0 + "movq %%mm1,(%5)\n" // wrote out ! row2 + "punpckhwd %%mm6,%%mm5\n" // 0 R3 G3 B3 0 R2 G2 B2 + "movq %%mm5,8(%5)\n" // wrote out ! row2 - // create B (result in mm5) - "movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1 - "movq %%mm4,%%mm5\n" // 0 L2 0 L0 0 l2 0 l1 - "paddsw %%mm1, %%mm3\n" // lum1+blue:x B3 x B1 x b3 x b1 - "paddsw %%mm1, %%mm5\n" // lum1+blue:x B2 x B0 x b2 x b0 - "packuswb %%mm3,%%mm3\n" // B3 B1 b3 b1 B3 B1 b3 b1 - "packuswb %%mm5,%%mm5\n" // B2 B0 b2 b0 B2 B0 b2 b0 - "punpcklbw %%mm3,%%mm5\n" // B3 B2 B1 B0 b3 b2 b1 b0 + "addl $4,%2\n" // lum+4 + "leal 16(%3),%3\n" // row1+16 + "leal 16(%5),%5\n" // row2+16 + "addl $2,(%%esp)\n" // cr+2 + "addl $2,%1\n" // cb+2 - // fill destination row1 (needed are mm6=Rr,mm7=Gg,mm5=Bb) + "addl $4,%6\n" // x+4 + "cmpl %4,%6\n" - "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 - "pxor %%mm4,%%mm4\n" // 0 0 0 0 0 0 0 0 - "movq %%mm6,%%mm1\n" // R3 R2 R1 R0 r3 r2 r1 r0 - "movq %%mm5,%%mm3\n" // B3 B2 B1 B0 b3 b2 b1 b0 - // process lower lum - "punpcklbw %%mm4,%%mm1\n" // 0 r3 0 r2 0 r1 0 r0 - "punpcklbw %%mm4,%%mm3\n" // 0 b3 0 b2 0 b1 0 b0 - "movq %%mm1,%%mm2\n" // 0 r3 0 r2 0 r1 0 r0 - "movq %%mm3,%%mm0\n" // 0 b3 0 b2 0 b1 0 b0 - "punpcklwd %%mm1,%%mm3\n" // 0 r1 0 b1 0 r0 0 b0 - "punpckhwd %%mm2,%%mm0\n" // 0 r3 0 b3 0 r2 0 b2 + "jl 1b\n" + "addl %4,%2\n" // lum += cols + "addl %8,%3\n" // row1+= mod + "addl %8,%5\n" // row2+= mod + "movl $0,%6\n" // x=0 + "cmpl %7,%2\n" + "jl 1b\n" - "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 - "movq %%mm7,%%mm1\n" // G3 G2 G1 G0 g3 g2 g1 g0 - "punpcklbw %%mm1,%%mm2\n" // g3 0 g2 0 g1 0 g0 0 - "punpcklwd %%mm4,%%mm2\n" // 0 0 g1 0 0 0 g0 0 - "por %%mm3, %%mm2\n" // 0 r1 g1 b1 0 r0 g0 b0 - "movq %%mm2,(%3)\n" // wrote out ! row1 - - "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 - "punpcklbw %%mm1,%%mm4\n" // g3 0 g2 0 g1 0 g0 0 - "punpckhwd %%mm2,%%mm4\n" // 0 0 g3 0 0 0 g2 0 - "por %%mm0, %%mm4\n" // 0 r3 g3 b3 0 r2 g2 b2 - "movq %%mm4,8(%3)\n" // wrote out ! row1 - - // fill destination row2 (needed are mm6=Rr,mm7=Gg,mm5=Bb) - // this can be done "destructive" - "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 - "punpckhbw %%mm2,%%mm6\n" // 0 R3 0 R2 0 R1 0 R0 - "punpckhbw %%mm1,%%mm5\n" // G3 B3 G2 B2 G1 B1 G0 B0 - "movq %%mm5,%%mm1\n" // G3 B3 G2 B2 G1 B1 G0 B0 - "punpcklwd %%mm6,%%mm1\n" // 0 R1 G1 B1 0 R0 G0 B0 - "movq %%mm1,(%5)\n" // wrote out ! row2 - "punpckhwd %%mm6,%%mm5\n" // 0 R3 G3 B3 0 R2 G2 B2 - "movq %%mm5,8(%5)\n" // wrote out ! row2 - - "addl $4,%2\n" // lum+4 - "leal 16(%3),%3\n" // row1+16 - "leal 16(%5),%5\n" // row2+16 - "addl $2, (%%esp)\n" // cr+2 - "addl $2, %1\n" // cb+2 - - "addl $4,%6\n" // x+4 - "cmpl %4,%6\n" - - "jl 1b\n" - "addl %4, %2\n" // lum += cols - "addl %8, %3\n" // row1+= mod - "addl %8, %5\n" // row2+= mod - "movl $0, %6\n" // x=0 - "cmpl %7, %2\n" - "jl 1b\n" - - "addl $4, %%esp\n" // get rid of the stack slot we reserved. - "emms\n" // reset MMX registers. - : - : "m" (cr), "r"(cb),"r"(lum), - "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod), - "m"(MMX_0080w),"m"(MMX_VgrnRGB),"m"(MMX_VredRGB), - "m"(MMX_FF00w),"m"(MMX_00FFw),"m"(MMX_UgrnRGB), - "m"(MMX_UbluRGB) + "addl $4,%%esp\n" // get rid of the stack slot we reserved. + "emms\n" // reset MMX registers. + : + : "m" (cr), "r"(cb),"r"(lum), + "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod), + "m"(MMX_0080w),"m"(MMX_VgrnRGB),"m"(MMX_VredRGB), + "m"(MMX_FF00w),"m"(MMX_00FFw),"m"(MMX_UgrnRGB), + "m"(MMX_UbluRGB) ); } @@ -246,184 +246,183 @@ void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, unsigned char *cb, unsigned char *out, int rows, int cols, int mod ) { - Uint16 *row1; - Uint16 *row2; + Uint16 *row1; + Uint16 *row2; - unsigned char* y = lum +cols*rows; /* Pointer to the end */ - int x=0; - row1 = (Uint16 *)out; /* 16 bit target */ - row2 = (Uint16 *)out+cols+mod; /* start of second row */ - mod = (mod+cols+mod)*2; /* increment for row1 in byte */ + unsigned char* y = lum +cols*rows; /* Pointer to the end */ + int x = 0; + row1 = (Uint16 *)out; /* 16 bit target */ + row2 = (Uint16 *)out+cols+mod; /* start of second row */ + mod = (mod+cols+mod)*2; /* increment for row1 in byte */ + __asm__ __volatile__( + // tap dance to workaround the inability to use %%ebx at will... + // move one thing to the stack... + "pushl $0\n" // save a slot on the stack. + "pushl %%ebx\n" // save %%ebx. + "movl %0, %%ebx\n" // put the thing in ebx. + "movl %%ebx, 4(%%esp)\n" // put the thing in the stack slot. + "popl %%ebx\n" // get back %%ebx (the PIC register). - __asm__ __volatile__( - // tap dance to workaround the inability to use %%ebx at will... - // move one thing to the stack... - "pushl $0\n" // save a slot on the stack. - "pushl %%ebx\n" // save %%ebx. - "movl %0, %%ebx\n" // put the thing in ebx. - "movl %%ebx, 4(%%esp)\n" // put the thing in the stack slot. - "popl %%ebx\n" // get back %%ebx (the PIC register). + ".align 8\n" + "1:\n" + "movd (%1), %%mm0\n" // 4 Cb 0 0 0 0 u3 u2 u1 u0 + "pxor %%mm7, %%mm7\n" + "pushl %%ebx\n" + "movl 4(%%esp), %%ebx\n" + "movd (%%ebx), %%mm1\n" // 4 Cr 0 0 0 0 v3 v2 v1 v0 + "popl %%ebx\n" - ".align 8\n" - "1:\n" - "movd (%1), %%mm0\n" // 4 Cb 0 0 0 0 u3 u2 u1 u0 - "pxor %%mm7, %%mm7\n" - "pushl %%ebx\n" - "movl 4(%%esp), %%ebx\n" - "movd (%%ebx), %%mm1\n" // 4 Cr 0 0 0 0 v3 v2 v1 v0 - "popl %%ebx\n" + "punpcklbw %%mm7, %%mm0\n" // 4 W cb 0 u3 0 u2 0 u1 0 u0 + "punpcklbw %%mm7, %%mm1\n" // 4 W cr 0 v3 0 v2 0 v1 0 v0 + "psubw %9, %%mm0\n" + "psubw %9, %%mm1\n" + "movq %%mm0, %%mm2\n" // Cb 0 u3 0 u2 0 u1 0 u0 + "movq %%mm1, %%mm3\n" // Cr + "pmullw %10, %%mm2\n" // Cb2green 0 R3 0 R2 0 R1 0 R0 + "movq (%2), %%mm6\n" // L1 l7 L6 L5 L4 L3 L2 L1 L0 + "pmullw %11, %%mm0\n" // Cb2blue + "pand %12, %%mm6\n" // L1 00 L6 00 L4 00 L2 00 L0 + "pmullw %13, %%mm3\n" // Cr2green + "movq (%2), %%mm7\n" // L2 + "pmullw %14, %%mm1\n" // Cr2red + "psrlw $8, %%mm7\n" // L2 00 L7 00 L5 00 L3 00 L1 + "pmullw %15, %%mm6\n" // lum1 + "paddw %%mm3, %%mm2\n" // Cb2green + Cr2green == green + "pmullw %15, %%mm7\n" // lum2 - "punpcklbw %%mm7, %%mm0\n" // 4 W cb 0 u3 0 u2 0 u1 0 u0 - "punpcklbw %%mm7, %%mm1\n" // 4 W cr 0 v3 0 v2 0 v1 0 v0 - "psubw %9, %%mm0\n" - "psubw %9, %%mm1\n" - "movq %%mm0, %%mm2\n" // Cb 0 u3 0 u2 0 u1 0 u0 - "movq %%mm1, %%mm3\n" // Cr - "pmullw %10, %%mm2\n" // Cb2green 0 R3 0 R2 0 R1 0 R0 - "movq (%2), %%mm6\n" // L1 l7 L6 L5 L4 L3 L2 L1 L0 - "pmullw %11, %%mm0\n" // Cb2blue - "pand %12, %%mm6\n" // L1 00 L6 00 L4 00 L2 00 L0 - "pmullw %13, %%mm3\n" // Cr2green - "movq (%2), %%mm7\n" // L2 - "pmullw %14, %%mm1\n" // Cr2red - "psrlw $8, %%mm7\n" // L2 00 L7 00 L5 00 L3 00 L1 - "pmullw %15, %%mm6\n" // lum1 - "paddw %%mm3, %%mm2\n" // Cb2green + Cr2green == green - "pmullw %15, %%mm7\n" // lum2 + "movq %%mm6, %%mm4\n" // lum1 + "paddw %%mm0, %%mm6\n" // lum1 +blue 00 B6 00 B4 00 B2 00 B0 + "movq %%mm4, %%mm5\n" // lum1 + "paddw %%mm1, %%mm4\n" // lum1 +red 00 R6 00 R4 00 R2 00 R0 + "paddw %%mm2, %%mm5\n" // lum1 +green 00 G6 00 G4 00 G2 00 G0 + "psraw $6, %%mm4\n" // R1 0 .. 64 + "movq %%mm7, %%mm3\n" // lum2 00 L7 00 L5 00 L3 00 L1 + "psraw $6, %%mm5\n" // G1 - .. + + "paddw %%mm0, %%mm7\n" // Lum2 +blue 00 B7 00 B5 00 B3 00 B1 + "psraw $6, %%mm6\n" // B1 0 .. 64 + "packuswb %%mm4, %%mm4\n" // R1 R1 + "packuswb %%mm5, %%mm5\n" // G1 G1 + "packuswb %%mm6, %%mm6\n" // B1 B1 + "punpcklbw %%mm4, %%mm4\n" + "punpcklbw %%mm5, %%mm5\n" - "movq %%mm6, %%mm4\n" // lum1 - "paddw %%mm0, %%mm6\n" // lum1 +blue 00 B6 00 B4 00 B2 00 B0 - "movq %%mm4, %%mm5\n" // lum1 - "paddw %%mm1, %%mm4\n" // lum1 +red 00 R6 00 R4 00 R2 00 R0 - "paddw %%mm2, %%mm5\n" // lum1 +green 00 G6 00 G4 00 G2 00 G0 - "psraw $6, %%mm4\n" // R1 0 .. 64 - "movq %%mm7, %%mm3\n" // lum2 00 L7 00 L5 00 L3 00 L1 - "psraw $6, %%mm5\n" // G1 - .. + - "paddw %%mm0, %%mm7\n" // Lum2 +blue 00 B7 00 B5 00 B3 00 B1 - "psraw $6, %%mm6\n" // B1 0 .. 64 - "packuswb %%mm4, %%mm4\n" // R1 R1 - "packuswb %%mm5, %%mm5\n" // G1 G1 - "packuswb %%mm6, %%mm6\n" // B1 B1 - "punpcklbw %%mm4, %%mm4\n" - "punpcklbw %%mm5, %%mm5\n" + "pand %16, %%mm4\n" + "psllw $3, %%mm5\n" // GREEN 1 + "punpcklbw %%mm6, %%mm6\n" + "pand %17, %%mm5\n" + "pand %16, %%mm6\n" + "por %%mm5, %%mm4\n" // + "psrlw $11, %%mm6\n" // BLUE 1 + "movq %%mm3, %%mm5\n" // lum2 + "paddw %%mm1, %%mm3\n" // lum2 +red 00 R7 00 R5 00 R3 00 R1 + "paddw %%mm2, %%mm5\n" // lum2 +green 00 G7 00 G5 00 G3 00 G1 + "psraw $6, %%mm3\n" // R2 + "por %%mm6, %%mm4\n" // MM4 + "psraw $6, %%mm5\n" // G2 + "movq (%2, %4), %%mm6\n" // L3 load lum2 + "psraw $6, %%mm7\n" + "packuswb %%mm3, %%mm3\n" + "packuswb %%mm5, %%mm5\n" + "packuswb %%mm7, %%mm7\n" + "pand %12, %%mm6\n" // L3 + "punpcklbw %%mm3, %%mm3\n" + "punpcklbw %%mm5, %%mm5\n" + "pmullw %15, %%mm6\n" // lum3 + "punpcklbw %%mm7, %%mm7\n" + "psllw $3, %%mm5\n" // GREEN 2 + "pand %16, %%mm7\n" + "pand %16, %%mm3\n" + "psrlw $11, %%mm7\n" // BLUE 2 + "pand %17, %%mm5\n" + "por %%mm7, %%mm3\n" + "movq (%2,%4), %%mm7\n" // L4 load lum2 + "por %%mm5, %%mm3\n" // + "psrlw $8, %%mm7\n" // L4 + "movq %%mm4, %%mm5\n" + "punpcklwd %%mm3, %%mm4\n" + "pmullw %15, %%mm7\n" // lum4 + "punpckhwd %%mm3, %%mm5\n" - "pand %16, %%mm4\n" - "psllw $3, %%mm5\n" // GREEN 1 - "punpcklbw %%mm6, %%mm6\n" - "pand %17, %%mm5\n" - "pand %16, %%mm6\n" - "por %%mm5, %%mm4\n" // - "psrlw $11, %%mm6\n" // BLUE 1 - "movq %%mm3, %%mm5\n" // lum2 - "paddw %%mm1, %%mm3\n" // lum2 +red 00 R7 00 R5 00 R3 00 R1 - "paddw %%mm2, %%mm5\n" // lum2 +green 00 G7 00 G5 00 G3 00 G1 - "psraw $6, %%mm3\n" // R2 - "por %%mm6, %%mm4\n" // MM4 - "psraw $6, %%mm5\n" // G2 - "movq (%2, %4), %%mm6\n" // L3 load lum2 - "psraw $6, %%mm7\n" - "packuswb %%mm3, %%mm3\n" - "packuswb %%mm5, %%mm5\n" - "packuswb %%mm7, %%mm7\n" - "pand %12, %%mm6\n" // L3 - "punpcklbw %%mm3, %%mm3\n" - "punpcklbw %%mm5, %%mm5\n" - "pmullw %15, %%mm6\n" // lum3 - "punpcklbw %%mm7, %%mm7\n" - "psllw $3, %%mm5\n" // GREEN 2 - "pand %16, %%mm7\n" - "pand %16, %%mm3\n" - "psrlw $11, %%mm7\n" // BLUE 2 - "pand %17, %%mm5\n" - "por %%mm7, %%mm3\n" - "movq (%2,%4), %%mm7\n" // L4 load lum2 - "por %%mm5, %%mm3\n" // - "psrlw $8, %%mm7\n" // L4 - "movq %%mm4, %%mm5\n" - "punpcklwd %%mm3, %%mm4\n" - "pmullw %15, %%mm7\n" // lum4 - "punpckhwd %%mm3, %%mm5\n" + "movq %%mm4, (%3)\n" // write row1 + "movq %%mm5, 8(%3)\n" // write row1 - "movq %%mm4, (%3)\n" // write row1 - "movq %%mm5, 8(%3)\n" // write row1 + "movq %%mm6, %%mm4\n" // Lum3 + "paddw %%mm0, %%mm6\n" // Lum3 +blue - "movq %%mm6, %%mm4\n" // Lum3 - "paddw %%mm0, %%mm6\n" // Lum3 +blue + "movq %%mm4, %%mm5\n" // Lum3 + "paddw %%mm1, %%mm4\n" // Lum3 +red + "paddw %%mm2, %%mm5\n" // Lum3 +green + "psraw $6, %%mm4\n" + "movq %%mm7, %%mm3\n" // Lum4 + "psraw $6, %%mm5\n" + "paddw %%mm0, %%mm7\n" // Lum4 +blue + "psraw $6, %%mm6\n" // Lum3 +blue + "movq %%mm3, %%mm0\n" // Lum4 + "packuswb %%mm4, %%mm4\n" + "paddw %%mm1, %%mm3\n" // Lum4 +red + "packuswb %%mm5, %%mm5\n" + "paddw %%mm2, %%mm0\n" // Lum4 +green + "packuswb %%mm6, %%mm6\n" + "punpcklbw %%mm4, %%mm4\n" + "punpcklbw %%mm5, %%mm5\n" + "punpcklbw %%mm6, %%mm6\n" + "psllw $3, %%mm5\n" // GREEN 3 + "pand %16, %%mm4\n" + "psraw $6, %%mm3\n" // psr 6 + "psraw $6, %%mm0\n" + "pand %16, %%mm6\n" // BLUE + "pand %17, %%mm5\n" + "psrlw $11, %%mm6\n" // BLUE 3 + "por %%mm5, %%mm4\n" + "psraw $6, %%mm7\n" + "por %%mm6, %%mm4\n" + "packuswb %%mm3, %%mm3\n" + "packuswb %%mm0, %%mm0\n" + "packuswb %%mm7, %%mm7\n" + "punpcklbw %%mm3, %%mm3\n" + "punpcklbw %%mm0, %%mm0\n" + "punpcklbw %%mm7, %%mm7\n" + "pand %16, %%mm3\n" + "pand %16, %%mm7\n" // BLUE + "psllw $3, %%mm0\n" // GREEN 4 + "psrlw $11, %%mm7\n" + "pand %17, %%mm0\n" + "por %%mm7, %%mm3\n" + "por %%mm0, %%mm3\n" - "movq %%mm4, %%mm5\n" // Lum3 - "paddw %%mm1, %%mm4\n" // Lum3 +red - "paddw %%mm2, %%mm5\n" // Lum3 +green - "psraw $6, %%mm4\n" - "movq %%mm7, %%mm3\n" // Lum4 - "psraw $6, %%mm5\n" - "paddw %%mm0, %%mm7\n" // Lum4 +blue - "psraw $6, %%mm6\n" // Lum3 +blue - "movq %%mm3, %%mm0\n" // Lum4 - "packuswb %%mm4, %%mm4\n" - "paddw %%mm1, %%mm3\n" // Lum4 +red - "packuswb %%mm5, %%mm5\n" - "paddw %%mm2, %%mm0\n" // Lum4 +green - "packuswb %%mm6, %%mm6\n" - "punpcklbw %%mm4, %%mm4\n" - "punpcklbw %%mm5, %%mm5\n" - "punpcklbw %%mm6, %%mm6\n" - "psllw $3, %%mm5\n" // GREEN 3 - "pand %16, %%mm4\n" - "psraw $6, %%mm3\n" // psr 6 - "psraw $6, %%mm0\n" - "pand %16, %%mm6\n" // BLUE - "pand %17, %%mm5\n" - "psrlw $11, %%mm6\n" // BLUE 3 - "por %%mm5, %%mm4\n" - "psraw $6, %%mm7\n" - "por %%mm6, %%mm4\n" - "packuswb %%mm3, %%mm3\n" - "packuswb %%mm0, %%mm0\n" - "packuswb %%mm7, %%mm7\n" - "punpcklbw %%mm3, %%mm3\n" - "punpcklbw %%mm0, %%mm0\n" - "punpcklbw %%mm7, %%mm7\n" - "pand %16, %%mm3\n" - "pand %16, %%mm7\n" // BLUE - "psllw $3, %%mm0\n" // GREEN 4 - "psrlw $11, %%mm7\n" - "pand %17, %%mm0\n" - "por %%mm7, %%mm3\n" - "por %%mm0, %%mm3\n" + "movq %%mm4, %%mm5\n" - "movq %%mm4, %%mm5\n" + "punpcklwd %%mm3, %%mm4\n" + "punpckhwd %%mm3, %%mm5\n" - "punpcklwd %%mm3, %%mm4\n" - "punpckhwd %%mm3, %%mm5\n" + "movq %%mm4, (%5)\n" + "movq %%mm5, 8(%5)\n" - "movq %%mm4, (%5)\n" - "movq %%mm5, 8(%5)\n" + "addl $8, %6\n" + "addl $8, %2\n" + "addl $4, (%%esp)\n" + "addl $4, %1\n" + "cmpl %4, %6\n" + "leal 16(%3), %3\n" + "leal 16(%5),%5\n" // row2+16 - "addl $8, %6\n" - "addl $8, %2\n" - "addl $4, (%%esp)\n" - "addl $4, %1\n" - "cmpl %4, %6\n" - "leal 16(%3), %3\n" - "leal 16(%5),%5\n" // row2+16 - - - "jl 1b\n" - "addl %4, %2\n" // lum += cols - "addl %8, %3\n" // row1+= mod - "addl %8, %5\n" // row2+= mod - "movl $0, %6\n" // x=0 - "cmpl %7, %2\n" - "jl 1b\n" - "addl $4, %%esp\n" // get rid of the stack slot we reserved. - "emms\n" - : - : "m" (cr), "r"(cb),"r"(lum), - "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod), - "m"(MMX_0080w),"m"(MMX_Ugrn565),"m"(MMX_Ublu5x5), - "m"(MMX_00FFw),"m"(MMX_Vgrn565),"m"(MMX_Vred5x5), - "m"(MMX_Ycoeff),"m"(MMX_red565),"m"(MMX_grn565)); + "jl 1b\n" + "addl %4, %2\n" // lum += cols + "addl %8, %3\n" // row1+= mod + "addl %8, %5\n" // row2+= mod + "movl $0, %6\n" // x=0 + "cmpl %7, %2\n" + "jl 1b\n" + "addl $4, %%esp\n" // get rid of the stack slot we reserved. + "emms\n" + : + : "m" (cr), "r"(cb),"r"(lum), + "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod), + "m"(MMX_0080w),"m"(MMX_Ugrn565),"m"(MMX_Ublu5x5), + "m"(MMX_00FFw),"m"(MMX_Vgrn565),"m"(MMX_Vred5x5), + "m"(MMX_Ycoeff),"m"(MMX_red565),"m"(MMX_grn565) + ); } #endif /* GCC3 i386 inline assembly */ From 5f3ed9032b26dac99bad96dd349ad7a03378ad7e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 11 Jul 2007 07:25:57 +0000 Subject: [PATCH 201/241] Merged r3207:3208 from trunk/SDL: *INDENT-OFF* for inline asm. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402481 --- src/video/SDL_yuv_mmx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/video/SDL_yuv_mmx.c b/src/video/SDL_yuv_mmx.c index cd0fcbf52..1e35477e4 100644 --- a/src/video/SDL_yuv_mmx.c +++ b/src/video/SDL_yuv_mmx.c @@ -27,6 +27,8 @@ #include "mmx.h" +/* *INDENT-OFF* */ + static mmx_t MMX_0080w = { .ud = {0x00800080, 0x00800080} }; static mmx_t MMX_00FFw = { .ud = {0x00ff00ff, 0x00ff00ff} }; static mmx_t MMX_FF00w = { .ud = {0xff00ff00, 0xff00ff00} }; @@ -425,5 +427,7 @@ void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, ); } +/* *INDENT-ON* */ + #endif /* GCC3 i386 inline assembly */ From f7f530f9e08cc0d1a56a81f9dcd445975a7d5aa6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 11 Jul 2007 07:47:47 +0000 Subject: [PATCH 202/241] Added more release notes. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402483 --- docs.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs.html b/docs.html index 8bf29222e..77a1cb82a 100644 --- a/docs.html +++ b/docs.html @@ -52,6 +52,9 @@ SDL 1.2.12 is a minor bug fix release.

Unofficial support for the Nintendo DS platform has been added.

+

+ Reenabled MMX assembly for YUV overlay processing (GNU C Compiler only). +

Unix Notes

@@ -81,6 +84,9 @@ SDL 1.2.12 is a minor bug fix release.

Closed minor memory leak in XME code.

+

+ Fixed TEXTRELs in the library to resolve some PIC issues. +

Windows Notes

From 34fbbeed5386dbd0bc954f0f69ce1c59e6c781b1 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 11 Jul 2007 07:53:12 +0000 Subject: [PATCH 203/241] Added key composition support, courtesy of Kuon --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402484 --- src/video/quartz/SDL_QuartzEvents.m | 12 +++++------- src/video/quartz/SDL_QuartzVideo.h | 2 ++ src/video/quartz/SDL_QuartzVideo.m | 7 +++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/video/quartz/SDL_QuartzEvents.m b/src/video/quartz/SDL_QuartzEvents.m index 1647570b5..2edc4b8a0 100644 --- a/src/video/quartz/SDL_QuartzEvents.m +++ b/src/video/quartz/SDL_QuartzEvents.m @@ -254,7 +254,7 @@ void QZ_InitOSKeymap (_THIS) { static void QZ_DoKey (_THIS, int state, NSEvent *event) { NSString *chars; - unsigned int numChars; + unsigned int i, numChars; SDL_keysym key; /* @@ -265,7 +265,8 @@ static void QZ_DoKey (_THIS, int state, NSEvent *event) { contains multiple characters, we'll use 0 as the scancode/keysym. */ - if (SDL_TranslateUNICODE) { + if (SDL_TranslateUNICODE && state == SDL_PRESSED) { + [field_edit interpretKeyEvents:[NSArray arrayWithObject:event]]; chars = [ event characters ]; numChars = [ chars length ]; } else { @@ -281,7 +282,7 @@ static void QZ_DoKey (_THIS, int state, NSEvent *event) { SDL_PrivateKeyboard (state, &key); } - else if (numChars == 1) { + else if (numChars >= 1) { key.scancode = [ event keyCode ]; key.sym = keymap [ key.scancode ]; @@ -289,11 +290,8 @@ static void QZ_DoKey (_THIS, int state, NSEvent *event) { key.mod = KMOD_NONE; SDL_PrivateKeyboard (state, &key); - } - else /* (numChars > 1) */ { - int i; - for (i = 0; i < numChars; i++) { + for (i = 1; i < numChars; i++) { key.scancode = 0; key.sym = 0; diff --git a/src/video/quartz/SDL_QuartzVideo.h b/src/video/quartz/SDL_QuartzVideo.h index 50aa38432..7ffedbf71 100644 --- a/src/video/quartz/SDL_QuartzVideo.h +++ b/src/video/quartz/SDL_QuartzVideo.h @@ -99,6 +99,7 @@ typedef struct SDL_PrivateVideoData { SDL_Rect **client_mode_list; /* resolution list to pass back to client */ SDLKey keymap[256]; /* Mac OS X to SDL key mapping */ Uint32 current_mods; /* current keyboard modifiers, to track modifier state */ + NSText *field_edit; /* a field editor for keyboard composition processing */ Uint32 last_virtual_button;/* last virtual mouse button pressed */ io_connect_t power_connection; /* used with IOKit to detect wake from sleep */ Uint8 expect_mouse_up; /* used to determine when to send mouse up events */ @@ -146,6 +147,7 @@ typedef struct SDL_PrivateVideoData { #define client_mode_list (this->hidden->client_mode_list) #define keymap (this->hidden->keymap) #define current_mods (this->hidden->current_mods) +#define field_edit (this->hidden->field_edit) #define last_virtual_button (this->hidden->last_virtual_button) #define power_connection (this->hidden->power_connection) #define expect_mouse_up (this->hidden->expect_mouse_up) diff --git a/src/video/quartz/SDL_QuartzVideo.m b/src/video/quartz/SDL_QuartzVideo.m index 9a1759fbe..28dba613d 100644 --- a/src/video/quartz/SDL_QuartzVideo.m +++ b/src/video/quartz/SDL_QuartzVideo.m @@ -169,6 +169,7 @@ static void QZ_DeleteDevice (SDL_VideoDevice *device) { static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format) { + NSRect r = NSMakeRect(0.0, 0.0, 0.0, 0.0); const char *env = NULL; /* Initialize the video settings; this data persists between mode switches */ @@ -202,6 +203,7 @@ static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format) { cursor_should_be_visible = YES; cursor_visible = YES; current_mods = 0; + field_edit = [[NSTextView alloc] initWithFrame:r]; if ( Gestalt(gestaltSystemVersion, &system_version) != noErr ) system_version = 0; @@ -1456,6 +1458,11 @@ static void QZ_VideoQuit (_THIS) { opengl_library = NULL; } this->gl_config.driver_loaded = 0; + + if (field_edit) { + [field_edit release]; + field_edit = NULL; + } } #if 0 /* Not used (apparently, it's really slow) */ From c746a535e35fa5f72c69442cc9d3b3b4c5002a30 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Jul 2007 02:51:58 +0000 Subject: [PATCH 204/241] Warn Visual C++ users if they have a stale configure generated SDL_config.h --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402491 --- include/SDL_config.h.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index abb1b447d..13a3f9a03 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -28,6 +28,11 @@ /* General platform specific identifiers */ #include "SDL_platform.h" +/* Make sure that this isn't included by Visual C++ */ +#ifdef _MSC_VER +#error You should copy include/SDL_config.h.default to include/SDL_config.h +#endif + /* C language features */ #undef const #undef inline From 2bad9cfdd240bf2bee7848acb46561addf9986e9 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Jul 2007 05:19:55 +0000 Subject: [PATCH 205/241] Fixed joystick name detection --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402493 --- src/joystick/win32/SDL_mmjoystick.c | 101 +++++++++++++--------------- 1 file changed, 46 insertions(+), 55 deletions(-) diff --git a/src/joystick/win32/SDL_mmjoystick.c b/src/joystick/win32/SDL_mmjoystick.c index d54c82237..e71f8f84d 100644 --- a/src/joystick/win32/SDL_mmjoystick.c +++ b/src/joystick/win32/SDL_mmjoystick.c @@ -76,67 +76,58 @@ static char *GetJoystickName(int index, const char *szRegKey) index (1-16) listed in the registry */ char *name = NULL; + HKEY hTopKey; HKEY hKey; DWORD regsize; LONG regresult; - unsigned char regkey[256]; - unsigned char regvalue[256]; - unsigned char regname[256]; + char regkey[256]; + char regvalue[256]; + char regname[256]; - SDL_snprintf((char *) regkey, SDL_arraysize(regkey), "%s\\%s\\%s", - REGSTR_PATH_JOYCONFIG, - szRegKey, - REGSTR_KEY_JOYCURR); - regresult = RegOpenKeyExA(HKEY_LOCAL_MACHINE, - (LPTSTR) ®key, 0, KEY_READ, &hKey); - if (regresult == ERROR_SUCCESS) - { - /* - find the registry key name for the - joystick's properties - */ - regsize = sizeof(regname); - SDL_snprintf((char *) regvalue, SDL_arraysize(regvalue), - "Joystick%d%s", index+1, - REGSTR_VAL_JOYOEMNAME); - regresult = RegQueryValueExA(hKey, - (char *) regvalue, 0, 0, (LPBYTE) ®name, - (LPDWORD) ®size); - RegCloseKey(hKey); - if (regresult == ERROR_SUCCESS) - { - /* open that registry key */ - SDL_snprintf((char *) regkey, SDL_arraysize(regkey), "%s\\%s", - REGSTR_PATH_JOYOEM, regname); - regresult = RegOpenKeyExA(HKEY_LOCAL_MACHINE, - (char *) regkey, 0, KEY_READ, &hKey); - if (regresult == ERROR_SUCCESS) - { - /* find the size for the OEM name text */ - regsize = sizeof(regvalue); - regresult = - RegQueryValueExA(hKey, - REGSTR_VAL_JOYOEMNAME, - 0, 0, NULL, - (LPDWORD) ®size); - if (regresult == ERROR_SUCCESS) - { - /* - allocate enough memory - for the OEM name text ... - */ - name = (char *) SDL_malloc(regsize); - /* ... and read it from the registry */ - regresult = - RegQueryValueExA(hKey, - REGSTR_VAL_JOYOEMNAME, 0, 0, - (LPBYTE) name, - (LPDWORD) ®size); - RegCloseKey(hKey); - } - } + SDL_snprintf(regkey, SDL_arraysize(regkey), "%s\\%s\\%s", + REGSTR_PATH_JOYCONFIG, szRegKey, REGSTR_KEY_JOYCURR); + hTopKey = HKEY_LOCAL_MACHINE; + regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey); + if (regresult != ERROR_SUCCESS) { + hTopKey = HKEY_CURRENT_USER; + regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey); + } + if (regresult != ERROR_SUCCESS) { + return NULL; + } + + /* find the registry key name for the joystick's properties */ + regsize = sizeof(regname); + SDL_snprintf(regvalue, SDL_arraysize(regvalue), "Joystick%d%s", index+1, REGSTR_VAL_JOYOEMNAME); + regresult = RegQueryValueExA(hKey, regvalue, 0, 0, (LPBYTE)regname, ®size); + RegCloseKey(hKey); + + if (regresult != ERROR_SUCCESS) { + return NULL; + } + + /* open that registry key */ + SDL_snprintf(regkey, SDL_arraysize(regkey), "%s\\%s", REGSTR_PATH_JOYOEM, regname); + regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey); + if (regresult != ERROR_SUCCESS) { + return NULL; + } + + /* find the size for the OEM name text */ + regsize = sizeof(regvalue); + regresult = RegQueryValueExA(hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, NULL, ®size); + if (regresult == ERROR_SUCCESS) { + /* allocate enough memory for the OEM name text ... */ + name = (char *) SDL_malloc(regsize); + if ( name ) { + /* ... and read it from the registry */ + regresult = RegQueryValueExA(hKey, + REGSTR_VAL_JOYOEMNAME, 0, 0, + (LPBYTE) name, ®size); } } + RegCloseKey(hKey); + return(name); } From dfcf33773e1d1c26a9a4c2abeb8032345c353ffa Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Jul 2007 05:30:17 +0000 Subject: [PATCH 206/241] Added note about SDL_config.h --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402494 --- VisualC.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/VisualC.html b/VisualC.html index f5dbe784c..ad2ed97a6 100644 --- a/VisualC.html +++ b/VisualC.html @@ -45,6 +45,10 @@ This is done by right clicking on each project in turn (Projects are listed in the Workspace panel in the FileView tab), and selecting "Build".

+

+ If you get an error about SDL_config.h being missing, you should + copy include/SDL_config.h.default to include/SDL_config.h and try again. +

You may get a few warnings, but you should not get any errors. You do have to have at least the DirectX 5 SDK installed, however. The latest From 49f5340ada44ba531dc8311aee28356bf7fc66d9 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Jul 2007 07:29:19 +0000 Subject: [PATCH 207/241] Fixed bug #455 If passed "" for the character set, let iconv_open() interpret it as locale. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402501 --- src/stdlib/SDL_iconv.c | 54 ++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c index 9eaabead4..498969de1 100644 --- a/src/stdlib/SDL_iconv.c +++ b/src/stdlib/SDL_iconv.c @@ -107,10 +107,8 @@ static struct { const char *name; int format; } encodings[] = { - { "646", ENCODING_ASCII }, { "ASCII", ENCODING_ASCII }, { "US-ASCII", ENCODING_ASCII }, - { "LATIN1", ENCODING_LATIN1 }, { "8859-1", ENCODING_LATIN1 }, { "ISO-8859-1", ENCODING_LATIN1 }, { "UTF8", ENCODING_UTF8 }, @@ -133,12 +131,38 @@ static struct { { "UCS-4", ENCODING_UCS4 }, }; +static const char *getlocale() +{ + const char *lang; + + lang = SDL_getenv("LC_ALL"); + if ( !lang ) { + lang = SDL_getenv("LC_CTYPE"); + } + if ( !lang ) { + lang = SDL_getenv("LC_MESSAGES"); + } + if ( !lang ) { + lang = SDL_getenv("LANG"); + } + if ( !lang || !*lang || SDL_strcmp(lang, "C") == 0 ) { + lang = "ASCII"; + } + return lang; +} + SDL_iconv_t SDL_iconv_open(const char *tocode, const char *fromcode) { int src_fmt = ENCODING_UNKNOWN; int dst_fmt = ENCODING_UNKNOWN; int i; + if ( !fromcode || !*fromcode ) { + fromcode = getlocale(); + } + if ( !tocode || !*tocode ) { + fromcode = getlocale(); + } for ( i = 0; i < SDL_arraysize(encodings); ++i ) { if ( SDL_strcasecmp(fromcode, encodings[i].name) == 0 ) { src_fmt = encodings[i].format; @@ -772,26 +796,6 @@ int SDL_iconv_close(SDL_iconv_t cd) #endif /* !HAVE_ICONV */ -static const char *getlocale() -{ - const char *lang; - - lang = SDL_getenv("LC_ALL"); - if ( !lang ) { - lang = SDL_getenv("LC_CTYPE"); - } - if ( !lang ) { - lang = SDL_getenv("LC_MESSAGES"); - } - if ( !lang ) { - lang = SDL_getenv("LANG"); - } - if ( !lang || SDL_strcmp(lang, "C") == 0 ) { - lang = "ASCII"; - } - return lang; -} - char *SDL_iconv_string(const char *tocode, const char *fromcode, const char *inbuf, size_t inbytesleft) { SDL_iconv_t cd; @@ -801,12 +805,6 @@ char *SDL_iconv_string(const char *tocode, const char *fromcode, const char *inb size_t outbytesleft; size_t retCode = 0; - if ( !fromcode || !*fromcode ) { - fromcode = getlocale(); - } - if ( !tocode || !*tocode ) { - tocode = getlocale(); - } cd = SDL_iconv_open(tocode, fromcode); if ( cd == (SDL_iconv_t)-1 ) { return NULL; From 98c318704770b72e36cb01e99e1220f9cceb7063 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Jul 2007 07:47:29 +0000 Subject: [PATCH 208/241] Fixed iconv handling on Solaris 11 --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402502 --- src/stdlib/SDL_iconv.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c index 498969de1..fa8d9da0f 100644 --- a/src/stdlib/SDL_iconv.c +++ b/src/stdlib/SDL_iconv.c @@ -806,6 +806,16 @@ char *SDL_iconv_string(const char *tocode, const char *fromcode, const char *inb size_t retCode = 0; cd = SDL_iconv_open(tocode, fromcode); + if ( cd == (SDL_iconv_t)-1 ) { + /* See if we can recover here (fixes iconv on Solaris 11) */ + if ( !tocode || !*tocode ) { + tocode = "UTF-8"; + } + if ( !fromcode || !*fromcode ) { + tocode = "UTF-8"; + } + cd = SDL_iconv_open(tocode, fromcode); + } if ( cd == (SDL_iconv_t)-1 ) { return NULL; } From b38871d1850af0fd693bee64182b98522113e6d6 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Jul 2007 08:04:10 +0000 Subject: [PATCH 209/241] Ryan's fix is still good for the built-in version of iconv_open() --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402505 --- src/stdlib/SDL_iconv.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c index fa8d9da0f..307c73ca4 100644 --- a/src/stdlib/SDL_iconv.c +++ b/src/stdlib/SDL_iconv.c @@ -131,9 +131,10 @@ static struct { { "UCS-4", ENCODING_UCS4 }, }; -static const char *getlocale() +static const char *getlocale(char *buffer, size_t bufsize) { const char *lang; + char *ptr; lang = SDL_getenv("LC_ALL"); if ( !lang ) { @@ -148,7 +149,20 @@ static const char *getlocale() if ( !lang || !*lang || SDL_strcmp(lang, "C") == 0 ) { lang = "ASCII"; } - return lang; + + /* We need to trim down strings like "en_US.UTF-8@blah" to "UTF-8" */ + ptr = SDL_strchr(lang, '.'); + if (ptr != NULL) { + lang = ptr + 1; + } + + SDL_strlcpy(buffer, lang, bufsize); + ptr = SDL_strchr(buffer, '@'); + if (ptr != NULL) { + *ptr = '\0'; /* chop end of string. */ + } + + return buffer; } SDL_iconv_t SDL_iconv_open(const char *tocode, const char *fromcode) @@ -156,12 +170,14 @@ SDL_iconv_t SDL_iconv_open(const char *tocode, const char *fromcode) int src_fmt = ENCODING_UNKNOWN; int dst_fmt = ENCODING_UNKNOWN; int i; + char fromcode_buffer[64]; + char tocode_buffer[64]; if ( !fromcode || !*fromcode ) { - fromcode = getlocale(); + fromcode = getlocale(fromcode_buffer, sizeof(fromcode_buffer)); } if ( !tocode || !*tocode ) { - fromcode = getlocale(); + tocode = getlocale(tocode_buffer, sizeof(tocode_buffer)); } for ( i = 0; i < SDL_arraysize(encodings); ++i ) { if ( SDL_strcasecmp(fromcode, encodings[i].name) == 0 ) { From 60af778a01a8bccb89e9553c4253b7d33ab5e773 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Jul 2007 08:05:19 +0000 Subject: [PATCH 210/241] A better fix for building DGA code on Solaris 8, inspired by the NetBSD pkgsrc patch. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402506 --- src/video/dga/SDL_dgavideo.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/dga/SDL_dgavideo.h b/src/video/dga/SDL_dgavideo.h index 36d5af295..a0915da58 100644 --- a/src/video/dga/SDL_dgavideo.h +++ b/src/video/dga/SDL_dgavideo.h @@ -25,6 +25,7 @@ #define _SDL_dgavideo_h #include +#include #include #include "SDL_mouse.h" From 04195088927cc332ac4f58116e58e7b6c0fea743 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 12 Jul 2007 19:00:08 +0000 Subject: [PATCH 211/241] Formatting with tabs --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402508 --- src/video/gem/SDL_gemvideo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/gem/SDL_gemvideo.h b/src/video/gem/SDL_gemvideo.h index 844607825..de96628fb 100644 --- a/src/video/gem/SDL_gemvideo.h +++ b/src/video/gem/SDL_gemvideo.h @@ -49,13 +49,13 @@ void GEM_wind_redraw(_THIS, int winhandle, short *inside); struct SDL_PrivateVideoData { Uint16 buf2scr_ops; /* Operations to get buffer to screen */ - void *buffer1; /* Our shadow buffers */ + void *buffer1; /* Our shadow buffers */ void *buffer2; /* VDI infos */ short vdi_handle; /* VDI handle */ short full_w, full_h; /* Fullscreen size */ - short bpp; /* Colour depth */ + short bpp; /* Colour depth */ short pixelsize; /* Bytes per pixel */ short old_numcolors; /* Number of colors in saved palette */ Uint16 pitch; /* Line length */ From 03537c7353f8aa26bb3e605d71ef75c1f4978162 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 13 Jul 2007 03:57:40 +0000 Subject: [PATCH 212/241] Update default cross-compile install prefix for the latest mingw toolchain --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402510 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index ec4091045..5bffd518f 100644 --- a/configure.in +++ b/configure.in @@ -2373,7 +2373,7 @@ case "$host" in ARCH=win32 if test "$build" != "$host"; then # cross-compiling # Default cross-compile location - ac_default_prefix=/usr/local/cross-tools/i386-mingw32msvc + ac_default_prefix=/usr/local/cross-tools/i386-mingw32 else # Look for the location of the tools and install there if test "$BUILD_PREFIX" != ""; then From 5aafadda16f32be4f1df502a3e8df3549d9a028b Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 13 Jul 2007 16:09:16 +0000 Subject: [PATCH 213/241] Simplify setting window title --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402511 --- src/video/gem/SDL_gemevents.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/video/gem/SDL_gemevents.c b/src/video/gem/SDL_gemevents.c index 0e029eca7..6bcf817da 100644 --- a/src/video/gem/SDL_gemevents.c +++ b/src/video/gem/SDL_gemevents.c @@ -167,16 +167,14 @@ void GEM_PumpEvents(_THIS) /* Refresh window name ? */ if (GEM_refresh_name) { - if ( SDL_GetAppState() & SDL_APPACTIVE ) { - /* Fullscreen/windowed */ - if (GEM_title_name) { - wind_set(GEM_handle,WF_NAME,(short)(((unsigned long)GEM_title_name)>>16),(short)(((unsigned long)GEM_title_name) & 0xffff),0,0); - } - } else { - /* Iconified */ - if (GEM_icon_name) { - wind_set(GEM_handle,WF_NAME,(short)(((unsigned long)GEM_icon_name)>>16),(short)(((unsigned long)GEM_icon_name) & 0xffff),0,0); - } + const char *window_name = + (SDL_GetAppState() & SDL_APPACTIVE) + ? GEM_title_name : GEM_icon_name; + if (window_name) { + wind_set(GEM_handle,WF_NAME, + (short)(((unsigned long)window_name)>>16), + (short)(((unsigned long)window_name) & 0xffff), + 0,0); } GEM_refresh_name = SDL_FALSE; } From 739cd03b1dd69376efbbe12b19c60dee2be04bc6 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 13 Jul 2007 18:44:43 +0000 Subject: [PATCH 214/241] Call GEM_CheckMouseMode everytime something may change mouse form, and do it properly --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402513 --- src/video/gem/SDL_gemevents.c | 38 +++++++++++++----------------- src/video/gem/SDL_gemmouse.c | 44 ++++++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/src/video/gem/SDL_gemevents.c b/src/video/gem/SDL_gemevents.c index 6bcf817da..19c7c7459 100644 --- a/src/video/gem/SDL_gemevents.c +++ b/src/video/gem/SDL_gemevents.c @@ -89,11 +89,8 @@ void GEM_PumpEvents(_THIS) if (!GEM_fullscreen && (GEM_handle>=0)) { wind_get (GEM_handle, WF_WORKXYWH, &x2, &y2, &w2, &h2); event_mask |= MU_M1; - if ( (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { - mouse_event = MO_LEAVE; - } else { - mouse_event = MO_ENTER; - } + mouse_event = ( (SDL_GetAppState() & SDL_APPMOUSEFOCUS) + == SDL_APPMOUSEFOCUS) ? MO_LEAVE : MO_ENTER; } resultat = evnt_multi( @@ -123,22 +120,11 @@ void GEM_PumpEvents(_THIS) /* Mouse entering/leaving window */ if (resultat & MU_M1) { if (this->input_grab == SDL_GRAB_OFF) { - if (SDL_GetAppState() & SDL_APPMOUSEFOCUS) { - SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); - if (SDL_GetAppState() & SDL_APPINPUTFOCUS) { - graf_mouse(ARROW, NULL); - } - } else { - SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); - if (SDL_GetAppState() & SDL_APPINPUTFOCUS) { - if (GEM_cursor == (void *) -1) { - graf_mouse(M_OFF, NULL); - } else if (GEM_cursor) { - graf_mouse(USER_DEF, GEM_cursor->mform_p); - } - } - } + /* Switch mouse focus state */ + SDL_PrivateAppActive((mouse_event == MO_ENTER), + SDL_APPMOUSEFOCUS); } + GEM_CheckMouseMode(this); } /* Timer event ? */ @@ -182,10 +168,10 @@ void GEM_PumpEvents(_THIS) static int do_messages(_THIS, short *message) { - int quit, posted; + int quit, posted, check_mouse_mode; short x2,y2,w2,h2; - quit=0; + quit = check_mouse_mode = 0; switch (message[0]) { case WM_CLOSED: case AP_TERM: @@ -203,6 +189,7 @@ static int do_messages(_THIS, short *message) if (VDI_setpalette) { VDI_setpalette(this, VDI_curpalette); } + check_mouse_mode = 1; break; case WM_REDRAW: if (!GEM_lock_redraw) { @@ -222,6 +209,7 @@ static int do_messages(_THIS, short *message) wind_set(GEM_handle,WF_NAME,(short)(((unsigned long)GEM_icon_name)>>16),(short)(((unsigned long)GEM_icon_name) & 0xffff),0,0); GEM_refresh_name = SDL_FALSE; } + check_mouse_mode = 1; break; case WM_UNICONIFY: wind_set(message[3],WF_UNICONIFY,message[4],message[5],message[6],message[7]); @@ -234,6 +222,7 @@ static int do_messages(_THIS, short *message) wind_set(GEM_handle,WF_NAME,(short)(((unsigned long)GEM_title_name)>>16),(short)(((unsigned long)GEM_title_name) & 0xffff),0,0); GEM_refresh_name = SDL_FALSE; } + check_mouse_mode = 1; break; case WM_SIZED: wind_set (message[3], WF_CURRXYWH, message[4], message[5], message[6], message[7]); @@ -270,8 +259,13 @@ static int do_messages(_THIS, short *message) if (VDI_setpalette) { VDI_setpalette(this, VDI_oldpalette); } + check_mouse_mode = 1; break; } + + if (check_mouse_mode) { + GEM_CheckMouseMode(this); + } return quit; } diff --git a/src/video/gem/SDL_gemmouse.c b/src/video/gem/SDL_gemmouse.c index e8b1e0b0f..3d0acf89e 100644 --- a/src/video/gem/SDL_gemmouse.c +++ b/src/video/gem/SDL_gemmouse.c @@ -140,12 +140,8 @@ WMcursor *GEM_CreateWMCursor(_THIS, int GEM_ShowWMCursor(_THIS, WMcursor *cursor) { GEM_cursor = cursor; - if (cursor == NULL) { - graf_mouse(M_OFF, NULL); - GEM_cursor = (void *) -1; - } else if (cursor->mform_p) { - graf_mouse(USER_DEF, cursor->mform_p); - } + + GEM_CheckMouseMode(this); #ifdef DEBUG_VIDEO_GEM printf("sdl:video:gem: ShowWMCursor(0x%08x)\n", (long) cursor); @@ -170,19 +166,39 @@ void GEM_WarpWMCursor(_THIS, Uint16 x, Uint16 y) void GEM_CheckMouseMode(_THIS) { + const Uint8 full_focus = (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS); + int set_system_cursor = 1, show_system_cursor = 1; + #ifdef DEBUG_VIDEO_GEM printf("sdl:video:gem: check mouse mode\n"); #endif /* If the mouse is hidden and input is grabbed, we use relative mode */ - if ( (!(SDL_cursorstate & CURSOR_VISIBLE)) && - (this->input_grab != SDL_GRAB_OFF) && - (SDL_GetAppState() & SDL_APPACTIVE) ) { - SDL_AtariXbios_LockMousePosition(SDL_TRUE); - GEM_mouse_relative = SDL_TRUE; + GEM_mouse_relative = (!(SDL_cursorstate & CURSOR_VISIBLE)) + && (this->input_grab != SDL_GRAB_OFF) + && (SDL_GetAppState() & SDL_APPACTIVE); + SDL_AtariXbios_LockMousePosition(GEM_mouse_relative); + + if (SDL_cursorstate & CURSOR_VISIBLE) { + /* Application defined cursor only over the application window */ + if ((SDL_GetAppState() & full_focus) == full_focus) { + if (GEM_cursor) { + graf_mouse(USER_DEF, GEM_cursor->mform_p); + set_system_cursor = 0; + } else { + show_system_cursor = 0; + } + } } else { - SDL_AtariXbios_LockMousePosition(SDL_FALSE); - GEM_mouse_relative = SDL_FALSE; - graf_mouse(M_ON, NULL); + /* Mouse cursor hidden only over the application window */ + if ((SDL_GetAppState() & full_focus) == full_focus) { + set_system_cursor = 0; + show_system_cursor = 0; + } + } + + graf_mouse(show_system_cursor ? M_ON : M_OFF, NULL); + if (set_system_cursor) { + graf_mouse(ARROW, NULL); } } From 9445a05944cc3c09013a3ad5377d5a97227f8c0a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 14 Jul 2007 06:45:01 +0000 Subject: [PATCH 215/241] Mac OS X thinks we want a function call to SDL_memcpy() and not memcpy() here, thanks to macro replacement issues. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402521 --- src/stdlib/SDL_malloc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/stdlib/SDL_malloc.c b/src/stdlib/SDL_malloc.c index 3d973f625..e2e9041de 100644 --- a/src/stdlib/SDL_malloc.c +++ b/src/stdlib/SDL_malloc.c @@ -610,7 +610,6 @@ DEFAULT_MMAP_THRESHOLD default: 256K #endif /* MALLINFO_FIELD_TYPE */ #define memset SDL_memset -#define memcpy SDL_memcpy #define malloc SDL_malloc #define calloc SDL_calloc #define realloc SDL_realloc @@ -3839,7 +3838,7 @@ static void* internal_realloc(mstate m, void* oldmem, size_t bytes) { void* newmem = internal_malloc(m, bytes); if (newmem != 0) { size_t oc = oldsize - overhead_for(oldp); - memcpy(newmem, oldmem, (oc < bytes)? oc : bytes); + SDL_memcpy(newmem, oldmem, (oc < bytes)? oc : bytes); internal_free(m, oldmem); } return newmem; From e95642a89066563da409a2b34613191d99792eec Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 14 Jul 2007 07:01:38 +0000 Subject: [PATCH 216/241] Removed some unused static variables. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402523 --- src/video/SDL_yuv_mmx.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/video/SDL_yuv_mmx.c b/src/video/SDL_yuv_mmx.c index 1e35477e4..12deba4a5 100644 --- a/src/video/SDL_yuv_mmx.c +++ b/src/video/SDL_yuv_mmx.c @@ -42,16 +42,11 @@ static mmx_t MMX_VgrnRGB = { .uw = {0xffd2, 0xffd2, 0xffd2, 0xffd2} }; static mmx_t MMX_Ublu5x5 = { .uw = {0x0081, 0x0081, 0x0081, 0x0081} }; static mmx_t MMX_Vred5x5 = { .uw = {0x0066, 0x0066, 0x0066, 0x0066} }; -static mmx_t MMX_Ugrn555 = { .uw = {0xffe7, 0xffe7, 0xffe7, 0xffe7} }; -static mmx_t MMX_Vgrn555 = { .uw = {0xffcc, 0xffcc, 0xffcc, 0xffcc} }; static mmx_t MMX_Ugrn565 = { .uw = {0xffe8, 0xffe8, 0xffe8, 0xffe8} }; static mmx_t MMX_Vgrn565 = { .uw = {0xffcd, 0xffcd, 0xffcd, 0xffcd} }; -static mmx_t MMX_red555 = { .uw = {0x7c00, 0x7c00, 0x7c00, 0x7c00} }; static mmx_t MMX_red565 = { .uw = {0xf800, 0xf800, 0xf800, 0xf800} }; -static mmx_t MMX_grn555 = { .uw = {0x03e0, 0x03e0, 0x03e0, 0x03e0} }; static mmx_t MMX_grn565 = { .uw = {0x07e0, 0x07e0, 0x07e0, 0x07e0} }; -static mmx_t MMX_blu5x5 = { .uw = {0x001f, 0x001f, 0x001f, 0x001f} }; /** This MMX assembler is my first assembler/MMX program ever. From cdd5782864b16d9ee551d986d290c72ebcc8f7dc Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 14 Jul 2007 07:06:46 +0000 Subject: [PATCH 217/241] Reverted r3255:3256. Don't actually need it unless the build is broken. :) --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402526 --- src/stdlib/SDL_malloc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/stdlib/SDL_malloc.c b/src/stdlib/SDL_malloc.c index e2e9041de..3d973f625 100644 --- a/src/stdlib/SDL_malloc.c +++ b/src/stdlib/SDL_malloc.c @@ -610,6 +610,7 @@ DEFAULT_MMAP_THRESHOLD default: 256K #endif /* MALLINFO_FIELD_TYPE */ #define memset SDL_memset +#define memcpy SDL_memcpy #define malloc SDL_malloc #define calloc SDL_calloc #define realloc SDL_realloc @@ -3838,7 +3839,7 @@ static void* internal_realloc(mstate m, void* oldmem, size_t bytes) { void* newmem = internal_malloc(m, bytes); if (newmem != 0) { size_t oc = oldsize - overhead_for(oldp); - SDL_memcpy(newmem, oldmem, (oc < bytes)? oc : bytes); + memcpy(newmem, oldmem, (oc < bytes)? oc : bytes); internal_free(m, oldmem); } return newmem; From f162e3a203d36555b6b5ea2b5d4164d259efbdcf Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 14 Jul 2007 07:26:34 +0000 Subject: [PATCH 218/241] Mac OS X/x86 won't build the MMX/YUV inline assembly without optimizations enabled (not enough registers), so for now, we only build it if we see the __OPTIMIZE__ #define, which GCC provides when you build at -O1 or higher. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402527 --- src/video/SDL_yuv_mmx.c | 2 +- src/video/SDL_yuv_sw.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/SDL_yuv_mmx.c b/src/video/SDL_yuv_mmx.c index 12deba4a5..059dd50c4 100644 --- a/src/video/SDL_yuv_mmx.c +++ b/src/video/SDL_yuv_mmx.c @@ -21,7 +21,7 @@ */ #include "SDL_config.h" -#if (__GNUC__ > 2) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES +#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES #include "SDL_stdinc.h" diff --git a/src/video/SDL_yuv_sw.c b/src/video/SDL_yuv_sw.c index 66c2bb7dc..13c4a92e1 100644 --- a/src/video/SDL_yuv_sw.c +++ b/src/video/SDL_yuv_sw.c @@ -121,7 +121,7 @@ struct private_yuvhwdata { /* The colorspace conversion functions */ -#if (__GNUC__ > 2) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES +#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES extern void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, unsigned char *lum, unsigned char *cr, unsigned char *cb, unsigned char *out, @@ -1061,7 +1061,7 @@ SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_S case SDL_YV12_OVERLAY: case SDL_IYUV_OVERLAY: if ( display->format->BytesPerPixel == 2 ) { -#if (__GNUC__ > 2) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES +#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES /* inline assembly functions */ if ( SDL_HasMMX() && (Rmask == 0xF800) && (Gmask == 0x07E0) && @@ -1083,7 +1083,7 @@ SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_S swdata->Display2X = Color24DitherYV12Mod2X; } if ( display->format->BytesPerPixel == 4 ) { -#if (__GNUC__ > 2) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES +#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES /* inline assembly functions */ if ( SDL_HasMMX() && (Rmask == 0x00FF0000) && (Gmask == 0x0000FF00) && From 73b9604f5db5bd91467b7f13b385a7d14a56afd6 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 14 Jul 2007 08:00:50 +0000 Subject: [PATCH 219/241] Fixed bug #373 Patch contributed from Transgaming's Cider project - create a window and view in fullscreen mode so the cursor can be set --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402529 --- src/video/quartz/SDL_QuartzVideo.m | 68 ++++++++++++++++++++++++++++++ src/video/quartz/SDL_QuartzWM.m | 2 +- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/video/quartz/SDL_QuartzVideo.m b/src/video/quartz/SDL_QuartzVideo.m index 28dba613d..13acee0be 100644 --- a/src/video/quartz/SDL_QuartzVideo.m +++ b/src/video/quartz/SDL_QuartzVideo.m @@ -367,6 +367,13 @@ static void QZ_UnsetVideoMode (_THIS, BOOL to_desktop) { SDL_free (sw_buffers[0]); } + /* If we still have a valid window, close it. */ + if ( qz_window ) { + [ qz_window close ]; + [ qz_window release ]; + qz_window = nil; + window_view = nil; + } /* Release the OpenGL context Do this first to avoid trash on the display before fade @@ -411,6 +418,8 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt boolean_t exact_match = 0; NSRect screen_rect; CGError error; + NSRect contentRect; + BOOL isCustom = NO; CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken; /* Fade to black to hide resolution-switching flicker (and garbage @@ -503,6 +512,59 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt if ( CGDisplayCanSetPalette (display_id) ) current->flags |= SDL_HWPALETTE; + /* The code below checks for any valid custom windows and views. If none are + available, then we create new ones. Window/View code was added in FULLSCREEN + so that special events like the changing of the cursor image would be handled + ( only the front-most and active application can change the cursor appearance + and with no valid window/view in FULLSCREEN, SDL wouldn't update its cursor. ) + */ + /* Check for user-specified window and view */ + { + char *windowPtrString = getenv ("SDL_NSWindowPointer"); + char *viewPtrString = getenv ("SDL_NSQuickDrawViewPointer"); + + contentRect = NSMakeRect (0, 0, width, height); + + if (windowPtrString && viewPtrString) { + /* Release any previous window */ + if ( qz_window ) { + [ qz_window release ]; + qz_window = nil; + } + + qz_window = (NSWindow*)atoi(windowPtrString); + window_view = (NSQuickDrawView*)atoi(viewPtrString); + isCustom = YES; + /* + Retain reference to window because we + might release it in QZ_UnsetVideoMode + */ + [ qz_window retain ]; + } + } + /* Check if we should recreate the window */ + if (qz_window == nil) { + /* Manually create a window, avoids having a nib file resource */ + qz_window = [ [ SDL_QuartzWindow alloc ] + initWithContentRect:contentRect + styleMask:nil + backing:NSBackingStoreBuffered + defer:NO ]; + + if (qz_window != nil) { + [ qz_window setAcceptsMouseMovedEvents:YES ]; + [ qz_window setViewsNeedDisplay:NO ]; + } + } + /* We already have a window, just change its size */ + else { + if (!isCustom) { + [ qz_window setContentSize:contentRect.size ]; + current->flags |= (SDL_NOFRAME|SDL_RESIZABLE) & mode_flags; + [ window_view setFrameSize:contentRect.size ]; + } + } + /* Setup OpenGL for a fullscreen context */ if (flags & SDL_OPENGL) { @@ -513,6 +575,12 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt goto ERR_NO_GL; } + /* Initialize the NSView and add it to our window. The presence of a valid window and + view allow the cursor to be changed whilst in fullscreen.*/ + window_view = [ [ NSView alloc ] initWithFrame:contentRect ]; + [ [ qz_window contentView ] addSubview:window_view ]; + [ window_view release ]; + ctx = [ gl_context cglContext ]; err = CGLSetFullScreen (ctx); diff --git a/src/video/quartz/SDL_QuartzWM.m b/src/video/quartz/SDL_QuartzWM.m index dab99f6c1..37e7ececb 100644 --- a/src/video/quartz/SDL_QuartzWM.m +++ b/src/video/quartz/SDL_QuartzWM.m @@ -105,7 +105,7 @@ void QZ_HideMouse (_THIS) { } BOOL QZ_IsMouseInWindow (_THIS) { - if (qz_window == nil) return YES; /*fullscreen*/ + if (qz_window == nil || (mode_flags & SDL_FULLSCREEN)) return YES; /*fullscreen*/ else { NSPoint p = [ qz_window mouseLocationOutsideOfEventStream ]; p.y -= 1.0f; /* Apparently y goes from 1 to h, not from 0 to h-1 (i.e. the "location of the mouse" seems to be defined as "the location of the top left corner of the mouse pointer's hot pixel" */ From 585eb48cad6105ca0ae08c052b41497a0a7a80e6 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 14 Jul 2007 08:27:06 +0000 Subject: [PATCH 220/241] More improvements for bug #373 Show the SDL cursor in the window and the arrow cursor outside the window. This is also supposed to show the SDL cursor when activated, but that code isn't working yet... --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402530 --- src/video/quartz/SDL_QuartzEvents.m | 37 ++++++++++++++++++++--------- src/video/quartz/SDL_QuartzVideo.h | 2 +- src/video/quartz/SDL_QuartzWM.m | 8 +++---- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/video/quartz/SDL_QuartzEvents.m b/src/video/quartz/SDL_QuartzEvents.m index 2edc4b8a0..2c91d06c2 100644 --- a/src/video/quartz/SDL_QuartzEvents.m +++ b/src/video/quartz/SDL_QuartzEvents.m @@ -623,11 +623,22 @@ static void QZ_GetMouseLocation (_THIS, NSPoint *p) { void QZ_DoActivate (_THIS) { - SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS | (QZ_IsMouseInWindow (this) ? SDL_APPMOUSEFOCUS : 0)); - - /* Hide the cursor if it was hidden by SDL_ShowCursor() */ - if (!cursor_should_be_visible) - QZ_HideMouse (this); + BOOL isInGameWin = QZ_IsMouseInWindow (this); + + SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS | (isInGameWin ? SDL_APPMOUSEFOCUS : 0)); + + /* Reset the cursor state */ + /* FIXME: This doesn't currently work... + Apparently you can't set the cursor inside windowDidBecomeKey + */ + if ( isInGameWin ) { + if (cursor_should_be_visible) + SDL_SetCursor (NULL); + else + QZ_HideMouse (this); + } else { + QZ_ShowMouse (this, [NSCursor arrowCursor]); + } /* Regrab input, only if it was previously grabbed */ if ( current_grab_mode == SDL_GRAB_ON ) { @@ -656,7 +667,7 @@ void QZ_DoDeactivate (_THIS) { /* Show the cursor if it was hidden by SDL_ShowCursor() */ if (!cursor_should_be_visible) - QZ_ShowMouse (this); + QZ_ShowMouse (this, [NSCursor arrowCursor]); } void QZ_SleepNotificationHandler (void * refcon, @@ -870,8 +881,7 @@ void QZ_PumpEvents (_THIS) into the game window. This still generates a mouse moved event, but not as a result of the warp (so it's in the right direction). */ - if ( grab_state == QZ_VISIBLE_GRAB && - !isInGameWin ) { + if ( grab_state == QZ_VISIBLE_GRAB && !isInGameWin ) { NSPoint p; QZ_GetMouseLocation (this, &p); @@ -909,15 +919,20 @@ void QZ_PumpEvents (_THIS) cursor enters the window again, making it obvious to the user that the grab is broken.*/ CGAssociateMouseAndMouseCursorPosition (1); - if (!cursor_should_be_visible) - QZ_ShowMouse (this); + + QZ_ShowMouse (this, [NSCursor arrowCursor]); } else if ( isInGameWin && (SDL_GetAppState() & (SDL_APPMOUSEFOCUS | SDL_APPINPUTFOCUS)) == SDL_APPINPUTFOCUS ) { SDL_PrivateAppActive (1, SDL_APPMOUSEFOCUS); - if (!cursor_should_be_visible) + + if (cursor_should_be_visible) { + SDL_SetCursor (NULL); + } else { QZ_HideMouse (this); + } + if (grab_state == QZ_INVISIBLE_GRAB) { /*see comment above*/ QZ_PrivateWarpCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2); CGAssociateMouseAndMouseCursorPosition (0); diff --git a/src/video/quartz/SDL_QuartzVideo.h b/src/video/quartz/SDL_QuartzVideo.h index 7ffedbf71..e480bfa50 100644 --- a/src/video/quartz/SDL_QuartzVideo.h +++ b/src/video/quartz/SDL_QuartzVideo.h @@ -224,7 +224,7 @@ SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height, void QZ_PrivateWarpCursor (_THIS, int x, int y); void QZ_ChangeGrabState (_THIS, int action); void QZ_RegisterForSleepNotifications (_THIS); -void QZ_ShowMouse (_THIS); +void QZ_ShowMouse (_THIS, NSCursor *cursor); void QZ_HideMouse (_THIS); void QZ_PrivateGlobalToLocal (_THIS, NSPoint *p); void QZ_PrivateCocoaToSDL (_THIS, NSPoint *p); diff --git a/src/video/quartz/SDL_QuartzWM.m b/src/video/quartz/SDL_QuartzWM.m index 37e7ececb..eee652c53 100644 --- a/src/video/quartz/SDL_QuartzWM.m +++ b/src/video/quartz/SDL_QuartzWM.m @@ -90,11 +90,12 @@ outOfMemory: return(NULL); } -void QZ_ShowMouse (_THIS) { +void QZ_ShowMouse (_THIS, NSCursor *cursor) { if (!cursor_visible) { [ NSCursor unhide ]; cursor_visible = YES; } + [ cursor set ]; } void QZ_HideMouse (_THIS) { @@ -116,16 +117,15 @@ BOOL QZ_IsMouseInWindow (_THIS) { int QZ_ShowWMCursor (_THIS, WMcursor *cursor) { if ( cursor == NULL) { + QZ_HideMouse (this); if ( cursor_should_be_visible ) { - QZ_HideMouse (this); cursor_should_be_visible = NO; QZ_ChangeGrabState (this, QZ_HIDECURSOR); } } else { - [ cursor->nscursor set ]; + QZ_ShowMouse (this, cursor->nscursor); if ( ! cursor_should_be_visible ) { - QZ_ShowMouse (this); cursor_should_be_visible = YES; QZ_ChangeGrabState (this, QZ_SHOWCURSOR); } From 1012f68044dca1afbdb4a8b7aa1170dad4a0c115 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 14 Jul 2007 21:09:54 +0000 Subject: [PATCH 221/241] Use SDL C functions (fixes security warnings on OpenBSD) --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402531 --- src/video/x11/SDL_x11video.c | 50 +++++++++++++++++------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 7fde77eb4..99ff2aa2a 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -438,7 +438,9 @@ static void create_aux_windows(_THIS) /* Open an input method. */ if (SDL_IM == NULL) { - char *old_locale, *old_modifiers; + char *old_locale = NULL, *old_modifiers = NULL; + const char *p; + size_t n; /* I'm not comfortable to do locale setup here. However, we need C library locale (and xlib modifiers) to be set based on the @@ -455,29 +457,21 @@ static void create_aux_windows(_THIS) /* Save the current (application program's) locale settings. */ - old_locale = setlocale(LC_ALL, NULL); - old_modifiers = XSetLocaleModifiers(NULL); - if (old_locale == NULL || old_modifiers == NULL) { - /* The specs guarantee that the query - calls to above functions never - fail, so we should never come - here. */ - SDL_SetError("failed to retreive current locale settings"); - old_locale = NULL; - old_modifiers = NULL; - } else { - /* Save retreived values in our own - storage, since they may be - overwritten by the successive calls - to - setlocale/XSetLocaleModifiers. */ - char const *p; - p = old_locale; - old_locale = SDL_malloc(strlen(p) + 1); - strcpy(old_locale, p); - p = old_modifiers; - old_modifiers = SDL_malloc(strlen(p) + 1); - strcpy(old_modifiers, p); + p = setlocale(LC_ALL, NULL); + if ( p ) { + n = SDL_strlen(p)+1; + old_locale = SDL_stack_alloc(char, n); + if ( old_locale ) { + SDL_strlcpy(old_locale, p, n); + } + } + p = XSetLocaleModifiers(NULL); + if ( p ) { + n = SDL_strlen(p)+1; + old_modifiers = SDL_stack_alloc(char, n); + if ( old_modifiers ) { + SDL_strlcpy(old_modifiers, p, n); + } } /* Fetch the user's preferences and open the @@ -489,15 +483,17 @@ static void create_aux_windows(_THIS) /* Restore the application's locale settings so that we don't break the application's expected behaviour. */ - if (old_locale != NULL && old_modifiers != NULL) { + if ( old_locale ) { /* We need to restore the C library locale first, since the interpretation of the X modifier may depend on it. */ setlocale(LC_ALL, old_locale); - SDL_free(old_locale); + SDL_stack_free(old_locale); + } + if ( old_modifiers ) { XSetLocaleModifiers(old_modifiers); - SDL_free(old_modifiers); + SDL_stack_free(old_modifiers); } } From 0468ab7f14481793ee5e37c2aa1911e159ec2a88 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 15 Jul 2007 14:05:31 +0000 Subject: [PATCH 222/241] I think this fixes bug #454 --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402533 --- src/video/maccommon/SDL_macevents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/maccommon/SDL_macevents.c b/src/video/maccommon/SDL_macevents.c index 4c5bce3f8..499329aa9 100644 --- a/src/video/maccommon/SDL_macevents.c +++ b/src/video/maccommon/SDL_macevents.c @@ -159,8 +159,8 @@ static int Mac_HandleEvents(_THIS, int wait4it) /* Check the current state of the keyboard */ if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) { KeyMap keys; - const Uint8 *keysptr = (Uint8 *) &keys; - const Uint8 *last_keysptr = (Uint8 *) &last_keys; + const Uint8 *keysptr = (Uint8 *) keys; + const Uint8 *last_keysptr = (Uint8 *) last_keys; /* Check for special non-event keys */ if ( event.modifiers != last_mods ) { From 3b3b5c04292e4d6eb8b5a175af1d1990496a3681 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 15 Jul 2007 14:14:45 +0000 Subject: [PATCH 223/241] An attempt at fixing Bugzilla #454. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402534 --- src/video/maccommon/SDL_macevents.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/maccommon/SDL_macevents.c b/src/video/maccommon/SDL_macevents.c index 499329aa9..e531c6caf 100644 --- a/src/video/maccommon/SDL_macevents.c +++ b/src/video/maccommon/SDL_macevents.c @@ -159,8 +159,8 @@ static int Mac_HandleEvents(_THIS, int wait4it) /* Check the current state of the keyboard */ if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) { KeyMap keys; - const Uint8 *keysptr = (Uint8 *) keys; - const Uint8 *last_keysptr = (Uint8 *) last_keys; + const Uint32 *keysptr = (Uint32 *) &keys; + const Uint32 *last_keysptr = (Uint32 *) &last_keys; /* Check for special non-event keys */ if ( event.modifiers != last_mods ) { From 33dff0e2405c7b6b19affb784d669daf75dc5606 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 15 Jul 2007 15:58:00 +0000 Subject: [PATCH 224/241] Patch from Christian Walther Yes, the idea to use a cursor rectangle instead of [NSCursor set] has occurred to me too, and it does seem to be the most elegant way. Here's my attempt at an implementation --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402535 --- src/video/quartz/SDL_QuartzEvents.m | 31 +++++----------------- src/video/quartz/SDL_QuartzVideo.h | 2 -- src/video/quartz/SDL_QuartzVideo.m | 1 + src/video/quartz/SDL_QuartzWM.h | 27 +++++++++++++++++++ src/video/quartz/SDL_QuartzWM.m | 40 +++++++++++++++++------------ src/video/quartz/SDL_QuartzWindow.h | 4 +++ src/video/quartz/SDL_QuartzWindow.m | 13 ++++++++++ 7 files changed, 75 insertions(+), 43 deletions(-) create mode 100644 src/video/quartz/SDL_QuartzWM.h diff --git a/src/video/quartz/SDL_QuartzEvents.m b/src/video/quartz/SDL_QuartzEvents.m index 2c91d06c2..2e1296636 100644 --- a/src/video/quartz/SDL_QuartzEvents.m +++ b/src/video/quartz/SDL_QuartzEvents.m @@ -22,6 +22,7 @@ #include "SDL_config.h" #include "SDL_QuartzVideo.h" +#include "SDL_QuartzWM.h" #include /* For wake from sleep detection */ #include /* For wake from sleep detection */ @@ -623,22 +624,9 @@ static void QZ_GetMouseLocation (_THIS, NSPoint *p) { void QZ_DoActivate (_THIS) { - BOOL isInGameWin = QZ_IsMouseInWindow (this); + SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS | (QZ_IsMouseInWindow (this) ? SDL_APPMOUSEFOCUS : 0)); - SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS | (isInGameWin ? SDL_APPMOUSEFOCUS : 0)); - - /* Reset the cursor state */ - /* FIXME: This doesn't currently work... - Apparently you can't set the cursor inside windowDidBecomeKey - */ - if ( isInGameWin ) { - if (cursor_should_be_visible) - SDL_SetCursor (NULL); - else - QZ_HideMouse (this); - } else { - QZ_ShowMouse (this, [NSCursor arrowCursor]); - } + QZ_UpdateCursor(this); /* Regrab input, only if it was previously grabbed */ if ( current_grab_mode == SDL_GRAB_ON ) { @@ -665,9 +653,7 @@ void QZ_DoDeactivate (_THIS) { /* Reassociate mouse and cursor */ CGAssociateMouseAndMouseCursorPosition (1); - /* Show the cursor if it was hidden by SDL_ShowCursor() */ - if (!cursor_should_be_visible) - QZ_ShowMouse (this, [NSCursor arrowCursor]); + QZ_UpdateCursor(this); } void QZ_SleepNotificationHandler (void * refcon, @@ -904,6 +890,7 @@ void QZ_PumpEvents (_THIS) if ( !isInGameWin && (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { SDL_PrivateAppActive (0, SDL_APPMOUSEFOCUS); + if (grab_state == QZ_INVISIBLE_GRAB) /*The cursor has left the window even though it is disassociated from the mouse (and therefore @@ -920,18 +907,14 @@ void QZ_PumpEvents (_THIS) to the user that the grab is broken.*/ CGAssociateMouseAndMouseCursorPosition (1); - QZ_ShowMouse (this, [NSCursor arrowCursor]); + QZ_UpdateCursor(this); } else if ( isInGameWin && (SDL_GetAppState() & (SDL_APPMOUSEFOCUS | SDL_APPINPUTFOCUS)) == SDL_APPINPUTFOCUS ) { SDL_PrivateAppActive (1, SDL_APPMOUSEFOCUS); - if (cursor_should_be_visible) { - SDL_SetCursor (NULL); - } else { - QZ_HideMouse (this); - } + QZ_UpdateCursor(this); if (grab_state == QZ_INVISIBLE_GRAB) { /*see comment above*/ QZ_PrivateWarpCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2); diff --git a/src/video/quartz/SDL_QuartzVideo.h b/src/video/quartz/SDL_QuartzVideo.h index e480bfa50..44e25ef07 100644 --- a/src/video/quartz/SDL_QuartzVideo.h +++ b/src/video/quartz/SDL_QuartzVideo.h @@ -224,8 +224,6 @@ SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height, void QZ_PrivateWarpCursor (_THIS, int x, int y); void QZ_ChangeGrabState (_THIS, int action); void QZ_RegisterForSleepNotifications (_THIS); -void QZ_ShowMouse (_THIS, NSCursor *cursor); -void QZ_HideMouse (_THIS); void QZ_PrivateGlobalToLocal (_THIS, NSPoint *p); void QZ_PrivateCocoaToSDL (_THIS, NSPoint *p); BOOL QZ_IsMouseInWindow (_THIS); diff --git a/src/video/quartz/SDL_QuartzVideo.m b/src/video/quartz/SDL_QuartzVideo.m index 13acee0be..10d502830 100644 --- a/src/video/quartz/SDL_QuartzVideo.m +++ b/src/video/quartz/SDL_QuartzVideo.m @@ -756,6 +756,7 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width, } [ qz_window setDelegate: [ [ [ SDL_QuartzWindowDelegate alloc ] init ] autorelease ] ]; + [ qz_window setContentView: [ [ [ SDL_QuartzView alloc ] init ] autorelease ] ]; } /* We already have a window, just change its size */ else { diff --git a/src/video/quartz/SDL_QuartzWM.h b/src/video/quartz/SDL_QuartzWM.h new file mode 100644 index 000000000..e1ae17895 --- /dev/null +++ b/src/video/quartz/SDL_QuartzWM.h @@ -0,0 +1,27 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2003 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +struct WMcursor { + NSCursor *nscursor; +}; + +void QZ_UpdateCursor(_THIS); diff --git a/src/video/quartz/SDL_QuartzWM.m b/src/video/quartz/SDL_QuartzWM.m index eee652c53..f544dc975 100644 --- a/src/video/quartz/SDL_QuartzWM.m +++ b/src/video/quartz/SDL_QuartzWM.m @@ -22,12 +22,9 @@ #include "SDL_config.h" #include "SDL_QuartzVideo.h" +#include "SDL_QuartzWM.h" -struct WMcursor { - NSCursor *nscursor; -}; - void QZ_FreeWMCursor (_THIS, WMcursor *cursor) { if ( cursor != NULL ) { @@ -90,18 +87,21 @@ outOfMemory: return(NULL); } -void QZ_ShowMouse (_THIS, NSCursor *cursor) { - if (!cursor_visible) { - [ NSCursor unhide ]; - cursor_visible = YES; - } - [ cursor set ]; -} +void QZ_UpdateCursor (_THIS) { + BOOL state; -void QZ_HideMouse (_THIS) { - if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) && cursor_visible) { - [ NSCursor hide ]; - cursor_visible = NO; + if (cursor_should_be_visible || !(SDL_GetAppState() & SDL_APPMOUSEFOCUS)) { + state = YES; + } else { + state = NO; + } + if (state != cursor_visible) { + if (state) { + [ NSCursor unhide ]; + } else { + [ NSCursor hide ]; + } + cursor_visible = state; } } @@ -117,18 +117,24 @@ BOOL QZ_IsMouseInWindow (_THIS) { int QZ_ShowWMCursor (_THIS, WMcursor *cursor) { if ( cursor == NULL) { - QZ_HideMouse (this); if ( cursor_should_be_visible ) { cursor_should_be_visible = NO; QZ_ChangeGrabState (this, QZ_HIDECURSOR); } + QZ_UpdateCursor(this); } else { - QZ_ShowMouse (this, cursor->nscursor); + if (qz_window ==nil || (mode_flags & SDL_FULLSCREEN)) { + [ cursor->nscursor set ]; + } + else { + [ qz_window invalidateCursorRectsForView: [ qz_window contentView ] ]; + } if ( ! cursor_should_be_visible ) { cursor_should_be_visible = YES; QZ_ChangeGrabState (this, QZ_SHOWCURSOR); } + QZ_UpdateCursor(this); } return 1; diff --git a/src/video/quartz/SDL_QuartzWindow.h b/src/video/quartz/SDL_QuartzWindow.h index 20077ee89..cdfdec47e 100644 --- a/src/video/quartz/SDL_QuartzWindow.h +++ b/src/video/quartz/SDL_QuartzWindow.h @@ -37,3 +37,7 @@ - (BOOL)windowShouldClose:(id)sender; @end +/* Subclass of NSView to set cursor rectangle */ +@interface SDL_QuartzView : NSView +- (void)resetCursorRects; +@end diff --git a/src/video/quartz/SDL_QuartzWindow.m b/src/video/quartz/SDL_QuartzWindow.m index ffbf1eadf..b56f9a701 100644 --- a/src/video/quartz/SDL_QuartzWindow.m +++ b/src/video/quartz/SDL_QuartzWindow.m @@ -22,6 +22,7 @@ #include "SDL_config.h" #include "SDL_QuartzVideo.h" +#include "SDL_QuartzWM.h" #include "SDL_QuartzWindow.h" /* @@ -217,3 +218,15 @@ static void QZ_SetPortAlphaOpaque () { } @end + +@implementation SDL_QuartzView + +- (void)resetCursorRects +{ + SDL_Cursor *sdlc = SDL_GetCursor(); + if (sdlc != NULL && sdlc->wm_cursor != NULL) { + [self addCursorRect: [self visibleRect] cursor: sdlc->wm_cursor->nscursor]; + } +} + +@end From 53dae52ecbe11c15faea84cde464fc55a830eea0 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 15 Jul 2007 16:33:45 +0000 Subject: [PATCH 225/241] Dump more information about each joystick in testjoytick.c --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402536 --- test/testjoystick.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/testjoystick.c b/test/testjoystick.c index c406bdc91..648e85fae 100644 --- a/test/testjoystick.c +++ b/test/testjoystick.c @@ -158,8 +158,19 @@ int main(int argc, char *argv[]) /* Print information about the joysticks */ printf("There are %d joysticks attached\n", SDL_NumJoysticks()); for ( i=0; i Date: Sun, 15 Jul 2007 17:22:39 +0000 Subject: [PATCH 226/241] Final fix for bug #373 ------- Comment #13 From Christian Walther 2007-07-15 10:04:56 [reply] ------- Created an attachment (id=229) [details] patch to reinstate the SDL cursor after an NSApplicationActivatedEvent Oops, you're right. My testcursor.c has diverged so far from the original that I missed that. In fact, now that I think about it, that issue isn't even addressed by the cursor rectangle patch - it is only concerned with windowed mode (and fixes the problem there as a side effect). The problem in fullscreen is still the same as before. How about the attachment for a fix? (I can confirm that [NSCursor set] doesn't seem to have any effect when called from QZ_DoActivate().) --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402538 --- src/video/quartz/SDL_QuartzEvents.m | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/video/quartz/SDL_QuartzEvents.m b/src/video/quartz/SDL_QuartzEvents.m index 2e1296636..0e9097607 100644 --- a/src/video/quartz/SDL_QuartzEvents.m +++ b/src/video/quartz/SDL_QuartzEvents.m @@ -945,7 +945,16 @@ void QZ_PumpEvents (_THIS) break; case NSFlagsChanged: break; - /* case NSAppKitDefined: break; */ + case NSAppKitDefined: + [ NSApp sendEvent:event ]; + if ([ event subtype ] == NSApplicationActivatedEventType && (mode_flags & SDL_FULLSCREEN)) { + /* the default handling of this event seems to reset any cursor set by [NSCursor set] (used by SDL_SetCursor() in fullscreen mode) to the default system arrow cursor */ + SDL_Cursor *sdlc = SDL_GetCursor(); + if (sdlc != NULL && sdlc->wm_cursor != NULL) { + [ sdlc->wm_cursor->nscursor set ]; + } + } + break; /* case NSApplicationDefined: break; */ /* case NSPeriodic: break; */ /* case NSCursorUpdate: break; */ From d069678465ca963e3f1031b40be4300eb9cfae0d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 15 Jul 2007 17:26:50 +0000 Subject: [PATCH 227/241] Merged r3295:3296 from trunk/SDL: testjoystick reusing "joystick" variable. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402540 --- test/testjoystick.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/test/testjoystick.c b/test/testjoystick.c index 648e85fae..1cd823452 100644 --- a/test/testjoystick.c +++ b/test/testjoystick.c @@ -158,18 +158,17 @@ int main(int argc, char *argv[]) /* Print information about the joysticks */ printf("There are %d joysticks attached\n", SDL_NumJoysticks()); for ( i=0; i Date: Sun, 15 Jul 2007 19:00:22 +0000 Subject: [PATCH 228/241] Added a patch note for the Mac OS X cursor bug --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402541 --- docs.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs.html b/docs.html index 77a1cb82a..64b110ced 100644 --- a/docs.html +++ b/docs.html @@ -133,6 +133,9 @@ SDL 1.2.12 is a minor bug fix release.

Fixed mouse jitter when multiple motion events are queued up in Mac OS X.

+

+ Fixed changing the cursor in fullscreen mode on Mac OS X. +

Mac OS Classic Notes

From 5adb9f2f7e685352ba675df439bc814587a3c793 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 15 Jul 2007 19:43:54 +0000 Subject: [PATCH 229/241] Fixed building on Windows CE --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402542 --- src/video/windib/SDL_dibvideo.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/video/windib/SDL_dibvideo.c b/src/video/windib/SDL_dibvideo.c index 285a83547..9480b908b 100644 --- a/src/video/windib/SDL_dibvideo.c +++ b/src/video/windib/SDL_dibvideo.c @@ -939,6 +939,7 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) entry->peBlue = colors[i].b; entry->peFlags = PC_NOCOLLAPSE; } +#ifdef SYSPAL_NOSTATIC /* Check to make sure black and white are in position */ if ( GetSystemPaletteUse(hdc) != SYSPAL_NOSTATIC256 ) { moved_entries += CheckPaletteEntry(screen_logpal, 0, 0x00, 0x00, 0x00); @@ -950,9 +951,12 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) in the desired palette, set those entries (10-245) and then map everything into the new system palette. */ +#endif +#ifndef _WIN32_WCE /* Copy the entries into the system palette */ UnrealizeObject(screen_pal); +#endif SetPaletteEntries(screen_pal, 0, screen_logpal->palNumEntries, screen_logpal->palPalEntry); SelectPalette(hdc, screen_pal, FALSE); RealizePalette(hdc); @@ -1156,6 +1160,7 @@ void DIB_VideoQuit(_THIS) /* Exported for the windows message loop only */ static void DIB_GrabStaticColors(HWND window) { +#ifdef SYSPAL_NOSTATIC HDC hdc; hdc = GetDC(window); @@ -1164,14 +1169,17 @@ static void DIB_GrabStaticColors(HWND window) SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC); } ReleaseDC(window, hdc); +#endif } static void DIB_ReleaseStaticColors(HWND window) { +#ifdef SYSPAL_NOSTATIC HDC hdc; hdc = GetDC(window); SetSystemPaletteUse(hdc, SYSPAL_STATIC); ReleaseDC(window, hdc); +#endif } static void DIB_Activate(_THIS, BOOL active, BOOL minimized) { @@ -1191,7 +1199,9 @@ static void DIB_RealizePalette(_THIS) HDC hdc; hdc = GetDC(SDL_Window); +#ifndef _WIN32_WCE UnrealizeObject(screen_pal); +#endif SelectPalette(hdc, screen_pal, FALSE); if ( RealizePalette(hdc) ) { InvalidateRect(SDL_Window, NULL, FALSE); From be91b51038ac427ef4c75050021265ad1adf485f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 15 Jul 2007 21:50:07 +0000 Subject: [PATCH 230/241] Fixed bug #457 Don't crash if passed a NULL overlay. The app crashes anyway, since it's not checking the return value of the create call, but at least it's not crashing in SDL anymore. :) --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402543 --- src/video/SDL_yuv.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/video/SDL_yuv.c b/src/video/SDL_yuv.c index 396b7c0f5..1136ceb36 100644 --- a/src/video/SDL_yuv.c +++ b/src/video/SDL_yuv.c @@ -65,11 +65,18 @@ SDL_Overlay *SDL_CreateYUVOverlay(int w, int h, Uint32 format, int SDL_LockYUVOverlay(SDL_Overlay *overlay) { + if ( overlay == NULL ) { + SDL_SetError("Passed NULL overlay"); + return -1; + } return overlay->hwfuncs->Lock(current_video, overlay); } void SDL_UnlockYUVOverlay(SDL_Overlay *overlay) { + if ( overlay == NULL ) { + return; + } overlay->hwfuncs->Unlock(current_video, overlay); } @@ -79,6 +86,11 @@ int SDL_DisplayYUVOverlay(SDL_Overlay *overlay, SDL_Rect *dstrect) int srcx, srcy, srcw, srch; int dstx, dsty, dstw, dsth; + if ( overlay == NULL || dstrect == NULL ) { + SDL_SetError("Passed NULL overlay or dstrect"); + return -1; + } + /* Clip the rectangle to the screen area */ srcx = 0; srcy = 0; @@ -128,10 +140,11 @@ int SDL_DisplayYUVOverlay(SDL_Overlay *overlay, SDL_Rect *dstrect) void SDL_FreeYUVOverlay(SDL_Overlay *overlay) { - if ( overlay ) { - if ( overlay->hwfuncs ) { - overlay->hwfuncs->FreeHW(current_video, overlay); - } - SDL_free(overlay); + if ( overlay == NULL ) { + return; } + if ( overlay->hwfuncs ) { + overlay->hwfuncs->FreeHW(current_video, overlay); + } + SDL_free(overlay); } From c44a317291b513d5ce2b33ad61f088511787b182 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 16 Jul 2007 00:07:02 +0000 Subject: [PATCH 231/241] Fixed bug #428 This fix is overkill, but approved by Doug Lea, and he'll be releasing a new version of his malloc.c sometime next month. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402546 --- src/stdlib/SDL_malloc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/stdlib/SDL_malloc.c b/src/stdlib/SDL_malloc.c index 3d973f625..3a6009e0d 100644 --- a/src/stdlib/SDL_malloc.c +++ b/src/stdlib/SDL_malloc.c @@ -3408,7 +3408,7 @@ static void* sys_alloc(mstate m, size_t nb) { if (ss == 0) { /* First time through or recovery */ char* base = (char*)CALL_MORECORE(0); if (base != CMFAIL) { - asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE); + asize = granularity_align(nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE); /* Adjust to end on a page boundary */ if (!is_page_aligned(base)) asize += (page_align((size_t)base) - (size_t)base); @@ -3422,7 +3422,7 @@ static void* sys_alloc(mstate m, size_t nb) { } else { /* Subtract out existing available top space from MORECORE request. */ - asize = granularity_align(nb - m->topsize + TOP_FOOT_SIZE + SIZE_T_ONE); + asize = granularity_align(nb - m->topsize + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE); /* Use mem here only if it did continuously extend old space */ if (asize < HALF_MAX_SIZE_T && (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) { @@ -3435,7 +3435,7 @@ static void* sys_alloc(mstate m, size_t nb) { if (br != CMFAIL) { /* Try to use/extend the space we did get */ if (asize < HALF_MAX_SIZE_T && asize < nb + TOP_FOOT_SIZE + SIZE_T_ONE) { - size_t esize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE - asize); + size_t esize = granularity_align(nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE - asize); if (esize < HALF_MAX_SIZE_T) { char* end = (char*)CALL_MORECORE(esize); if (end != CMFAIL) @@ -3459,7 +3459,7 @@ static void* sys_alloc(mstate m, size_t nb) { } if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ - size_t req = nb + TOP_FOOT_SIZE + SIZE_T_ONE; + size_t req = nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE; size_t rsize = granularity_align(req); if (rsize > nb) { /* Fail if wraps around zero */ char* mp = (char*)(CALL_MMAP(rsize)); @@ -3472,7 +3472,7 @@ static void* sys_alloc(mstate m, size_t nb) { } if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ - size_t asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE); + size_t asize = granularity_align(nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE); if (asize < HALF_MAX_SIZE_T) { char* br = CMFAIL; char* end = CMFAIL; From 0d40fac1254d34e65e3b61747bdf9237e435c3e1 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 16 Jul 2007 03:27:26 +0000 Subject: [PATCH 232/241] Added support for building version.rc in Windows build. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402548 --- Makefile.in | 1 + build-scripts/makedep.sh | 12 +++++++++++- configure.in | 4 ++++ src/main/win32/version.rc | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/main/win32/version.rc diff --git a/Makefile.in b/Makefile.in index dd281351c..a11c104fa 100644 --- a/Makefile.in +++ b/Makefile.in @@ -30,6 +30,7 @@ INSTALL = @INSTALL@ NASM = @NASM@ @NASMFLAGS@ AR = @AR@ RANLIB = @RANLIB@ +WINDRES = @WINDRES@ TARGET = libSDL.la SOURCES = @SOURCES@ diff --git a/build-scripts/makedep.sh b/build-scripts/makedep.sh index cebc36f1c..ceffe275b 100755 --- a/build-scripts/makedep.sh +++ b/build-scripts/makedep.sh @@ -41,7 +41,11 @@ search_deps() for src in $SOURCES do echo "Generating dependencies for $src" ext=`echo $src | sed 's|.*\.\(.*\)|\1|'` - obj=`echo $src | sed "s|^.*/\([^ ]*\)\..*|\1.lo|g"` + if test x"$ext" = x"rc"; then + obj=`echo $src | sed "s|^.*/\([^ ]*\)\..*|\1.o|g"` + else + obj=`echo $src | sed "s|^.*/\([^ ]*\)\..*|\1.lo|g"` + fi echo "\$(objects)/$obj: $src \\" >>${output}.new search_deps $src | sort | uniq >>${output}.new case $ext in @@ -73,6 +77,12 @@ __EOF__ \$(LIBTOOL) --mode=compile \$(CC) \$(CFLAGS) \$(EXTRA_CFLAGS) -c $src -o \$@ +__EOF__ + ;; + rc) cat >>${output}.new <<__EOF__ + + \$(WINDRES) $src \$@ + __EOF__ ;; *) echo "Unknown file extension: $ext";; diff --git a/configure.in b/configure.in index 5bffd518f..eed460461 100644 --- a/configure.in +++ b/configure.in @@ -96,6 +96,7 @@ AC_PROG_CC AC_PROG_CXX AC_PROG_INSTALL AC_PROG_MAKE_SET +AC_CHECK_PROGS(WINDRES, windres i386-mingw32-windres) dnl Check for compiler characteristics AC_C_CONST @@ -2436,6 +2437,7 @@ case "$host" in EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldxguid" fi # The Win32 platform requires special setup + SOURCES="$SOURCES $srcdir/src/main/win32/*.rc" SDLMAIN_SOURCES="$srcdir/src/main/win32/*.c" SDL_CFLAGS="$SDL_CFLAGS -Dmain=SDL_main" SDL_LIBS="-lmingw32 -lSDLmain $SDL_LIBS -mwindows" @@ -2702,6 +2704,7 @@ OBJECTS=`echo $OBJECTS | sed 's,[[^ ]]*/\([[^ ]]*\)\.cc,$(objects)/\1.lo,g'` OBJECTS=`echo $OBJECTS | sed 's,[[^ ]]*/\([[^ ]]*\)\.m,$(objects)/\1.lo,g'` OBJECTS=`echo $OBJECTS | sed 's,[[^ ]]*/\([[^ ]]*\)\.c,$(objects)/\1.lo,g'` OBJECTS=`echo $OBJECTS | sed 's,[[^ ]]*/\([[^ ]]*\)\.S,$(objects)/\1.lo,g'` +OBJECTS=`echo $OBJECTS | sed 's,[[^ ]]*/\([[^ ]]*\)\.rc,$(objects)/\1.o,g'` SDLMAIN_OBJECTS=`echo $SDLMAIN_SOURCES | sed 's,[[^ ]]*/\([[^ ]]*\)\.cc,$(objects)/\1.o,g'` SDLMAIN_OBJECTS=`echo $SDLMAIN_OBJECTS | sed 's,[[^ ]]*/\([[^ ]]*\)\.m,$(objects)/\1.o,g'` @@ -2771,6 +2774,7 @@ AC_SUBST(BUILD_CFLAGS) AC_SUBST(EXTRA_CFLAGS) AC_SUBST(BUILD_LDFLAGS) AC_SUBST(EXTRA_LDFLAGS) +AC_SUBST(WINDRES) AC_OUTPUT([ Makefile sdl-config SDL.spec SDL.qpg sdl.pc diff --git a/src/main/win32/version.rc b/src/main/win32/version.rc new file mode 100644 index 000000000..d1b27f181 --- /dev/null +++ b/src/main/win32/version.rc @@ -0,0 +1,39 @@ +#define APSTUDIO_READONLY_SYMBOLS +#include "afxres.h" +#undef APSTUDIO_READONLY_SYMBOLS + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,2,12,0 + PRODUCTVERSION 1,2,12,0 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "\0" + VALUE "FileDescription", "SDL\0" + VALUE "FileVersion", "1, 2, 12, 0\0" + VALUE "InternalName", "SDL\0" + VALUE "LegalCopyright", "Copyright © 2007 Sam Lantinga\0" + VALUE "OriginalFilename", "SDL.dll\0" + VALUE "ProductName", "Simple DirectMedia Layer\0" + VALUE "ProductVersion", "1, 2, 12, 0\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END From 62756e27c79f9c8dd958016a3ac402bb5d4b5f66 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 16 Jul 2007 05:08:20 +0000 Subject: [PATCH 233/241] Always advertise hardware palette, since Windows will remap colors for us. We do grab the system colors if the application requested fullscreen or a real hardware palette. This allows gamma fading, etc. to work, and is what previous versions did. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402550 --- src/video/windib/SDL_dibvideo.c | 21 ++++++++++++--------- src/video/windib/SDL_dibvideo.h | 2 ++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/video/windib/SDL_dibvideo.c b/src/video/windib/SDL_dibvideo.c index 9480b908b..371d7e9df 100644 --- a/src/video/windib/SDL_dibvideo.c +++ b/src/video/windib/SDL_dibvideo.c @@ -637,10 +637,11 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, #endif /* !NO_CHANGEDISPLAYSETTINGS */ /* Reset the palette and create a new one if necessary */ + if ( grab_palette ) { + DIB_ReleaseStaticColors(SDL_Window); + grab_palette = FALSE; + } if ( screen_pal != NULL ) { - if ( video->flags & SDL_HWPALETTE ) { - DIB_ReleaseStaticColors(SDL_Window); - } /* RJR: March 28, 2000 delete identity palette if switching from a palettized mode */ DeleteObject(screen_pal); @@ -650,6 +651,7 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, SDL_free(screen_logpal); screen_logpal = NULL; } + if ( bpp <= 8 ) { /* RJR: March 28, 2000 @@ -755,10 +757,11 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, this->UpdateRects = DIB_NormalUpdate; /* Set video surface flags */ - if ( (flags & (SDL_FULLSCREEN|SDL_HWPALETTE)) != 0 ) { - /* BitBlt() maps colors for us */ - video->flags |= SDL_HWPALETTE; + if ( screen_pal && (flags & (SDL_FULLSCREEN|SDL_HWPALETTE)) ) { + grab_palette = TRUE; } + /* BitBlt() maps colors for us */ + video->flags |= SDL_HWPALETTE; } #ifndef _WIN32_WCE /* Resize the window */ @@ -976,7 +979,7 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) mdc = CreateCompatibleDC(hdc); SelectObject(mdc, screen_bmp); SetDIBColorTable(mdc, firstcolor, ncolors, pal); - if ( moved_entries || !(this->screen->flags & SDL_HWPALETTE) ) { + if ( moved_entries || !grab_palette ) { BitBlt(hdc, 0, 0, this->screen->w, this->screen->h, mdc, 0, 0, SRCCOPY); } @@ -1098,7 +1101,7 @@ void DIB_VideoQuit(_THIS) if ( SDL_Window ) { /* Delete the screen bitmap (also frees screen->pixels) */ if ( this->screen ) { - if ( this->screen->flags & SDL_HWPALETTE ) { + if ( grab_palette ) { DIB_ReleaseStaticColors(SDL_Window); } #ifndef NO_CHANGEDISPLAYSETTINGS @@ -1183,7 +1186,7 @@ static void DIB_ReleaseStaticColors(HWND window) } static void DIB_Activate(_THIS, BOOL active, BOOL minimized) { - if ( screen_pal && (this->screen->flags & SDL_HWPALETTE) ) { + if ( grab_palette ) { if ( !active ) { DIB_ReleaseStaticColors(SDL_Window); DIB_RealizePalette(this); diff --git a/src/video/windib/SDL_dibvideo.h b/src/video/windib/SDL_dibvideo.h index efc6ebc8b..043c11d15 100644 --- a/src/video/windib/SDL_dibvideo.h +++ b/src/video/windib/SDL_dibvideo.h @@ -41,6 +41,7 @@ struct SDL_PrivateVideoData { HBITMAP screen_bmp; HPALETTE screen_pal; LOGPALETTE *screen_logpal; + BOOL grab_palette; int allow_screensaver; @@ -60,6 +61,7 @@ struct SDL_PrivateVideoData { #define screen_bmp (this->hidden->screen_bmp) #define screen_pal (this->hidden->screen_pal) #define screen_logpal (this->hidden->screen_logpal) +#define grab_palette (this->hidden->grab_palette) #define SDL_nummodes (this->hidden->SDL_nummodes) #define SDL_modelist (this->hidden->SDL_modelist) From 385916fd13cbbbdbab12ff34787abc3874ef61fb Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 18 Jul 2007 04:04:24 +0000 Subject: [PATCH 234/241] Better windres detection --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402553 --- configure.in | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index eed460461..2f55d286e 100644 --- a/configure.in +++ b/configure.in @@ -96,7 +96,12 @@ AC_PROG_CC AC_PROG_CXX AC_PROG_INSTALL AC_PROG_MAKE_SET -AC_CHECK_PROGS(WINDRES, windres i386-mingw32-windres) +if test -z "$host_alias"; then + hostaliaswindres= +else + hostaliaswindres="$host_alias-windres" +fi +AC_CHECK_PROGS(WINDRES, [windres $hostaliaswindres $host_os-windres]) dnl Check for compiler characteristics AC_C_CONST From d2459bb368a74c442555c29e17dd6b5a98ca3b23 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 18 Jul 2007 04:07:46 +0000 Subject: [PATCH 235/241] Updating copyright date for Version.rc --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402555 --- VisualC.zip | Bin 42465 -> 42466 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/VisualC.zip b/VisualC.zip index d4a5a2a4fdb3f5154d2830a9bbce6c48b2a47ca5..e6da47aa90fae01bef376c78c0f31d5d09048ef6 100644 GIT binary patch delta 1450 zcmZ9Mc}&x19LD**RG@;kf_zz~YIlw&|g0a?Kmv>;Z2$~6u_g+#?L73CO| zFGmZsP$+JSi?}-Rzys8wFa`sUNa8r^053KbP}~elf7EQ*o4m>Ad7f{+f4$E;-iIdo zP=%ZI4T+p9$Rp^@VRINiOrNk^PkZit_nIl;tu?wLk#n^ZlD)x%Hi?{j{^~4=s0|Az zubDl7OJv6a?TGe%T5?U$pE2Q1zHa||Nr;PUxe|AIG zyH0aH{EJ8LB03^3mIep*UB54oc}VD1qp#}A7$;99hj-pA_bDLzUyfYtH!$%j4JGCZ z#cc@}O&GRi`t%EQYI0SVUaV_@mGG%;>D0^`>fIc^U+xP#;G~2ov9u}qSrO-zpZ(?1S z@JY%$i1_j`Rq|0W;(cWJ)>ugzU(m2PP`Q{eb71tBk6|VYtS3IszGv_4RCk+g({qeojrI%3B}=%`G@ z)6qx@i?pg(Tgytb{`(Xj=s%Rc-`rnOasS*vl#==~ITqnXFL3UjfqIp21ay8U3$?&X>h0>ThNrCmU zjf7VLHf-EzsP{ohOE^;>g3kEi?o9nk5H@g7bPz5FgA733;Ej~HtdxhM=@2{+$+sZs z794NMS!iqtNf9J4m)ihGVU3tkcuI;`4w+F#P@wQa^U=6v*GPn6g*OU{(Mdj54cU#! zh$n(br8)fB=!2hyJl9Hu_*NDgFUON}tu6*9strM{;G_U1O9|_Llpm?JEjeZZiO6{yUxzv zZo_#aMrO|t#b0&bH@Of#oTy|PU9_1b-I~4`RFKIN3^a&AIXP)UVpfw9Ho z-0&4MM_#TP%QNzc++!G%6Ri#U&CMB0!EvMn5t;?S~)!WDbA6-U(}VepRuPa z#%SdTJEqsFu28^l7aQ=C*e&FB!I>Nve8TA@=QF!~m&dR}-SPYU7_xD#8>SH^1`#>}0FYx;V% zUg3JEaU$nOjCgpNaBwOuQYs*A>sWS$GpbmB!Y?N|zM;SCl}Xg+vX+|dnY%bX8L1tt zEuR!-2s6gw*{x4HWKWiD@>-&dIrb(VBhDRMZ#-ZVby|!6qr*^JrT@NPqd7}o}YN%KRs~QYWrWW_#$&_?{z)vWjoY-M&bAto{4yEz6PJ zGqb!K-A#ficOTyFiCNKGUgNiO{WEFJC8v(z=PccL1-Z`Jfdd}vM%sB_XWfx*7&*WC z&?SSPPOQ;B$vTr<;4PQmsh*hnqV|_dRXfaC$)&X(WDm&<^XhtC*2i zf!gDxNBR~q+&9h&YxWo4%{lSa*^I?kV&i-c zc=;vt#T^ujwmHK`t&7OZ4_{XkgBxn z`s_j6Y*9$)U3$se+IyU=TipurzD?mZ|BZ+;U1vLzp1!loOOqtlQs|?P>GE#!c055f zzMyb0k+Z0dy7~*p9cmqD;E}Tg9@2H8mQMVT3PqJ9`3T)$p2!sr?2j=y)74SK`D@)Z zyg1rKe%jA&ft%PEw7~JUX)@)-(Se%k`*B>u`4?5y&O+wLe4sUw5wj2b(HSOaeQr!my{Xvx)}8 zRle9NSX>>AMqR)~Y7F_+p2*r&EyZjj__Lae_OdnB6oe9c5Q<5NwpNXvi?yI$%t3

cL_O7d;KoL{(@B2qi33u~ChBBwX}xUK)iM zf{DZ&*45Gwi>Hnnh3G*tPZzRkS!iaf8V%NZBj0TrNrdBd2EeJ~qSD9(C$&Jws=8}kx-Qg<%|Ia`z`J@HvJz^rG59oaQDVBrT0lz!3t8vDWFrOsZQ!E4^HPzw o2(~tIu@)$4jKU(|pT Date: Thu, 19 Jul 2007 08:08:16 +0000 Subject: [PATCH 236/241] Fixed bug #461 Fixed a couple of bugs in the OpenGL window reset. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402556 --- src/video/wincommon/SDL_wingl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/video/wincommon/SDL_wingl.c b/src/video/wincommon/SDL_wingl.c index 88ceffce7..e807111ce 100644 --- a/src/video/wincommon/SDL_wingl.c +++ b/src/video/wincommon/SDL_wingl.c @@ -50,13 +50,15 @@ static int WIN_GL_ResetWindow(_THIS) DestroyWindow(SDL_Window); WIN_FlushMessageQueue(); + SDL_resizing = 1; SDL_Window = CreateWindow(SDL_Appname, SDL_Appname, style, rect.left, rect.top, (rect.right-rect.left)+1, - (rect.top-rect.bottom)+1, + (rect.bottom-rect.top)+1, NULL, NULL, SDL_Instance, NULL); WIN_FlushMessageQueue(); + SDL_resizing = 0; if ( SDL_Window ) { this->SetCaption(this, this->wm_title, this->wm_icon); From 0b1d4865684af171d02a8b3d7a24438ca186af7f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 19 Jul 2007 08:12:45 +0000 Subject: [PATCH 237/241] Added patch note for bug #461 --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402557 --- docs.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs.html b/docs.html index 64b110ced..6e2d106b5 100644 --- a/docs.html +++ b/docs.html @@ -98,6 +98,9 @@ SDL 1.2.12 is a minor bug fix release.

The windib driver now supports more mouse buttons with WM_XBUTTON events.

+

+ On Windows, SDL_SetVideoMode() will re-create the window instead of failing if the multisample settings are changed. +

Added support for UTF-8 window titles on Windows.

From 482db6b458e1fd7e51cb393933e4987711f51d22 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 20 Jul 2007 02:58:28 +0000 Subject: [PATCH 238/241] Fixed warnings in NO_STDIO mode --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402558 --- src/main/win32/SDL_win32_main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/win32/SDL_win32_main.c b/src/main/win32/SDL_win32_main.c index d78708f33..ae0be4571 100644 --- a/src/main/win32/SDL_win32_main.c +++ b/src/main/win32/SDL_win32_main.c @@ -234,12 +234,6 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) char **argv; int argc; char *cmdline; - DWORD pathlen; -#ifdef _WIN32_WCE - wchar_t path[MAX_PATH]; -#else - char path[MAX_PATH]; -#endif #ifdef _WIN32_WCE wchar_t *bufp; int nLen; @@ -248,6 +242,12 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) size_t nLen; #endif #ifndef NO_STDIO_REDIRECT + DWORD pathlen; +#ifdef _WIN32_WCE + wchar_t path[MAX_PATH]; +#else + char path[MAX_PATH]; +#endif FILE *newfp; #endif From 0a9a1e25b84b12f8566fd2b8c00d6acf424b925b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 20 Jul 2007 03:25:40 +0000 Subject: [PATCH 239/241] > Hi Ryan, > I checked the list you linked to, but did not see any reference to whether > the Win32 window centering bug was fixed... Has that been addressed at all? > I refer to the bug where, unless one has globally set the > SDL_WINDOW_CENTERED variable in the OS, only the 1st window that is created > will be centered. Subsequent calls to SetVideoMode will create a window tha t > shares the same upper-left corner location. I'm working on that now, thanks for reporting it. What I'm doing is if the width and height are the same, I'm leaving the window position alone, but if they're different they will respect the positioning environment variables. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402559 --- src/video/windib/SDL_dibvideo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/video/windib/SDL_dibvideo.c b/src/video/windib/SDL_dibvideo.c index 371d7e9df..d86b45770 100644 --- a/src/video/windib/SDL_dibvideo.c +++ b/src/video/windib/SDL_dibvideo.c @@ -468,6 +468,7 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { SDL_Surface *video; + int prev_w, prev_h; Uint32 prev_flags; DWORD style; const DWORD directstyle = @@ -531,6 +532,8 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, /* Fill in part of the video surface */ prev_flags = video->flags; + prev_w = video->w; + prev_h = video->h; video->flags = 0; /* Clear flags */ video->w = width; video->h = height; @@ -774,7 +777,7 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, const char *window = NULL; const char *center = NULL; - if ( !SDL_windowX && !SDL_windowY ) { + if ( video->w != prev_w || video->h != prev_h ) { window = SDL_getenv("SDL_VIDEO_WINDOW_POS"); center = SDL_getenv("SDL_VIDEO_CENTERED"); if ( window ) { From 3dc65ba6141af3b089f872a7327514e8ececf26f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 20 Jul 2007 03:30:41 +0000 Subject: [PATCH 240/241] Merged window position fix from windib code --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402560 --- src/video/windx5/SDL_dx5video.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/video/windx5/SDL_dx5video.c b/src/video/windx5/SDL_dx5video.c index aae58be62..50b74f614 100644 --- a/src/video/windx5/SDL_dx5video.c +++ b/src/video/windx5/SDL_dx5video.c @@ -1018,6 +1018,7 @@ SDL_Surface *DX5_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { SDL_Surface *video; + int prev_w, prev_h; HRESULT result; DWORD sharemode; DWORD style; @@ -1103,6 +1104,8 @@ SDL_Surface *DX5_SetVideoMode(_THIS, SDL_Surface *current, } /* Fill in part of the video surface */ + prev_w = video->w; + prev_h = video->h; video->flags = 0; /* Clear flags */ video->w = width; video->h = height; @@ -1178,7 +1181,7 @@ SDL_Surface *DX5_SetVideoMode(_THIS, SDL_Surface *current, const char *window = NULL; const char *center = NULL; - if ( !SDL_windowX && !SDL_windowY ) { + if ( video->w != prev_w || video->h != prev_h ) { window = SDL_getenv("SDL_VIDEO_WINDOW_POS"); center = SDL_getenv("SDL_VIDEO_CENTERED"); if ( window ) { @@ -1454,6 +1457,8 @@ SDL_Surface *DX5_SetVideoMode(_THIS, SDL_Surface *current, SDL_OutOfMemory(); return(NULL); } + prev_w = video->w; + prev_h = video->h; video->w = width; video->h = height; video->pitch = 0; @@ -1581,7 +1586,7 @@ SDL_Surface *DX5_SetVideoMode(_THIS, SDL_Surface *current, const char *window = NULL; const char *center = NULL; - if ( !SDL_windowX && !SDL_windowY ) { + if ( video->w != prev_w || video->h != prev_h ) { window = SDL_getenv("SDL_VIDEO_WINDOW_POS"); center = SDL_getenv("SDL_VIDEO_CENTERED"); if ( window ) { From 558a231a131aae33d509ac4b743eff9306593789 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 20 Jul 2007 08:17:45 +0000 Subject: [PATCH 241/241] I'm not sure if this helps anything, but it was clearly wrong. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402561 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 2f55d286e..62f95880b 100644 --- a/configure.in +++ b/configure.in @@ -937,7 +937,7 @@ AC_HELP_STRING([--enable-x11-shared], [dynamically load X11 support [[default=ma x11ext_lib='libXext.so' ;; *) - x11_lib_spec=[`echo $X_LIBS | sed 's/.*-L\([^ ]*\).*/\1/'`] + x11_lib_path=[`echo $X_LIBS | sed 's/.*-L\([^ ]*\).*/\1/'`] for path in $x11_lib_path /usr/lib /usr/X11/lib /usr/X11R6/lib; do if test "x$x11_lib" = "x"; then x11_lib=[`ls -- $path/libX11.so.[0-9] 2>/dev/null | sort -r | sed 's/.*\/\(.*\)/\1/; q'`]