From a855d6202536ff28e5aae4f22a0f31d8f5b325d0 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Sat, 21 Jan 2017 15:18:31 -0500 Subject: Port of Duke Nukem 3D This ports Fabien Sanglard's Chocolate Duke to run on a version of SDL for Rockbox. Change-Id: I8f2c4c78af19de10c1633ed7bb7a997b43256dd9 --- apps/plugins/sdl/src/video/fbcon/SDL_fbriva.c | 222 ++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 apps/plugins/sdl/src/video/fbcon/SDL_fbriva.c (limited to 'apps/plugins/sdl/src/video/fbcon/SDL_fbriva.c') diff --git a/apps/plugins/sdl/src/video/fbcon/SDL_fbriva.c b/apps/plugins/sdl/src/video/fbcon/SDL_fbriva.c new file mode 100644 index 0000000000..eb4b71f1bb --- /dev/null +++ b/apps/plugins/sdl/src/video/fbcon/SDL_fbriva.c @@ -0,0 +1,222 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_video.h" +#include "../SDL_blit.h" +#include "SDL_fbriva.h" +#include "riva_mmio.h" +#include "riva_regs.h" + + +static int FifoEmptyCount = 0; +static int FifoFreeCount = 0; + +/* Wait for vertical retrace */ +static void WaitVBL(_THIS) +{ + volatile Uint8 *port = (Uint8 *)(mapped_io + PCIO_OFFSET + 0x3DA); + + while ( (*port & 0x08) ) + ; + while ( !(*port & 0x08) ) + ; +} +static void NV3WaitIdle(_THIS) +{ + RivaRop *Rop = (RivaRop *)(mapped_io + ROP_OFFSET); + while ( (Rop->FifoFree < FifoEmptyCount) || + (*(mapped_io + PGRAPH_OFFSET + 0x000006B0) & 0x01) ) + ; +} +static void NV4WaitIdle(_THIS) +{ + RivaRop *Rop = (RivaRop *)(mapped_io + ROP_OFFSET); + while ( (Rop->FifoFree < FifoEmptyCount) || + (*(mapped_io + PGRAPH_OFFSET + 0x00000700) & 0x01) ) + ; +} + +#if 0 /* Not yet implemented? */ +/* Sets video mem colorkey and accelerated blit function */ +static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key) +{ + return(0); +} + +/* Sets per surface hardware alpha value */ +static int SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 value) +{ + return(0); +} +#endif /* Not yet implemented */ + +static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) +{ + int dstX, dstY; + int dstW, dstH; + RivaBitmap *Bitmap = (RivaBitmap *)(mapped_io + BITMAP_OFFSET); + + /* Don't blit to the display surface when switched away */ + if ( switched_away ) { + return -2; /* no hardware access */ + } + if ( dst == this->screen ) { + SDL_mutexP(hw_lock); + } + + /* Set up the X/Y base coordinates */ + dstW = rect->w; + dstH = rect->h; + FB_dst_to_xy(this, dst, &dstX, &dstY); + + /* Adjust for the current rectangle */ + dstX += rect->x; + dstY += rect->y; + + RIVA_FIFO_FREE(Bitmap, 1); + Bitmap->Color1A = color; + + RIVA_FIFO_FREE(Bitmap, 2); + Bitmap->UnclippedRectangle[0].TopLeft = (dstX << 16) | dstY; + Bitmap->UnclippedRectangle[0].WidthHeight = (dstW << 16) | dstH; + + FB_AddBusySurface(dst); + + if ( dst == this->screen ) { + SDL_mutexV(hw_lock); + } + return(0); +} + +static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + SDL_VideoDevice *this = current_video; + int srcX, srcY; + int dstX, dstY; + int dstW, dstH; + RivaScreenBlt *Blt = (RivaScreenBlt *)(mapped_io + BLT_OFFSET); + + /* FIXME: For now, only blit to display surface */ + if ( dst->pitch != SDL_VideoSurface->pitch ) { + return(src->map->sw_blit(src, srcrect, dst, dstrect)); + } + + /* Don't blit to the display surface when switched away */ + if ( switched_away ) { + return -2; /* no hardware access */ + } + if ( dst == this->screen ) { + SDL_mutexP(hw_lock); + } + + /* Calculate source and destination base coordinates (in pixels) */ + dstW = dstrect->w; + dstH = dstrect->h; + FB_dst_to_xy(this, src, &srcX, &srcY); + FB_dst_to_xy(this, dst, &dstX, &dstY); + + /* Adjust for the current blit rectangles */ + srcX += srcrect->x; + srcY += srcrect->y; + dstX += dstrect->x; + dstY += dstrect->y; + + RIVA_FIFO_FREE(Blt, 3); + Blt->TopLeftSrc = (srcY << 16) | srcX; + Blt->TopLeftDst = (dstY << 16) | dstX; + Blt->WidthHeight = (dstH << 16) | dstW; + + FB_AddBusySurface(src); + FB_AddBusySurface(dst); + + if ( dst == this->screen ) { + SDL_mutexV(hw_lock); + } + return(0); +} + +static int CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst) +{ + int accelerated; + + /* Set initial acceleration on */ + src->flags |= SDL_HWACCEL; + + /* Set the surface attributes */ + if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { + if ( ! this->info.blit_hw_A ) { + src->flags &= ~SDL_HWACCEL; + } + } + if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { + if ( ! this->info.blit_hw_CC ) { + src->flags &= ~SDL_HWACCEL; + } + } + + /* Check to see if final surface blit is accelerated */ + accelerated = !!(src->flags & SDL_HWACCEL); + if ( accelerated ) { + src->map->hw_blit = HWAccelBlit; + } + return(accelerated); +} + +void FB_RivaAccel(_THIS, __u32 card) +{ + RivaRop *Rop = (RivaRop *)(mapped_io + ROP_OFFSET); + + /* We have hardware accelerated surface functions */ + this->CheckHWBlit = CheckHWBlit; + wait_vbl = WaitVBL; + switch (card) { + case FB_ACCEL_NV3: + wait_idle = NV3WaitIdle; + break; + case FB_ACCEL_NV4: + wait_idle = NV4WaitIdle; + break; + default: + /* Hmm... FIXME */ + break; + } + FifoEmptyCount = Rop->FifoFree; + + /* The Riva has an accelerated color fill */ + this->info.blit_fill = 1; + this->FillHWRect = FillHWRect; + + /* The Riva has accelerated normal and colorkey blits. */ + this->info.blit_hw = 1; +#if 0 /* Not yet implemented? */ + this->info.blit_hw_CC = 1; + this->SetHWColorKey = SetHWColorKey; +#endif + +#if 0 /* Not yet implemented? */ + /* The Riva has an accelerated alpha blit */ + this->info.blit_hw_A = 1; + this->SetHWAlpha = SetHWAlpha; +#endif +} -- cgit v1.2.3