diff --git a/README.QNX b/README.QNX index 91a477837..2b4992e8e 100644 --- a/README.QNX +++ b/README.QNX @@ -1,5 +1,5 @@ README by Mike Gorchak , -Last changed at 30 Sep 2003. +Last changed at 14 Feb 2004. ====================================================================== Table of Contents: @@ -13,7 +13,7 @@ Table of Contents: 7. Environment variables. ====================================================================== -OpenGL: +1. OpenGL: OpenGL works well and is stable, but fullscreen mode has not been heavily tested yet. @@ -34,7 +34,7 @@ line in the ph_SetupOpenGLContext() function or change the argument to PHOGL_ATTRIB_FORCE_HW or PHOGL_ATTRIB_FAVOR_HW. ====================================================================== -Wheel and multi-button mouses: +2. Wheel and multi-button mouses: Photon emits keyboard events (key up and down) when the mouse wheel is moved. The key_scan field appears valid, and it contains zero. @@ -54,14 +54,14 @@ I've tested it on: front, but works not with any window, looks like bug-o-feature :). ====================================================================== -CDROM handling issues: +3. CDROM handling issues: Access to CDROM can only be provided with 'root' privileges. I can't do anything about that, /dev/cd0 has brw------- permissions and root:root rights. ====================================================================== -Hardware video overlays: +4. Hardware video overlays: Overlays can flicker during window movement, resizing, etc. It happens because the photon driver updates the real window contents be- @@ -82,20 +82,20 @@ smaller). It's really strange, looks like the overlay doesn't like negative coordinates. ======================================================================= -Shared library building: +5. Shared library building: A shared library can be built, but before running the autogen.sh script you must manually delete the libtool.m4 stuff from the acinclu- de.m4 file (it comes after the ESD detection code up to the end of the -file), because the libtool stuff in the acinclude.m4 file is very old -in SDL distribution before the version 1.2.7 and doesn't know anything +file), because the libtool stuff in the acinclude.m4 file was very old +in SDL distribution before the version 1.2.7 and doesn't knew anything about QNX. SDL 1.2.7 distribution contain the new libtool.m4 script, but anyway it is broken :), Just remove it, then run "libtoolize --force --copy", delete the file aclocal.m4 and after that run the autogen.sh script. ====================================================================== -Some building issues: +6. Some building issues: Feel free to not use the --disable-shared configure option if you' ve read the above comment about 'Shared library building'. Otherwise @@ -123,11 +123,16 @@ x11 support, e.g.: --prefix=/usr --without-x ====================================================================== -Environment variables: +7. Environment variables: Please note that the photon driver is sensible to the following environmental variables: + * SDL_PHOTON_FULLSCREEN_REFRESH - this environment variable controls +the refresh rate in all fullscreen modes. Be carefull !!! Photon drivers +usually do not checking the maximum refresh rate, which video adapter or +monitor supports. + * SDL_VIDEO_WINDOW_POS - can be set in the "X,Y" format. If X and Y coordinates are bigger than the current desktop resolution, then win- dow positioning across virtual consoles is activated. If X and Y are diff --git a/src/video/photon/SDL_ph_events.c b/src/video/photon/SDL_ph_events.c index 6dedbb166..18feb13f7 100644 --- a/src/video/photon/SDL_ph_events.c +++ b/src/video/photon/SDL_ph_events.c @@ -47,17 +47,13 @@ static char rcsid = #include "SDL_ph_events_c.h" #include "SDL_phyuv_c.h" - - /* The translation tables from a photon keysym to a SDL keysym */ static SDLKey ODD_keymap[256]; static SDLKey MISC_keymap[0xFF + 1]; SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym); /* Check to see if this is a repeated key. - (idea shamelessly lifted from GII -- thanks guys! :) - */ - + (idea shamelessly lifted from GII -- thanks guys! :) */ static int ph_WarpedMotion(_THIS, PhEvent_t *winEvent) { PhRect_t *rect = PhGetRects( winEvent ); @@ -117,8 +113,6 @@ static Uint8 ph2sdl_mousebutton(unsigned short button_state) return (mouse_button); } -// void* PtAppCreateContext(); - static int ph_DispatchEvent(_THIS) { int posted; @@ -127,7 +121,7 @@ static int ph_DispatchEvent(_THIS) PhKeyEvent_t* keyEvent; PhWindowEvent_t* winEvent; int i, buttons; - SDL_Rect sdlrects[50]; + SDL_Rect sdlrects[PH_SDL_MAX_RECTS]; posted = 0; @@ -217,12 +211,12 @@ static int ph_DispatchEvent(_THIS) set_motion_sensitivity(this, -1); posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); } - /* quit request */ + /* request quit */ else if (winEvent->event_f==Ph_WM_CLOSE) { posted = SDL_PrivateQuit(); } - /* hide/unhide request */ + /* request hide/unhide */ else if (winEvent->event_f==Ph_WM_HIDE) { if (currently_hided) @@ -287,9 +281,16 @@ static int ph_DispatchEvent(_THIS) { if (event->num_rects!=0) { + int numrects; + if (SDL_VideoSurface) { rect = PhGetRects(event); + if (event->num_rects>PH_SDL_MAX_RECTS) + { + /* sorry, buffers underrun, we'll update only first PH_SDL_MAX_RECTS rects */ + numrects=PH_SDL_MAX_RECTS; + } for(i=0; inum_rects; i++) { @@ -368,6 +369,32 @@ static int ph_DispatchEvent(_THIS) case Ph_EV_INFO: { + if (event->subtype==Ph_OFFSCREEN_INVALID) + { + unsigned long* EvInfoData; + + EvInfoData=(unsigned long*)PhGetData(event); + + switch (*EvInfoData) + { + case Pg_VIDEO_MODE_SWITCHED: + { + } + break; + case Pg_ENTERED_DIRECT: + { + } + break; + case Pg_EXITED_DIRECT: + { + } + break; + case Pg_DRIVER_STARTED: + { + } + break; + } + } } break; } @@ -387,10 +414,9 @@ int ph_Pending(_THIS) { case Ph_EVENT_MSG: return 1; - break; case -1: - perror("ph_Pending(): PhEventNext failed"); - break; + SDL_SetError("ph_Pending(): PhEventNext failed.\n"); + return 0; default: return 0; } diff --git a/src/video/photon/SDL_ph_events_c.h b/src/video/photon/SDL_ph_events_c.h index 4c048e3e8..de80a7149 100644 --- a/src/video/photon/SDL_ph_events_c.h +++ b/src/video/photon/SDL_ph_events_c.h @@ -30,7 +30,9 @@ static char rcsid = #include "SDL_ph_video.h" -#define EVENT_SIZE sizeof(PhEvent_t) + 1000 +#define PH_SDL_MAX_RECTS 256 +#define PH_EVENT_SAFETY_POOL 512 +#define EVENT_SIZE (sizeof(PhEvent_t) + 1000 + PH_EVENT_SAFETY_POOL) /* Functions to be exported */ extern void ph_InitOSKeymap(_THIS); diff --git a/src/video/photon/SDL_ph_image.c b/src/video/photon/SDL_ph_image.c index d7de71033..ff69a0288 100644 --- a/src/video/photon/SDL_ph_image.c +++ b/src/video/photon/SDL_ph_image.c @@ -164,7 +164,7 @@ int ph_SetupOCImage(_THIS, SDL_Surface *screen) screen->pitch = OCImage.offscreen_context->pitch; - OCImage.dc_ptr = (unsigned char *) PdGetOffscreenContextPtr(OCImage.offscreen_context); + OCImage.dc_ptr = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_context); if (OCImage.dc_ptr == NULL) { @@ -212,7 +212,7 @@ int ph_SetupFullScreenImage(_THIS, SDL_Surface* screen) if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) { - OCImage.offscreen_backcontext = PdDupOffscreenContext(OCImage.offscreen_context, Pg_OSC_CRTC_SAFE | Pg_OSC_MEM_PAGE_ALIGN); + OCImage.offscreen_backcontext = PdDupOffscreenContext(OCImage.offscreen_context, Pg_OSC_MEM_PAGE_ALIGN | Pg_OSC_CRTC_SAFE); if (OCImage.offscreen_backcontext == NULL) { SDL_SetError("ph_SetupFullScreenImage(): PdCreateOffscreenContext(back) function failed !\n"); @@ -240,15 +240,32 @@ int ph_SetupFullScreenImage(_THIS, SDL_Surface* screen) } /* wait for the hardware */ + PgFlush(); PgWaitHWIdle(); 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); + OCImage.current = 0; + PhDCSetCurrent(OCImage.offscreen_context); + screen->pitch = OCImage.offscreen_context->pitch; + screen->pixels = OCImage.FrameData0; + + /* emulate 640x400 videomode */ + if (videomode_emulatemode==1) + { + int i; + + for (i=0; i<40; i++) + { + memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch); + } + for (i=440; i<480; i++) + { + memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch); + } + screen->pixels+=screen->pitch*40; + } + PgSwapDisplay(OCImage.offscreen_backcontext, 0); } else { @@ -256,11 +273,29 @@ int ph_SetupFullScreenImage(_THIS, SDL_Surface* screen) PhDCSetCurrent(OCImage.offscreen_context); screen->pitch = OCImage.offscreen_context->pitch; screen->pixels = OCImage.FrameData0; + + /* emulate 640x400 videomode */ + if (videomode_emulatemode==1) + { + int i; + + for (i=0; i<40; i++) + { + memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch); + } + for (i=440; i<480; i++) + { + memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch); + } + screen->pixels+=screen->pitch*40; + } } this->UpdateRects = ph_OCDCUpdate; + /* wait for the hardware */ PgFlush(); + PgWaitHWIdle(); return 0; } @@ -427,75 +462,497 @@ void ph_DestroyImage(_THIS, SDL_Surface* screen) } } +int ph_UpdateHWInfo(_THIS) +{ + PgVideoModeInfo_t vmode; + PgHWCaps_t hwcaps; + + /* Update video ram amount */ + if (PgGetGraphicsHWCaps(&hwcaps) < 0) + { + SDL_SetError("ph_UpdateHWInfo(): GetGraphicsHWCaps() function failed !\n"); + return -1; + } + this->info.video_mem=hwcaps.currently_available_video_ram/1024; + + /* obtain current mode capabilities */ + if (PgGetVideoModeInfo(hwcaps.current_video_mode, &vmode) < 0) + { + SDL_SetError("ph_UpdateHWInfo(): GetVideoModeInfo() function failed !\n"); + return -1; + } + + this->info.blit_hw = 1; + + if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_ALPHA_BLEND) == PgVM_MODE_CAP2_ALPHA_BLEND) + { + this->info.blit_hw_A = 1; + } + else + { + this->info.blit_hw_A = 0; + } + + if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_CHROMA) == PgVM_MODE_CAP2_CHROMA) + { + this->info.blit_hw_CC = 1; + } + else + { + this->info.blit_hw_CC = 0; + } + + return 0; +} + int ph_SetupUpdateFunction(_THIS, SDL_Surface* screen, Uint32 flags) { + int setupresult=-1; + ph_DestroyImage(this, screen); #ifdef HAVE_OPENGL if ((flags & SDL_OPENGL)==SDL_OPENGL) { - return ph_SetupOpenGLImage(this, screen); + setupresult=ph_SetupOpenGLImage(this, screen); + } + else + { +#endif /* HAVE_OPENGL */ + if ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN) + { + setupresult=ph_SetupFullScreenImage(this, screen); + } + else + { + if ((flags & SDL_HWSURFACE)==SDL_HWSURFACE) + { + setupresult=ph_SetupOCImage(this, screen); + } + else + { + setupresult=ph_SetupImage(this, screen); + } + } +#ifdef HAVE_OPENGL } #endif /* HAVE_OPENGL */ - if ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN) + if (setupresult!=-1) { - return ph_SetupFullScreenImage(this, screen); + ph_UpdateHWInfo(this); } - if ((flags & SDL_HWSURFACE)==SDL_HWSURFACE) - { - return ph_SetupOCImage(this, screen); - } - - return ph_SetupImage(this, screen); + + return setupresult; } int ph_AllocHWSurface(_THIS, SDL_Surface* surface) { - return(-1); + PgHWCaps_t hwcaps; + + if (surface->hwdata!=NULL) + { + SDL_SetError("ph_AllocHWSurface(): hwdata already exists!\n"); + return -1; + } + surface->hwdata=malloc(sizeof(struct private_hwdata)); + memset(surface->hwdata, 0x00, sizeof(struct private_hwdata)); + surface->hwdata->offscreenctx=PdCreateOffscreenContext(0, surface->w, surface->h, Pg_OSC_MEM_PAGE_ALIGN); + if (surface->hwdata->offscreenctx == NULL) + { + SDL_SetError("ph_AllocHWSurface(): PdCreateOffscreenContext() function failed !\n"); + return -1; + } + surface->pixels=PdGetOffscreenContextPtr(surface->hwdata->offscreenctx); + if (surface->pixels==NULL) + { + PhDCRelease(surface->hwdata->offscreenctx); + SDL_SetError("ph_AllocHWSurface(): PdGetOffscreenContextPtr() function failed !\n"); + return -1; + } + surface->pitch=surface->hwdata->offscreenctx->pitch; + surface->flags|=SDL_HWSURFACE; + surface->flags|=SDL_PREALLOC; + +#if 0 /* FIXME */ + /* create simple offscreen lock */ + surface->hwdata->crlockparam.flags=0; + if (PdCreateOffscreenLock(surface->hwdata->offscreenctx, &surface->hwdata->crlockparam)!=EOK) + { + PhDCRelease(surface->hwdata->offscreenctx); + SDL_SetError("ph_AllocHWSurface(): Can't create offscreen lock !\n"); + return -1; + } +#endif /* 0 */ + + /* Update video ram amount */ + if (PgGetGraphicsHWCaps(&hwcaps) < 0) + { + PdDestroyOffscreenLock(surface->hwdata->offscreenctx); + PhDCRelease(surface->hwdata->offscreenctx); + SDL_SetError("ph_AllocHWSurface(): GetGraphicsHWCaps() function failed !\n"); + return -1; + } + this->info.video_mem=hwcaps.currently_available_video_ram/1024; + + return 0; } void ph_FreeHWSurface(_THIS, SDL_Surface* surface) { + PgHWCaps_t hwcaps; + + if (surface->hwdata==NULL) + { + SDL_SetError("ph_FreeHWSurface(): no hwdata!\n"); + return; + } + if (surface->hwdata->offscreenctx == NULL) + { + SDL_SetError("ph_FreeHWSurface(): no offscreen context to delete!\n"); + return; + } + +#if 0 /* FIXME */ + /* unlock the offscreen context if it has been locked before destroy it */ + if (PdIsOffscreenLocked(surface->hwdata->offscreenctx)==Pg_OSC_LOCKED) + { + PdUnlockOffscreen(surface->hwdata->offscreenctx); + } + + PdDestroyOffscreenLock(surface->hwdata->offscreenctx); +#endif /* 0 */ + + PhDCRelease(surface->hwdata->offscreenctx); + + free(surface->hwdata); + surface->hwdata=NULL; + + /* Update video ram amount */ + if (PgGetGraphicsHWCaps(&hwcaps) < 0) + { + SDL_SetError("ph_FreeHWSurface(): GetGraphicsHWCaps() function failed !\n"); + return; + } + this->info.video_mem=hwcaps.currently_available_video_ram/1024; + return; } +int ph_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst) +{ + if ((src->hwdata==NULL) && (src != this->screen)) + { + SDL_SetError("ph_CheckHWBlit(): Source surface haven't hardware specific data.\n"); + src->flags&=~SDL_HWACCEL; + return -1; + } + if ((src->flags & SDL_HWSURFACE) != SDL_HWSURFACE) + { + SDL_SetError("ph_CheckHWBlit(): Source surface isn't a hardware surface.\n"); + src->flags&=~SDL_HWACCEL; + return -1; + } + + if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) + { + if (this->info.blit_hw_CC!=1) + { + src->flags&=~SDL_HWACCEL; + src->map->hw_blit=NULL; + return -1; + } + } + + if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA) + { + if (this->info.blit_hw_A!=1) + { + src->flags&=~SDL_HWACCEL; + src->map->hw_blit=NULL; + return -1; + } + } + + src->flags|=SDL_HWACCEL; + src->map->hw_blit = ph_HWAccelBlit; + + return 1; +} + +PgColor_t ph_ExpandColor(_THIS, SDL_Surface* surface, Uint32 color) +{ + Uint32 truecolor; + + /* Photon API accepts true colors only during hw filling operations */ + switch(surface->format->BitsPerPixel) + { + case 8: + { + if ((surface->format->palette) && (color<=surface->format->palette->ncolors)) + { + truecolor=PgRGB(surface->format->palette->colors[color].r, + surface->format->palette->colors[color].g, + surface->format->palette->colors[color].b); + } + else + { + SDL_SetError("ph_ExpandColor(): Color out of range for the 8bpp mode !\n"); + return 0xFFFFFFFFUL; + } + } + break; + case 15: + { + truecolor = ((color & 0x00007C00UL) << 9) | /* R */ + ((color & 0x000003E0UL) << 6) | /* G */ + ((color & 0x0000001FUL) << 3) | /* B */ + ((color & 0x00007000UL) << 4) | /* R compensation */ + ((color & 0x00000380UL) << 1) | /* G compensation */ + ((color & 0x0000001CUL) >> 2); /* B compensation */ + } + break; + case 16: + { + truecolor = ((color & 0x0000F800UL) << 8) | /* R */ + ((color & 0x000007E0UL) << 5) | /* G */ + ((color & 0x0000001FUL) << 3) | /* B */ + ((color & 0x0000E000UL) << 3) | /* R compensation */ + ((color & 0x00000600UL) >> 1) | /* G compensation */ + ((color & 0x0000001CUL) >> 2); /* B compensation */ + + } + break; + case 24: + { + truecolor=color & 0x00FFFFFFUL; + } + break; + case 32: + { + truecolor=color; + } + break; + default: + { + SDL_SetError("ph_ExpandColor(): Unsupported depth for the hardware operations !\n"); + return 0xFFFFFFFFUL; + } + } + + return truecolor; +} + +int ph_FillHWRect(_THIS, SDL_Surface* surface, SDL_Rect* rect, Uint32 color) +{ + PgColor_t oldcolor; + Uint32 truecolor; + int ydisp=0; + + truecolor=ph_ExpandColor(this, surface, color); + if (truecolor==0xFFFFFFFFUL) + { + return -1; + } + + oldcolor=PgSetFillColor(truecolor); + + /* 640x400 videomode emulation */ + if (videomode_emulatemode==1) + { + ydisp+=40; + } + + PgDrawIRect(rect->x, rect->y+ydisp, rect->w+rect->x-1, rect->h+rect->y+ydisp-1, Pg_DRAW_FILL); + PgSetFillColor(oldcolor); + PgFlush(); + PgWaitHWIdle(); + + return 0; +} + int ph_FlipHWSurface(_THIS, SDL_Surface* screen) { + PhArea_t farea; + if ((screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) { + /* flush all drawing ops before blitting */ + PgFlush(); PgWaitHWIdle(); - if (OCImage.current==0) + + farea.pos.x=0; + farea.pos.y=0; + farea.size.w=screen->w; + farea.size.h=screen->h; + + /* emulate 640x400 videomode */ + if (videomode_emulatemode==1) { - PgSwapDisplay(OCImage.offscreen_context, 0); - OCImage.current=1; - screen->pitch = OCImage.offscreen_backcontext->pitch; - screen->pixels = OCImage.FrameData1; - PhDCSetCurrent(OCImage.offscreen_backcontext); - PgFlush(); - } - else - { - PgSwapDisplay(OCImage.offscreen_backcontext, 0); - OCImage.current=0; - screen->pitch = OCImage.offscreen_context->pitch; - screen->pixels = OCImage.FrameData0; - PhDCSetCurrent(OCImage.offscreen_context); - PgFlush(); + farea.pos.y+=40; } + + PgContextBlitArea(OCImage.offscreen_context, &farea, OCImage.offscreen_backcontext, &farea); + + /* flush the blitting */ + PgFlush(); + PgWaitHWIdle(); } return 0; } -int ph_LockHWSurface(_THIS, SDL_Surface *surface) +int ph_LockHWSurface(_THIS, SDL_Surface* surface) { - return(0); + +#if 0 /* FIXME */ + int lockresult; + + if (surface->hwdata == NULL) + { + return; + } + + surface->hwdata->lockparam.flags=0; + surface->hwdata->lockparam.time_out=NULL; + lockresult=PdLockOffscreen(surface->hwdata->offscreenctx, &surface->hwdata->lockparam); + + switch (lockresult) + { + case EOK: + break; + case Pg_OSC_LOCK_DEADLOCK: + SDL_SetError("ph_LockHWSurface(): Deadlock detected !\n"); + return -1; + case Pg_OSC_LOCK_INVALID: + SDL_SetError("ph_LockHWSurface(): Lock invalid !\n"); + return -1; + default: + SDL_SetError("ph_LockHWSurface(): Can't lock the surface !\n"); + return -1; + } +#endif /* 0 */ + + return 0; } -void ph_UnlockHWSurface(_THIS, SDL_Surface *surface) +void ph_UnlockHWSurface(_THIS, SDL_Surface* surface) { + +#if 0 /* FIXME */ + int unlockresult; + + if ((surface == NULL) || (surface->hwdata == NULL)) + { + return; + } + + if (PdIsOffscreenLocked(surface->hwdata->offscreenctx)==Pg_OSC_LOCKED) + { + unlockresult=PdUnlockOffscreen(surface->hwdata->offscreenctx); + } +#endif /* 0 */ + return; } +int ph_HWAccelBlit(SDL_Surface* src, SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect) +{ + SDL_VideoDevice* this=current_video; + PhArea_t srcarea; + PhArea_t dstarea; + int ydisp=0; + + /* 640x400 videomode emulation */ + if (videomode_emulatemode==1) + { + ydisp+=40; + } + + srcarea.pos.x=srcrect->x; + srcarea.pos.y=srcrect->y; + srcarea.size.w=srcrect->w; + srcarea.size.h=srcrect->h; + + dstarea.pos.x=dstrect->x; + dstarea.pos.y=dstrect->y; + dstarea.size.w=dstrect->w; + dstarea.size.h=dstrect->h; + + if (((src == this->screen) || (src->hwdata!=NULL)) && ((dst == this->screen) || (dst->hwdata!=NULL))) + { + if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) + { + ph_SetHWColorKey(this, src, src->format->colorkey); + PgChromaOn(); + } + + if (dst == this->screen) + { + if (src == this->screen) + { + /* blitting from main screen to main screen */ + dstarea.pos.y+=ydisp; + srcarea.pos.y+=ydisp; + PgContextBlitArea(OCImage.offscreen_context, &srcarea, OCImage.offscreen_context, &dstarea); + } + else + { + /* blitting from offscreen to main screen */ + dstarea.pos.y+=ydisp; + PgContextBlitArea(src->hwdata->offscreenctx, &srcarea, OCImage.offscreen_context, &dstarea); + } + } + else + { + if (src == this->screen) + { + /* blitting from main screen to offscreen */ + srcarea.pos.y+=ydisp; + PgContextBlitArea(OCImage.offscreen_context, &srcarea, dst->hwdata->offscreenctx, &dstarea); + } + else + { + /* blitting offscreen to offscreen */ + PgContextBlitArea(src->hwdata->offscreenctx, &srcarea, dst->hwdata->offscreenctx, &dstarea); + } + } + + if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) + { + PgChromaOff(); + } + } + else + { + SDL_SetError("ph_HWAccelBlit(): Source or target surface is not a hardware surface !\n"); + return -1; + } + + PgFlush(); + PgWaitHWIdle(); + + return 0; +} + +int ph_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key) +{ + if (surface->hwdata!=NULL) + { + surface->hwdata->colorkey=ph_ExpandColor(this, surface, key); + if (surface->hwdata->colorkey==0xFFFFFFFFUL) + { + return -1; + } + } + PgSetChroma(surface->hwdata->colorkey, Pg_CHROMA_SRC_MATCH | Pg_CHROMA_NODRAW); + + return 0; +} + +int ph_SetHWAlpha(_THIS, SDL_Surface* surface, Uint8 alpha) +{ + return -1; +} + #ifdef HAVE_OPENGL void ph_OpenGLUpdate(_THIS, int numrects, SDL_Rect* rects) { @@ -513,12 +970,12 @@ void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) for (i=0; ih) + { + if ((mode_info.height==480) && (screen->h==400)) + { + videomode_emulatemode=1; + } + } + else + { + videomode_emulatemode=0; + } } /* save old video mode caps */ @@ -266,6 +306,15 @@ int ph_EnterFullScreen(_THIS, SDL_Surface* screen) settings.refresh = 0; settings.flags = 0; + refreshrate=getenv("SDL_PHOTON_FULLSCREEN_REFRESH"); + if (refreshrate!=NULL) + { + if (sscanf(refreshrate, "%d", &refreshratenum)==1) + { + settings.refresh = refreshratenum; + } + } + if (PgSetVideoMode(&settings) < 0) { SDL_SetError("ph_EnterFullScreen(): PgSetVideoMode() call failed !\n"); diff --git a/src/video/photon/SDL_ph_video.c b/src/video/photon/SDL_ph_video.c index ee1e0d206..9356ec9c4 100644 --- a/src/video/photon/SDL_ph_video.c +++ b/src/video/photon/SDL_ph_video.c @@ -68,7 +68,7 @@ static int phstatus=-1; static int ph_Available(void) { - if (phstatus==-1) + if (phstatus!=0) { phstatus=PtInit(NULL); if (phstatus==0) @@ -116,10 +116,10 @@ static SDL_VideoDevice *ph_CreateDevice(int devindex) device->UpdateRects = NULL; /* set up in ph_SetupUpdateFunction */ device->VideoQuit = ph_VideoQuit; device->AllocHWSurface = ph_AllocHWSurface; - device->CheckHWBlit = NULL; - device->FillHWRect = NULL; - device->SetHWColorKey = NULL; - device->SetHWAlpha = NULL; + device->CheckHWBlit = ph_CheckHWBlit; + device->FillHWRect = ph_FillHWRect; + device->SetHWColorKey = ph_SetHWColorKey; + device->SetHWAlpha = ph_SetHWAlpha; device->LockHWSurface = ph_LockHWSurface; device->UnlockHWSurface = ph_UnlockHWSurface; device->FlipHWSurface = ph_FlipHWSurface; @@ -254,6 +254,14 @@ static int ph_SetupWindow(_THIS, int w, int h, int flags) } else { + if ((flags & SDL_HWSURFACE) == SDL_HWSURFACE) + { + PtSetArg(&args[nargs++], Pt_ARG_BASIC_FLAGS, Pt_TRUE, Pt_BASIC_PREVENT_FILL); + } + else + { + PtSetArg(&args[nargs++], Pt_ARG_FILL_COLOR, Pg_BLACK, 0); + } if (!currently_maximized) { windowpos = getenv("SDL_VIDEO_WINDOW_POS"); @@ -293,8 +301,6 @@ static int ph_SetupWindow(_THIS, int w, int h, int flags) } } - PtSetArg(&args[nargs++], Pt_ARG_FILL_COLOR, Pg_BLACK, 0); - /* if window is maximized render it as maximized */ if (currently_maximized) { @@ -311,7 +317,7 @@ static int ph_SetupWindow(_THIS, int w, int h, int flags) /* bring the focus to the window */ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFOCUS); - /* allow to catch hide events */ + /* allow to catch hide event */ 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); } @@ -320,6 +326,11 @@ static int ph_SetupWindow(_THIS, int w, int h, int flags) PtRealizeWidget(window); PtWindowToFront(window); +#if 0 /* FIXME */ + PtGetResource(window, Pt_ARG_POS, &olddim, 0); + fprintf(stderr, "POSITION: %d, %d\n", olddim->w, olddim->h); +#endif + return 0; } @@ -350,9 +361,9 @@ static const struct ColourMasks* ph_GetColourMasks(int bpp) return NULL; } -static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat) +static int ph_VideoInit(_THIS, SDL_PixelFormat* vformat) { - PgHWCaps_t my_hwcaps; + PgHWCaps_t hwcaps; int i; window=NULL; @@ -391,14 +402,14 @@ static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat) return -1; } - if (PgGetGraphicsHWCaps(&my_hwcaps) < 0) + if (PgGetGraphicsHWCaps(&hwcaps) < 0) { SDL_SetError("ph_VideoInit(): GetGraphicsHWCaps function failed !\n"); this->FreeWMCursor(this, SDL_BlankCursor); return -1; } - if (PgGetVideoModeInfo(my_hwcaps.current_video_mode, &desktop_mode) < 0) + if (PgGetVideoModeInfo(hwcaps.current_video_mode, &desktop_mode) < 0) { SDL_SetError("ph_VideoInit(): PgGetVideoModeInfo function failed !\n"); this->FreeWMCursor(this, SDL_BlankCursor); @@ -437,15 +448,22 @@ static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat) OCImage.CurrentFrameData = NULL; OCImage.FrameData0 = NULL; OCImage.FrameData1 = NULL; + videomode_emulatemode = 0; + this->info.video_mem=hwcaps.currently_available_video_ram/1024; this->info.wm_available = 1; + this->info.hw_available = 1; + this->info.blit_fill = 1; + this->info.blit_hw = 1; + this->info.blit_hw_A = 0; + this->info.blit_hw_CC = 1; return 0; } -static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, - int width, int height, int bpp, Uint32 flags) +static SDL_Surface* ph_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { + PgHWCaps_t hwcaps; const struct ColourMasks* mask; /* Lock the event thread, in multi-threading environments */ @@ -474,13 +492,13 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, return NULL; } -#ifdef HAVE_OPENGL if ((current->flags & SDL_OPENGL)==SDL_OPENGL) { -#else - if ((current->flags & SDL_OPENGL)==SDL_OPENGL) /* if no built-in OpenGL support */ +#if !defined(HAVE_OPENGL) + if ((current->flags & SDL_OPENGL)==SDL_OPENGL) { - SDL_SetError("ph_SetVideoMode(): no OpenGL support, try to recompile library.\n"); + /* if no built-in OpenGL support */ + SDL_SetError("ph_SetVideoMode(): no OpenGL support, you need to recompile SDL.\n"); current->flags &= ~SDL_OPENGL; return NULL; #endif /* HAVE_OPENGL */ @@ -500,13 +518,12 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, } else { - /* remove this if we'll support non-fullscreen sw/hw+doublebuf */ + /* remove this if we'll have support for the non-fullscreen sw/hw+doublebuf one day */ current->flags &= ~SDL_DOUBLEBUF; /* Use offscreen memory if SDL_HWSURFACE flag is set */ if ((current->flags & SDL_HWSURFACE) == SDL_HWSURFACE) { - if (desktopbpp!=bpp) { current->flags &= ~SDL_HWSURFACE; @@ -556,9 +573,18 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, PgFlush(); } + visualbpp=bpp; + + if (PgGetGraphicsHWCaps(&hwcaps) < 0) + { + SDL_SetError("ph_SetVideoMode(): GetGraphicsHWCaps function failed !\n"); + return NULL; + } + this->info.video_mem=hwcaps.currently_available_video_ram/1024; + SDL_Unlock_EventThread(); - /* We're done! */ + /* We've done! */ return (current); } diff --git a/src/video/photon/SDL_ph_video.h b/src/video/photon/SDL_ph_video.h index eb4e85436..49a526a52 100644 --- a/src/video/photon/SDL_ph_video.h +++ b/src/video/photon/SDL_ph_video.h @@ -96,8 +96,9 @@ struct SDL_PrivateVideoData int mouse_relative; WMcursor* BlankCursor; + uint32_t videomode_emulatemode; - Uint32 depth; /* current visual depth (not bpp) */ + Uint32 visualbpp; /* current visual bpp */ Uint32 desktopbpp; /* bpp of desktop at the moment of start */ Uint32 desktoppal; /* palette mode emulation or system */ @@ -109,25 +110,27 @@ struct SDL_PrivateVideoData SDL_Overlay* overlay; }; -#define mode_settings (this->hidden->mode_settings) -#define window (this->hidden->Window) -#define SDL_Image (this->hidden->image) -#define OCImage (this->hidden->ocimage) -#define old_video_mode (this->hidden->old_video_mode) -#define old_refresh_rate (this->hidden->old_refresh_rate) -#define graphics_card_caps (this->hidden->graphics_card_caps) -#define desktopbpp (this->hidden->desktopbpp) -#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 currently_maximized (this->hidden->currently_maximized) -#define event (this->hidden->event) -#define current_overlay (this->hidden->overlay) -#define desktop_mode (this->hidden->desktop_mode) -#define mouse_relative (this->hidden->mouse_relative) -#define SDL_BlankCursor (this->hidden->BlankCursor) +#define mode_settings (this->hidden->mode_settings) +#define window (this->hidden->Window) +#define SDL_Image (this->hidden->image) +#define OCImage (this->hidden->ocimage) +#define old_video_mode (this->hidden->old_video_mode) +#define old_refresh_rate (this->hidden->old_refresh_rate) +#define graphics_card_caps (this->hidden->graphics_card_caps) +#define desktopbpp (this->hidden->desktopbpp) +#define visualbpp (this->hidden->visualbpp) +#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 currently_maximized (this->hidden->currently_maximized) +#define event (this->hidden->event) +#define current_overlay (this->hidden->overlay) +#define desktop_mode (this->hidden->desktop_mode) +#define mouse_relative (this->hidden->mouse_relative) +#define SDL_BlankCursor (this->hidden->BlankCursor) +#define videomode_emulatemode (this->hidden->videomode_emulatemode) #ifdef HAVE_OPENGL #define oglctx (this->hidden->OGLContext) diff --git a/test/testvidinfo.c b/test/testvidinfo.c index 813263ef2..2b4b1d023 100644 --- a/test/testvidinfo.c +++ b/test/testvidinfo.c @@ -27,6 +27,12 @@ void PrintFlags(Uint32 flags) if ( flags & SDL_DOUBLEBUF ) { printf(" | SDL_DOUBLEBUF"); } + if ( flags & SDL_SRCCOLORKEY ) { + printf(" | SDL_SRCCOLORKEY"); + } + if ( flags & SDL_RLEACCEL ) { + printf(" | SDL_RLEACCEL"); + } } int RunBlitTests(SDL_Surface *screen, SDL_Surface *bmp, int blitcount) @@ -67,7 +73,7 @@ int RunModeTests(SDL_Surface *screen) float seconds; int i; Uint8 r, g, b; - SDL_Surface *bmp, *tmp; + SDL_Surface *bmp, *bmpcc, *tmp; SDL_Event event; while ( SDL_PollEvent(&event) ) { @@ -116,6 +122,7 @@ int RunModeTests(SDL_Surface *screen) return 0; } + /* run the generic blit test */ bmp = SDL_LoadBMP("sample.bmp"); if ( ! bmp ) { printf("Couldn't load sample.bmp: %s\n", SDL_GetError()); @@ -135,6 +142,29 @@ int RunModeTests(SDL_Surface *screen) printf("%d blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames); } + /* run the colorkeyed blit test */ + bmpcc = SDL_LoadBMP("sample.bmp"); + if ( ! bmpcc ) { + printf("Couldn't load sample.bmp: %s\n", SDL_GetError()); + return 0; + } + printf("Running freshly loaded cc blit test: %dx%d at %d bpp, flags: ", + bmpcc->w, bmpcc->h, bmpcc->format->BitsPerPixel); + SDL_SetColorKey(bmpcc, SDL_SRCCOLORKEY | SDL_RLEACCEL, *(Uint8 *)bmpcc->pixels); + + PrintFlags(bmpcc->flags); + printf("\n"); + then = SDL_GetTicks(); + frames = RunBlitTests(screen, bmpcc, NUM_BLITS); + now = SDL_GetTicks(); + seconds = (float)(now - then) / 1000.0f; + if ( seconds > 0.0f ) { + printf("%d cc blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds); + } else { + printf("%d cc blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames); + } + + /* run the generic blit test */ tmp = bmp; bmp = SDL_DisplayFormat(bmp); SDL_FreeSurface(tmp); @@ -155,6 +185,30 @@ int RunModeTests(SDL_Surface *screen) } else { printf("%d blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames); } + + /* run the colorkeyed blit test */ + tmp = bmpcc; + bmpcc = SDL_DisplayFormat(bmpcc); + SDL_FreeSurface(tmp); + if ( ! bmpcc ) { + printf("Couldn't convert sample.bmp: %s\n", SDL_GetError()); + return 0; + } + printf("Running display format cc blit test: %dx%d at %d bpp, flags: ", + bmpcc->w, bmpcc->h, bmpcc->format->BitsPerPixel); + PrintFlags(bmpcc->flags); + printf("\n"); + then = SDL_GetTicks(); + frames = RunBlitTests(screen, bmpcc, NUM_BLITS); + now = SDL_GetTicks(); + seconds = (float)(now - then) / 1000.0f; + if ( seconds > 0.0f ) { + printf("%d cc blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds); + } else { + printf("%d cc blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames); + } + + SDL_FreeSurface(bmpcc); SDL_FreeSurface(bmp); while ( SDL_PollEvent(&event) ) {