📄 sdl_blit_n.c
字号:
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id: SDL_blit_N.c,v 1.4 2002/04/22 21:38:03 wmay Exp $";
#endif
#include <stdio.h>
#include "SDL_types.h"
#include "SDL_video.h"
#include "SDL_blit.h"
#include "SDL_byteorder.h"
/* Function to check the CPU flags */
#define MMX_CPU 0x800000
#ifdef USE_ASMBLIT
#define CPU_Flags() Hermes_X86_CPU()
#else
#define CPU_Flags() 0L
#endif
/* Functions to blit from N-bit surfaces to other surfaces */
#ifdef USE_ASMBLIT
/* Heheheh, we coerce Hermes into using SDL blit information */
#define X86_ASSEMBLER
#define HermesConverterInterface SDL_BlitInfo
#define HermesClearInterface void
#define STACKCALL
typedef Uint32 int32;
#include "HeadMMX.h"
#include "HeadX86.h"
#else
/* This is now endian dependent */
#if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
#define HI 1
#define LO 0
#else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
#define HI 0
#define LO 1
#endif
/* Special optimized blit for RGB 8-8-8 --> RGB 3-3-2 */
#define RGB888_RGB332(dst, src) { \
dst = (((src)&0x00E00000)>>16)| \
(((src)&0x0000E000)>>11)| \
(((src)&0x000000C0)>>6); \
}
static void Blit_RGB888_index8(SDL_BlitInfo *info)
{
#ifndef USE_DUFFS_LOOP
int c;
#endif
int width, height;
Uint32 *src;
const Uint8 *map;
Uint8 *dst;
int srcskip, dstskip;
/* Set up some basic variables */
width = info->d_width;
height = info->d_height;
src = (Uint32 *)info->s_pixels;
srcskip = info->s_skip/4;
dst = info->d_pixels;
dstskip = info->d_skip;
map = info->table;
if ( map == NULL ) {
while ( height-- ) {
#ifdef USE_DUFFS_LOOP
DUFFS_LOOP(
RGB888_RGB332(*dst++, *src);
, width);
#else
for ( c=width/4; c; --c ) {
/* Pack RGB into 8bit pixel */
++src;
RGB888_RGB332(*dst++, *src);
++src;
RGB888_RGB332(*dst++, *src);
++src;
RGB888_RGB332(*dst++, *src);
++src;
}
switch ( width & 3 ) {
case 3:
RGB888_RGB332(*dst++, *src);
++src;
case 2:
RGB888_RGB332(*dst++, *src);
++src;
case 1:
RGB888_RGB332(*dst++, *src);
++src;
}
#endif /* USE_DUFFS_LOOP */
src += srcskip;
dst += dstskip;
}
} else {
int pixel;
while ( height-- ) {
#ifdef USE_DUFFS_LOOP
DUFFS_LOOP(
RGB888_RGB332(pixel, *src);
*dst++ = map[pixel];
++src;
, width);
#else
for ( c=width/4; c; --c ) {
/* Pack RGB into 8bit pixel */
RGB888_RGB332(pixel, *src);
*dst++ = map[pixel];
++src;
RGB888_RGB332(pixel, *src);
*dst++ = map[pixel];
++src;
RGB888_RGB332(pixel, *src);
*dst++ = map[pixel];
++src;
RGB888_RGB332(pixel, *src);
*dst++ = map[pixel];
++src;
}
switch ( width & 3 ) {
case 3:
RGB888_RGB332(pixel, *src);
*dst++ = map[pixel];
++src;
case 2:
RGB888_RGB332(pixel, *src);
*dst++ = map[pixel];
++src;
case 1:
RGB888_RGB332(pixel, *src);
*dst++ = map[pixel];
++src;
}
#endif /* USE_DUFFS_LOOP */
src += srcskip;
dst += dstskip;
}
}
}
/* Special optimized blit for RGB 8-8-8 --> RGB 5-5-5 */
#define RGB888_RGB555(dst, src) { \
*(Uint16 *)(dst) = (((*src)&0x00F80000)>>9)| \
(((*src)&0x0000F800)>>6)| \
(((*src)&0x000000F8)>>3); \
}
#define RGB888_RGB555_TWO(dst, src) { \
*(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>9)| \
(((src[HI])&0x0000F800)>>6)| \
(((src[HI])&0x000000F8)>>3))<<16)| \
(((src[LO])&0x00F80000)>>9)| \
(((src[LO])&0x0000F800)>>6)| \
(((src[LO])&0x000000F8)>>3); \
}
static void Blit_RGB888_RGB555(SDL_BlitInfo *info)
{
#ifndef USE_DUFFS_LOOP
int c;
#endif
int width, height;
Uint32 *src;
Uint16 *dst;
int srcskip, dstskip;
/* Set up some basic variables */
width = info->d_width;
height = info->d_height;
src = (Uint32 *)info->s_pixels;
srcskip = info->s_skip/4;
dst = (Uint16 *)info->d_pixels;
dstskip = info->d_skip/2;
#ifdef USE_DUFFS_LOOP
while ( height-- ) {
DUFFS_LOOP(
RGB888_RGB555(dst, src);
++src;
++dst;
, width);
src += srcskip;
dst += dstskip;
}
#else
/* Memory align at 4-byte boundary, if necessary */
if ( (long)dst & 0x03 ) {
/* Don't do anything if width is 0 */
if ( width == 0 ) {
return;
}
--width;
while ( height-- ) {
/* Perform copy alignment */
RGB888_RGB555(dst, src);
++src;
++dst;
/* Copy in 4 pixel chunks */
for ( c=width/4; c; --c ) {
RGB888_RGB555_TWO(dst, src);
src += 2;
dst += 2;
RGB888_RGB555_TWO(dst, src);
src += 2;
dst += 2;
}
/* Get any leftovers */
switch (width & 3) {
case 3:
RGB888_RGB555(dst, src);
++src;
++dst;
case 2:
RGB888_RGB555_TWO(dst, src);
src += 2;
dst += 2;
break;
case 1:
RGB888_RGB555(dst, src);
++src;
++dst;
break;
}
src += srcskip;
dst += dstskip;
}
} else {
while ( height-- ) {
/* Copy in 4 pixel chunks */
for ( c=width/4; c; --c ) {
RGB888_RGB555_TWO(dst, src);
src += 2;
dst += 2;
RGB888_RGB555_TWO(dst, src);
src += 2;
dst += 2;
}
/* Get any leftovers */
switch (width & 3) {
case 3:
RGB888_RGB555(dst, src);
++src;
++dst;
case 2:
RGB888_RGB555_TWO(dst, src);
src += 2;
dst += 2;
break;
case 1:
RGB888_RGB555(dst, src);
++src;
++dst;
break;
}
src += srcskip;
dst += dstskip;
}
}
#endif /* USE_DUFFS_LOOP */
}
/* Special optimized blit for RGB 8-8-8 --> RGB 5-6-5 */
#define RGB888_RGB565(dst, src) { \
*(Uint16 *)(dst) = (((*src)&0x00F80000)>>8)| \
(((*src)&0x0000FC00)>>5)| \
(((*src)&0x000000F8)>>3); \
}
#define RGB888_RGB565_TWO(dst, src) { \
*(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>8)| \
(((src[HI])&0x0000FC00)>>5)| \
(((src[HI])&0x000000F8)>>3))<<16)| \
(((src[LO])&0x00F80000)>>8)| \
(((src[LO])&0x0000FC00)>>5)| \
(((src[LO])&0x000000F8)>>3); \
}
static void Blit_RGB888_RGB565(SDL_BlitInfo *info)
{
#ifndef USE_DUFFS_LOOP
int c;
#endif
int width, height;
Uint32 *src;
Uint16 *dst;
int srcskip, dstskip;
/* Set up some basic variables */
width = info->d_width;
height = info->d_height;
src = (Uint32 *)info->s_pixels;
srcskip = info->s_skip/4;
dst = (Uint16 *)info->d_pixels;
dstskip = info->d_skip/2;
#ifdef USE_DUFFS_LOOP
while ( height-- ) {
DUFFS_LOOP(
RGB888_RGB565(dst, src);
++src;
++dst;
, width);
src += srcskip;
dst += dstskip;
}
#else
/* Memory align at 4-byte boundary, if necessary */
if ( (long)dst & 0x03 ) {
/* Don't do anything if width is 0 */
if ( width == 0 ) {
return;
}
--width;
while ( height-- ) {
/* Perform copy alignment */
RGB888_RGB565(dst, src);
++src;
++dst;
/* Copy in 4 pixel chunks */
for ( c=width/4; c; --c ) {
RGB888_RGB565_TWO(dst, src);
src += 2;
dst += 2;
RGB888_RGB565_TWO(dst, src);
src += 2;
dst += 2;
}
/* Get any leftovers */
switch (width & 3) {
case 3:
RGB888_RGB565(dst, src);
++src;
++dst;
case 2:
RGB888_RGB565_TWO(dst, src);
src += 2;
dst += 2;
break;
case 1:
RGB888_RGB565(dst, src);
++src;
++dst;
break;
}
src += srcskip;
dst += dstskip;
}
} else {
while ( height-- ) {
/* Copy in 4 pixel chunks */
for ( c=width/4; c; --c ) {
RGB888_RGB565_TWO(dst, src);
src += 2;
dst += 2;
RGB888_RGB565_TWO(dst, src);
src += 2;
dst += 2;
}
/* Get any leftovers */
switch (width & 3) {
case 3:
RGB888_RGB565(dst, src);
++src;
++dst;
case 2:
RGB888_RGB565_TWO(dst, src);
src += 2;
dst += 2;
break;
case 1:
RGB888_RGB565(dst, src);
++src;
++dst;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -