diff --git a/BUGS b/BUGS index 5b709c19d..218bf3d15 100644 --- a/BUGS +++ b/BUGS @@ -1,204 +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/ - -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/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 diff --git a/EpocBuildFiles.zip b/EpocBuildFiles.zip deleted file mode 100644 index 9de7244f9..000000000 Binary files a/EpocBuildFiles.zip and /dev/null differ 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/Makefile.in b/Makefile.in index 4795229db..a11c104fa 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@ @@ -29,6 +30,7 @@ INSTALL = @INSTALL@ NASM = @NASM@ @NASMFLAGS@ AR = @AR@ RANLIB = @RANLIB@ +WINDRES = @WINDRES@ TARGET = libSDL.la SOURCES = @SOURCES@ @@ -38,13 +40,15 @@ 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 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) @@ -80,51 +84,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 - for src in $(srcdir)/include/*.h; do \ - file=`echo $$src | sed -e 's|^.*/||'`; \ - $(INSTALL) -m 644 $$src $(includedir)/SDL/$$file; \ + $(SHELL) $(auxdir)/mkinstalldirs $(DESTDIR)$(includedir)/SDL + for file in $(HDRS); do \ + $(INSTALL) -m 644 $(srcdir)/include/$$file $(DESTDIR)$(includedir)/SDL/$$file; \ done - $(INSTALL) -m 644 include/SDL_config.h $(includedir)/SDL/SDL_config.h -install-lib: - $(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) + $(INSTALL) -m 644 include/SDL_config.h $(DESTDIR)$(includedir)/SDL/SDL_config.h +install-lib: $(objects) $(objects)/$(TARGET) $(objects)/$(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 src in $(srcdir)/include/*.h; do \ - file=`echo $$src | sed -e 's|^.*/||'`; \ - rm -f $(includedir)/SDL/$$file; \ + for file in $(HDRS); do \ + 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: @@ -169,10 +171,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 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 rm -f $(HOME)/SDL-1.2.zip zip -r $(HOME)/SDL-1.2.zip SDL-1.2 diff --git a/README b/README index 17ea835c0..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 AmigaOS, 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.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/README.Epoc b/README.Epoc deleted file mode 100644 index 380cb2527..000000000 --- a/README.Epoc +++ /dev/null @@ -1,75 +0,0 @@ - -============================================================================== -Using the Simple DirectMedia Layer with EPOC/SymbianOS 6.0 -============================================================================== - -============================================================================== -I. Building the Simple DirectMedia Layer libraries: - - You can get Symbian SDK from: - http://www.symbian.com. - - First create "Epoc" directory under SDL main directory and unpack - EpocBuildFiles.zip in it. - - To build the librarys goto "epoc" directory and type: - bldmake bldfiles - abld makefile vc6 (for creating Microsoft Visual C++ makefiles) - abld build wins udeb (building for wins emulator) - abld build armi urel (building for real device) - -============================================================================== -II. Building the Simple DirectMedia Layer programs: - - Building SDL test programs is easy once you have built the libraries: - abld test build wins udeb - abld test build armi urel - - Supported real screen resolutions - 320 x 200 x 8 bit - 320 x 200 x 12 bit - 640 x 200 x 8 bit - 640 x 200 x 12 bit - Supported "emulated" screen resolutions - 640 x 400 x 8 bit - 640 x 400 x 12 bit - 640 x 480 x 8 bit - 640 x 480 x 12 bit - "Emulated" resolutions are implemented by by shrinking the screen vertically - i.e. only every second scanline is drawn. This is mainly ment to be used for - testing quick ports of programs. Using faked resolutions is a waste of memory - and cpu power! - -============================================================================== -III. Running test programs - - Copy executable to the device and run it from the File manager. The Esc - key quits demo programs. In Crystal, Exe programs do not appear in task list - nor in Extras :-(. Test programs are tested in Nokia 9210 Communicator. - - Special keys used in SDL: - The Caps lock key enables or disables the virtual cursor. - Function keys are mapped as follows: - F1=chr+q, F2=chr+w,..., F8=chr+i, - F9=chr+a,..., F12=chr+d. - -============================================================================== -IV. Enjoy! :) - - If you have a project you'd like me to know about, or want to ask questions, - go ahead and join the SDL developer's mailing list by sending e-mail to: - - sdl-request@libsdl.org - - and put "subscribe" into the subject of the message. Or alternatively you - can use the web interface: - - http://www.libsdl.org/mailman/listinfo/sdl - - You can find more info about Epoc version of SDL from Hannu Viitala's - homepage - http://www.mbnet.fi/~haviital - -============================================================================== - - diff --git a/README.MiNT b/README.MiNT index 25a7d5658..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: @@ -127,12 +124,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 +210,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/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/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. diff --git a/README.Symbian b/README.Symbian new file mode 100644 index 000000000..32d925a00 --- /dev/null +++ b/README.Symbian @@ -0,0 +1,23 @@ +============================================================================== +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. +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/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/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 diff --git a/VisualC.zip b/VisualC.zip index 030db1cde..e6da47aa9 100644 Binary files a/VisualC.zip and b/VisualC.zip differ 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/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" # 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 79cac877f..62f95880b 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) @@ -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 @@ -96,6 +96,12 @@ AC_PROG_CC AC_PROG_CXX AC_PROG_INSTALL AC_PROG_MAKE_SET +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 @@ -124,7 +130,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) @@ -189,7 +202,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" @@ -220,6 +232,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]]]), @@ -451,6 +465,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, @@ -511,21 +582,25 @@ 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 + 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 -r /usr/X11R6/include/audio/audiolib.h; then + if test x$have_audio_hdr = xyes -a x$have_audio_lib = xyes; 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 AC_DEFINE(SDL_AUDIO_DRIVER_NAS) SOURCES="$SOURCES $srcdir/src/audio/nas/*.c" @@ -597,38 +672,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/" + 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) @@ -844,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'`] @@ -1118,6 +1211,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 @@ -1466,6 +1560,7 @@ CheckOpenGLX11() AC_TRY_COMPILE([ #include #include + #include ],[ ],[ video_opengl=yes @@ -1676,7 +1771,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" @@ -2019,8 +2114,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) @@ -2141,6 +2241,7 @@ case "$host" in CheckALSA CheckARTSC CheckESD + CheckPulseAudio CheckNAS CheckX11 CheckNANOX @@ -2278,7 +2379,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 @@ -2341,6 +2442,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" @@ -2417,10 +2519,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) @@ -2453,8 +2552,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 @@ -2474,6 +2573,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 @@ -2484,6 +2584,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 @@ -2564,11 +2668,13 @@ 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... + AC_DEFINE(SDL_JOYSTICK_DUMMY) SOURCES="$SOURCES $srcdir/src/joystick/dummy/*.c" + fi fi if test x$have_cdrom != xyes; then if test x$enable_cdrom = xyes; then @@ -2603,6 +2709,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'` @@ -2612,10 +2719,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 +2737,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" @@ -2672,6 +2779,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/docs.html b/docs.html index 8b00610c8..6e2d106b5 100644 --- a/docs.html +++ b/docs.html @@ -14,6 +14,151 @@ 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, Windows, 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() +

+

+ Fixed compiling with Sun Studio. +

+

+ 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. +

+

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

+

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

+

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

+
+ +

Unix Notes

+ +
+

+ Fixed detection of X11 DGA mouse support. +

+

+ Improved XIM support for asian character sets. +

+

+ 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. +

+

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

+
+ +

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. +

+

+ 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. +

+

+ Fixed joystick detection on Windows. +

+

+ Improved performance with Win32 file I/O. +

+

+ 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. +

+

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

+
+ +

Mac OS Classic Notes

+ +
+

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

+
+ +

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. 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)

dummyvoid *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\&. diff --git a/include/SDL_config.h.default b/include/SDL_config.h.default index 8970ec3d5..c82f42adf 100644 --- a/include/SDL_config.h.default +++ b/include/SDL_config.h.default @@ -26,14 +26,14 @@ #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" #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 6f89569c9..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 @@ -130,6 +135,7 @@ #undef HAVE_NANOSLEEP #undef HAVE_CLOCK_GETTIME #undef HAVE_DLVSYM +#undef HAVE_GETPAGESIZE #else /* We may need some replacement for stdarg.h here */ @@ -149,7 +155,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 @@ -163,6 +168,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 @@ -195,7 +202,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,10 +227,8 @@ #undef SDL_LOADSO_WIN32 /* Enable various threading systems */ -#undef SDL_THREAD_AMIGA #undef SDL_THREAD_BEOS #undef SDL_THREAD_DC -#undef SDL_THREAD_EPOC #undef SDL_THREAD_OS2 #undef SDL_THREAD_PTH #undef SDL_THREAD_PTHREAD @@ -234,11 +238,9 @@ #undef SDL_THREAD_WIN32 /* Enable various timer systems */ -#undef SDL_TIMER_AMIGA #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 @@ -250,14 +252,12 @@ /* 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 #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_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_config_macosx.h b/include/SDL_config_macosx.h index 8f04930d5..481c22edc 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 @@ -114,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 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_config_symbian.h b/include/SDL_config_symbian.h new file mode 100644 index 000000000..003a49157 --- /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_config_win32.h b/include/SDL_config_win32.h index 23e4868c2..cfb44d2a0 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; @@ -46,6 +46,13 @@ 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 #else /* !__GNUC__ && !_MSC_VER */ typedef signed char int8_t; typedef unsigned char uint8_t; 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/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/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/include/SDL_stdinc.h b/include/SDL_stdinc.h index 62535629f..891a9ac88 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 { @@ -127,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" @@ -181,10 +185,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 @@ -263,7 +267,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 +299,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; \ @@ -561,19 +571,17 @@ 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); -#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) +extern DECLSPEC char * SDLCALL SDL_iconv_string(const char *tocode, const char *fromcode, const char *inbuf, size_t inbytesleft); +#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/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/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/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; 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/include/begin_code.h b/include/begin_code.h index 40279337f..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,14 +120,16 @@ #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 #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++ */ 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]" diff --git a/src/SDL.c b/src/SDL.c index 64a3e93dc..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; @@ -323,7 +325,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 84a5e0742..3e2316df2 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 @@ -82,9 +85,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, @@ -101,11 +101,17 @@ 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 #if SDL_AUDIO_DRIVER_DART &DART_bootstrap, +#endif +#if SDL_AUDIO_DRIVER_EPOCAUDIO + &EPOCAudio_bootstrap, #endif NULL }; @@ -115,10 +121,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 +130,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 +141,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 +153,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! */ @@ -216,6 +190,7 @@ int SDLCALL SDL_RunAudio(void *audiop) stream = audio->fake_stream; } } + SDL_memset(stream, silence, stream_len); if ( ! audio->paused ) { @@ -253,14 +228,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()); @@ -350,7 +317,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 +348,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; @@ -471,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 ) { @@ -491,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 ) { @@ -508,10 +474,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 */ @@ -521,8 +484,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); @@ -533,33 +495,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 ) { @@ -591,7 +532,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 ) { @@ -602,12 +544,11 @@ 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: /* 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 @@ -624,11 +565,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 +638,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/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 3c361155e..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; } @@ -1374,7 +1339,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; } diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index 13e2dd516..1fc920a32 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; @@ -146,9 +149,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; @@ -165,12 +165,18 @@ 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 #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/amigaos/SDL_ahiaudio.c b/src/audio/amigaos/SDL_ahiaudio.c deleted file mode 100644 index c9a4c1a4f..000000000 --- a/src/audio/amigaos/SDL_ahiaudio.c +++ /dev/null @@ -1,337 +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) -{ -// int width; - - D(bug("AHI opening...\n")); - - /* Determine the audio parameters from the AudioSpec */ - switch ( spec->format & 0xFF ) { - - 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 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: { - 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; - } - - 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/arts/SDL_artsaudio.c b/src/audio/arts/SDL_artsaudio.c index 59949a52f..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" @@ -60,6 +65,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 +79,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 +136,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 +264,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 +302,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"); diff --git a/src/audio/baudio/SDL_beaudio.cc b/src/audio/baudio/SDL_beaudio.cc index b074f9c2b..fce0ecb32 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; + Uint16 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..a37a5e222 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) { + Uint16 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..a28ea5a7f 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); - } + Uint16 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..f9bd31047 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; + Uint16 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/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 ) { 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 39e7a6d22..d4c43cfcf 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; @@ -349,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 de35debf5..41f78c999 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; + Uint16 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 = spec->format & 0xff; + format_signed = (spec->format & (1<<15)); + format_bigendian = (spec->format & (1<<12)); + 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) { @@ -386,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_it.S b/src/audio/mint/SDL_mintaudio_it.S index e9eab5922..c751a5912 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,29 @@ _SDL_MintAudio_XbiosInterrupt: moveml d0-d7/a0-a6,sp@- + /* 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 */ jsr _SDL_MintAudio_Callback + /* 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 */ subl #savamt,savptr @@ -131,17 +152,37 @@ _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 */ eorw #1,_SDL_MintAudio_numbuf - moveml d0-d7/a0-a6,sp@- + moveml d0-d1/a0-a1,sp@- + + /* 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 */ jsr _SDL_MintAudio_Callback + /* 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 */ moveq #0,d0 @@ -169,7 +210,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: @@ -195,9 +236,29 @@ _SDL_MintAudio_StfaInterrupt: moveml d0-d7/a0-a6,sp@- + /* 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 */ jsr _SDL_MintAudio_Callback + /* 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 */ moveq #0,d0 diff --git a/src/audio/mint/SDL_mintaudio_mcsn.c b/src/audio/mint/SDL_mintaudio_mcsn.c index 9741a3bea..a464184e3 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) { @@ -391,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 552a7b224..4ad1fdd36 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++) { @@ -310,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 016d4fa59..4a1af3f39 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) { @@ -341,6 +342,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 */ @@ -433,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) { @@ -480,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); 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/video/cybergfx/SDL_amigamouse_c.h b/src/audio/nds/SDL_ndsaudio.h similarity index 70% rename from src/video/cybergfx/SDL_amigamouse_c.h rename to src/audio/nds/SDL_ndsaudio.h index aad19b627..d4eb2a5bf 100644 --- a/src/video/cybergfx/SDL_amigamouse_c.h +++ b/src/audio/nds/SDL_ndsaudio.h @@ -21,12 +21,20 @@ */ #include "SDL_config.h" -#include "SDL_cgxvideo.h" +#ifndef _SDL_lowaudio_h +#define _SDL_lowaudio_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); +#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/thread/amigaos/SDL_systhread_c.h b/src/audio/nds/sound9.c similarity index 50% rename from src/thread/amigaos/SDL_systhread_c.h rename to src/audio/nds/sound9.c index 53ba3c8c6..0cf732562 100644 --- a/src/thread/amigaos/SDL_systhread_c.h +++ b/src/audio/nds/sound9.c @@ -20,42 +20,42 @@ slouken@libsdl.org */ #include "SDL_config.h" +#include "SDL_stdinc.h" -#include -#include -#include -#if defined (__SASC) || defined(STORMC4_WOS) -#include -#include -#else -#include -#include -#endif +#include "soundcommon.h" -#include "mydebug.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); -extern struct ExecBase *SysBase; -extern struct DosLibrary *DOSBase; + 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; +} -#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*/ +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/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/amigaos/SDL_ahiaudio.h b/src/audio/pulse/SDL_pulseaudio.h similarity index 55% rename from src/audio/amigaos/SDL_ahiaudio.h rename to src/audio/pulse/SDL_pulseaudio.h index b9ef339c6..e19189b6d 100644 --- a/src/audio/amigaos/SDL_ahiaudio.h +++ b/src/audio/pulse/SDL_pulseaudio.h @@ -1,6 +1,6 @@ /* SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga + 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 @@ -16,45 +16,38 @@ 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 + Stéphan Kochen + stephan@kochen.nl + + Based on parts of the ALSA and ESounD output drivers. */ #include "SDL_config.h" -#ifndef _SDL_ahiaudio_h -#define _SDL_ahiaudio_h - -#include -#include -#ifdef __SASC -#include -#else -#include -#endif - -#include -#include "mydebug.h" +#ifndef _SDL_pulseaudio_h +#define _SDL_pulseaudio_h #include "../SDL_sysaudio.h" -/* Hidden "this" pointer for the audio functions */ +/* Hidden "this" pointer for the video 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; + /* 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 audio_port (this->hidden->audio_port) -#define audio_req (this->hidden->audio_req) +#define stream (this->hidden->stream) +#define parent (this->hidden->parent) #define mixbuf (this->hidden->mixbuf) -#define current_buffer (this->hidden->current_buffer) -#define playing (this->hidden->playing) +#define mixlen (this->hidden->mixlen) + +#endif /* _SDL_pulseaudio_h */ -#endif /* _SDL_ahiaudio_h */ 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/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 }; 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, ','); 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..e463bf11c 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 @@ -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 @@ -54,9 +56,12 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con int a_mode; if (!context) - return -1; + 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 */ @@ -72,7 +77,13 @@ 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)*/ + 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 { @@ -80,8 +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, @@ -100,12 +113,14 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con #endif /* _WIN32_WCE */ if (h==INVALID_HANDLE_VALUE) { + 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; context->hidden.win32io.append = a_mode; - + return 0; /* ok */ } static int SDLCALL win32_file_seek(SDL_RWops *context, int offset, int whence) @@ -117,7 +132,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 +150,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 +161,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, (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; + 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 +217,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 +246,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); @@ -372,12 +431,11 @@ 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() */ - 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; } 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..d2d31ecdc 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: @@ -285,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 @@ -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 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/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]) { diff --git a/src/joystick/darwin/SDL_sysjoystick.c b/src/joystick/darwin/SDL_sysjoystick.c index 022c992d4..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? @@ -652,7 +650,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); 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 }, 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 */ 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/joystick/win32/SDL_mmjoystick.c b/src/joystick/win32/SDL_mmjoystick.c index 2523bbec4..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); } @@ -167,7 +158,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 ) { 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: */ + diff --git a/src/loadso/dlopen/SDL_sysloadso.c b/src/loadso/dlopen/SDL_sysloadso.c index ebd595500..550acad3e 100644 --- a/src/loadso/dlopen/SDL_sysloadso.c +++ b/src/loadso/dlopen/SDL_sysloadso.c @@ -45,11 +45,12 @@ void *SDL_LoadFunction(void *handle, const char *name) { void *symbol = dlsym(handle, name); if ( symbol == NULL ) { + /* 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); if ( symbol == NULL ) { SDL_SetError("Failed loading %s: %s", name, (const char *)dlerror()); diff --git a/src/main/epoc/SDL_main.cpp b/src/main/symbian/EKA1/SDL_main.cpp similarity index 61% rename from src/main/epoc/SDL_main.cpp rename to src/main/symbian/EKA1/SDL_main.cpp index 0139c701a..a3296e43a 100644 --- a/src/main/epoc/SDL_main.cpp +++ b/src/main/symbian/EKA1/SDL_main.cpp @@ -1,6 +1,6 @@ /* SDL - Simple DirectMedia Layer - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga + 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 @@ -17,7 +17,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga - slouken@libsdl.org + slouken@devolution.com */ /* @@ -39,17 +39,6 @@ #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); @@ -63,16 +52,33 @@ extern "C" void exit (int ret); /* Epoc main function */ -GLDEF_C TInt E32Main() +#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(); - #if defined(__WINS__) - /* arrange for access to Win32 stdin/stdout/stderr */ - RWin32Stream::StartServer(); - #endif - /* Arrange for multi-threaded operation */ SpawnPosixServerThread(); @@ -80,50 +86,67 @@ GLDEF_C TInt E32Main() int argc=0; char** argv=0; char** envp=0; + +#ifndef __WINS__ __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 - - +#else + GetCmdLine(argc, argv); +#endif /* Start the application! */ /* Create stdlib */ _REENT; - /* Set process and thread priority */ - RThread currentThread; + /* Set process and thread priority and name */ - currentThread.Rename(_L("SdlProgram")); + 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 */ + /* 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! */ + //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; - return(KErrNone); + 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); } - -EXPORT_C TInt WinsMain(TAny *) - { - E32Main(); - 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/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 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 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/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c index 1a94e0f3b..307c73ca4 100644 --- a/src/stdlib/SDL_iconv.c +++ b/src/stdlib/SDL_iconv.c @@ -28,13 +28,27 @@ #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, - 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); + size_t retCode; +#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) { case E2BIG: @@ -95,7 +109,7 @@ static struct { } encodings[] = { { "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 }, @@ -117,12 +131,54 @@ static struct { { "UCS-4", ENCODING_UCS4 }, }; +static const char *getlocale(char *buffer, size_t bufsize) +{ + const char *lang; + char *ptr; + + 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"; + } + + /* 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) { 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_buffer, sizeof(fromcode_buffer)); + } + if ( !tocode || !*tocode ) { + tocode = getlocale(tocode_buffer, sizeof(tocode_buffer)); + } for ( i = 0; i < SDL_arraysize(encodings); ++i ) { if ( SDL_strcasecmp(fromcode, encodings[i].name) == 0 ) { src_fmt = encodings[i].format; @@ -149,11 +205,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 +812,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; @@ -765,6 +822,16 @@ char *SDL_iconv_string(const char *tocode, const char *fromcode, char *inbuf, si 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; } 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; diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index 02a93a5d9..0ab5af6bb 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; @@ -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--; } @@ -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 ) { diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h index 13501db6d..472d8a071 100644 --- a/src/thread/SDL_thread_c.h +++ b/src/thread/SDL_thread_c.h @@ -27,14 +27,10 @@ /* 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 #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 @@ -45,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/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_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/thread/epoc/SDL_sysmutex.cpp b/src/thread/symbian/SDL_sysmutex.cpp similarity index 63% rename from src/thread/epoc/SDL_sysmutex.cpp rename to src/thread/symbian/SDL_sysmutex.cpp index 179201261..ac20744a4 100644 --- a/src/thread/epoc/SDL_sysmutex.cpp +++ b/src/thread/symbian/SDL_sysmutex.cpp @@ -1,25 +1,24 @@ /* SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga + 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 Lesser General Public + modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + 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 - Lesser General Public License for more details. + Library 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 + 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 + slouken@devolution.com */ -#include "SDL_config.h" /* SDL_sysmutex.cpp @@ -28,19 +27,35 @@ */ +#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 + +#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*); @@ -48,6 +63,11 @@ 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) @@ -61,6 +81,7 @@ SDL_mutex *SDL_CreateMutex(void) } SDL_mutex* mutex = new /*(ELeave)*/ SDL_mutex; mutex->handle = rmutex.Handle(); + EpocSdlEnv::AppendCleanupItem(TSdlCleanupItem(DeleteMutex, mutex)); return(mutex); } @@ -71,8 +92,12 @@ void SDL_DestroyMutex(SDL_mutex *mutex) { RMutex rmutex; rmutex.SetHandle(mutex->handle); - rmutex.Signal(); + if(rmutex.IsHeld()) + { + rmutex.Signal(); + } rmutex.Close(); + EpocSdlEnv::RemoveCleanupItem(mutex); delete(mutex); mutex = NULL; } diff --git a/src/thread/epoc/SDL_syssem.cpp b/src/thread/symbian/SDL_syssem.cpp similarity index 79% rename from src/thread/epoc/SDL_syssem.cpp rename to src/thread/symbian/SDL_syssem.cpp index c3982d2df..55036952b 100644 --- a/src/thread/epoc/SDL_syssem.cpp +++ b/src/thread/symbian/SDL_syssem.cpp @@ -1,25 +1,24 @@ /* SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 Sam Lantinga + 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 Lesser General Public + modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + 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 - Lesser General Public License for more details. + Library 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 + 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 + slouken@devolution.com */ -#include "SDL_config.h" /* SDL_syssem.cpp @@ -27,8 +26,15 @@ 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" @@ -43,8 +49,11 @@ struct SDL_semaphore 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) { @@ -74,13 +83,15 @@ void SDL_DestroySemaphore(SDL_sem *sem) { RSemaphore sema; sema.SetHandle(sem->handle); - sema.Signal(sema.Count()); + while(--sem->count) + sema.Signal(); sema.Close(); delete sem; sem = NULL; } } +#ifndef EKA2 struct TInfo { @@ -91,6 +102,8 @@ void SDL_DestroySemaphore(SDL_sem *sem) TInt iVal; }; + + TBool ThreadRun(TAny* aInfo) { TInfo* info = STATIC_CAST(TInfo*, aInfo); @@ -102,7 +115,7 @@ TBool ThreadRun(TAny* aInfo) return 0; } - +#endif void _WaitAll(SDL_sem *sem) @@ -131,7 +144,14 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) 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); @@ -153,6 +173,7 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) thread.Close(); return info->iVal; +#endif } int SDL_SemTryWait(SDL_sem *sem) @@ -164,7 +185,7 @@ int SDL_SemTryWait(SDL_sem *sem) return SDL_MUTEX_TIMEOUT; } -int SDL_SemWait(SDL_sem *sem) +int SDL_SemWait(SDL_sem *sem) { return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); } diff --git a/src/thread/epoc/SDL_systhread.cpp b/src/thread/symbian/SDL_systhread.cpp similarity index 75% rename from src/thread/epoc/SDL_systhread.cpp rename to src/thread/symbian/SDL_systhread.cpp index 708f004dc..180391868 100644 --- a/src/thread/epoc/SDL_systhread.cpp +++ b/src/thread/symbian/SDL_systhread.cpp @@ -1,6 +1,6 @@ /* SDL - Simple DirectMedia Layer - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga + 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 @@ -17,9 +17,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga - slouken@libsdl.org + slouken@devolution.com */ -#include "SDL_config.h" /* SDL_systhread.cpp @@ -28,23 +27,34 @@ 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_systhread.h" +#include "SDL_thread_c.h" + } #include +#include "epoc_sdl.h" static int object_count; int RunThread(TAny* data) { - SDL_RunThread(data); - return(0); + CTrapCleanup* cleanup = CTrapCleanup::New(); + TRAPD(err, SDL_RunThread(data)); + EpocSdlEnv::CleanupItems(); + delete cleanup; + return(err); } @@ -76,7 +86,7 @@ int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) { RThread rthread; - TInt status = CreateUnique(NewThread, &rthread, args); + const TInt status = CreateUnique(NewThread, &rthread, args); if (status != KErrNone) { delete(((RThread*)(thread->handle))); @@ -97,18 +107,30 @@ void SDL_SYS_SetupThread(void) Uint32 SDL_ThreadID(void) { RThread current; - TThreadId id = current.Id(); + const TThreadId id = current.Id(); return id; } void SDL_SYS_WaitThread(SDL_Thread *thread) { - RUndertaker taker; + 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(); + taker.Close();*/ + SDL_TRACE1("Closed thread", thread); } /* WARNING: This function is really a last resort. diff --git a/src/thread/epoc/SDL_systhread_c.h b/src/thread/symbian/SDL_systhread_c.h similarity index 91% rename from src/thread/epoc/SDL_systhread_c.h rename to src/thread/symbian/SDL_systhread_c.h index 6f5fd943b..be8b164c1 100644 --- a/src/thread/epoc/SDL_systhread_c.h +++ b/src/thread/symbian/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* SDL - Simple DirectMedia Layer - Copyright (C) 1997-2004 Sam Lantinga + 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 @@ -17,9 +17,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga - slouken@libsdl.org + slouken@devolution.com */ -#include "SDL_config.h" /* SDL_systhread_c.h 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/timer/mint/SDL_systimer.c b/src/timer/mint/SDL_systimer.c index 8963ca0b7..f9560c48d 100644 --- a/src/timer/mint/SDL_systimer.c +++ b/src/timer/mint/SDL_systimer.c @@ -48,20 +48,23 @@ #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; +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 */ @@ -70,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); @@ -105,42 +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; + void *old_stack; - supervisor=SDL_FALSE; + 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 d9b4a1b9b..f9c4be96d 100644 --- a/src/timer/mint/SDL_vbltimer.S +++ b/src/timer/mint/SDL_vbltimer.S @@ -27,12 +27,15 @@ */ #define _vbl_queue 0x456 +#define _hz_200 0x4ba .text .globl _SDL_AtariVblInstall .globl _SDL_AtariVblUninstall + .globl _SDL_MintAudio_hasfpu + /*--- Vector installer ---*/ _SDL_AtariVblInstall: @@ -40,6 +43,7 @@ _SDL_AtariVblInstall: lea _my_vbl,a0 clrw vbl_mutex + movel _hz_200.w, _SDL_Atari_hz200 /* Stop interrupts */ @@ -106,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 @@ -113,8 +120,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 @@ -123,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); diff --git a/src/video/cybergfx/SDL_cgxwm.c b/src/timer/nds/SDL_systimer.c similarity index 53% rename from src/video/cybergfx/SDL_cgxwm.c rename to src/timer/nds/SDL_systimer.c index 47a7d6002..b057623a4 100644 --- a/src/video/cybergfx/SDL_cgxwm.c +++ b/src/timer/nds/SDL_systimer.c @@ -21,43 +21,53 @@ */ #include "SDL_config.h" -#include "SDL_version.h" +#include "SDL_thread.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" +#include "SDL_error.h" +#include "../SDL_timer_c.h" -/* This is necessary for working properly with Enlightenment, etc. */ -#define USE_ICON_WINDOW +#include -void CGX_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask) +#define timers2ms(tlow,thigh)(tlow | (thigh<<16)) >> 5 + + +void SDL_StartTicks(void) { -/* Not yet implemented */ + TIMER0_DATA=0; + TIMER1_DATA=0; + TIMER0_CR=TIMER_ENABLE|TIMER_DIV_1024; + TIMER1_CR=TIMER_ENABLE|TIMER_CASCADE; } -void CGX_SetCaption(_THIS, const char *title, const char *icon) +Uint32 SDL_GetTicks(void) { - if(SDL_Window) - SetWindowTitles(SDL_Window,(char *)title,NULL); + return timers2ms(TIMER0_DATA, TIMER1_DATA); } -/* Iconify the window */ -int CGX_IconifyWindow(_THIS) +void SDL_Delay(Uint32 ms) +{ + Uint32 now; + now=timers2ms(TIMER0_DATA, TIMER1_DATA); + while((Uint32)timers2ms(TIMER0_DATA, TIMER1_DATA)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/timer/epoc/SDL_systimer.cpp b/src/timer/symbian/SDL_systimer.cpp similarity index 84% rename from src/timer/epoc/SDL_systimer.cpp rename to src/timer/symbian/SDL_systimer.cpp index 413135c79..f2fba3214 100644 --- a/src/timer/epoc/SDL_systimer.cpp +++ b/src/timer/symbian/SDL_systimer.cpp @@ -1,6 +1,6 @@ /* SDL - Simple DirectMedia Layer - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga + 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 @@ -17,16 +17,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga - slouken@libsdl.org + slouken@devolution.com */ -#include "SDL_config.h" - -#ifdef SDL_TIMER_EPOC /* SDL_systimer.cpp - Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi) + Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi) + Markus Mertama */ #include @@ -36,81 +34,81 @@ extern "C" { #include "SDL_error.h" #include "SDL_thread.h" #include "SDL_timer.h" -#include "../SDL_timer_c.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 ) { + { + 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 ) { + 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 */ +} // extern "C" 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-- ) { diff --git a/src/video/SDL_blit.h b/src/video/SDL_blit.h index 0ef24825d..9c43ce2c6 100644 --- a/src/video/SDL_blit.h +++ b/src/video/SDL_blit.h @@ -166,12 +166,21 @@ do { \ } while(0) /* Assemble R-G-B values into a specified pixel format and store them */ +#ifdef __NDS__ // FIXME +#define PIXEL_FROM_RGB(Pixel, fmt, r, g, b) \ +{ \ + Pixel = ((r>>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_blit_A.c b/src/video/SDL_blit_A.c index 71109a27a..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 */ @@ -369,7 +385,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({ @@ -1287,7 +1305,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) { @@ -1556,7 +1574,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; @@ -1587,7 +1605,7 @@ inline 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 */ : "rm" (amask), "rm" ((Uint32) sf->Ashift) ); while(height--) { 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); } 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 diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index e1568a7db..403fe9b3b 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 @@ -395,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 322b2f0e0..86a3352c1 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 @@ -111,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 @@ -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; @@ -1143,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); } @@ -1245,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; } @@ -1284,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); 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); } diff --git a/src/video/SDL_yuv_mmx.c b/src/video/SDL_yuv_mmx.c index 4a9fb1d67..059dd50c4 100644 --- a/src/video/SDL_yuv_mmx.c +++ b/src/video/SDL_yuv_mmx.c @@ -21,36 +21,32 @@ */ #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__) && __OPTIMIZE__ && 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}; +/* *INDENT-OFF* */ -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_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_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_Ycoeff = { .uw = {0x004a, 0x004a, 0x004a, 0x004a} }; -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_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 mmx_t MMX_Ublu5x5 = { .uw = {0x0081, 0x0081, 0x0081, 0x0081} }; +static mmx_t MMX_Vred5x5 = { .uw = {0x0066, 0x0066, 0x0066, 0x0066} }; +static mmx_t MMX_Ugrn565 = { .uw = {0xffe8, 0xffe8, 0xffe8, 0xffe8} }; +static mmx_t MMX_Vgrn565 = { .uw = {0xffcd, 0xffcd, 0xffcd, 0xffcd} }; + +static mmx_t MMX_red565 = { .uw = {0xf800, 0xf800, 0xf800, 0xf800} }; +static mmx_t MMX_grn565 = { .uw = {0x07e0, 0x07e0, 0x07e0, 0x07e0} }; /** This MMX assembler is my first assembler/MMX program ever. @@ -86,151 +82,160 @@ 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" - "1:\n" - - // create Cr (result in mm1) - "movd (%%ebx), %%mm1\n" // 0 0 0 0 v3 v2 v1 v0 - "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 + ".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 _MMX_VgrnRGB,%%mm0\n"// red*-46dec=0.7136*64 - "pmullw _MMX_VredRGB,%%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 _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 - "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 _MMX_0080w,%%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 - "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, %%ebx\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" - "emms\n" - "popl %%ebx\n" - : - : "m" (cr), "r"(cb),"r"(lum), - "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod)); + "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) + ); } void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, @@ -238,173 +243,186 @@ 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__( - "pushl %%ebx\n" - "movl %0, %%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" - ".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 - "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" - "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 - "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 - "movq (%2), %%mm7\n" // L2 - "pmullw _MMX_Vred5x5, %%mm1\n" // Cr2red - "psrlw $8, %%mm7\n" // L2 00 L7 00 L5 00 L3 00 L1 - "pmullw _MMX_Ycoeff, %%mm6\n" // lum1 - "paddw %%mm3, %%mm2\n" // Cb2green + Cr2green == green - "pmullw _MMX_Ycoeff, %%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 _MMX_red565, %%mm4\n" - "psllw $3, %%mm5\n" // GREEN 1 - "punpcklbw %%mm6, %%mm6\n" - "pand _MMX_grn565, %%mm5\n" - "pand _MMX_red565, %%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 _MMX_00FFw, %%mm6\n" // L3 - "punpcklbw %%mm3, %%mm3\n" - "punpcklbw %%mm5, %%mm5\n" - "pmullw _MMX_Ycoeff, %%mm6\n" // lum3 - "punpcklbw %%mm7, %%mm7\n" - "psllw $3, %%mm5\n" // GREEN 2 - "pand _MMX_red565, %%mm7\n" - "pand _MMX_red565, %%mm3\n" - "psrlw $11, %%mm7\n" // BLUE 2 - "pand _MMX_grn565, %%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 - "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 _MMX_red565, %%mm4\n" - "psraw $6, %%mm3\n" // psr 6 - "psraw $6, %%mm0\n" - "pand _MMX_red565, %%mm6\n" // BLUE - "pand _MMX_grn565, %%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 _MMX_red565, %%mm3\n" - "pand _MMX_red565, %%mm7\n" // BLUE - "psllw $3, %%mm0\n" // GREEN 4 - "psrlw $11, %%mm7\n" - "pand _MMX_grn565, %%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, %%ebx\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" - "emms\n" - "popl %%ebx\n" - : - :"m" (cr), "r"(cb),"r"(lum), - "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod)); + "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 /* GCC i386 inline assembly */ -#endif /* 0 */ +/* *INDENT-ON* */ + +#endif /* GCC3 i386 inline assembly */ + diff --git a/src/video/SDL_yuv_sw.c b/src/video/SDL_yuv_sw.c index c67d59296..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 0 /*defined(__GNUC__) && 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 0 /*defined(__GNUC__) && 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 0 /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES*/ +#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES /* inline assembly functions */ if ( SDL_HasMMX() && (Rmask == 0x00FF0000) && (Gmask == 0x0000FF00) && 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/Xxf86dga/XF86DGA.c b/src/video/Xext/Xxf86dga/XF86DGA.c index 4e3d662ff..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 */ 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/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 af4b7b72c..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 9f28ca9bc..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 5c0b8347b..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); 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 */ diff --git a/src/video/bwindow/SDL_BView.h b/src/video/bwindow/SDL_BView.h index 6d2547e3d..564d064ff 100644 --- a/src/video/bwindow/SDL_BView.h +++ b/src/video/bwindow/SDL_BView.h @@ -53,6 +53,10 @@ public: 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. */ diff --git a/src/video/bwindow/SDL_BWin.h b/src/video/bwindow/SDL_BWin.h index a6d3ef8d9..952d5a248 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; iEnableDirectMode(true); } if ( the_view != SDL_GLView ) { if ( the_view ) { @@ -267,7 +156,7 @@ public: return; } #endif - SDL_View->SetXYOffset(x, y); + SDL_View->SetXYOffset(x, y); } virtual void GetXYOffset(int &x, int &y) { #if SDL_VIDEO_OPENGL @@ -276,6 +165,16 @@ public: 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); } @@ -367,179 +266,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 +274,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..f011c57b2 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,339 @@ 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) { + int x, y; + + GetXYOffset(x, y); + x = (int)where.x - x; + y = (int)where.y - y; + + //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); + } + } else { + if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { + SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); + SDL_SetCursor(NULL); + } + + if ( mouse_relative ) { + 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); + } + } 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..232186d52 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) { - BPoint pt(x, 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 */ +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..59edec638 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,10 @@ 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; + bscreen.GetModeList(&dmodes, &nmodes); for ( i = 0; i < nmodes; ++i ) { if ( (bpp == ColorSpaceToBitsPerPixel(dmodes[i].space)) && @@ -433,7 +435,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 +451,18 @@ 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; + cx = (bounds.IntegerWidth() - width)/2; + cy = (bounds.IntegerHeight() - height)/2; + if ( fullscreen ) { /* Set offset for drawing */ - SDL_Win->SetXYOffset(xoff, yoff); + SDL_Win->SetXYOffset(cx, cy); } else { - /* Center window and reset the drawing offset */ SDL_Win->SetXYOffset(0, 0); } 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 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_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_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_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/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/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" 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; diff --git a/src/video/directfb/SDL_DirectFB_yuv.c b/src/video/directfb/SDL_DirectFB_yuv.c index 583b8274e..6366254ce 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) { 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 */ 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); diff --git a/src/video/fbcon/SDL_fbvideo.c b/src/video/fbcon/SDL_fbvideo.c index 2d97bcbeb..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" @@ -149,6 +153,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 +483,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 +565,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); 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); } diff --git a/src/video/gem/SDL_gemevents.c b/src/video/gem/SDL_gemevents.c index 09d6fa85b..19c7c7459 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=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( @@ -184,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 ? */ @@ -216,28 +141,26 @@ void GEM_PumpEvents(_THIS) /* Key pressed ? */ if (gem_currentkeyboard[i] && !gem_previouskeyboard[i]) SDL_PrivateKeyboard(SDL_PRESSED, - TranslateKey(i, gem_currentascii[i], &keysym, SDL_TRUE)); + SDL_Atari_TranslateKey(i, &keysym, SDL_TRUE)); /* Key unpressed ? */ if (gem_previouskeyboard[i] && !gem_currentkeyboard[i]) SDL_PrivateKeyboard(SDL_RELEASED, - TranslateKey(i, gem_currentascii[i], &keysym, SDL_FALSE)); + SDL_Atari_TranslateKey(i, &keysym, SDL_FALSE)); } SDL_memcpy(gem_previouskeyboard,gem_currentkeyboard,sizeof(gem_previouskeyboard)); /* 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; } @@ -245,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: @@ -266,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) { @@ -285,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]); @@ -297,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]); @@ -333,22 +259,24 @@ 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; } static void do_keyboard(short kc, short ks) { - int scancode, asciicode; + int scancode; if (kc) { - scancode=(kc>>8) & 127; - asciicode=kc & 255; - + scancode=(kc>>8) & (ATARIBIOS_MAXKEYS-1); gem_currentkeyboard[scancode]=0xFF; - gem_currentascii[scancode]=asciicode; } /* Read special keys */ diff --git a/src/video/gem/SDL_gemmouse.c b/src/video/gem/SDL_gemmouse.c index cc41bc5c3..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,16 +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) && */ /* Damn GEM can not grab */ - (SDL_GetAppState() & SDL_APPACTIVE) ) { - 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 { - GEM_mouse_relative = SDL_FALSE; + /* 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); } } diff --git a/src/video/gem/SDL_gemvideo.c b/src/video/gem/SDL_gemvideo.c index fea61dbd0..353e02779 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); @@ -467,6 +467,8 @@ int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat) SDL_AtariGL_InitPointers(this); #endif + this->info.wm_available = 1; + /* We're done! */ return(0); } @@ -619,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"); @@ -748,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) { @@ -776,17 +783,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); } } 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 */ 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; } diff --git a/src/video/maccommon/SDL_macevents.c b/src/video/maccommon/SDL_macevents.c index 0e4f813e2..e531c6caf 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 Uint32 *keysptr = (Uint32 *) &keys; + const Uint32 *last_keysptr = (Uint32 *) &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 */ 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 a1150d777..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; @@ -1378,8 +1382,12 @@ 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); + +#if SDL_MACCLASSIC_GAMMA_SUPPORT + Mac_QuitGamma(this); +#endif /* Free list of video modes */ if ( SDL_modelist != NULL ) { @@ -1391,7 +1399,7 @@ void DSp_VideoQuit(_THIS) } /* Unload DrawSprocket */ - DSpShutdown (); + DSpShutdown (); } #if SDL_VIDEO_OPENGL diff --git a/src/video/macrom/SDL_romvideo.c b/src/video/macrom/SDL_romvideo.c index fbe65fd9a..f0ab8dedc 100644 --- a/src/video/macrom/SDL_romvideo.c +++ b/src/video/macrom/SDL_romvideo.c @@ -158,12 +158,16 @@ 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; 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 +693,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); @@ -722,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 ) { 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: 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 =512*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/cybergfx/SDL_cgxgl_c.h b/src/video/nds/SDL_ndsvideo.h similarity index 51% rename from src/video/cybergfx/SDL_cgxgl_c.h rename to src/video/nds/SDL_ndsvideo.h index 4c04f59a5..22c11e6bf 100644 --- a/src/video/cybergfx/SDL_cgxgl_c.h +++ b/src/video/nds/SDL_ndsvideo.h @@ -21,31 +21,41 @@ */ #include "SDL_config.h" -/* StormMesa implementation of SDL OpenGL support */ +#ifndef _SDL_ndsvideo_h +#define _SDL_ndsvideo_h +#include "SDL_mouse.h" #include "../SDL_sysvideo.h" -#define _THIS SDL_VideoDevice *_this +/* Hidden "this" pointer for the video functions */ +#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; +/* Private display data */ + +struct SDL_PrivateVideoData { + int w, h; + void *buffer; + short ndsmode; + short secondbufferallocd; }; -/* 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 +/* +#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)) -#undef _THIS +#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/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)); diff --git a/src/video/quartz/SDL_QuartzEvents.m b/src/video/quartz/SDL_QuartzEvents.m index b18598c66..0e9097607 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 */ @@ -87,9 +88,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; @@ -249,7 +255,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; /* @@ -260,7 +266,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 { @@ -276,7 +283,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 ]; @@ -284,11 +291,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; @@ -621,10 +625,8 @@ 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); + + QZ_UpdateCursor(this); /* Regrab input, only if it was previously grabbed */ if ( current_grab_mode == SDL_GRAB_ON ) { @@ -651,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); + QZ_UpdateCursor(this); } void QZ_SleepNotificationHandler (void * refcon, @@ -717,7 +717,6 @@ void QZ_PumpEvents (_THIS) { static Uint32 screensaverTicks = 0; Uint32 nowTicks; - int firstMouseEvent; CGMouseDelta dx, dy; NSDate *distantPast; @@ -729,11 +728,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 ]; @@ -741,10 +742,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; @@ -846,29 +844,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 ]; } /* @@ -876,8 +867,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); @@ -900,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 @@ -915,15 +906,16 @@ 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_UpdateCursor(this); } else if ( isInGameWin && (SDL_GetAppState() & (SDL_APPMOUSEFOCUS | SDL_APPINPUTFOCUS)) == SDL_APPINPUTFOCUS ) { SDL_PrivateAppActive (1, SDL_APPMOUSEFOCUS); - if (!cursor_should_be_visible) - 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); CGAssociateMouseAndMouseCursorPosition (0); @@ -953,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; */ 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 diff --git a/src/video/quartz/SDL_QuartzVideo.h b/src/video/quartz/SDL_QuartzVideo.h index c7b68ec34..44e25ef07 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 @@ -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 */ @@ -98,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 */ @@ -127,6 +129,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) @@ -144,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) @@ -220,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); -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 8d41169ce..10d502830 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); @@ -184,12 +169,18 @@ 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 */ 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); @@ -212,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; @@ -375,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 @@ -385,10 +384,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 @@ -419,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 @@ -511,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) { @@ -521,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); @@ -696,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 { @@ -1466,6 +1527,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) */ 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 dab99f6c1..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,22 +87,26 @@ outOfMemory: return(NULL); } -void QZ_ShowMouse (_THIS) { - if (!cursor_visible) { - [ NSCursor unhide ]; - cursor_visible = YES; - } -} +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; } } 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" */ @@ -117,18 +118,23 @@ int QZ_ShowWMCursor (_THIS, WMcursor *cursor) { if ( cursor == NULL) { if ( cursor_should_be_visible ) { - QZ_HideMouse (this); cursor_should_be_visible = NO; QZ_ChangeGrabState (this, QZ_HIDECURSOR); } + QZ_UpdateCursor(this); } else { - [ cursor->nscursor set ]; + if (qz_window ==nil || (mode_flags & SDL_FULLSCREEN)) { + [ cursor->nscursor set ]; + } + else { + [ qz_window invalidateCursorRectsForView: [ qz_window contentView ] ]; + } if ( ! cursor_should_be_visible ) { - QZ_ShowMouse (this); 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 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; diff --git a/src/video/epoc/SDL_epocevents.cpp b/src/video/symbian/EKA1/SDL_epocevents.cpp similarity index 60% rename from src/video/epoc/SDL_epocevents.cpp rename to src/video/symbian/EKA1/SDL_epocevents.cpp index f0e6945e3..159193342 100644 --- a/src/video/epoc/SDL_epocevents.cpp +++ b/src/video/symbian/EKA1/SDL_epocevents.cpp @@ -1,6 +1,6 @@ /* SDL - Simple DirectMedia Layer - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga + 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 @@ -17,9 +17,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga - slouken@libsdl.org + slouken@devolution.com */ -#include "SDL_config.h" /* SDL_epocevents.cpp @@ -31,68 +30,107 @@ #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" -#include "../../events/SDL_events_c.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(int scancode, SDL_keysym *keysym); +static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym); +void DisableKeyBlocking(_THIS); }; /* extern "C" */ -TBool isCursorVisible = ETrue; +TBool isCursorVisible = EFalse; int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent) { int posted = 0; SDL_keysym keysym; - - - switch (aWsEvent.Type()) { +// 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 */ + 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 */ - if (pointerEvent->iType==TPointerEvent::EButton1Down) { + + switch (pointerEvent->iType) + { + case TPointerEvent::EButton1Down: posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0); - } - else if (pointerEvent->iType==TPointerEvent::EButton1Up) { + break; + case TPointerEvent::EButton1Up: posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0); - } - else if (pointerEvent->iType==TPointerEvent::EButton2Down) { + break; + case TPointerEvent::EButton2Down: posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0); - } - else if (pointerEvent->iType==TPointerEvent::EButton2Up) { + break; + case TPointerEvent::EButton2Up: posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0); - } - //!!posted += SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(aWsEvent.Key()->iScanCode, &keysym)); + 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 */ { - (void*)TranslateKey(aWsEvent.Key()->iScanCode, &keysym); - +#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: @@ -107,31 +145,98 @@ int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent) isCursorVisible = !isCursorVisible; break; } - +#endif posted += SDL_PrivateKeyboard(SDL_PRESSED, &keysym); break; } case EEventKeyUp: /* Key events */ - { - posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(aWsEvent.Key()->iScanCode, &keysym)); + { +#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; + { + 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 */ - { - //Private->EPOC_IsWindowFocused = EFalse; + { +/* + 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); @@ -144,9 +249,9 @@ int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent) break; } } - */ +#endif break; - } + } case EEventModifiersChanged: { @@ -196,6 +301,44 @@ void EPOC_PumpEvents(_THIS) } +_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; @@ -265,6 +408,61 @@ void EPOC_InitOSKeymap(_THIS) keymap[EStdKeyF11] = SDLK_F11; /* chr + d */ keymap[EStdKeyF12] = SDLK_F12; /* chr + f */ + #ifndef SYMBIAN_CRYSTAL + //!!7650 additions + #ifdef __WINS__ + keymap[EStdKeyXXX] = SDLK_RETURN; /* "fire" key */ + #else + keymap[EStdKeyDevice3] = SDLK_RETURN; /* "fire" key */ + #endif + keymap[EStdKeyNkpAsterisk] = SDLK_ASTERISK; + keymap[EStdKeyYes] = SDLK_HOME; /* "call" key */ + keymap[EStdKeyNo] = SDLK_END; /* "end call" key */ + keymap[EStdKeyDevice0] = SDLK_SPACE; /* right menu key */ + keymap[EStdKeyDevice1] = SDLK_ESCAPE; /* left menu key */ + keymap[EStdKeyDevice2] = SDLK_POWER; /* power key */ + #endif + + #ifdef SYMBIAN_CRYSTAL + keymap[EStdKeyMenu] = SDLK_ESCAPE; // menu key + keymap[EStdKeyDevice6] = SDLK_LEFT; // Rocker (joystick) left + keymap[EStdKeyDevice7] = SDLK_RIGHT; // Rocker (joystick) right + keymap[EStdKeyDevice8] = SDLK_UP; // Rocker (joystick) up + keymap[EStdKeyDevice9] = SDLK_DOWN; // Rocker (joystick) down + keymap[EStdKeyLeftFunc] = SDLK_LALT; //chr? + keymap[EStdKeyRightFunc] = SDLK_RALT; + keymap[EStdKeyDeviceA] = SDLK_RETURN; /* "fire" key */ +#endif + + /////////////////////////////////////////////////////////// + + RFs fs; + if(KErrNone == fs.Connect()) + { + RArray 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, @@ -345,9 +543,9 @@ void EPOC_InitOSKeymap(_THIS) -static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym) +static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym) { - char debug[256]; +// char debug[256]; //SDL_TRACE1("SDL: TranslateKey, scancode=%d", scancode); //!! /* Set the keysym information */ @@ -362,11 +560,11 @@ static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym) return keysym; } - keysym->mod = SDL_GetModState(); //!!Is this right?? + keysym->mod = SDL_GetModState(); /* Handle function keys: F1, F2, F3 ... */ if (keysym->mod & KMOD_META) { - if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphapet keys */ + if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphabet keys */ switch(scancode) { case 'Q': scancode = EStdKeyF1; break; case 'W': scancode = EStdKeyF2; break; @@ -393,6 +591,15 @@ static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym) 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; 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..07b1ab413 --- /dev/null +++ b/src/video/symbian/EKA2/dsa.cpp @@ -0,0 +1,1505 @@ +#include "dsa.h" +#include "sdlepocapi.h" +#include + + +LOCAL_C TInt BytesPerPixel(TDisplayMode aMode) + { + return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1; + } + + + + +template +NONSHARABLE_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) : + iStateFlags(0), + iSession(aSession) + + { +// 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; + diff --git a/src/video/wincommon/SDL_lowvideo.h b/src/video/wincommon/SDL_lowvideo.h index eb8d9581b..96ea1459a 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 @@ -81,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 584c18463..ac538d390 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" @@ -73,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); @@ -337,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 ) { @@ -356,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 { @@ -390,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; @@ -466,9 +476,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 +518,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 +558,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); @@ -779,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(); diff --git a/src/video/wincommon/SDL_syswm.c b/src/video/wincommon/SDL_syswm.c index c5ea7a864..8bd2c1880 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. @@ -226,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 @@ -234,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 } @@ -263,13 +274,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 +289,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); diff --git a/src/video/wincommon/SDL_wingl.c b/src/video/wincommon/SDL_wingl.c index 05933421c..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); @@ -109,15 +111,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 +128,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 +146,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 +163,8 @@ static void Init_WGL_ARB_extensions(_THIS) ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); WIN_FlushMessageQueue(); + + return pformat; } #endif /* SDL_VIDEO_OPENGL */ @@ -173,7 +174,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 }; @@ -188,6 +188,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 +295,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 +330,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 @@ -403,12 +407,20 @@ 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 ( this->gl_data->WGL_ARB_pixel_format ) { + + if (attrib == SDL_GL_SWAP_CONTROL) { + if ( this->gl_data->wglGetSwapIntervalEXT ) { + *value = this->gl_data->wglGetSwapIntervalEXT(); + return 0; + } + return -1; + } + + if ( this->gl_data->wglGetPixelFormatAttribivARB ) { int wgl_attrib; switch(attrib) { @@ -466,15 +478,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); } @@ -567,7 +570,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, diff --git a/src/video/wincommon/wmmsg.h b/src/video/wincommon/wmmsg.h index d057fc56d..175a8ceec 100644 --- a/src/video/wincommon/wmmsg.h +++ b/src/video/wincommon/wmmsg.h @@ -524,9 +524,9 @@ char *wmtab[] = { "WM_MBUTTONDOWN", "WM_MBUTTONUP", "WM_MOUSELAST", - "WM_MOUSELAST", - "UNKNOWN (523)", - "UNKNOWN (524)", + "WM_MOUSEWHEEL", + "WM_XBUTTONDOWN", + "WM_XBUTTONUP", "UNKNOWN (525)", "UNKNOWN (526)", "UNKNOWN (527)", diff --git a/src/video/windib/SDL_dibevents.c b/src/video/windib/SDL_dibevents.c index ce903c573..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 */ @@ -273,18 +278,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; iPumpEvents = 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,40 +252,30 @@ 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) { + const char *env = NULL; #ifndef NO_CHANGEDISPLAYSETTINGS int i; DEVMODE settings; @@ -370,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 */ @@ -380,6 +374,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); } @@ -470,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 = @@ -533,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; @@ -639,17 +640,26 @@ 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 ) { /* 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); @@ -750,10 +760,11 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, this->UpdateRects = DIB_NormalUpdate; /* Set video surface flags */ - if ( bpp <= 8 ) { - /* 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 */ @@ -766,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 ) { @@ -785,7 +796,12 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, bounds.top = SDL_windowY; bounds.right = SDL_windowX+video->w; 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) ) { @@ -870,6 +886,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) { @@ -880,23 +931,41 @@ 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); +#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); + 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. + */ +#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); - SDL_stack_free(entries); } #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) @@ -913,8 +982,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 || !grab_palette ) { + BitBlt(hdc, 0, 0, this->screen->w, this->screen->h, + mdc, 0, 0, SRCCOPY); + } DeleteDC(mdc); SDL_stack_free(pal); #endif @@ -1033,6 +1104,9 @@ void DIB_VideoQuit(_THIS) if ( SDL_Window ) { /* Delete the screen bitmap (also frees screen->pixels) */ if ( this->screen ) { + if ( grab_palette ) { + DIB_ReleaseStaticColors(SDL_Window); + } #ifndef NO_CHANGEDISPLAYSETTINGS if ( this->screen->flags & SDL_FULLSCREEN ) { ChangeDisplaySettings(NULL, 0); @@ -1044,6 +1118,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; @@ -1082,26 +1164,61 @@ void DIB_VideoQuit(_THIS) } /* Exported for the windows message loop only */ -static void DIB_FocusPalette(_THIS, int foreground) +static void DIB_GrabStaticColors(HWND window) +{ +#ifdef SYSPAL_NOSTATIC + HDC hdc; + + hdc = GetDC(window); + SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC256); + if ( GetSystemPaletteUse(hdc) != SYSPAL_NOSTATIC256 ) { + 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) +{ + if ( grab_palette ) { + 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); +#ifndef _WIN32_WCE + UnrealizeObject(screen_pal); +#endif 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 b759bec86..043c11d15 100644 --- a/src/video/windib/SDL_dibvideo.h +++ b/src/video/windib/SDL_dibvideo.h @@ -40,6 +40,10 @@ typedef enum struct SDL_PrivateVideoData { HBITMAP screen_bmp; HPALETTE screen_pal; + LOGPALETTE *screen_logpal; + BOOL grab_palette; + + int allow_screensaver; #define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */ int SDL_nummodes[NUM_MODELISTS]; @@ -56,6 +60,8 @@ 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 grab_palette (this->hidden->grab_palette) #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..50b74f614 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; @@ -1016,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; @@ -1101,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; @@ -1176,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 ) { @@ -1452,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; @@ -1579,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 ) { @@ -2421,6 +2428,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 ) { 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 } diff --git a/src/video/x11/SDL_x11dyn.c b/src/video/x11/SDL_x11dyn.c index a327c6ec8..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,9 +165,12 @@ 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) { /* 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; } @@ -176,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 47d6b2ceb..4c48a1805 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 @@ -461,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) ) { @@ -472,8 +737,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 +748,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; @@ -1136,9 +1406,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 +1428,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_x11gl.c b/src/video/x11/SDL_x11gl.c index 43334c10f..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 @@ -269,7 +271,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") ) { @@ -479,7 +481,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; } 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 */ diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h index fe71cc0de..9839fc9b3 100644 --- a/src/video/x11/SDL_x11sym.h +++ b/src/video/x11/SDL_x11sym.h @@ -143,8 +143,12 @@ 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) +SDL_X11_SYM(int,XRefreshKeyboardMapping,(XMappingEvent* a),(a),return) +SDL_X11_SYM(Display*,XDisplayOfIM,(XIM 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 94778967a..99ff2aa2a 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)); @@ -408,20 +415,107 @@ static void create_aux_windows(_THIS) } } - /* Setup the communication with the IM server */ - SDL_IM = NULL; - SDL_IC = NULL; + /* Setup the communication with the IM server */ + /* 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) { - SDL_IM = XOpenIM(SDL_Display, NULL, classname, classname); + /* 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 = 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 + 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. */ + 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 + 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 ) { + /* 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_stack_free(old_locale); + } + if ( old_modifiers ) { + XSetLocaleModifiers(old_modifiers); + SDL_stack_free(old_modifiers); + } + } + + /* Create a new input context for the new window just created. */ 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 +524,27 @@ 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); + 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); + } } } } @@ -441,6 +556,7 @@ static void create_aux_windows(_THIS) static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat) { + const char *env = NULL; char *display; int i; @@ -482,6 +598,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); } @@ -507,8 +625,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); @@ -546,7 +669,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 +685,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); @@ -956,33 +1083,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); @@ -1063,6 +1163,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)) ) { @@ -1071,6 +1199,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: @@ -1338,6 +1469,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; } @@ -1375,7 +1507,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 ) { @@ -1408,5 +1540,9 @@ void X11_VideoQuit(_THIS) /* Direct screen access, no memory buffer */ this->screen->pixels = NULL; } + +#if SDL_VIDEO_DRIVER_X11_XME + XiGMiscDestroy(); +#endif } 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; diff --git a/src/video/x11/SDL_x11wm.c b/src/video/x11/SDL_x11wm.c index a50215cd3..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); @@ -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); @@ -398,6 +400,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 +414,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); 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 */ diff --git a/symbian.zip b/symbian.zip new file mode 100644 index 000000000..b3686e926 Binary files /dev/null and b/symbian.zip differ 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 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/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 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 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; } 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; 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); 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" 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); diff --git a/test/testjoystick.c b/test/testjoystick.c index c406bdc91..1cd823452 100644 --- a/test/testjoystick.c +++ b/test/testjoystick.c @@ -160,6 +160,16 @@ int main(int argc, char *argv[]) for ( i=0; i +#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) { + const char *app = argv[0]; + fprintf(stderr, "USAGE: %s \n", app); + fprintf(stderr, " %s --hello \n", app); + 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, fn); + 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); +} + + 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__ 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");