Date: Sat, 2 Aug 2003 16:22:51 +0300
From: "Mike Gorchak"
Subject: New patches for QNX6
Here my patches for the SDL/QNX:
QNXSDL.diff - diff to non-QNX related sources:
- updated BUGS file, I think QNX6 is now will be officially supported
- configure.in - added shared library support for QNX, and removed dependency between the ALSA and QNX6.
- SDL_audio.c - added QNX NTO sound bootstrap insted of ALSA's.
- SDL_sysaudio.h - the same.
- SDL_nto_audio.c - the same.
- SDL_video.c - right now, QNX doesn't offer any method to obtain pointers to the OpenGL functions by function name, so they must be hardcoded in library, otherwise OpenGL will not be supported.
- testsprite.c - fixed: do not draw vertical red line if we are in non-double-buffered mode.
sdlqnxph.tar.gz - archive of the ./src/video/photon/* . Too many changes in code to make diffs :) :
+ Added stub for support hide/unhide window event
+ Added full YUV overlays support.
+ Added window maximize support.
+ Added mouse wheel events.
+ Added support for some specific key codes in Unicode mode (like ESC).
+ Added more checks to the all memory allocation code.
+ Added SDL_DOUBLEBUF support in all fullscreen modes.
+ Added fallback to window mode, if desired fullscreen mode is not supported.
+ Added stub support for the GL_LoadLibrary and GL_GetProcAddress functions.
+ Added resizable window support without caption.
! Fixed bug in the Ph_EV_EXPOSE event handler, when rectangles to update is 0 and when width or height of the rectangle is 0.
! Fixed bug in the event handler code. Events has not been passed to the window widget handler.
! Fixed codes for Win keys (Super/Hyper/Menu).
! Fixed memory leak, when deallocation palette.
! Fixed palette emulation code bugs.
! Fixed fullscreen and hwsurface handling.
! Fixed CLOSE button bug. First event was passed to the handler, but second terminated the application. Now all events passed to the application correctly.
- Removed all printfs in code, now SDL_SetError used instead of them.
- Disabled ToggleFullScreen function.
README.QNX - updated README.QNX file. Added much more issues.
--- a/BUGS Mon Jul 28 01:47:55 2003 +0000
+++ b/BUGS Mon Aug 04 00:52:42 2003 +0000
@@ -141,6 +141,10 @@
No console output screen. Printing to stdout do not have any effect.
+QNX:
+ Fullscreen switch doesn't work correctly.
+
+
OpenBSD: -= NOT YET SUPPORTED =-
This is reported to work, but I haven't verified this.
@@ -183,13 +187,6 @@
More information on this port is available at:
http://www.kom.e-technik.tu-darmstadt.de/~griff/SDL/
-QNX: -= NOT YET SUPPORTED =-
- Only static libraries are being made, no shared ones.
-
- The only hardware surface is the primary view surface.
-
- Fullscreen doesn't display correctly.
-
AmigaOS: -= NOT YET SUPPORTED =-
The OpenGL support isn't implemented yet.
--- a/README.QNX Mon Jul 28 01:47:55 2003 +0000
+++ b/README.QNX Mon Aug 04 00:52:42 2003 +0000
@@ -1,27 +1,94 @@
README by Mike Gorchak <mike@malva.ua>, <lestat@i.com.ua>
+Last changed at 29 Jul 2003.
+
+=========================================================================
+OpenGL:
OpenGL in window mode works well and stable, in fullscreen
-mode too, but fullscreen mode has not been heavily tested.
- If you have QNX RtP 6.1.0 w/ or w/o Patch A you must download
-new Photon3D runtime from http://developers.qnx.com. The versions
-of OS before 6.1.0 are not supported.
+mode too, but fullscreen mode has not been heavily tested yet.
+ If you have QNX RtP version 6.1.0 and above you must download
+new Photon3D runtime from http://developers.qnx.com or install it
+from public repository or from public CD, available with QNX. The
+versions of OS before 6.1.0 are not supported.
+ While creating OpenGL context software renderer mode is
+artificially selected (QSSL made acceleration only for Voodoo
+boards in fullscreen mode, sorry but I don't have this board to
+test OpenGL - maybe it work or maybe not :)). If you want accele-
+ration - you may remove some line in source code: find the file
+SDL_ph_video.c and remove the following
+
+ OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FORCE_SW;
+
+line in the ph_SetupOpenGLContext() function or change argument
+to the PHOGL_ATTRIB_FORCE_HW or PHOGL_ATTRIB_FAVOR_HW.
+
+=========================================================================
+Wheel and multibutton mouses:
+
+ Photon emitting keyboard events (key up and down) when moved
+mouse wheel. But key_scan field appears valid according to flags,
+and it contain zero. It is base method of detecting mouse wheel
+events under photon. It looks like a hack, but it works for me :)
+on different PC configurations.
+
+I'm tested it on:
+
+1. Genius Optical NetScroll/+ (1 wheel)
+2. A4Tech Optical GreatEye WheelMouse, model: WOP-35. (2 wheels +
+ 2 additional buttons). Wheel for vertical scrolling works as
+ usual, but second wheel for horizontal scrolling emitting two
+ consequented events up or down, so it can provide more fast
+ scrolling then the first wheel. Additional buttons doesn't
+ emitting any events, but its look like handled by photon in
+ unusual way - like click to front, but works not with any win-
+ dow, looks like bug-o-feature :).
+
+=========================================================================
+CDROM handling issues:
-Problems:
-1. While creating OpenGL context software renderer mode is
- artificially selected (QSSL made acceleration only for Voodoo
- boards in fullscreen mode, sorry but I don't have this board,
- if you want acceleration - you may remove some line in source
- code).
-2. Photon has some errors in detecting how much bits per pixel
- videomode has.
-3. No shared libraries yet. We need manually set flag to
- 'configure' --disable-shared.
-4. Due to Photon API limitation, flag SDL_HWSURFACE supported on-
- ly in case of desktop bpp is equal requested bpp in window mo-
- de.
+ Access to CDROM can be provided only with 'root' previleges.
+I can't do anything with this fact. /dev/cd0 have the brw-------
+flags and root:root rights.
+
+=========================================================================
+Video Overlays:
+ Overlays can flickering during the window movement, resizing,
+etc. It happens because photon driver updates the real window
+contents behind the overlay, then draws the temporary chroma key
+color over window contents. It can be done without the chroma key
+using but it cause overlay will be always on top. So flickering
+during the movement much better in that case.
+ Double buffering code temporary disabled in the photon driver
+code, beacuse on my GF2-MX it cause accidently buffer switch,
+which going to the old frame showing. S3 Savage3D have the same
+problem, but ATI Rage 128 has not this problem. I think it can be
+fixed later. Current code works very fine, so maybe double buffe-
+ring is not needed right now.
+ Something strange appears when you tried to move window with
+overlay beyond the left border of the screen. Overlay trying to
+stay at position x=0, but when tried to move it a bit more it
+jumps at posituin x=-60. Really strange, looks like overlay
+doesn't love the negotive coordinates.
+
+=========================================================================
+Shared library building:
+
+ Shared library can be built, but before running autogen.sh
+script you need manually delete the libtool m4 stuff from
+the acinclude.m4 file (it comes after ESD detection code up to
+end of the file). Because libtool stuff in the acinclude.m4 file
+very old and doesn't know anything about the QNX. Just remove it
+and run autogen.sh script.
+
+=========================================================================
Some building issues:
+ Feel free to not pass --disable-shared option to configure,
+if you read comment above about 'Shared library building'. Other-
+wise this option is strongly recomended, because the sdl-config
+script will be unfunctional.
+
Run configure script without x11 support, e.g.:
a) for OpenGL support:
@@ -42,3 +109,4 @@
--with-sdl-exec-prefix=/usr/local \
--prefix=/usr/local --without-x
+
--- a/configure.in Mon Jul 28 01:47:55 2003 +0000
+++ b/configure.in Mon Aug 04 00:52:42 2003 +0000
@@ -2531,6 +2531,9 @@
openbsd | netbsd | bsdi)
SHARED_SYSTEM_LIBS="$SYSTEM_LIBS"
;;
+ qnx)
+ SHARED_SYSTEM_LIBS="$SYSTEM_LIBS"
+ ;;
macosx)
SHARED_SYSTEM_LIBS="-framework Cocoa"
if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then
--- a/src/audio/SDL_audio.c Mon Jul 28 01:47:55 2003 +0000
+++ b/src/audio/SDL_audio.c Mon Aug 04 00:52:42 2003 +0000
@@ -50,6 +50,9 @@
#ifdef ALSA_SUPPORT
&ALSA_bootstrap,
#endif
+#ifdef QNXNTOAUDIO_SUPPORT
+ &QNXNTOAUDIO_bootstrap,
+#endif
#ifdef SUNAUDIO_SUPPORT
&SUNAUDIO_bootstrap,
#endif
--- a/src/audio/SDL_sysaudio.h Mon Jul 28 01:47:55 2003 +0000
+++ b/src/audio/SDL_sysaudio.h Mon Aug 04 00:52:42 2003 +0000
@@ -114,6 +114,9 @@
#ifdef ALSA_SUPPORT
extern AudioBootStrap ALSA_bootstrap;
#endif
+#ifdef QNXNTOAUDIO_SUPPORT
+extern AudioBootStrap QNXNTOAUDIO_bootstrap;
+#endif
#ifdef SUNAUDIO_SUPPORT
extern AudioBootStrap SUNAUDIO_bootstrap;
#endif
--- a/src/audio/nto/SDL_nto_audio.c Mon Jul 28 01:47:55 2003 +0000
+++ b/src/audio/nto/SDL_nto_audio.c Mon Aug 04 00:52:42 2003 +0000
@@ -163,9 +163,8 @@
return this;
}
-/* Don't change the name from "ALSA_bootstrap" - that's how it's called */
-AudioBootStrap ALSA_bootstrap = {
- DRIVER_NAME, "Neutrino PCM audio",
+AudioBootStrap QNXNTOAUDIO_bootstrap = {
+ DRIVER_NAME, "QNX6 NTO PCM audio",
Audio_Available, Audio_CreateDevice
};
@@ -489,4 +488,3 @@
/* We're ready to rock and roll. :-) */
return(0);
}
-
--- a/src/video/SDL_video.c Mon Jul 28 01:47:55 2003 +0000
+++ b/src/video/SDL_video.c Mon Aug 04 00:52:42 2003 +0000
@@ -727,6 +727,7 @@
#ifdef HAVE_OPENGL
/* Load GL symbols (before MakeCurrent, where we need glGetString). */
if ( flags & (SDL_OPENGL | SDL_OPENGLBLIT) ) {
+#ifndef __QNXNTO__
#define SDL_PROC(ret,func,params) \
do { \
video->func = SDL_GL_GetProcAddress(#func); \
@@ -735,6 +736,9 @@
return(NULL); \
} \
} while ( 0 );
+#else
+#define SDL_PROC(ret,func,params) video->func=func;
+#endif /* __QNXNTO__ */
#include "SDL_glfuncs.h"
#undef SDL_PROC
}
--- a/src/video/photon/SDL_ph_events.c Mon Jul 28 01:47:55 2003 +0000
+++ b/src/video/photon/SDL_ph_events.c Mon Aug 04 00:52:42 2003 +0000
@@ -29,11 +29,12 @@
#define DISABLE_X11
-#include <Ph.h>
#include <stdio.h>
#include <setjmp.h>
+#include <sys/time.h>
+
+#include <Ph.h>
#include <photon/PkKeyDef.h>
-#include <sys/time.h>
#include "SDL.h"
#include "SDL_syswm.h"
@@ -44,6 +45,8 @@
#include "SDL_ph_modes_c.h"
#include "SDL_ph_image_c.h"
#include "SDL_ph_events_c.h"
+#include "SDL_phyuv_c.h"
+
/* The translation tables from a photon keysym to a SDL keysym */
@@ -90,8 +93,8 @@
if( window )
{
- rid = PtWidgetRid( window );
- if( rid != 0 && PhRegionQuery( rid, ®ion, NULL, NULL, 0 ) == 0 )
+ rid = PtWidgetRid(window);
+ if( rid != 0 && PhRegionQuery(rid, ®ion, NULL, NULL, 0) == 0 )
{
region.events_sense=(region.events_sense & ~fields)|(flags & fields);
PhRegionChange(Ph_REGION_EV_SENSE, 0, ®ion, NULL, NULL);
@@ -114,6 +117,8 @@
return (mouse_button);
}
+// void* PtAppCreateContext();
+
static int ph_DispatchEvent(_THIS)
{
int posted;
@@ -217,15 +222,56 @@
{
posted = SDL_PrivateQuit();
}
+ /* request to hide/unhide */
+ else if (winEvent->event_f==Ph_WM_HIDE)
+ {
+ if (currently_hided)
+ {
+ /* got unhide window event */
+ /* TODO: restore application's palette if in palette mode */
+ currently_hided=0;
+ }
+ else
+ {
+ /* got hide window event */
+ /* TODO: restore original palette if in palette mode */
+ currently_hided=1;
+ }
+ }
/* request to resize */
else if (winEvent->event_f==Ph_WM_RESIZE)
{
SDL_PrivateResize(winEvent->size.w, winEvent->size.h);
}
+ /* request to move */
+ else if (winEvent->event_f==Ph_WM_MOVE)
+ {
+ if (current_overlay!=NULL)
+ {
+ int lockedstate=current_overlay->hwdata->locked;
+ int chromastate=current_overlay->hwdata->ischromakey;
+ SDL_Rect target;
+
+ current_overlay->hwdata->locked=1;
+ target.x=current_overlay->hwdata->CurrentViewPort.pos.x;
+ target.y=current_overlay->hwdata->CurrentViewPort.pos.y;
+ target.w=current_overlay->hwdata->CurrentViewPort.size.w;
+ target.h=current_overlay->hwdata->CurrentViewPort.size.h;
+ current_overlay->hwdata->ischromakey=0;
+ ph_DisplayYUVOverlay(this, current_overlay, &target);
+ current_overlay->hwdata->ischromakey=chromastate;
+ current_overlay->hwdata->locked=lockedstate;
+ }
+ }
/* request to maximize */
else if (winEvent->event_f==Ph_WM_MAX)
{
- /* TODO: get screen resolution, set window pos to 0, 0 and resize it ! */
+ /* window already moved and resized here */
+ SDL_PrivateResize(winEvent->size.w-winEvent->pos.x, winEvent->size.h-winEvent->pos.y);
+ }
+ /* request to restore */
+ else if (winEvent->event_f==Ph_WM_RESTORE)
+ {
}
}
break;
@@ -233,19 +279,38 @@
/* window has been resized, moved or removed */
case Ph_EV_EXPOSE:
{
- if (SDL_VideoSurface)
+ if (event->num_rects!=0)
{
- rect = PhGetRects(event);
-
- for(i=0;i<event->num_rects;i++)
+ if (SDL_VideoSurface)
{
- sdlrects[i].x = rect[i].ul.x;
- sdlrects[i].y = rect[i].ul.y;
- sdlrects[i].w = rect[i].lr.x - rect[i].ul.x + 1;
- sdlrects[i].h = rect[i].lr.y - rect[i].ul.y + 1;
+ rect = PhGetRects(event);
+
+ for(i=0;i<event->num_rects;i++)
+ {
+ sdlrects[i].x = rect[i].ul.x;
+ sdlrects[i].y = rect[i].ul.y;
+ sdlrects[i].w = rect[i].lr.x - rect[i].ul.x + 1;
+ sdlrects[i].h = rect[i].lr.y - rect[i].ul.y + 1;
+ }
+
+ this->UpdateRects(this, event->num_rects, sdlrects);
+
+ if (current_overlay!=NULL)
+ {
+ int lockedstate=current_overlay->hwdata->locked;
+ SDL_Rect target;
+
+ current_overlay->hwdata->locked=1;
+ target.x=current_overlay->hwdata->CurrentViewPort.pos.x;
+ target.y=current_overlay->hwdata->CurrentViewPort.pos.y;
+ target.w=current_overlay->hwdata->CurrentViewPort.size.w;
+ target.h=current_overlay->hwdata->CurrentViewPort.size.h;
+ current_overlay->hwdata->forcedredraw=1;
+ ph_DisplayYUVOverlay(this, current_overlay, &target);
+ current_overlay->hwdata->forcedredraw=0;
+ current_overlay->hwdata->locked=lockedstate;
+ }
}
-
- this->UpdateRects(this, event->num_rects, sdlrects);
}
}
break;
@@ -260,13 +325,32 @@
if (Pk_KF_Key_Down & keyEvent->key_flags)
{
+ /* split the wheel events from real key events */
+ if ((keyEvent->key_cap==Pk_Up) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
+ {
+ posted = SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0);
+ break;
+ }
+ if ((keyEvent->key_cap==Pk_Down) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
+ {
+ posted = SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0);
+ break;
+ }
posted = SDL_PrivateKeyboard(SDL_PRESSED, ph_TranslateKey(keyEvent, &keysym));
}
else /* must be key release */
{
- /* Ignore repeated key release events */
- /* if (! Pk_KF_Key_Repeat & keyEvent->key_flags ) */
-
+ /* split the wheel events from real key events */
+ if ((keyEvent->key_cap==Pk_Up) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
+ {
+ posted = SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0);
+ break;
+ }
+ if ((keyEvent->key_cap==Pk_Down) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
+ {
+ posted = SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0);
+ break;
+ }
posted = SDL_PrivateKeyboard(SDL_RELEASED, ph_TranslateKey( keyEvent, &keysym));
}
}
@@ -282,9 +366,9 @@
/* Flush the display connection and look to see if events are queued */
PgFlush();
- while( 1 )
- { /* note this is a non-blocking call */
- switch( PhEventPeek( event, EVENT_SIZE ) )
+ while (1)
+ {
+ switch(PhEventPeek(event, EVENT_SIZE))
{
case Ph_EVENT_MSG:
return 1;
@@ -308,6 +392,7 @@
while (ph_Pending(this))
{
+ PtEventHandler(event);
ph_DispatchEvent(this);
}
}
@@ -318,11 +403,15 @@
/* Odd keys used in international keyboards */
for (i=0; i<SDL_TABLESIZE(ODD_keymap); ++i)
+ {
ODD_keymap[i] = SDLK_UNKNOWN;
+ }
/* Map the miscellaneous keys */
for (i=0; i<SDL_TABLESIZE(MISC_keymap); ++i)
+ {
MISC_keymap[i] = SDLK_UNKNOWN;
+ }
MISC_keymap[Pk_BackSpace&0xFF] = SDLK_BACKSPACE;
MISC_keymap[Pk_Tab&0xFF] = SDLK_TAB;
@@ -388,15 +477,19 @@
MISC_keymap[Pk_Alt_L&0xFF] = SDLK_LALT;
MISC_keymap[Pk_Meta_R&0xFF] = SDLK_RMETA;
MISC_keymap[Pk_Meta_L&0xFF] = SDLK_LMETA;
- MISC_keymap[Pk_Super_L&0xFF] = SDLK_LSUPER; /* Left "Windows" */
- MISC_keymap[Pk_Super_R&0xFF] = SDLK_RSUPER; /* Right "Windows" */
+ MISC_keymap[Pk_Super_L&0xFF] = SDLK_LSUPER;
+ MISC_keymap[Pk_Super_R&0xFF] = SDLK_RSUPER;
MISC_keymap[Pk_Mode_switch&0xFF] = SDLK_MODE; /* "Alt Gr" key */
MISC_keymap[Pk_Help&0xFF] = SDLK_HELP;
MISC_keymap[Pk_Print&0xFF] = SDLK_PRINT;
MISC_keymap[Pk_Break&0xFF] = SDLK_BREAK;
- MISC_keymap[Pk_Menu&0xFF] = SDLK_MENU;
- MISC_keymap[Pk_Hyper_R&0xFF] = SDLK_MENU; /* Windows "Menu" key */
+ MISC_keymap[Pk_Menu&0xFF] = SDLK_MENU; /* Windows "Menu" key */
+
+ MISC_keymap[Pk_Hyper_R&0xFF] = SDLK_RSUPER; /* Right "Windows" */
+
+ /* Left "Windows" key, but it can't be catched by application */
+ MISC_keymap[Pk_Hyper_L&0xFF] = SDLK_LSUPER;
}
static unsigned long cap;
@@ -447,13 +540,23 @@
int utf8len;
wchar_t unicode;
- utf8len = PhKeyToMb(utf8, key);
- if (utf8len > 0)
+ switch (keysym->scancode)
{
- utf8len = mbtowc(&unicode, utf8, utf8len);
- if (utf8len > 0)
- keysym->unicode = unicode;
+ case 0x01: keysym->unicode = 27;
+ break;
+ default:
+ utf8len = PhKeyToMb(utf8, key);
+ if (utf8len > 0)
+ {
+ utf8len = mbtowc(&unicode, utf8, utf8len);
+ if (utf8len > 0)
+ {
+ keysym->unicode = unicode;
+ }
+ }
+ break;
}
+
}
return (keysym);
--- a/src/video/photon/SDL_ph_image.c Mon Jul 28 01:47:55 2003 +0000
+++ b/src/video/photon/SDL_ph_image.c Mon Aug 04 00:52:42 2003 +0000
@@ -35,54 +35,11 @@
#include "SDL_video.h"
#include "SDL_pixels_c.h"
#include "SDL_ph_image_c.h"
-
-/* Mask values for SDL_ReallocFormat() */
-struct ColourMasks
-{
- Uint32 red;
- Uint32 green;
- Uint32 blue;
- Uint32 alpha;
- Uint32 bpp;
-};
-
-static const struct ColourMasks *ph_GetColourMasks( int format )
-{
- /* The alpha mask doesn't appear to be needed */
- static const struct ColourMasks phColorMasks[5] = {
- /* 8 bit */ {0, 0, 0, 0, 8},
- /* 15 bit ARGB */ {0x7C00, 0x03E0, 0x001F, 0x8000, 16},
- /* 16 bit RGB */ {0xF800, 0x07E0, 0x001F, 0x0000, 16},
- /* 24 bit RGB */ {0xFF0000, 0x00FF00, 0x0000FF, 0x000000, 24},
- /* 32 bit ARGB */ {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, 32},
- };
-
- switch( format )
- {
- case Pg_IMAGE_PALETTE_BYTE:
- return &phColorMasks[0];
- break;
- case Pg_IMAGE_DIRECT_1555:
- case Pg_IMAGE_DIRECT_555:
- return &phColorMasks[1];
- break;
- case Pg_IMAGE_DIRECT_565:
- return &phColorMasks[2];
- break;
- case Pg_IMAGE_DIRECT_888:
- return &phColorMasks[3];
- break;
- case Pg_IMAGE_DIRECT_8888:
- return &phColorMasks[4];
- break;
- }
- return NULL;
-}
+#include "SDL_ph_modes_c.h"
int ph_SetupImage(_THIS, SDL_Surface *screen)
{
PgColor_t* palette=NULL;
- const struct ColourMasks* mask;
int type=0;
int bpp;
@@ -112,7 +69,7 @@
}
break;
default:{
- fprintf(stderr,"ph_SetupImage(): unsupported bpp=%d !\n", bpp);
+ SDL_SetError("ph_SetupImage(): unsupported bpp=%d !\n", bpp);
return -1;
}
break;
@@ -123,12 +80,18 @@
{
/* creating image palette */
palette=malloc(_Pg_MAX_PALETTE*sizeof(PgColor_t));
+ if (palette==NULL)
+ {
+ SDL_SetError("ph_SetupImage(): can't allocate memory for palette !\n");
+ return -1;
+ }
PgGetPalette(palette);
/* using shared memory for speed (set last param to 1) */
if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, palette, _Pg_MAX_PALETTE, 1)) == NULL)
{
- fprintf(stderr,"ph_SetupImage(): PhCreateImage failed for bpp=8 !\n");
+ SDL_SetError("ph_SetupImage(): PhCreateImage() failed for bpp=8 !\n");
+ free(palette);
return -1;
}
}
@@ -137,19 +100,13 @@
/* using shared memory for speed (set last param to 1) */
if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, NULL, 0, 1)) == NULL)
{
- fprintf(stderr,"ph_SetupImage: PhCreateImage failed !\n");
+ SDL_SetError("ph_SetupImage(): PhCreateImage() failed for bpp=%d !\n", bpp);
return -1;
}
}
screen->pixels = SDL_Image->image;
- screen->pitch = SDL_Image->bpl; /* Recalculated pitch, created by PhCreateImage */
-
- mask = ph_GetColourMasks(type);
- if (mask != NULL)
- {
- SDL_ReallocFormat(screen, mask->bpp, mask->red, mask->green, mask->blue, 0);
- }
+ screen->pitch = SDL_Image->bpl;
this->UpdateRects = ph_NormalUpdate;
@@ -158,11 +115,9 @@
int ph_SetupOCImage(_THIS, SDL_Surface *screen)
{
- const struct ColourMasks *mask;
int type = 0;
int bpp;
- screen->flags &= ~SDL_DOUBLEBUF;
OCImage.flags = screen->flags;
bpp=screen->format->BitsPerPixel;
@@ -191,7 +146,7 @@
}
break;
default:{
- fprintf(stderr,"ph_SetupOCImage(): unsupported bpp=%d !\n", bpp);
+ SDL_SetError("ph_SetupOCImage(): unsupported bpp=%d !\n", bpp);
return -1;
}
break;
@@ -203,35 +158,22 @@
if (OCImage.offscreen_context == NULL)
{
- fprintf(stderr, "ph_SetupOCImage(): PdCreateOffscreenContext failed !\n");
+ SDL_SetError("ph_SetupOCImage(): PdCreateOffscreenContext() function failed !\n");
return -1;
}
- /* If the bit depth of the context is different than was requested,
- * these values need to be updated accordingly. SDL will
- * allocate a shadow surface if it needs to. */
- mask = ph_GetColourMasks(OCImage.offscreen_context->format);
- if (mask != NULL)
- {
- SDL_ReallocFormat(screen, mask->bpp, mask->red, mask->green, mask->blue, 0);
+ screen->pitch = OCImage.offscreen_context->pitch;
+
+ OCImage.dc_ptr = (unsigned char *) PdGetOffscreenContextPtr(OCImage.offscreen_context);
- if (mask->bpp > 8)
- {
- screen->flags &= ~SDL_HWPALETTE;
- }
- }
-
- screen->pitch = OCImage.offscreen_context->pitch; /* Recalculated pitch */
-
- OCImage.dc_ptr.ptr8 = (unsigned char *) PdGetOffscreenContextPtr(OCImage.offscreen_context);
-
- if (OCImage.dc_ptr.ptr8 == NULL)
+ if (OCImage.dc_ptr == NULL)
{
- fprintf(stderr, "ph_SetupOCImage(): PdGetOffscreenContextPtr failed !\n");
+ SDL_SetError("ph_SetupOCImage(): PdGetOffscreenContextPtr function failed !\n");
+ PhDCRelease(OCImage.offscreen_context);
return -1;
}
- OCImage.FrameData0 = OCImage.dc_ptr.ptr8;
+ OCImage.FrameData0 = OCImage.dc_ptr;
OCImage.CurrentFrameData = OCImage.FrameData0;
OCImage.current = 0;
@@ -253,67 +195,108 @@
int ph_SetupFullScreenImage(_THIS, SDL_Surface* screen)
{
- const struct ColourMasks *mask;
- screen->flags &= ~SDL_DOUBLEBUF;
OCImage.flags = screen->flags;
- OCImage.offscreen_context = PdCreateOffscreenContext(0, 0, 0, Pg_OSC_MAIN_DISPLAY);
-
- if (OCImage.offscreen_context == NULL)
+ /* Begin direct mode */
+ if (!ph_EnterFullScreen(this, screen))
{
- fprintf(stderr, "ph_SetupFullScreenImage(): PdCreateOffscreenContext failed !\n");
return -1;
}
- /* If the bit depth of the context is different than was requested,
- * these values need to be updated accordingly. SDL will
- * allocate a shadow surface if it needs to. */
- mask = ph_GetColourMasks(OCImage.offscreen_context->format);
- if (mask != NULL)
+ /* store palette for fullscreen */
+ if ((screen->format->BitsPerPixel==8) && (desktopbpp!=8))
+ {
+ PgGetPalette(savedpal);
+ PgGetPalette(syspalph);
+ }
+
+ OCImage.offscreen_context = PdCreateOffscreenContext(0, 0, 0, Pg_OSC_MAIN_DISPLAY);
+ if (OCImage.offscreen_context == NULL)
{
- SDL_ReallocFormat(screen, mask->bpp, mask->red, mask->green, mask->blue, 0);
-
- if (mask->bpp > 8)
+ SDL_SetError("ph_SetupFullScreenImage(): PdCreateOffscreenContext() function failed !\n");
+ return -1;
+ }
+
+ if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF)
+ {
+ OCImage.offscreen_backcontext = PdDupOffscreenContext(OCImage.offscreen_context, Pg_OSC_CRTC_SAFE);
+ if (OCImage.offscreen_backcontext == NULL)
{
- screen->flags &= ~SDL_HWPALETTE;
+ SDL_SetError("ph_SetupFullScreenImage(): PdCreateOffscreenContext(back) function failed !\n");
+ return -1;
}
}
- screen->pitch = OCImage.offscreen_context->pitch; /* Recalculated pitch */
-
- OCImage.dc_ptr.ptr8 = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_context);
-
- if (OCImage.dc_ptr.ptr8 == NULL)
+ OCImage.FrameData0 = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_context);
+ if (OCImage.FrameData0 == NULL)
{
- fprintf(stderr, "ph_SetupOCImage(): PdGetOffscreenContextPtr failed !\n");
+ SDL_SetError("ph_SetupFullScreenImage(): PdGetOffscreenContextPtr() function failed !\n");
+ ph_DestroyImage(this, screen);
return -1;
}
- /* wait for hw */
+ if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF)
+ {
+ OCImage.FrameData1 = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_backcontext);
+ if (OCImage.FrameData1 == NULL)
+ {
+ SDL_SetError("ph_SetupFullScreenImage(back): PdGetOffscreenContextPtr() function failed !\n");
+ ph_DestroyImage(this, screen);
+ return -1;
+ }
+ }
+
+ /* wait for the hardware */
PgWaitHWIdle();
- OCImage.FrameData0 = OCImage.dc_ptr.ptr8;
- OCImage.CurrentFrameData = OCImage.FrameData0;
- OCImage.current = 0;
+ if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF)
+ {
+ OCImage.current = 1;
+ PhDCSetCurrent(OCImage.offscreen_backcontext);
+ screen->pitch = OCImage.offscreen_backcontext->pitch;
+ screen->pixels = OCImage.FrameData1;
+ PgSwapDisplay(OCImage.offscreen_context, 0);
+ }
+ else
+ {
+ OCImage.current = 0;
+ PhDCSetCurrent(OCImage.offscreen_context);
+ screen->pitch = OCImage.offscreen_context->pitch;
+ screen->pixels = OCImage.FrameData0;
+ }
- PhDCSetCurrent(OCImage.offscreen_context);
-
- screen->pixels = OCImage.CurrentFrameData;
-
- this->UpdateRects = ph_OCUpdate;
+ this->UpdateRects = ph_OCDCUpdate;
return 0;
}
void ph_DestroyImage(_THIS, SDL_Surface *screen)
{
+ if (currently_fullscreen)
+ {
+ /* if we right now in 8bpp fullscreen we must release palette */
+ if ((screen->format->BitsPerPixel==8) && (desktopbpp!=8))
+ {
+ PgSetPalette(syspalph, 0, -1, 0, 0, 0);
+ PgSetPalette(savedpal, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0);
+ PgFlush();
+ }
+ ph_LeaveFullScreen(this);
+ }
+
if (OCImage.offscreen_context != NULL)
{
PhDCRelease(OCImage.offscreen_context);
OCImage.offscreen_context = NULL;
OCImage.FrameData0 = NULL;
+ }
+ if (OCImage.offscreen_backcontext != NULL)
+ {
+ PhDCRelease(OCImage.offscreen_backcontext);
+ OCImage.offscreen_backcontext = NULL;
OCImage.FrameData1 = NULL;
}
+ OCImage.CurrentFrameData = NULL;
if (SDL_Image)
{
@@ -354,6 +337,7 @@
return ph_SetupImage(this, screen);
}
+
int ph_AllocHWSurface(_THIS, SDL_Surface *surface)
{
return(-1);
@@ -364,9 +348,41 @@
return;
}
-int ph_FlipHWSurface(_THIS, SDL_Surface *surface)
+int ph_FlipHWSurface(_THIS, SDL_Surface *screen)
{
- return(0);
+ PhArea_t area;
+
+ area.pos.x=0;
+ area.pos.y=0;
+ area.size.w=screen->w;
+ area.size.h=screen->h;
+
+ if ((screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
+ {
+ if (OCImage.current==0)
+ {
+ PgSwapDisplay(OCImage.offscreen_context, 0);
+ OCImage.current=1;
+ screen->pitch = OCImage.offscreen_backcontext->pitch;
+ screen->pixels = OCImage.FrameData1;
+// memcpy(OCImage.FrameData1, OCImage.FrameData0, OCImage.offscreen_context->shared_size);
+ PgContextBlitArea(OCImage.offscreen_context, &area, OCImage.offscreen_backcontext, &area);
+ PhDCSetCurrent(OCImage.offscreen_backcontext);
+ PgFlush();
+ }
+ else
+ {
+ PgSwapDisplay(OCImage.offscreen_backcontext, 0);
+ OCImage.current=0;
+ screen->pitch = OCImage.offscreen_context->pitch;
+ screen->pixels = OCImage.FrameData0;
+// memcpy(OCImage.FrameData0, OCImage.FrameData1, OCImage.offscreen_context->shared_size);
+ PgContextBlitArea(OCImage.offscreen_backcontext, &area, OCImage.offscreen_context, &area);
+ PhDCSetCurrent(OCImage.offscreen_context);
+ PgFlush();
+ }
+ }
+ return 0;
}
int ph_LockHWSurface(_THIS, SDL_Surface *surface)
@@ -399,6 +415,11 @@
continue;
}
+ if (rects[i].h==0) /* Clipped? */
+ {
+ continue;
+ }
+
ph_pos.x = rects[i].x;
ph_pos.y = rects[i].y;
ph_rect.ul.x = rects[i].x;
@@ -408,13 +429,13 @@
if (PgDrawPhImageRectmx(&ph_pos, SDL_Image, &ph_rect, 0) < 0)
{
- fprintf(stderr,"ph_NormalUpdate(): PgDrawPhImageRectmx failed !\n");
+ SDL_SetError("ph_NormalUpdate(): PgDrawPhImageRectmx failed !\n");
}
}
if (PgFlush() < 0)
{
- fprintf(stderr,"ph_NormalUpdate(): PgFlush failed.\n");
+ SDL_SetError("ph_NormalUpdate(): PgFlush failed.\n");
}
}
@@ -437,6 +458,11 @@
continue;
}
+ if (rects[i].h == 0) /* Clipped? */
+ {
+ continue;
+ }
+
src_rect.pos.x=rects[i].x;
src_rect.pos.y=rects[i].y;
dest_rect.pos.x=rects[i].x;
@@ -457,16 +483,16 @@
if (PgFlush() < 0)
{
- fprintf(stderr,"ph_OCUpdate(): PgFlush failed.\n");
- }
-
- /* later used to toggling double buffer */
- if (OCImage.current == 0)
- {
- OCImage.CurrentFrameData = OCImage.FrameData0;
- }
- else
- {
- OCImage.CurrentFrameData = OCImage.FrameData1;
+ SDL_SetError("ph_OCUpdate(): PgFlush failed.\n");
}
}
+
+void ph_OCDCUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ PgWaitHWIdle();
+
+ if (PgFlush() < 0)
+ {
+ SDL_SetError("ph_OCDCUpdate(): PgFlush failed.\n");
+ }
+}
--- a/src/video/photon/SDL_ph_image_c.h Mon Jul 28 01:47:55 2003 +0000
+++ b/src/video/photon/SDL_ph_image_c.h Mon Aug 04 00:52:42 2003 +0000
@@ -39,4 +39,5 @@
extern void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);
extern void ph_OCUpdate(_THIS, int numrects, SDL_Rect *rects);
+extern void ph_OCDCUpdate(_THIS, int numrects, SDL_Rect *rects);
extern void ph_OpenGLUpdate(_THIS, int numrects, SDL_Rect *rects);
--- a/src/video/photon/SDL_ph_modes.c Mon Jul 28 01:47:55 2003 +0000
+++ b/src/video/photon/SDL_ph_modes.c Mon Aug 04 00:52:42 2003 +0000
@@ -25,6 +25,7 @@
"@(#) $Id$";
#endif
+#include "SDL_error.h"
#include "SDL_ph_modes_c.h"
static unsigned long key1, key2;
@@ -39,8 +40,6 @@
{
if (PgGetVideoModeInfo(*(unsigned short*)mode1, &mode_info) < 0)
{
- fprintf(stderr,"error: In compare_modes_by_res PgGetVideoModeInfo failed on mode: 0x%x\n",
- *(unsigned short*)mode1);
return 0;
}
@@ -48,19 +47,26 @@
if (PgGetVideoModeInfo(*(unsigned short*)mode2, &mode_info) < 0)
{
- fprintf(stderr,"error: In compare_modes_by_res PgGetVideoModeInfo failed on mode: 0x%x\n",
- *(unsigned short*)mode2);
return 0;
}
key2 = mode_info.width * mode_info.height;
if (key1 > key2)
+ {
return 1;
- else if (key1 == key2)
- return 0;
+ }
else
- return -1;
+ {
+ if (key1 == key2)
+ {
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+ }
}
SDL_Rect **ph_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
@@ -76,7 +82,7 @@
if (PgGetVideoModeList( &mode_list ) < 0)
{
- fprintf(stderr,"error: PgGetVideoModeList failed\n");
+ SDL_SetError("ph_ListModes(): PgGetVideoModeList() function failed !\n");
return NULL;
}
@@ -86,7 +92,7 @@
{
if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
{
- fprintf(stderr,"error: PgGetVideoModeInfo failed on mode: 0x%x\n", mode_list.modes[i]);
+ SDL_SetError("ph_ListModes(): PgGetVideoModeInfo() function failed on mode: 0x%X.\n", mode_list.modes[i]);
return NULL;
}
if(mode_info.bits_per_pixel == format->BitsPerPixel)
@@ -120,22 +126,12 @@
/* return the mode associated with width, height and bpp */
/* if there is no mode then zero is returned */
-int get_mode(int width, int height, int bpp)
+int ph_GetVideoMode(int width, int height, int bpp)
{
int i;
- if(width<640)
- {
- width=640;
- }
- if(height<480)
- {
- height=480;
- }
-
if (PgGetVideoModeList(&mode_list) < 0)
{
- fprintf(stderr,"error: PgGetVideoModeList failed\n");
return -1;
}
@@ -144,7 +140,6 @@
{
if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
{
- fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
return 0;
}
@@ -159,89 +154,124 @@
return (i == mode_list.num_modes) ? 0 : mode_list.modes[i];
}
-int get_mode_any_format(int width, int height, int bpp)
/* return the mode associated with width, height and bpp */
/* if requested bpp is not found the mode with closest bpp is returned */
+int get_mode_any_format(int width, int height, int bpp)
{
int i, closest, delta, min_delta;
- if (PgGetVideoModeList( &mode_list ) < 0)
- {
- fprintf(stderr,"error: PgGetVideoModeList failed\n");
- return -1;
- }
+ if (PgGetVideoModeList(&mode_list) < 0)
+ {
+ return -1;
+ }
+
+ qsort(mode_list.modes, mode_list.num_modes, sizeof(unsigned short), compare_modes_by_res);
- qsort(mode_list.modes, mode_list.num_modes, sizeof(unsigned short), compare_modes_by_res);
- for(i=0;i<mode_list.num_modes;i++)
- {
- if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
- {
- fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
- return 0;
- }
- if ((mode_info.width == width) &&
- (mode_info.height == height))
+ for(i=0;i<mode_list.num_modes;i++)
+ {
+ if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
+ {
+ return 0;
+ }
+ if ((mode_info.width == width) && (mode_info.height == height))
+ {
break;
- }
- if (i<mode_list.num_modes)
- {
- /* get closest bpp */
- closest = i++;
- if (mode_info.bits_per_pixel == bpp)
- return mode_list.modes[closest];
+ }
+ }
+
+ if (i<mode_list.num_modes)
+ {
+ /* get closest bpp */
+ closest = i++;
+ if (mode_info.bits_per_pixel == bpp)
+ {
+ return mode_list.modes[closest];
+ }
+
+ min_delta = abs(mode_info.bits_per_pixel - bpp);
- min_delta = abs(mode_info.bits_per_pixel - bpp);
- while(1)
- {
- if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
- {
- fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
- return 0;
- }
+ while(1)
+ {
+ if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
+ {
+ return 0;
+ }
- if ((mode_info.width != width) ||
- (mode_info.height != height))
- break;
- else if (mode_info.bits_per_pixel == bpp)
- {
- closest = i;
- break;
- }
- else
- {
- delta = abs(mode_info.bits_per_pixel - bpp);
- if (delta < min_delta)
- {
- closest = i;
- min_delta = delta;
- }
- i++;
- }
- }
- return mode_list.modes[closest];
- }
- else
+ if ((mode_info.width != width) || (mode_info.height != height))
+ {
+ break;
+ }
+ else
+ {
+ if (mode_info.bits_per_pixel == bpp)
+ {
+ closest = i;
+ break;
+ }
+ else
+ {
+ delta = abs(mode_info.bits_per_pixel - bpp);
+ if (delta < min_delta)
+ {
+ closest = i;
+ min_delta = delta;
+ }
+ i++;
+ }
+ }
+ }
+ return mode_list.modes[closest];
+ }
+
return 0;
}
int ph_ToggleFullScreen(_THIS, int on)
{
- if (currently_fullscreen)
- {
- return ph_LeaveFullScreen(this);
- }
- else
- {
- return ph_EnterFullScreen(this);
- }
-
- return 0;
+ return -1;
}
-int ph_EnterFullScreen(_THIS)
+int ph_EnterFullScreen(_THIS, SDL_Surface* screen)
{
+ PgDisplaySettings_t settings;
+ int mode;
+
if (!currently_fullscreen)
{
+ /* Get the video mode and set it */
+ if (screen->flags & SDL_ANYFORMAT)
+ {
+ if ((mode = get_mode_any_format(screen->w, screen->h, screen->format->BitsPerPixel)) == 0)
+ {
+ SDL_SetError("ph_EnterFullScreen(): can't find appropriate video mode !\n");
+ return 0;
+ }
+ }
+ else
+ {
+ if ((mode = ph_GetVideoMode(screen->w, screen->h, screen->format->BitsPerPixel)) == 0)
+ {
+ SDL_SetError("ph_EnterFullScreen(): can't find appropriate video mode !\n");
+ return 0;
+ }
+ }
+
+ /* save old video mode caps */
+ PgGetVideoMode(&settings);
+ old_video_mode=settings.mode;
+ old_refresh_rate=settings.refresh;
+
+ /* setup new video mode */
+ settings.mode = mode;
+ settings.refresh = 0;
+ settings.flags = 0;
+
+ if (PgSetVideoMode(&settings) < 0)
+ {
+ SDL_SetError("ph_EnterFullScreen(): PgSetVideoMode() call failed !\n");
+ return 0;
+ }
+
if (this->screen)
{
if ((this->screen->flags & SDL_OPENGL)==SDL_OPENGL)
@@ -255,12 +285,12 @@
if (OCImage.direct_context==NULL)
{
OCImage.direct_context=(PdDirectContext_t*)PdCreateDirectContext();
- }
-
- if (!OCImage.direct_context)
- {
- fprintf(stderr, "ph_EnterFullScreen(): Can't create direct context !\n");
- return 0;
+ if (!OCImage.direct_context)
+ {
+ SDL_SetError("ph_EnterFullScreen(): Can't create direct context !\n");
+ ph_LeaveFullScreen(this);
+ return 0;
+ }
}
OCImage.oldDC=PdDirectStart(OCImage.direct_context);
@@ -277,7 +307,7 @@
if (currently_fullscreen)
{
- if ((this->screen->flags & SDL_OPENGL)==SDL_OPENGL)
+ if ((this->screen) && ((this->screen->flags & SDL_OPENGL)==SDL_OPENGL))
{
#ifdef HAVE_OPENGL
#endif /* HAVE_OPENGL */
@@ -285,22 +315,30 @@
}
else
{
- PdDirectStop(OCImage.direct_context);
- PdReleaseDirectContext(OCImage.direct_context);
- PhDCSetCurrent(OCImage.oldDC);
+ if (OCImage.direct_context)
+ {
+ PdDirectStop(OCImage.direct_context);
+ PdReleaseDirectContext(OCImage.direct_context);
+ OCImage.direct_context=NULL;
+ }
+ if (OCImage.oldDC)
+ {
+ PhDCSetCurrent(OCImage.oldDC);
+ OCImage.oldDC=NULL;
+ }
currently_fullscreen=0;
/* Restore old video mode */
if (old_video_mode != -1)
{
- mymode_settings.mode= (unsigned short) old_video_mode;
- mymode_settings.refresh= (unsigned short) old_refresh_rate;
- mymode_settings.flags= 0;
+ mymode_settings.mode = (unsigned short) old_video_mode;
+ mymode_settings.refresh = (unsigned short) old_refresh_rate;
+ mymode_settings.flags = 0;
if (PgSetVideoMode(&mymode_settings) < 0)
{
- fprintf(stderr, "Ph_LeaveFullScreen(): PgSetVideoMode failed !\n");
+ SDL_SetError("Ph_LeaveFullScreen(): PgSetVideoMode() function failed !\n");
return 0;
}
}
@@ -308,7 +346,6 @@
old_video_mode=-1;
old_refresh_rate=-1;
}
-
}
return 1;
}
--- a/src/video/photon/SDL_ph_modes_c.h Mon Jul 28 01:47:55 2003 +0000
+++ b/src/video/photon/SDL_ph_modes_c.h Mon Aug 04 00:52:42 2003 +0000
@@ -36,9 +36,9 @@
extern SDL_Rect **ph_ListModes(_THIS,SDL_PixelFormat *format, Uint32 flags);
extern void ph_FreeVideoModes(_THIS);
extern int ph_ResizeFullScreen(_THIS);
-extern int ph_EnterFullScreen(_THIS);
+extern int ph_EnterFullScreen(_THIS, SDL_Surface* screen);
extern int ph_LeaveFullScreen(_THIS);
-extern int get_mode(int width, int height, int bpp);
+extern int ph_GetVideoMode(int width, int height, int bpp);
extern int get_mode_any_format(int width, int height, int bpp);
extern int ph_ToggleFullScreen(_THIS, int on);
--- a/src/video/photon/SDL_ph_mouse.c Mon Jul 28 01:47:55 2003 +0000
+++ b/src/video/photon/SDL_ph_mouse.c Mon Aug 04 00:52:42 2003 +0000
@@ -46,19 +46,18 @@
{
SDL_Lock_EventThread();
- if (PtSetResource( window, Pt_ARG_CURSOR_TYPE, Ph_CURSOR_INHERIT, 0) < 0)
+ if (PtSetResource(window, Pt_ARG_CURSOR_TYPE, Ph_CURSOR_INHERIT, 0) < 0)
{
/* TODO: output error msg */
}
SDL_Unlock_EventThread();
}
- /* free(cursor->ph_cursor.images); */
+
free(cursor);
}
-WMcursor *ph_CreateWMCursor(_THIS,
- Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
+WMcursor *ph_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
{
WMcursor* cursor;
int clen, i;
@@ -73,8 +72,12 @@
memset(cursor,0,sizeof(WMcursor));
cursor->ph_cursor = (PhCursorDef_t *) malloc(sizeof(PhCursorDef_t) + 32*4*2);
+
if (cursor->ph_cursor == NULL)
- printf("cursor malloc failed\n");
+ {
+ SDL_SetError("ph_CreateWMCursor(): cursor malloc failed !\n");
+ return NULL;
+ }
memset(cursor->ph_cursor,0,(sizeof(PhCursorDef_t) + 32*4*2));
@@ -137,7 +140,7 @@
return (0);
}
- /* Set the photon cursor cursor, or blank if cursor is NULL */
+ /* Set the photon cursor, or blank if cursor is NULL */
if (cursor!=NULL)
{
PtSetArg(&args[0], Pt_ARG_CURSOR_TYPE, Ph_CURSOR_BITMAP, 0);
@@ -148,7 +151,7 @@
}
else /* Ph_CURSOR_NONE */
{
- PtSetArg( &args[0], Pt_ARG_CURSOR_TYPE, Ph_CURSOR_NONE, 0);
+ PtSetArg(&args[0], Pt_ARG_CURSOR_TYPE, Ph_CURSOR_NONE, 0);
nargs = 1;
}
--- a/src/video/photon/SDL_ph_video.c Mon Jul 28 01:47:55 2003 +0000
+++ b/src/video/photon/SDL_ph_video.c Mon Aug 04 00:52:42 2003 +0000
@@ -59,9 +59,12 @@
static void ph_UpdateMouse(_THIS);
#ifdef HAVE_OPENGL
-int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags);
+static int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags);
static void ph_GL_SwapBuffers(_THIS);
static int ph_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
+static int ph_GL_LoadLibrary(_THIS, const char* path);
+static void* ph_GL_GetProcAddress(_THIS, const char* proc);
+
#endif /* HAVE_OPENGL */
static int ph_Available(void)
@@ -109,7 +112,7 @@
device->ToggleFullScreen = ph_ToggleFullScreen;
device->UpdateMouse = ph_UpdateMouse;
device->SetColors = ph_SetColors;
- device->UpdateRects = NULL; /* ph_SetupUpdateFunction */
+ device->UpdateRects = NULL; /* set up in ph_SetupUpdateFunction */
device->VideoQuit = ph_VideoQuit;
device->AllocHWSurface = ph_AllocHWSurface;
device->CheckHWBlit = NULL;
@@ -134,19 +137,21 @@
device->PumpEvents = ph_PumpEvents;
/* OpenGL support. */
- device->GL_LoadLibrary = NULL;
- device->GL_GetProcAddress = NULL;
device->GL_MakeCurrent = NULL;
#ifdef HAVE_OPENGL
device->GL_SwapBuffers = ph_GL_SwapBuffers;
device->GL_GetAttribute = ph_GL_GetAttribute;
+ device->GL_LoadLibrary = ph_GL_LoadLibrary;
+ device->GL_GetProcAddress = ph_GL_GetProcAddress;
#else
device->GL_SwapBuffers = NULL;
device->GL_GetAttribute = NULL;
+ device->GL_LoadLibrary = NULL;
+ device->GL_GetProcAddress = NULL;
#endif /* HAVE_OPENGL */
device->free = ph_DeleteDevice;
-
+
return device;
}
@@ -179,10 +184,6 @@
PtWidget_t *widget;
widget = PtCreateWidget(PtWindow, NULL, 0, 0);
- if (widget == NULL)
- {
- SDL_SetError("Couldn't create video window");
- }
return widget;
}
@@ -199,28 +200,38 @@
if ((flags & SDL_RESIZABLE) == SDL_RESIZABLE)
{
- PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX);
- PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_RESIZE | Ph_WM_MAX);
- PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_CLOSE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_MAX | Ph_WM_RESTORE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_RESIZE | Ph_WM_MOVE | Ph_WM_MAX | Ph_WM_RESTORE | Ph_WM_CLOSE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX | Ph_WM_RENDER_COLLAPSE | Ph_WM_RENDER_RETURN);
}
else
{
- PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX);
- PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX);
- PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX | Ph_WM_RENDER_COLLAPSE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX | Ph_WM_RESTORE | Ph_WM_CLOSE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX | Ph_WM_RESTORE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_MOVE | Ph_WM_CLOSE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX | Ph_WM_RENDER_COLLAPSE | Ph_WM_RENDER_RETURN);
}
if (((flags & SDL_NOFRAME)==SDL_NOFRAME) || ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN))
{
- PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Pt_TRUE);
+ if ((flags & SDL_RESIZABLE) != SDL_RESIZABLE)
+ {
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Pt_TRUE);
+ }
+ else
+ {
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Pt_TRUE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_BORDER);
+ }
}
else
{
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_BORDER | Ph_WM_RENDER_TITLE |
- Ph_WM_RENDER_CLOSE | Ph_WM_RENDER_MENU | Ph_WM_RENDER_MIN);
+ Ph_WM_RENDER_CLOSE | Ph_WM_RENDER_MENU | Ph_WM_RENDER_MIN);
}
- if (flags & SDL_FULLSCREEN)
+ if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
{
PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0);
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_FFRONT | Ph_WM_MAX);
@@ -231,6 +242,7 @@
{
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISFRONT | Ph_WM_STATE_ISMAX | Ph_WM_STATE_ISALTKEY);
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_HIDE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_HIDE);
PtSetArg(&args[nargs++], Pt_ARG_RESIZE_FLAGS, Pt_FALSE, Pt_RESIZE_XY_AS_REQUIRED);
}
@@ -240,10 +252,38 @@
return 0;
}
+static const struct ColourMasks* ph_GetColourMasks(int bpp)
+{
+ /* The alpha mask doesn't appears to be needed */
+ static const struct ColourMasks phColorMasks[5] = {
+ /* 8 bit */ {0, 0, 0, 0, 8},
+ /* 15 bit ARGB */ {0x7C00, 0x03E0, 0x001F, 0x8000, 15},
+ /* 16 bit RGB */ {0xF800, 0x07E0, 0x001F, 0x0000, 16},
+ /* 24 bit RGB */ {0xFF0000, 0x00FF00, 0x0000FF, 0x000000, 24},
+ /* 32 bit ARGB */ {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, 32},
+ };
+
+ switch (bpp)
+ {
+ case 8:
+ return &phColorMasks[0];
+ case 15:
+ return &phColorMasks[1];
+ case 16:
+ return &phColorMasks[2];
+ case 24:
+ return &phColorMasks[3];
+ case 32:
+ return &phColorMasks[4];
+ }
+ return NULL;
+}
+
static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat)
{
PgVideoModeInfo_t my_mode_info;
PgHWCaps_t my_hwcaps;
+ int i;
window=NULL;
desktoppal=SDLPH_PAL_NONE;
@@ -264,6 +304,7 @@
window = ph_CreateWindow(this);
if (window == NULL)
{
+ SDL_SetError("ph_VideoInit(): Couldn't create video window !\n");
return -1;
}
@@ -274,17 +315,21 @@
if (SDL_BlankCursor == NULL)
{
- fprintf(stderr, "ph_VideoInit(): could not create blank cursor !\n");
+ return -1;
}
if (PgGetGraphicsHWCaps(&my_hwcaps) < 0)
{
- fprintf(stderr,"ph_VideoInit(): GetGraphicsHWCaps failed !\n");
+ SDL_SetError("ph_VideoInit(): GetGraphicsHWCaps function failed !\n");
+ this->FreeWMCursor(this, SDL_BlankCursor);
+ return -1;
}
if (PgGetVideoModeInfo(my_hwcaps.current_video_mode, &my_mode_info) < 0)
{
- fprintf(stderr,"ph_VideoInit(): PgGetVideoModeInfo failed !\n");
+ SDL_SetError("ph_VideoInit(): PgGetVideoModeInfo function failed !\n");
+ this->FreeWMCursor(this, SDL_BlankCursor);
+ return -1;
}
/* We need to return BytesPerPixel as it in used by CreateRGBsurface */
@@ -298,8 +343,27 @@
PgGetPalette(savedpal);
PgGetPalette(syspalph);
}
+ else
+ {
+ for(i=0; i<_Pg_MAX_PALETTE; i++)
+ {
+ savedpal[i]=PgRGB(0, 0, 0);
+ syspalph[i]=PgRGB(0, 0, 0);
+ }
+ }
currently_fullscreen = 0;
+ currently_hided = 0;
+ current_overlay = NULL;
+
+ OCImage.direct_context = NULL;
+ OCImage.offscreen_context = NULL;
+ OCImage.offscreen_backcontext = NULL;
+ OCImage.oldDC = NULL;
+ OCImage.CurrentFrameData = NULL;
+ OCImage.FrameData0 = NULL;
+ OCImage.FrameData1 = NULL;
+
this->info.wm_available = 1;
@@ -309,18 +373,33 @@
static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current,
int width, int height, int bpp, Uint32 flags)
{
- PgDisplaySettings_t settings;
- SDL_Color* colors;
- int mode;
- int rtnval;
- int i;
+ const struct ColourMasks* mask;
/* Lock the event thread, in multi-threading environments */
SDL_Lock_EventThread();
current->flags = flags;
- ph_SetupWindow(this, width, height, flags);
+ /* if we do not have desired fullscreen mode, then fallback into window mode */
+ if (((current->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) && (ph_GetVideoMode(width, height, bpp)==0))
+ {
+ current->flags &= ~SDL_FULLSCREEN;
+ current->flags &= ~SDL_NOFRAME;
+ current->flags &= ~SDL_RESIZABLE;
+ }
+
+ ph_SetupWindow(this, width, height, current->flags);
+
+ mask = ph_GetColourMasks(bpp);
+ if (mask != NULL)
+ {
+ SDL_ReallocFormat(current, mask->bpp, mask->red, mask->green, mask->blue, 0);
+ }
+ else
+ {
+ SDL_SetError("ph_SetVideoMode(): desired bpp is not supported by photon !\n");
+ return NULL;
+ }
#ifdef HAVE_OPENGL
if (current->flags & SDL_OPENGL)
@@ -334,72 +413,41 @@
{
/* if context creation fail, report no OpenGL to high level */
current->flags &= ~SDL_OPENGL;
+ return NULL;
}
#else
if (current->flags & SDL_OPENGL) /* if no built-in OpenGL support */
{
- fprintf(stderr, "ph_SetVideoMode(): no OpenGL support, try to recompile library.\n");
+ SDL_SetError("ph_SetVideoMode(): no OpenGL support, try to recompile library.\n");
current->flags &= ~SDL_OPENGL;
return NULL;
#endif /* HAVE_OPENGL */
}
else
{
- /* Initialize the window */
- if (current->flags & SDL_FULLSCREEN) /* Direct Context , assume SDL_HWSURFACE also set */
+ /* Initialize internal variables */
+ if ((current->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
{
- /* Get the video mode and set it */
- if (current->flags & SDL_ANYFORMAT)
- {
- if ((mode = get_mode_any_format(width, height, bpp)) == 0)
- {
- fprintf(stderr,"ph_SetVideoMode(): get_mode_any_format failed !\n");
- exit(1);
- }
- }
- else
- {
- if ((mode = get_mode(width, height, bpp)) == 0)
- {
- fprintf(stderr,"ph_SetVideoMode(): get_mode failed !\n");
- exit(1);
- }
- }
-
if (bpp==8)
{
desktoppal=SDLPH_PAL_SYSTEM;
}
-
- /* save old video mode caps */
- PgGetVideoMode(&settings);
- old_video_mode=settings.mode;
- old_refresh_rate=settings.refresh;
-
- /* setup new video mode */
- settings.mode = mode;
- settings.refresh = 0;
- settings.flags = 0;
-
- if (PgSetVideoMode(&settings) < 0)
- {
- fprintf(stderr,"ph_SetVideoMode(): PgSetVideoMode failed !\n");
- }
current->flags &= ~SDL_RESIZABLE; /* no resize for Direct Context */
- current->flags |= SDL_HWSURFACE;
-
- /* Begin direct mode */
- ph_EnterFullScreen(this);
-
- } /* end fullscreen flag */
+ }
else
{
- /* Use offscreen memory iff SDL_HWSURFACE flag is set */
- if (current->flags & SDL_HWSURFACE)
+ /* remove this if we'll support non-fullscreen sw/hw+doublebuf */
+ current->flags &= ~SDL_DOUBLEBUF;
+
+ /* Use offscreen memory if SDL_HWSURFACE flag is set */
+ if ((current->flags & SDL_HWSURFACE) == SDL_HWSURFACE)
{
- /* no stretch blit in offscreen context */
- current->flags &= ~SDL_RESIZABLE;
+
+ if (desktopbpp!=bpp)
+ {
+ current->flags &= ~SDL_HWSURFACE;
+ }
}
/* using palette emulation code in window mode */
@@ -407,33 +455,16 @@
{
if (desktopbpp>=15)
{
- desktoppal=SDLPH_PAL_EMULATE;
+ desktoppal = SDLPH_PAL_EMULATE;
}
else
{
- desktoppal=SDLPH_PAL_SYSTEM;
- }
-
- /* fill the palette */
- PgGetPalette(savedpal);
- PgGetPalette(syspalph);
-
- current->format->palette = calloc(1, sizeof(SDL_Palette));
- current->format->palette->ncolors = _Pg_MAX_PALETTE;
- current->format->palette->colors = (SDL_Color *)calloc(_Pg_MAX_PALETTE, sizeof(SDL_Color));
-
- colors = current->format->palette->colors;
-
- for(i=0; i<256; i++)
- {
- colors[i].r = PgRedValue(syspalph[i]);
- colors[i].g = PgGreenValue(syspalph[i]);
- colors[i].b = PgBlueValue(syspalph[i]);
+ desktoppal = SDLPH_PAL_SYSTEM;
}
}
else
{
- desktoppal=SDLPH_PAL_NONE;
+ desktoppal = SDLPH_PAL_NONE;
}
}
}
@@ -441,22 +472,22 @@
current->w = width;
current->h = height;
- /* These values can be overridden in ph_SetupUpdateFunction() */
- current->format->BitsPerPixel = bpp;
- current->format->BytesPerPixel = (bpp+7)/8;
- current->pitch = SDL_CalculatePitch(current);
+ if (desktoppal==SDLPH_PAL_SYSTEM)
+ {
+ current->flags|=SDL_HWPALETTE;
+ }
- /* Must call at least once it setup image planes */
- rtnval = ph_SetupUpdateFunction(this, current, current->flags);
-
- if (rtnval==-1)
+ /* Must call at least once for setup image planes */
+ if (ph_SetupUpdateFunction(this, current, current->flags)==-1)
{
- fprintf(stderr,"ph_SetVideoMode(): ph_SetupUpdateFunction failed !\n");
return NULL;
}
- /* finish window drawing */
- PtFlush();
+ /* finish window drawing, if we are not in fullscreen, of course */
+ if ((current->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN)
+ {
+ PtFlush();
+ }
SDL_Unlock_EventThread();
@@ -470,12 +501,15 @@
PhRegion_t region_info;
#endif /* HAVE_OPENGL */
- ph_DestroyImage(this, SDL_VideoSurface);
+ /* restore palette */
+ if (desktopbpp==8)
+ {
+ PgSetPalette(syspalph, 0, -1, 0, 0, 0);
+ PgSetPalette(savedpal, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0);
+ PgFlush();
+ }
- if (currently_fullscreen)
- {
- ph_LeaveFullScreen(this);
- }
+ ph_DestroyImage(this, SDL_VideoSurface);
#ifdef HAVE_OPENGL
/* prevent double SEGFAULT during parachute mode */
@@ -509,14 +543,6 @@
}
#endif /* HAVE_OPENGL */
- /* restore palette */
- if (desktoppal!=SDLPH_PAL_NONE)
- {
- PgSetPalette(savedpal, 1, 0, _Pg_MAX_PALETTE, Pg_PALSET_HARD | Pg_PALSET_FORCE_EXPOSE, 0);
- /* pass -1, to force release palette */
- PgSetPalette(savedpal, 1, 0, -1, Pg_PALSET_HARD | Pg_PALSET_FORCE_EXPOSE, 0);
- }
-
if (event!=NULL)
{
free(event);
@@ -543,6 +569,7 @@
syspalph[i] = PgRGB(colors[i-firstcolor].r, colors[i-firstcolor].g, colors[i-firstcolor].b);
SDL_Image->palette[i] = syspalph[i];
}
+
/* image needs to be redrawn */
this->UpdateRects(this, 1, &updaterect);
}
@@ -559,14 +586,14 @@
if ((this->screen->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN)
{
/* window mode must use soft palette */
- PgSetPalette(&syspalph[firstcolor], 1, firstcolor, ncolors, Pg_PALSET_SOFT, 0);
+ PgSetPalette(&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0);
/* image needs to be redrawn */
this->UpdateRects(this, 1, &updaterect);
}
else
{
/* fullscreen mode must use hardware palette */
- PgSetPalette(&syspalph[firstcolor], 1, firstcolor, ncolors, Pg_PALSET_HARDLOCKED, 0);
+ PgSetPalette(&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0);
}
}
else
@@ -628,7 +655,7 @@
if (oglctx==NULL)
{
- fprintf(stderr,"ph_SetupOpenGLContext(): cannot create OpenGL context.\n");
+ SDL_SetError("ph_SetupOpenGLContext(): cannot create OpenGL context !\n");
return (-1);
}
@@ -675,6 +702,19 @@
return 0;
}
+int ph_GL_LoadLibrary(_THIS, const char* path)
+{
+ /* if code compiled with HAVE_OPENGL, the library already linked */
+ this->gl_config.driver_loaded = 1;
+
+ return 0;
+}
+
+void* ph_GL_GetProcAddress(_THIS, const char* proc)
+{
+ return NULL;
+}
+
#endif /* HAVE_OPENGL */
static void ph_UpdateMouse(_THIS)
--- a/src/video/photon/SDL_ph_video.h Mon Jul 28 01:47:55 2003 +0000
+++ b/src/video/photon/SDL_ph_video.h Mon Aug 04 00:52:42 2003 +0000
@@ -20,22 +20,23 @@
slouken@libsdl.org
*/
-#ifndef _SDL_ph_video_h
-#define _SDL_ph_video_h
+#ifndef __SDL_PH_VIDEO_H__
+#define __SDL_PH_VIDEO_H__
#include "SDL_mouse.h"
#include "SDL_sysvideo.h"
-#include "Ph.h"
-#include "Pt.h"
+#include <Ph.h>
+#include <Pt.h>
#include <photon/Pg.h>
#include <photon/PdDirect.h>
+
#ifdef HAVE_OPENGL
-#include <photon/PdGL.h>
+ #include <photon/PdGL.h>
#endif /* HAVE_OPENGL */
/* Hidden "this" pointer for the video functions */
-#define _THIS SDL_VideoDevice *this
+#define _THIS SDL_VideoDevice* this
#define PH_OGL_MAX_ATTRIBS 32
@@ -43,18 +44,23 @@
#define SDLPH_PAL_EMULATE 0x00000001L
#define SDLPH_PAL_SYSTEM 0x00000002L
-typedef union vidptr{
- uint8_t* volatile ptr8;
- uint16_t* volatile ptr16;
- uint32_t* volatile ptr32;
- } VidPtr_t;
-
-typedef struct {
+typedef struct
+{
unsigned char* Y;
unsigned char* V;
unsigned char* U;
} FRAMEDATA;
+/* Mask values for SDL_ReallocFormat() */
+struct ColourMasks
+{
+ Uint32 red;
+ Uint32 green;
+ Uint32 blue;
+ Uint32 alpha;
+ Uint32 bpp;
+};
+
/* Private display data */
struct SDL_PrivateVideoData {
PgDisplaySettings_t mode_settings;
@@ -69,8 +75,9 @@
struct {
PdDirectContext_t* direct_context;
PdOffscreenContext_t* offscreen_context;
+ PdOffscreenContext_t* offscreen_backcontext;
PhDrawContext_t* oldDC;
- VidPtr_t dc_ptr;
+ uint8_t* dc_ptr;
unsigned char* CurrentFrameData;
unsigned char* FrameData0;
unsigned char* FrameData1;
@@ -85,13 +92,15 @@
int mouse_relative;
WMcursor* BlankCursor;
- int depth; /* current visual depth (not bpp) */
- int desktopbpp; /* bpp of desktop at the moment of start */
- int desktoppal; /* palette mode emulation or system */
+ int depth; /* current visual depth (not bpp) */
+ int desktopbpp; /* bpp of desktop at the moment of start */
+ int desktoppal; /* palette mode emulation or system */
int currently_fullscreen;
+ int currently_hided; /* 1 - window hided (minimazed), 0 - normal */
PhEvent_t* event;
+ SDL_Overlay* overlay;
};
#define mode_settings (this->hidden->mode_settings)
@@ -106,11 +115,13 @@
#define desktoppal (this->hidden->desktoppal)
#define savedpal (this->hidden->savedpal)
#define syspalph (this->hidden->syspalph)
+#define currently_fullscreen (this->hidden->currently_fullscreen)
+#define currently_hided (this->hidden->currently_hided)
+#define event (this->hidden->event)
+#define current_overlay (this->hidden->overlay)
/* Old variable names */
#define mouse_relative (this->hidden->mouse_relative)
-#define currently_fullscreen (this->hidden->currently_fullscreen)
-#define event (this->hidden->event)
#define SDL_BlankCursor (this->hidden->BlankCursor)
-#endif /* _SDL_x11video_h */
+#endif /* __SDL_PH_VIDEO_H__ */
--- a/src/video/photon/SDL_ph_wm.c Mon Jul 28 01:47:55 2003 +0000
+++ b/src/video/photon/SDL_ph_wm.c Mon Aug 04 00:52:42 2003 +0000
@@ -75,8 +75,9 @@
memset( &windowevent, 0, sizeof (event) );
windowevent.event_f = Ph_WM_HIDE;
windowevent.event_state = Ph_WM_EVSTATE_HIDE;
- windowevent.rid = PtWidgetRid( window );
- PtForwardWindowEvent( &windowevent );
+ windowevent.rid = PtWidgetRid(window);
+ PtForwardWindowEvent(&windowevent);
+
SDL_Unlock_EventThread();
return 0;
--- a/src/video/photon/SDL_phyuv.c Mon Jul 28 01:47:55 2003 +0000
+++ b/src/video/photon/SDL_phyuv.c Mon Aug 04 00:52:42 2003 +0000
@@ -25,7 +25,7 @@
"@(#) $Id$";
#endif
-/* This is the QNX Realtime Platform version for SDL YUV video overlays */
+/* This is the QNX Realtime Platform version of SDL YUV video overlays */
#include <stdlib.h>
#include <string.h>
@@ -43,36 +43,15 @@
#define OVERLAY_STATE_ACTIVE 1
/* The functions used to manipulate software video overlays */
-static struct private_yuvhwfuncs ph_yuvfuncs = {
+static struct private_yuvhwfuncs ph_yuvfuncs =
+{
ph_LockYUVOverlay,
ph_UnlockYUVOverlay,
ph_DisplayYUVOverlay,
ph_FreeYUVOverlay
};
-struct private_yuvhwdata {
- FRAMEDATA* CurrentFrameData;
- FRAMEDATA* FrameData0;
- FRAMEDATA* FrameData1;
- PgScalerProps_t props;
- PgScalerCaps_t caps;
- PgVideoChannel_t* channel;
- PhArea_t CurrentWindow;
- long format;
- int planar;
- int scaler_on;
- int current;
- long YStride;
- long VStride;
- long UStride;
- int ischromakey;
- long chromakey;
- unsigned long State;
- long flags;
- int locked;
-};
-
-int grab_ptrs2(PgVideoChannel_t* channel, FRAMEDATA* Frame0, FRAMEDATA* Frame1 )
+int grab_ptrs2(PgVideoChannel_t* channel, FRAMEDATA* Frame0, FRAMEDATA* Frame1)
{
int planes = 0;
@@ -96,11 +75,11 @@
return planes;
}
-SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
+SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface* display)
{
- SDL_Overlay *overlay;
- struct private_yuvhwdata *hwdata;
- int xv_port;
+ SDL_Overlay* overlay;
+ struct private_yuvhwdata* hwdata;
+ int vidport;
int rtncode;
int planes;
int i=0;
@@ -109,15 +88,17 @@
/* Create the overlay structure */
overlay = calloc(1, sizeof(SDL_Overlay));
- if (overlay == NULL) {
+ if (overlay == NULL)
+ {
SDL_OutOfMemory();
- return (NULL);
+ return NULL;
}
/* Fill in the basic members */
overlay->format = format;
overlay->w = width;
overlay->h = height;
+ overlay->hwdata = NULL;
/* Set up the YUV surface function structure */
overlay->hwfuncs = &ph_yuvfuncs;
@@ -125,36 +106,41 @@
/* Create the pixel data and lookup tables */
hwdata = calloc(1, sizeof(struct private_yuvhwdata));
- overlay->hwdata = hwdata;
- if (hwdata == NULL) {
+ if (hwdata == NULL)
+ {
SDL_OutOfMemory();
SDL_FreeYUVOverlay(overlay);
- return(NULL);
+ return NULL;
}
+ overlay->hwdata = hwdata;
+
PhDCSetCurrent(0);
if (overlay->hwdata->channel == NULL)
{
- if ((overlay->hwdata->channel = PgCreateVideoChannel(Pg_VIDEO_CHANNEL_SCALER,0)) == NULL)
+ if ((overlay->hwdata->channel = PgCreateVideoChannel(Pg_VIDEO_CHANNEL_SCALER, 0)) == NULL)
{
SDL_SetError("ph_CreateYUVOverlay(): Create channel failed: %s\n", strerror(errno));
SDL_FreeYUVOverlay(overlay);
-
- return(NULL);
+ return NULL;
}
}
+ overlay->hwdata->forcedredraw=0;
+
PtGetAbsPosition(window, &pos.x, &pos.y);
- overlay->hwdata->CurrentWindow.pos.x = pos.x;
- overlay->hwdata->CurrentWindow.pos.y = pos.y;
- overlay->hwdata->CurrentWindow.size.w = width;
- overlay->hwdata->CurrentWindow.size.h = height;
+ overlay->hwdata->CurrentWindowPos.x = pos.x;
+ overlay->hwdata->CurrentWindowPos.y = pos.y;
+ overlay->hwdata->CurrentViewPort.pos.x = 0;
+ overlay->hwdata->CurrentViewPort.pos.y = 0;
+ overlay->hwdata->CurrentViewPort.size.w = width;
+ overlay->hwdata->CurrentViewPort.size.h = height;
overlay->hwdata->State = OVERLAY_STATE_UNINIT;
overlay->hwdata->FrameData0 = (FRAMEDATA *) calloc(1, sizeof(FRAMEDATA));
overlay->hwdata->FrameData1 = (FRAMEDATA *) calloc(1, sizeof(FRAMEDATA));
- xv_port = -1;
+ vidport = -1;
i=0;
overlay->hwdata->ischromakey=0;
@@ -171,7 +157,7 @@
{
overlay->hwdata->ischromakey=1;
}
- xv_port=1;
+ vidport=1;
break;
}
}
@@ -183,33 +169,28 @@
} while(1);
- if (xv_port == -1)
+ if (vidport == -1)
{
SDL_SetError("No available video ports for requested format\n");
SDL_FreeYUVOverlay(overlay);
- return(NULL);
+ return NULL;
}
-
+
overlay->hwdata->format = format;
overlay->hwdata->props.format = format;
overlay->hwdata->props.size = sizeof(PgScalerProps_t);
- overlay->hwdata->props.src_dim.w = width;
- overlay->hwdata->props.src_dim.h = height;
-
- /* Don't use chromakey for now, blitting a surface will cover the window,
- * and therefore the chroma. */
- overlay->hwdata->chromakey = 0;
- PtSetResource(window, Pt_ARG_FILL_COLOR, overlay->hwdata->chromakey, 0);
+ overlay->hwdata->props.src_dim.w = width;
+ overlay->hwdata->props.src_dim.h = height;
- PhAreaToRect(&overlay->hwdata->CurrentWindow, &overlay->hwdata->props.viewport);
+ overlay->hwdata->chromakey = PgGetOverlayChromaColor();
+
+ PhAreaToRect(&overlay->hwdata->CurrentViewPort, &overlay->hwdata->props.viewport);
overlay->hwdata->props.flags = Pg_SCALER_PROP_DOUBLE_BUFFER;
if ((overlay->hwdata->ischromakey)&&(overlay->hwdata->chromakey))
{
overlay->hwdata->props.flags |= Pg_SCALER_PROP_CHROMA_ENABLE;
- overlay->hwdata->props.color_key = overlay->hwdata->chromakey;
- overlay->hwdata->props.color_key_mask = 0x00FFFFFFUL;
}
else
{
@@ -221,9 +202,8 @@
switch(rtncode)
{
case -1: SDL_SetError("PgConfigScalerChannel failed\n");
- SDL_FreeYUVOverlay(overlay);
- return(NULL);
- break;
+ SDL_FreeYUVOverlay(overlay);
+ return NULL;
case 1:
case 0:
default:
@@ -232,21 +212,39 @@
planes = grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
- if(overlay->hwdata->channel->yplane1 != NULL)
+ if(overlay->hwdata->channel->yplane1 != NULL)
overlay->hwdata->YStride = overlay->hwdata->channel->yplane1->pitch;
- if(overlay->hwdata->channel->uplane1 != NULL)
+ if(overlay->hwdata->channel->uplane1 != NULL)
overlay->hwdata->UStride = overlay->hwdata->channel->uplane1->pitch;
- if(overlay->hwdata->channel->vplane1 != NULL)
+ if(overlay->hwdata->channel->vplane1 != NULL)
overlay->hwdata->VStride = overlay->hwdata->channel->vplane1->pitch;
+ /* check for the validness of all planes */
+ if ((overlay->hwdata->channel->yplane1 == NULL) &&
+ (overlay->hwdata->channel->uplane1 == NULL) &&
+ (overlay->hwdata->channel->vplane1 == NULL))
+ {
+ SDL_FreeYUVOverlay(overlay);
+ SDL_SetError("PgConfigScaler() returns all planes equal NULL\n");
+ return NULL;
+ }
+/*
overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
- if(overlay->hwdata->current==0)
+ if (overlay->hwdata->current==0)
+ {
overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
+ }
else
+ {
overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
+ }
+*/
+ overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
+/*
overlay->hwdata->locked = 1;
+*/
/* Find the pitch and offset values for the overlay */
overlay->planes = planes;
@@ -279,29 +277,36 @@
overlay->hwdata->scaler_on = 0;
overlay->hw_overlay = 1;
- return (overlay);
+ current_overlay=overlay;
+
+ return overlay;
}
-int ph_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
+int ph_LockYUVOverlay(_THIS, SDL_Overlay* overlay)
{
if (overlay == NULL)
+ {
return 0;
-
- overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
- if (overlay->hwdata->current == -1)
- {
- SDL_SetError("PgNextFrame failed, bailing out\n");
- SDL_FreeYUVOverlay(overlay);
- return(NULL);
}
overlay->hwdata->locked = 1;
- /* set current frame for double buffering */
+/* overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
+ if (overlay->hwdata->current == -1)
+ {
+ SDL_SetError("ph_LockYUVOverlay: PgNextFrame() failed, bailing out\n");
+ SDL_FreeYUVOverlay(overlay);
+ return 0;
+ }
+
if (overlay->hwdata->current == 0)
+ {
overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
+ }
else
+ {
overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
+ }
if (overlay->planes > 0)
{
@@ -318,67 +323,83 @@
overlay->pitches[2] = overlay->hwdata->channel->vplane1->pitch;
overlay->pixels[2] = overlay->hwdata->CurrentFrameData->V;
}
+*/
return(0);
}
-void ph_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
+void ph_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay)
{
- int rtncode;
-
- if(overlay == NULL)
- return;
-
- if(overlay->hwdata->scaler_on == 1)
+ if (overlay == NULL)
{
- rtncode =PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));
- switch(rtncode)
- {
- case -1:
- SDL_SetError("PgConfigScalerChannel failed\n");
- SDL_FreeYUVOverlay(overlay);
- break;
- case 1:
- grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
- break;
- case 0:
- default:
- break;
- }
+ return;
}
- /* This would be the best place to draw chromakey but we do not have a SDL_Surface in the args
- * This means we might see a chromakey flicker at startup. */
+ overlay->hwdata->locked = 0;
}
-int ph_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect)
+int ph_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* dstrect)
{
int rtncode;
PhPoint_t pos;
+ SDL_Rect backrect;
+ PhRect_t windowextent;
+ int winchanged=0;
- if(overlay == NULL)
+ if ((overlay == NULL) || (overlay->hwdata==NULL))
+ {
+ return -1;
+ }
+
+ if (overlay->hwdata->State == OVERLAY_STATE_UNINIT)
+ {
return -1;
+ }
+
+ PtGetAbsPosition(window, &pos.x, &pos.y);
+ if ((pos.x!=overlay->hwdata->CurrentWindowPos.x) ||
+ (pos.y!=overlay->hwdata->CurrentWindowPos.y))
+ {
+ winchanged=1;
+ overlay->hwdata->CurrentWindowPos.x=pos.x;
+ overlay->hwdata->CurrentWindowPos.y=pos.y;
+ }
- /* If CurrentWindow has change, move the viewport */
- if((overlay->hwdata->CurrentWindow.pos.x != dstrect->x) ||
- (overlay->hwdata->CurrentWindow.pos.y != dstrect->y) ||
- (overlay->hwdata->CurrentWindow.size.w != dstrect->w) ||
- (overlay->hwdata->CurrentWindow.size.h != dstrect->h) ||
- (overlay->hwdata->scaler_on==0))
+ /* If CurrentViewPort position/size has been changed, then move/resize the viewport */
+ if ((overlay->hwdata->CurrentViewPort.pos.x != dstrect->x) ||
+ (overlay->hwdata->CurrentViewPort.pos.y != dstrect->y) ||
+ (overlay->hwdata->CurrentViewPort.size.w != dstrect->w) ||
+ (overlay->hwdata->CurrentViewPort.size.h != dstrect->h) ||
+ (overlay->hwdata->scaler_on==0) || (winchanged==1) ||
+ (overlay->hwdata->forcedredraw==1))
{
- if(overlay->hwdata->State == OVERLAY_STATE_UNINIT)
- return -1;
+
+ if (overlay->hwdata->ischromakey==1)
+ {
+ /* restore screen behind the overlay/chroma color. */
+ backrect.x=overlay->hwdata->CurrentViewPort.pos.x;
+ backrect.y=overlay->hwdata->CurrentViewPort.pos.y;
+ backrect.w=overlay->hwdata->CurrentViewPort.size.w;
+ backrect.h=overlay->hwdata->CurrentViewPort.size.h;
+ this->UpdateRects(this, 1, &backrect);
+
+ /* Draw the new rectangle of the chroma color at the viewport position */
+ PgSetFillColor(overlay->hwdata->chromakey);
+ PgDrawIRect(dstrect->x, dstrect->y, dstrect->x+dstrect->w-1, dstrect->y+dstrect->h-1, Pg_DRAW_FILL);
+ PgFlush();
+ }
overlay->hwdata->props.flags |= Pg_SCALER_PROP_SCALER_ENABLE;
overlay->hwdata->scaler_on = 1;
- PtGetAbsPosition(window, &pos.x, &pos.y);
- overlay->hwdata->CurrentWindow.pos.x = pos.x + dstrect->x;
- overlay->hwdata->CurrentWindow.pos.y = pos.y + dstrect->y;
- overlay->hwdata->CurrentWindow.size.w = dstrect->w;
- overlay->hwdata->CurrentWindow.size.h = dstrect->h;
-
- PhAreaToRect(&overlay->hwdata->CurrentWindow, &overlay->hwdata->props.viewport);
+ PhWindowQueryVisible(Ph_QUERY_CONSOLE, 0, PtWidgetRid(window), &windowextent);
+ overlay->hwdata->CurrentViewPort.pos.x = pos.x-windowextent.ul.x+dstrect->x;
+ overlay->hwdata->CurrentViewPort.pos.y = pos.y-windowextent.ul.y+dstrect->y;
+ overlay->hwdata->CurrentViewPort.size.w = dstrect->w;
+ overlay->hwdata->CurrentViewPort.size.h = dstrect->h;
+ PhAreaToRect(&overlay->hwdata->CurrentViewPort, &overlay->hwdata->props.viewport);
+ overlay->hwdata->CurrentViewPort.pos.x = dstrect->x;
+ overlay->hwdata->CurrentViewPort.pos.y = dstrect->y;
rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));
@@ -397,19 +418,26 @@
}
}
- if (!overlay->hwdata->locked)
+
+/*
+ if (overlay->hwdata->locked==0)
{
overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
if (overlay->hwdata->current == -1)
{
- SDL_SetError("PgNextVideoFrame failed\n");
+ SDL_SetError("ph_LockYUVOverlay: PgNextFrame() failed, bailing out\n");
SDL_FreeYUVOverlay(overlay);
return 0;
}
+
if (overlay->hwdata->current == 0)
+ {
overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
+ }
else
+ {
overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
+ }
if (overlay->planes > 0)
{
@@ -427,17 +455,33 @@
overlay->pixels[2] = overlay->hwdata->CurrentFrameData->V;
}
}
+*/
return 0;
}
void ph_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
{
+ SDL_Rect backrect;
+
if (overlay == NULL)
+ {
return;
+ }
if (overlay->hwdata == NULL)
+ {
return;
+ }
+
+ current_overlay=NULL;
+
+ /* restore screen behind the overlay/chroma color. */
+ backrect.x=overlay->hwdata->CurrentViewPort.pos.x;
+ backrect.y=overlay->hwdata->CurrentViewPort.pos.y;
+ backrect.w=overlay->hwdata->CurrentViewPort.size.w;
+ backrect.h=overlay->hwdata->CurrentViewPort.size.h;
+ this->UpdateRects(this, 1, &backrect);
/* it is need for some buggy drivers, that can't hide overlay before */
/* freeing buffer, so we got trash on the srceen */
--- a/src/video/photon/SDL_phyuv_c.h Mon Jul 28 01:47:55 2003 +0000
+++ b/src/video/photon/SDL_phyuv_c.h Mon Aug 04 00:52:42 2003 +0000
@@ -25,13 +25,37 @@
"@(#) $Id$";
#endif
-/* This is the XFree86 Xv extension implementation of YUV video overlays */
+/* This is the photon implementation of YUV video overlays */
#include "SDL_video.h"
#include "SDL_ph_video.h"
-extern SDL_Overlay *ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display);
-extern int ph_LockYUVOverlay(_THIS, SDL_Overlay *overlay);
-extern void ph_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay);
-extern int ph_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect);
-extern void ph_FreeYUVOverlay(_THIS, SDL_Overlay *overlay);
+struct private_yuvhwdata
+{
+ FRAMEDATA* CurrentFrameData;
+ FRAMEDATA* FrameData0;
+ FRAMEDATA* FrameData1;
+ PgScalerProps_t props;
+ PgScalerCaps_t caps;
+ PgVideoChannel_t* channel;
+ PhArea_t CurrentViewPort;
+ PhPoint_t CurrentWindowPos;
+ long format;
+ int scaler_on;
+ int current;
+ long YStride;
+ long VStride;
+ long UStride;
+ int ischromakey;
+ long chromakey;
+ int forcedredraw;
+ unsigned long State;
+ long flags;
+ int locked;
+};
+
+extern SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface* display);
+extern int ph_LockYUVOverlay(_THIS, SDL_Overlay* overlay);
+extern void ph_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay);
+extern int ph_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* dstrect);
+extern void ph_FreeYUVOverlay(_THIS, SDL_Overlay* overlay);
--- a/test/testsprite.c Mon Jul 28 01:47:55 2003 +0000
+++ b/test/testsprite.c Mon Aug 04 00:52:42 2003 +0000
@@ -54,10 +54,6 @@
void MoveSprites(SDL_Surface *screen, Uint32 background)
{
-#if DEBUG_FLIP
- static int t = 0;
-#endif
-
int i, nupdates;
SDL_Rect area, *position, *velocity;
@@ -90,15 +86,19 @@
#if DEBUG_FLIP
{
- Uint32 color = SDL_MapRGB (screen->format, 255, 0, 0);
- SDL_Rect r;
- r.x = (sin((float)t * 2 * 3.1459) + 1.0) / 2.0 * (screen->w-20);
- r.y = 0;
- r.w = 20;
- r.h = screen->h;
+ if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
+ static int t = 0;
+
+ Uint32 color = SDL_MapRGB (screen->format, 255, 0, 0);
+ SDL_Rect r;
+ r.x = (sin((float)t * 2 * 3.1459) + 1.0) / 2.0 * (screen->w-20);
+ r.y = 0;
+ r.w = 20;
+ r.h = screen->h;
- SDL_FillRect (screen, &r, color);
- t+=2;
+ SDL_FillRect (screen, &r, color);
+ t+=2;
+ }
}
#endif