/contrib/sdk/sources/SDL-1.2.2_newlib/src/audio/SDL_kolibri_audio.c |
---|
0,0 → 1,297 |
#include "SDL_audio.h" |
#include <menuet/os.h> |
#include <stdlib.h> |
#include <string.h> |
#include <sound.h> |
#include <stdio.h> |
static void GetNotify(__u32* event) |
{ |
__asm__("int $0x40" :: "a"(68),"b"(14),"c"(event)); |
} |
static int CreateThread(void* fn, char* p_stack) |
{ |
int res; |
__asm__("int $0x40" : "=a"(res) : "a"(51),"b"(1),"c"(fn),"d"(p_stack)); |
return res; |
} |
static char pinfo[1024]; |
static int GetProcessInfo(int slot) |
{ |
int res; |
__asm__("int $0x40" : "=a"(res) : "a"(9),"b"(pinfo),"c"(slot)); |
return res; |
} |
static void ActivateWnd(int slot) |
{ |
__asm__("int $0x40" :: "a"(18),"b"(3),"c"(slot)); |
} |
static void Yield(void) |
{ |
__asm__("int $0x40" :: "a"(68),"b"(1)); |
} |
static int bInitialized=0; |
static SNDBUF hBuff=0; |
static char* data=NULL; |
static int audio_tid=0; |
static int main_slot; |
static __u32 main_tid; |
static char audio_thread_stack[40960]; |
static __u32 used_format=0; |
static volatile int mix_size=0; |
static void (*callback)(void* userdata, Uint8* stream, int len); |
static void* userdata; |
int SDL_AudioInit(const char* driver_name) |
{ |
if (bInitialized) |
{ |
SDL_SetError("audio already initialized"); |
return -1; |
} |
int ver; |
if (InitSound(&ver)) |
{ |
SDL_printf("Warning: cannot load drivers, sound output will be disabled\n"); |
return 0; |
} |
bInitialized = 1; |
return 0; |
} |
void SDL_AudioQuit(void) |
{ |
} |
char* SDL_AudioDriverName(char* namebuf, int maxlen) |
{ |
if (!bInitialized) |
return NULL; |
strncpy(namebuf,"KolibriAudio",maxlen); |
return namebuf; |
} |
#define AUDIO_SUSPEND 1 |
#define AUDIO_RESUME 2 |
#define AUDIO_DIE 3 |
static volatile int audio_command=0,audio_response=0,bLocked=0,bInCallback=0; |
static void audio_thread(void) |
{ |
SDL_printf("audio_thread created\n"); |
int bPaused; |
__u32 event[6]; |
// initialize |
if (CreateBuffer(used_format|PCM_RING, 0, &hBuff)) |
{ |
audio_response=1; |
__menuet__sys_exit(); |
} |
GetBufferSize(hBuff, &mix_size); |
SDL_printf("buffer created, size is %d\n",mix_size); |
mix_size >>= 1; |
data = malloc(mix_size); |
audio_response=1; |
if (!data) __menuet__sys_exit(); |
// wait for resume |
while (audio_command!=AUDIO_RESUME) |
Yield(); |
// initialize |
/* bInCallback=1; |
callback(userdata,data,mix_size); |
SetBuffer(hBuff,data,0,mix_size); |
callback(userdata,data,mix_size); |
SetBuffer(hBuff,data,mix_size,mix_size); |
bInCallback=0;*/ |
audio_command=0; |
bPaused=0; |
audio_response=1; |
PlayBuffer(hBuff,0); |
// main loop |
for (;;) |
{ |
if (audio_command==AUDIO_RESUME) |
{ |
PlayBuffer(hBuff,0); |
audio_command = 0; |
bPaused = 0; |
audio_response = 1; |
} |
else if (audio_command==AUDIO_SUSPEND) |
{ |
StopBuffer(hBuff); |
audio_command = 0; |
bPaused = 1; |
audio_response = 1; |
} |
else if (audio_command==AUDIO_DIE) |
{ |
audio_response = 1; |
StopBuffer(hBuff); |
DestroyBuffer(hBuff); |
__menuet__sys_exit(); |
} |
else |
{ |
GetProcessInfo(main_slot); |
if (pinfo[0x32]==9 || *(__u32*)(pinfo+0x1E)!=main_tid) |
{ |
audio_command = AUDIO_DIE; |
continue; |
} |
} |
if (bPaused) |
__menuet__delay100(5); |
else |
{ |
GetNotify(event); |
if (event[0] != 0xFF000001) |
continue; |
while (bLocked) |
Yield(); |
bInCallback=1; |
callback(userdata,data,mix_size); |
bInCallback=0; |
SetBuffer(hBuff,data,event[3],mix_size); |
} |
} |
} |
int SDL_OpenAudio(SDL_AudioSpec* desired, SDL_AudioSpec* obtained) |
{ |
if (!bInitialized) |
{ |
SDL_SetError("Audio device was not initialized"); |
return -1; |
} |
if (!obtained) |
{ |
SDL_SetError("Audio format: software emulation is not supported"); |
return -1; |
} |
if (used_format) |
{ |
SDL_SetError("Audio device was already opened"); |
return -1; |
} |
memcpy(obtained,desired,sizeof(SDL_AudioSpec)); |
switch (desired->freq) |
{ |
#define HANDLE_FREQ(freq,symb) \ |
case freq: \ |
switch (desired->channels) \ |
{ \ |
case 1: \ |
switch (desired->format) \ |
{ \ |
case AUDIO_U8: \ |
case AUDIO_S8: \ |
used_format = PCM_1_8_##symb; \ |
break; \ |
case AUDIO_U16SYS: \ |
case AUDIO_S16SYS: \ |
used_format = PCM_1_16_##symb; \ |
break; \ |
} \ |
break; \ |
case 2: \ |
switch (desired->format) \ |
{ \ |
case AUDIO_U8: \ |
case AUDIO_S8: \ |
used_format = PCM_2_8_##symb; \ |
break; \ |
case AUDIO_U16SYS: \ |
case AUDIO_S16SYS: \ |
used_format = PCM_2_16_##symb; \ |
break; \ |
} \ |
break; \ |
} \ |
break; |
HANDLE_FREQ(48000,48); |
HANDLE_FREQ(44100,44); |
HANDLE_FREQ(32000,32); |
HANDLE_FREQ(24000,24); |
HANDLE_FREQ(22050,22); |
HANDLE_FREQ(16000,16); |
HANDLE_FREQ(12000,12); |
HANDLE_FREQ(11025,11); |
HANDLE_FREQ(8000,8); |
} |
if (!used_format) |
{ |
SDL_SetError("Unknown audio format"); |
return -1; |
} |
callback=desired->callback; |
userdata=desired->userdata; |
GetProcessInfo(-1); |
main_tid = *(__u32*)(pinfo+0x1E); |
for (main_slot=0;;main_slot++) |
{ |
GetProcessInfo(main_slot); |
if (pinfo[0x32]!=9 && *(__u32*)(pinfo+0x1E)==main_tid) |
break; |
} |
audio_tid=CreateThread(audio_thread,audio_thread_stack+40960); |
if (audio_tid<0) |
{ |
SDL_SetError("Cannot create audio thread"); |
return -1; |
} |
ActivateWnd(main_slot); |
while (!audio_response) |
Yield(); |
if (!hBuff) |
{ |
SDL_SetError("Cannot create audio buffer"); |
return -1; |
} |
if (!data) |
{ |
SDL_SetError("Cannot allocate audio buffer"); |
return -1; |
} |
obtained->silence = (desired->format == AUDIO_U8 ? 0x80 : 0); |
obtained->size = mix_size; |
obtained->samples = obtained->size / obtained->channels; |
if (desired->format == AUDIO_U16SYS || desired->format == AUDIO_S16SYS) |
obtained->samples /= 2; |
SDL_printf("obtained size is %d, samples %d\n",obtained->size, |
obtained->samples); |
return 0; |
} |
void SDL_CloseAudio(void) |
{ |
if (!audio_tid) return; |
audio_response = 0; |
audio_command = AUDIO_DIE; |
while (!audio_response) |
Yield(); |
free(data); |
used_format = 0; |
} |
void SDL_PauseAudio(int pause_on) |
{ |
if (!audio_tid) return; |
audio_response = 0; |
audio_command = pause_on?AUDIO_SUSPEND:AUDIO_RESUME; |
while (!audio_response) |
Yield(); |
} |
void SDL_LockAudio(void) |
{ |
if (!audio_tid) return; |
bLocked = 1; |
while (bInCallback) |
Yield(); |
} |
void SDL_UnlockAudio(void) |
{ |
bLocked = 0; |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/endian/SDL_endian.c |
---|
0,0 → 1,105 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* Functions for dynamically reading and writing endian-specific values */ |
#include "SDL_endian.h" |
Uint16 SDL_ReadLE16 (SDL_RWops *src) |
{ |
Uint16 value; |
SDL_RWread(src, &value, (sizeof value), 1); |
return(SDL_SwapLE16(value)); |
} |
Uint16 SDL_ReadBE16 (SDL_RWops *src) |
{ |
Uint16 value; |
SDL_RWread(src, &value, (sizeof value), 1); |
return(SDL_SwapBE16(value)); |
} |
Uint32 SDL_ReadLE32 (SDL_RWops *src) |
{ |
Uint32 value; |
SDL_RWread(src, &value, (sizeof value), 1); |
return(SDL_SwapLE32(value)); |
} |
Uint32 SDL_ReadBE32 (SDL_RWops *src) |
{ |
Uint32 value; |
SDL_RWread(src, &value, (sizeof value), 1); |
return(SDL_SwapBE32(value)); |
} |
Uint64 SDL_ReadLE64 (SDL_RWops *src) |
{ |
Uint64 value; |
SDL_RWread(src, &value, (sizeof value), 1); |
return(SDL_SwapLE64(value)); |
} |
Uint64 SDL_ReadBE64 (SDL_RWops *src) |
{ |
Uint64 value; |
SDL_RWread(src, &value, (sizeof value), 1); |
return(SDL_SwapBE64(value)); |
} |
int SDL_WriteLE16 (SDL_RWops *dst, Uint16 value) |
{ |
value = SDL_SwapLE16(value); |
return(SDL_RWwrite(dst, &value, (sizeof value), 1)); |
} |
int SDL_WriteBE16 (SDL_RWops *dst, Uint16 value) |
{ |
value = SDL_SwapBE16(value); |
return(SDL_RWwrite(dst, &value, (sizeof value), 1)); |
} |
int SDL_WriteLE32 (SDL_RWops *dst, Uint32 value) |
{ |
value = SDL_SwapLE32(value); |
return(SDL_RWwrite(dst, &value, (sizeof value), 1)); |
} |
int SDL_WriteBE32 (SDL_RWops *dst, Uint32 value) |
{ |
value = SDL_SwapBE32(value); |
return(SDL_RWwrite(dst, &value, (sizeof value), 1)); |
} |
int SDL_WriteLE64 (SDL_RWops *dst, Uint64 value) |
{ |
value = SDL_SwapLE64(value); |
return(SDL_RWwrite(dst, &value, (sizeof value), 1)); |
} |
int SDL_WriteBE64 (SDL_RWops *dst, Uint64 value) |
{ |
value = SDL_SwapBE64(value); |
return(SDL_RWwrite(dst, &value, (sizeof value), 1)); |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/events/SDL_active.c |
---|
0,0 → 1,91 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* Application focus/iconification handling code for SDL */ |
#include <stdio.h> |
#include <string.h> |
#include "SDL_events.h" |
#include "SDL_events_c.h" |
/* These are static for our active event handling code */ |
static Uint8 SDL_appstate = 0; |
/* Public functions */ |
int SDL_AppActiveInit(void) |
{ |
/* Start completely active */ |
SDL_appstate = (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS); |
/* That's it! */ |
return(0); |
} |
Uint8 SDL_GetAppState(void) |
{ |
return(SDL_appstate); |
} |
/* This is global for SDL_eventloop.c */ |
int SDL_PrivateAppActive(Uint8 gain, Uint8 state) |
{ |
int posted; |
Uint8 new_state; |
/* Modify the current state with the given mask */ |
if ( gain ) { |
new_state = (SDL_appstate | state); |
} else { |
new_state = (SDL_appstate & ~state); |
} |
/* Drop events that don't change state */ |
if ( new_state == SDL_appstate ) { |
return(0); |
} |
/* Update internal active state */ |
SDL_appstate = new_state; |
/* Post the event, if desired */ |
posted = 0; |
if ( SDL_ProcessEvents[SDL_ACTIVEEVENT] == SDL_ENABLE ) { |
SDL_Event event; |
memset(&event, 0, sizeof(event)); |
event.type = SDL_ACTIVEEVENT; |
event.active.gain = gain; |
event.active.state = state; |
if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { |
posted = 1; |
SDL_PushEvent(&event); |
} |
} |
/* If we lost keyboard focus, post key-up events */ |
if ( (state & SDL_APPINPUTFOCUS) && !gain ) { |
SDL_ResetKeyboard(); |
} |
return(posted); |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/events/SDL_events.c |
---|
0,0 → 1,471 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* General event handling code for SDL */ |
#include <stdio.h> |
#include <string.h> |
#include "SDL.h" |
#include "SDL_thread.h" |
#include "SDL_mutex.h" |
#include "SDL_events.h" |
#include "SDL_events_c.h" |
#include "SDL_timer_c.h" |
#ifndef DISABLE_JOYSTICK |
#include "SDL_joystick_c.h" |
#endif |
#ifndef ENABLE_X11 |
#define DISABLE_X11 |
#endif |
#include "SDL_syswm.h" |
#include "SDL_sysevents.h" |
/* Public data -- the event filter */ |
SDL_EventFilter SDL_EventOK = NULL; |
Uint8 SDL_ProcessEvents[SDL_NUMEVENTS]; |
static Uint32 SDL_eventstate = 0; |
/* Private data -- event queue */ |
#define MAXEVENTS 128 |
static struct { |
SDL_mutex *lock; |
int active; |
int head; |
int tail; |
SDL_Event event[MAXEVENTS]; |
int wmmsg_next; |
struct SDL_SysWMmsg wmmsg[MAXEVENTS]; |
} SDL_EventQ; |
/* Private data -- event locking structure */ |
static struct { |
SDL_mutex *lock; |
int safe; |
} SDL_EventLock; |
/* Thread functions */ |
static SDL_Thread *SDL_EventThread = NULL; /* Thread handle */ |
static Uint32 event_thread; /* The event thread id */ |
void SDL_Lock_EventThread(void) |
{ |
if ( SDL_EventThread && (SDL_ThreadID() != event_thread) ) { |
/* Grab lock and spin until we're sure event thread stopped */ |
SDL_mutexP(SDL_EventLock.lock); |
while ( ! SDL_EventLock.safe ) { |
SDL_Delay(1); |
} |
} |
} |
void SDL_Unlock_EventThread(void) |
{ |
if ( SDL_EventThread && (SDL_ThreadID() != event_thread) ) { |
SDL_mutexV(SDL_EventLock.lock); |
} |
} |
static int SDL_GobbleEvents(void *unused) |
{ |
SDL_SetTimerThreaded(2); |
event_thread = SDL_ThreadID(); |
while ( SDL_EventQ.active ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
/* Get events from the video subsystem */ |
if ( video ) { |
video->PumpEvents(this); |
} |
/* Queue pending key-repeat events */ |
SDL_CheckKeyRepeat(); |
#ifndef DISABLE_JOYSTICK |
/* Check for joystick state change */ |
if ( SDL_numjoysticks && (SDL_eventstate & SDL_JOYEVENTMASK) ) { |
SDL_JoystickUpdate(); |
} |
#endif |
/* Give up the CPU for the rest of our timeslice */ |
SDL_EventLock.safe = 1; |
if( SDL_timer_running ) { |
SDL_ThreadedTimerCheck(); |
} |
SDL_Delay(1); |
/* Check for event locking. |
On the P of the lock mutex, if the lock is held, this thread |
will wait until the lock is released before continuing. The |
safe flag will be set, meaning that the other thread can go |
about it's business. The safe flag is reset before the V, |
so as soon as the mutex is free, other threads can see that |
it's not safe to interfere with the event thread. |
*/ |
SDL_mutexP(SDL_EventLock.lock); |
SDL_EventLock.safe = 0; |
SDL_mutexV(SDL_EventLock.lock); |
} |
SDL_SetTimerThreaded(0); |
event_thread = 0; |
return(0); |
} |
static int SDL_StartEventThread(Uint32 flags) |
{ |
/* Reset everything to zero */ |
SDL_EventThread = NULL; |
memset(&SDL_EventLock, 0, sizeof(SDL_EventLock)); |
/* Create the lock and set ourselves active */ |
#ifndef DISABLE_THREADS |
SDL_EventQ.lock = SDL_CreateMutex(); |
if ( SDL_EventQ.lock == NULL ) { |
#ifdef macintosh /* On MacOS 7/8, you can't multithread, so no lock needed */ |
; |
#else |
return(-1); |
#endif |
} |
#endif /* !DISABLE_THREADS */ |
SDL_EventQ.active = 1; |
if ( (flags&SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD ) { |
SDL_EventLock.lock = SDL_CreateMutex(); |
if ( SDL_EventLock.lock == NULL ) { |
return(-1); |
} |
SDL_EventLock.safe = 0; |
SDL_EventThread = SDL_CreateThread(SDL_GobbleEvents, NULL); |
if ( SDL_EventThread == NULL ) { |
return(-1); |
} |
} else { |
event_thread = 0; |
} |
return(0); |
} |
static void SDL_StopEventThread(void) |
{ |
SDL_EventQ.active = 0; |
if ( SDL_EventThread ) { |
SDL_WaitThread(SDL_EventThread, NULL); |
SDL_EventThread = NULL; |
SDL_DestroyMutex(SDL_EventLock.lock); |
} |
SDL_DestroyMutex(SDL_EventQ.lock); |
} |
Uint32 SDL_EventThreadID(void) |
{ |
return(event_thread); |
} |
/* Public functions */ |
void SDL_StopEventLoop(void) |
{ |
/* Halt the event thread, if running */ |
SDL_StopEventThread(); |
/* Clean out EventQ */ |
SDL_EventQ.head = 0; |
SDL_EventQ.tail = 0; |
SDL_EventQ.wmmsg_next = 0; |
} |
/* This function (and associated calls) may be called more than once */ |
int SDL_StartEventLoop(Uint32 flags) |
{ |
int retcode; |
/* Clean out the event queue */ |
SDL_EventThread = NULL; |
SDL_EventQ.lock = NULL; |
SDL_StopEventLoop(); |
/* No filter to start with, process most event types */ |
SDL_EventOK = NULL; |
memset(SDL_ProcessEvents,SDL_ENABLE,sizeof(SDL_ProcessEvents)); |
SDL_eventstate = ~0; |
/* It's not save to call SDL_EventState() yet */ |
SDL_eventstate &= ~(0x00000001 << SDL_SYSWMEVENT); |
SDL_ProcessEvents[SDL_SYSWMEVENT] = SDL_IGNORE; |
/* Initialize event handlers */ |
retcode = 0; |
retcode += SDL_AppActiveInit(); |
retcode += SDL_KeyboardInit(); |
retcode += SDL_MouseInit(); |
retcode += SDL_QuitInit(); |
if ( retcode < 0 ) { |
/* We don't expect them to fail, but... */ |
return(-1); |
} |
/* Create the lock and event thread */ |
if ( SDL_StartEventThread(flags) < 0 ) { |
SDL_StopEventLoop(); |
return(-1); |
} |
return(0); |
} |
/* Add an event to the event queue -- called with the queue locked */ |
static int SDL_AddEvent(SDL_Event *event) |
{ |
int tail, added; |
tail = (SDL_EventQ.tail+1)%MAXEVENTS; |
if ( tail == SDL_EventQ.head ) { |
/* Overflow, drop event */ |
added = 0; |
} else { |
SDL_EventQ.event[SDL_EventQ.tail] = *event; |
if (event->type == SDL_SYSWMEVENT) { |
/* Note that it's possible to lose an event */ |
int next = SDL_EventQ.wmmsg_next; |
SDL_EventQ.wmmsg[next] = *event->syswm.msg; |
SDL_EventQ.event[SDL_EventQ.tail].syswm.msg = |
&SDL_EventQ.wmmsg[next]; |
SDL_EventQ.wmmsg_next = (next+1)%MAXEVENTS; |
} |
SDL_EventQ.tail = tail; |
added = 1; |
} |
return(added); |
} |
/* Cut an event, and return the next valid spot, or the tail */ |
/* -- called with the queue locked */ |
static int SDL_CutEvent(int spot) |
{ |
if ( spot == SDL_EventQ.head ) { |
SDL_EventQ.head = (SDL_EventQ.head+1)%MAXEVENTS; |
return(SDL_EventQ.head); |
} else |
if ( (spot+1)%MAXEVENTS == SDL_EventQ.tail ) { |
SDL_EventQ.tail = spot; |
return(SDL_EventQ.tail); |
} else |
/* We cut the middle -- shift everything over */ |
{ |
int here, next; |
/* This can probably be optimized with memcpy() -- careful! */ |
if ( --SDL_EventQ.tail < 0 ) { |
SDL_EventQ.tail = MAXEVENTS-1; |
} |
for ( here=spot; here != SDL_EventQ.tail; here = next ) { |
next = (here+1)%MAXEVENTS; |
SDL_EventQ.event[here] = SDL_EventQ.event[next]; |
} |
return(spot); |
} |
/* NOTREACHED */ |
} |
/* Lock the event queue, take a peep at it, and unlock it */ |
int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, |
Uint32 mask) |
{ |
int i, used; |
/* Don't look after we've quit */ |
if ( ! SDL_EventQ.active ) { |
return(0); |
} |
/* Lock the event queue */ |
used = 0; |
if ( SDL_mutexP(SDL_EventQ.lock) == 0 ) { |
if ( action == SDL_ADDEVENT ) { |
for ( i=0; i<numevents; ++i ) { |
used += SDL_AddEvent(&events[i]); |
} |
} else { |
SDL_Event tmpevent; |
int spot; |
/* If 'events' is NULL, just see if they exist */ |
if ( events == NULL ) { |
action = SDL_PEEKEVENT; |
numevents = 1; |
events = &tmpevent; |
} |
spot = SDL_EventQ.head; |
while ((used < numevents)&&(spot != SDL_EventQ.tail)) { |
if ( mask & SDL_EVENTMASK(SDL_EventQ.event[spot].type) ) { |
events[used++] = SDL_EventQ.event[spot]; |
if ( action == SDL_GETEVENT ) { |
spot = SDL_CutEvent(spot); |
} else { |
spot = (spot+1)%MAXEVENTS; |
} |
} else { |
spot = (spot+1)%MAXEVENTS; |
} |
} |
} |
SDL_mutexV(SDL_EventQ.lock); |
} else { |
SDL_SetError("Couldn't lock event queue"); |
used = -1; |
} |
return(used); |
} |
/* Run the system dependent event loops */ |
void SDL_PumpEvents(void) |
{ |
if ( !SDL_EventThread ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
/* Get events from the video subsystem */ |
if ( video ) { |
video->PumpEvents(this); |
} |
/* Queue pending key-repeat events */ |
SDL_CheckKeyRepeat(); |
#ifndef DISABLE_JOYSTICK |
/* Check for joystick state change */ |
if ( SDL_numjoysticks && (SDL_eventstate & SDL_JOYEVENTMASK) ) { |
SDL_JoystickUpdate(); |
} |
#endif |
} |
} |
/* Public functions */ |
int SDL_PollEvent (SDL_Event *event) |
{ |
SDL_PumpEvents(); |
return(SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)); |
} |
int SDL_WaitEvent (SDL_Event *event) |
{ |
while ( 1 ) { |
SDL_PumpEvents(); |
switch(SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) { |
case -1: return -1; |
case 1: return 1; |
case 0: SDL_Delay(10); |
} |
} |
} |
int SDL_PushEvent(SDL_Event *event) |
{ |
return(SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0)); |
} |
void SDL_SetEventFilter (SDL_EventFilter filter) |
{ |
SDL_Event bitbucket; |
/* Set filter and discard pending events */ |
SDL_EventOK = filter; |
while ( SDL_PollEvent(&bitbucket) > 0 ) |
; |
} |
SDL_EventFilter SDL_GetEventFilter(void) |
{ |
return(SDL_EventOK); |
} |
Uint8 SDL_EventState (Uint8 type, int state) |
{ |
SDL_Event bitbucket; |
Uint8 current_state; |
/* If SDL_ALLEVENTS was specified... */ |
if ( type == 0xFF ) { |
current_state = SDL_IGNORE; |
for ( type=0; type<SDL_NUMEVENTS; ++type ) { |
if ( SDL_ProcessEvents[type] != SDL_IGNORE ) { |
current_state = SDL_ENABLE; |
} |
SDL_ProcessEvents[type] = state; |
if ( state == SDL_ENABLE ) { |
SDL_eventstate |= (0x00000001 << (type)); |
} else { |
SDL_eventstate &= ~(0x00000001 << (type)); |
} |
} |
while ( SDL_PollEvent(&bitbucket) > 0 ) |
; |
return(current_state); |
} |
/* Just set the state for one event type */ |
current_state = SDL_ProcessEvents[type]; |
switch (state) { |
case SDL_IGNORE: |
case SDL_ENABLE: |
/* Set state and discard pending events */ |
SDL_ProcessEvents[type] = state; |
if ( state == SDL_ENABLE ) { |
SDL_eventstate |= (0x00000001 << (type)); |
} else { |
SDL_eventstate &= ~(0x00000001 << (type)); |
} |
while ( SDL_PollEvent(&bitbucket) > 0 ) |
; |
break; |
default: |
/* Querying state? */ |
break; |
} |
return(current_state); |
} |
/* This is a generic event handler. |
*/ |
int SDL_PrivateSysWMEvent(SDL_SysWMmsg *message) |
{ |
int posted; |
posted = 0; |
if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) { |
SDL_Event event; |
memset(&event, 0, sizeof(event)); |
event.type = SDL_SYSWMEVENT; |
event.syswm.msg = message; |
if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { |
posted = 1; |
SDL_PushEvent(&event); |
} |
} |
/* Update internal event state */ |
return(posted); |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/events/SDL_events_c.h |
---|
0,0 → 1,78 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_events_c.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; |
#endif |
/* Useful functions and variables from SDL_events.c */ |
#include "SDL_events.h" |
/* Start and stop the event processing loop */ |
extern int SDL_StartEventLoop(Uint32 flags); |
extern void SDL_StopEventLoop(void); |
extern void SDL_QuitInterrupt(void); |
extern void SDL_Lock_EventThread(); |
extern void SDL_Unlock_EventThread(); |
extern Uint32 SDL_EventThreadID(void); |
/* Event handler init routines */ |
extern int SDL_AppActiveInit(void); |
extern int SDL_KeyboardInit(void); |
extern int SDL_MouseInit(void); |
extern int SDL_QuitInit(void); |
/* The event filter function */ |
extern SDL_EventFilter SDL_EventOK; |
/* The array of event processing states */ |
extern Uint8 SDL_ProcessEvents[SDL_NUMEVENTS]; |
/* Internal event queueing functions |
(from SDL_active.c, SDL_mouse.c, SDL_keyboard.c, SDL_quit.c, SDL_events.c) |
*/ |
extern int SDL_PrivateAppActive(Uint8 gain, Uint8 state); |
extern int SDL_PrivateMouseMotion(Uint8 buttonstate, int relative, |
Sint16 x, Sint16 y); |
extern int SDL_PrivateMouseButton(Uint8 state, Uint8 button,Sint16 x,Sint16 y); |
extern int SDL_PrivateKeyboard(Uint8 state, SDL_keysym *key); |
extern int SDL_PrivateResize(int w, int h); |
extern int SDL_PrivateExpose(void); |
extern int SDL_PrivateQuit(void); |
extern int SDL_PrivateSysWMEvent(SDL_SysWMmsg *message); |
/* Used by the activity event handler to remove mouse focus */ |
extern void SDL_MouseFocus(int focus); |
/* Used by the activity event handler to remove keyboard focus */ |
extern void SDL_ResetKeyboard(void); |
/* Used by the event loop to queue pending keyboard repeat events */ |
extern void SDL_CheckKeyRepeat(void); |
/* Used by the OS keyboard code to detect whether or not to do UNICODE */ |
#ifndef DEFAULT_UNICODE_TRANSLATION |
#define DEFAULT_UNICODE_TRANSLATION 0 /* Default off because of overhead */ |
#endif |
extern int SDL_TranslateUNICODE; |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/events/SDL_expose.c |
---|
0,0 → 1,51 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* Refresh event handling code for SDL */ |
#include "SDL_events.h" |
#include "SDL_events_c.h" |
/* This is global for SDL_eventloop.c */ |
int SDL_PrivateExpose(void) |
{ |
int posted; |
SDL_Event events[32]; |
/* Pull out all old refresh events */ |
SDL_PeepEvents(events, sizeof(events)/sizeof(events[0]), |
SDL_GETEVENT, SDL_VIDEOEXPOSEMASK); |
/* Post the event, if desired */ |
posted = 0; |
if ( SDL_ProcessEvents[SDL_VIDEOEXPOSE] == SDL_ENABLE ) { |
SDL_Event event; |
event.type = SDL_VIDEOEXPOSE; |
if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { |
posted = 1; |
SDL_PushEvent(&event); |
} |
} |
return(posted); |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/events/SDL_keyboard.c |
---|
0,0 → 1,560 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* General keyboard handling code for SDL */ |
#include <stdio.h> |
#include <ctype.h> |
#include <stdlib.h> |
#include <string.h> |
#include "SDL_error.h" |
#include "SDL_events.h" |
#include "SDL_timer.h" |
#include "SDL_events_c.h" |
#include "SDL_sysevents.h" |
/* Global keystate information */ |
static Uint8 SDL_KeyState[SDLK_LAST]; |
static SDLMod SDL_ModState; |
int SDL_TranslateUNICODE = 0; |
static char *keynames[SDLK_LAST]; /* Array of keycode names */ |
/* |
* jk 991215 - added |
*/ |
struct { |
int firsttime; /* if we check against the delay or repeat value */ |
int delay; /* the delay before we start repeating */ |
int interval; /* the delay between key repeat events */ |
Uint32 timestamp; /* the time the first keydown event occurred */ |
SDL_Event evt; /* the event we are supposed to repeat */ |
} SDL_KeyRepeat; |
/* Public functions */ |
int SDL_KeyboardInit(void) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
Uint16 i; |
/* Set default mode of UNICODE translation */ |
SDL_EnableUNICODE(DEFAULT_UNICODE_TRANSLATION); |
/* Initialize the tables */ |
SDL_ModState = KMOD_NONE; |
for ( i=0; i<SDL_TABLESIZE(keynames); ++i ) |
keynames[i] = NULL; |
for ( i=0; i<SDL_TABLESIZE(SDL_KeyState); ++i ) |
SDL_KeyState[i] = SDL_RELEASED; |
video->InitOSKeymap(this); |
SDL_EnableKeyRepeat(0, 0); |
/* Fill in the blanks in keynames */ |
keynames[SDLK_BACKSPACE] = "backspace"; |
keynames[SDLK_TAB] = "tab"; |
keynames[SDLK_CLEAR] = "clear"; |
keynames[SDLK_RETURN] = "return"; |
keynames[SDLK_PAUSE] = "pause"; |
keynames[SDLK_ESCAPE] = "escape"; |
keynames[SDLK_SPACE] = "space"; |
keynames[SDLK_EXCLAIM] = "!"; |
keynames[SDLK_QUOTEDBL] = "\""; |
keynames[SDLK_HASH] = "#"; |
keynames[SDLK_DOLLAR] = "$"; |
keynames[SDLK_AMPERSAND] = "&"; |
keynames[SDLK_QUOTE] = "'"; |
keynames[SDLK_LEFTPAREN] = "("; |
keynames[SDLK_RIGHTPAREN] = ")"; |
keynames[SDLK_ASTERISK] = "*"; |
keynames[SDLK_PLUS] = "+"; |
keynames[SDLK_COMMA] = ","; |
keynames[SDLK_MINUS] = "-"; |
keynames[SDLK_PERIOD] = "."; |
keynames[SDLK_SLASH] = "/"; |
keynames[SDLK_0] = "0"; |
keynames[SDLK_1] = "1"; |
keynames[SDLK_2] = "2"; |
keynames[SDLK_3] = "3"; |
keynames[SDLK_4] = "4"; |
keynames[SDLK_5] = "5"; |
keynames[SDLK_6] = "6"; |
keynames[SDLK_7] = "7"; |
keynames[SDLK_8] = "8"; |
keynames[SDLK_9] = "9"; |
keynames[SDLK_COLON] = ":"; |
keynames[SDLK_SEMICOLON] = ";"; |
keynames[SDLK_LESS] = "<"; |
keynames[SDLK_EQUALS] = "="; |
keynames[SDLK_GREATER] = ">"; |
keynames[SDLK_QUESTION] = "?"; |
keynames[SDLK_AT] = "@"; |
keynames[SDLK_LEFTBRACKET] = "["; |
keynames[SDLK_BACKSLASH] = "\\"; |
keynames[SDLK_RIGHTBRACKET] = "]"; |
keynames[SDLK_CARET] = "^"; |
keynames[SDLK_UNDERSCORE] = "_"; |
keynames[SDLK_BACKQUOTE] = "`"; |
keynames[SDLK_a] = "a"; |
keynames[SDLK_b] = "b"; |
keynames[SDLK_c] = "c"; |
keynames[SDLK_d] = "d"; |
keynames[SDLK_e] = "e"; |
keynames[SDLK_f] = "f"; |
keynames[SDLK_g] = "g"; |
keynames[SDLK_h] = "h"; |
keynames[SDLK_i] = "i"; |
keynames[SDLK_j] = "j"; |
keynames[SDLK_k] = "k"; |
keynames[SDLK_l] = "l"; |
keynames[SDLK_m] = "m"; |
keynames[SDLK_n] = "n"; |
keynames[SDLK_o] = "o"; |
keynames[SDLK_p] = "p"; |
keynames[SDLK_q] = "q"; |
keynames[SDLK_r] = "r"; |
keynames[SDLK_s] = "s"; |
keynames[SDLK_t] = "t"; |
keynames[SDLK_u] = "u"; |
keynames[SDLK_v] = "v"; |
keynames[SDLK_w] = "w"; |
keynames[SDLK_x] = "x"; |
keynames[SDLK_y] = "y"; |
keynames[SDLK_z] = "z"; |
keynames[SDLK_DELETE] = "delete"; |
keynames[SDLK_WORLD_0] = "world 0"; |
keynames[SDLK_WORLD_1] = "world 1"; |
keynames[SDLK_WORLD_2] = "world 2"; |
keynames[SDLK_WORLD_3] = "world 3"; |
keynames[SDLK_WORLD_4] = "world 4"; |
keynames[SDLK_WORLD_5] = "world 5"; |
keynames[SDLK_WORLD_6] = "world 6"; |
keynames[SDLK_WORLD_7] = "world 7"; |
keynames[SDLK_WORLD_8] = "world 8"; |
keynames[SDLK_WORLD_9] = "world 9"; |
keynames[SDLK_WORLD_10] = "world 10"; |
keynames[SDLK_WORLD_11] = "world 11"; |
keynames[SDLK_WORLD_12] = "world 12"; |
keynames[SDLK_WORLD_13] = "world 13"; |
keynames[SDLK_WORLD_14] = "world 14"; |
keynames[SDLK_WORLD_15] = "world 15"; |
keynames[SDLK_WORLD_16] = "world 16"; |
keynames[SDLK_WORLD_17] = "world 17"; |
keynames[SDLK_WORLD_18] = "world 18"; |
keynames[SDLK_WORLD_19] = "world 19"; |
keynames[SDLK_WORLD_20] = "world 20"; |
keynames[SDLK_WORLD_21] = "world 21"; |
keynames[SDLK_WORLD_22] = "world 22"; |
keynames[SDLK_WORLD_23] = "world 23"; |
keynames[SDLK_WORLD_24] = "world 24"; |
keynames[SDLK_WORLD_25] = "world 25"; |
keynames[SDLK_WORLD_26] = "world 26"; |
keynames[SDLK_WORLD_27] = "world 27"; |
keynames[SDLK_WORLD_28] = "world 28"; |
keynames[SDLK_WORLD_29] = "world 29"; |
keynames[SDLK_WORLD_30] = "world 30"; |
keynames[SDLK_WORLD_31] = "world 31"; |
keynames[SDLK_WORLD_32] = "world 32"; |
keynames[SDLK_WORLD_33] = "world 33"; |
keynames[SDLK_WORLD_34] = "world 34"; |
keynames[SDLK_WORLD_35] = "world 35"; |
keynames[SDLK_WORLD_36] = "world 36"; |
keynames[SDLK_WORLD_37] = "world 37"; |
keynames[SDLK_WORLD_38] = "world 38"; |
keynames[SDLK_WORLD_39] = "world 39"; |
keynames[SDLK_WORLD_40] = "world 40"; |
keynames[SDLK_WORLD_41] = "world 41"; |
keynames[SDLK_WORLD_42] = "world 42"; |
keynames[SDLK_WORLD_43] = "world 43"; |
keynames[SDLK_WORLD_44] = "world 44"; |
keynames[SDLK_WORLD_45] = "world 45"; |
keynames[SDLK_WORLD_46] = "world 46"; |
keynames[SDLK_WORLD_47] = "world 47"; |
keynames[SDLK_WORLD_48] = "world 48"; |
keynames[SDLK_WORLD_49] = "world 49"; |
keynames[SDLK_WORLD_50] = "world 50"; |
keynames[SDLK_WORLD_51] = "world 51"; |
keynames[SDLK_WORLD_52] = "world 52"; |
keynames[SDLK_WORLD_53] = "world 53"; |
keynames[SDLK_WORLD_54] = "world 54"; |
keynames[SDLK_WORLD_55] = "world 55"; |
keynames[SDLK_WORLD_56] = "world 56"; |
keynames[SDLK_WORLD_57] = "world 57"; |
keynames[SDLK_WORLD_58] = "world 58"; |
keynames[SDLK_WORLD_59] = "world 59"; |
keynames[SDLK_WORLD_60] = "world 60"; |
keynames[SDLK_WORLD_61] = "world 61"; |
keynames[SDLK_WORLD_62] = "world 62"; |
keynames[SDLK_WORLD_63] = "world 63"; |
keynames[SDLK_WORLD_64] = "world 64"; |
keynames[SDLK_WORLD_65] = "world 65"; |
keynames[SDLK_WORLD_66] = "world 66"; |
keynames[SDLK_WORLD_67] = "world 67"; |
keynames[SDLK_WORLD_68] = "world 68"; |
keynames[SDLK_WORLD_69] = "world 69"; |
keynames[SDLK_WORLD_70] = "world 70"; |
keynames[SDLK_WORLD_71] = "world 71"; |
keynames[SDLK_WORLD_72] = "world 72"; |
keynames[SDLK_WORLD_73] = "world 73"; |
keynames[SDLK_WORLD_74] = "world 74"; |
keynames[SDLK_WORLD_75] = "world 75"; |
keynames[SDLK_WORLD_76] = "world 76"; |
keynames[SDLK_WORLD_77] = "world 77"; |
keynames[SDLK_WORLD_78] = "world 78"; |
keynames[SDLK_WORLD_79] = "world 79"; |
keynames[SDLK_WORLD_80] = "world 80"; |
keynames[SDLK_WORLD_81] = "world 81"; |
keynames[SDLK_WORLD_82] = "world 82"; |
keynames[SDLK_WORLD_83] = "world 83"; |
keynames[SDLK_WORLD_84] = "world 84"; |
keynames[SDLK_WORLD_85] = "world 85"; |
keynames[SDLK_WORLD_86] = "world 86"; |
keynames[SDLK_WORLD_87] = "world 87"; |
keynames[SDLK_WORLD_88] = "world 88"; |
keynames[SDLK_WORLD_89] = "world 89"; |
keynames[SDLK_WORLD_90] = "world 90"; |
keynames[SDLK_WORLD_91] = "world 91"; |
keynames[SDLK_WORLD_92] = "world 92"; |
keynames[SDLK_WORLD_93] = "world 93"; |
keynames[SDLK_WORLD_94] = "world 94"; |
keynames[SDLK_WORLD_95] = "world 95"; |
keynames[SDLK_KP0] = "[0]"; |
keynames[SDLK_KP1] = "[1]"; |
keynames[SDLK_KP2] = "[2]"; |
keynames[SDLK_KP3] = "[3]"; |
keynames[SDLK_KP4] = "[4]"; |
keynames[SDLK_KP5] = "[5]"; |
keynames[SDLK_KP6] = "[6]"; |
keynames[SDLK_KP7] = "[7]"; |
keynames[SDLK_KP8] = "[8]"; |
keynames[SDLK_KP9] = "[9]"; |
keynames[SDLK_KP_PERIOD] = "[.]"; |
keynames[SDLK_KP_DIVIDE] = "[/]"; |
keynames[SDLK_KP_MULTIPLY] = "[*]"; |
keynames[SDLK_KP_MINUS] = "[-]"; |
keynames[SDLK_KP_PLUS] = "[+]"; |
keynames[SDLK_KP_ENTER] = "enter"; |
keynames[SDLK_KP_EQUALS] = "equals"; |
keynames[SDLK_UP] = "up"; |
keynames[SDLK_DOWN] = "down"; |
keynames[SDLK_RIGHT] = "right"; |
keynames[SDLK_LEFT] = "left"; |
keynames[SDLK_DOWN] = "down"; |
keynames[SDLK_INSERT] = "insert"; |
keynames[SDLK_HOME] = "home"; |
keynames[SDLK_END] = "end"; |
keynames[SDLK_PAGEUP] = "page up"; |
keynames[SDLK_PAGEDOWN] = "page down"; |
keynames[SDLK_F1] = "f1"; |
keynames[SDLK_F2] = "f2"; |
keynames[SDLK_F3] = "f3"; |
keynames[SDLK_F4] = "f4"; |
keynames[SDLK_F5] = "f5"; |
keynames[SDLK_F6] = "f6"; |
keynames[SDLK_F7] = "f7"; |
keynames[SDLK_F8] = "f8"; |
keynames[SDLK_F9] = "f9"; |
keynames[SDLK_F10] = "f10"; |
keynames[SDLK_F11] = "f11"; |
keynames[SDLK_F12] = "f12"; |
keynames[SDLK_F13] = "f13"; |
keynames[SDLK_F14] = "f14"; |
keynames[SDLK_F15] = "f15"; |
keynames[SDLK_NUMLOCK] = "numlock"; |
keynames[SDLK_CAPSLOCK] = "caps lock"; |
keynames[SDLK_SCROLLOCK] = "scroll lock"; |
keynames[SDLK_RSHIFT] = "right shift"; |
keynames[SDLK_LSHIFT] = "left shift"; |
keynames[SDLK_RCTRL] = "right ctrl"; |
keynames[SDLK_LCTRL] = "left ctrl"; |
keynames[SDLK_RALT] = "right alt"; |
keynames[SDLK_LALT] = "left alt"; |
keynames[SDLK_RMETA] = "right meta"; |
keynames[SDLK_LMETA] = "left meta"; |
keynames[SDLK_LSUPER] = "left super"; /* "Windows" keys */ |
keynames[SDLK_RSUPER] = "right super"; |
keynames[SDLK_MODE] = "alt gr"; |
keynames[SDLK_COMPOSE] = "compose"; |
keynames[SDLK_HELP] = "help"; |
keynames[SDLK_PRINT] = "print screen"; |
keynames[SDLK_SYSREQ] = "sys req"; |
keynames[SDLK_BREAK] = "break"; |
keynames[SDLK_MENU] = "menu"; |
keynames[SDLK_POWER] = "power"; |
keynames[SDLK_EURO] = "euro"; |
/* Done. Whew. */ |
return(0); |
} |
/* We lost the keyboard, so post key up messages for all pressed keys */ |
void SDL_ResetKeyboard(void) |
{ |
SDL_keysym keysym; |
SDLKey key; |
memset(&keysym, 0, (sizeof keysym)); |
for ( key=SDLK_FIRST; key<SDLK_LAST; ++key ) { |
if ( SDL_KeyState[key] == SDL_PRESSED ) { |
keysym.sym = key; |
SDL_PrivateKeyboard(SDL_RELEASED, &keysym); |
} |
} |
SDL_KeyRepeat.timestamp = 0; |
} |
int SDL_EnableUNICODE(int enable) |
{ |
int old_mode; |
old_mode = SDL_TranslateUNICODE; |
if ( enable >= 0 ) { |
SDL_TranslateUNICODE = enable; |
} |
return(old_mode); |
} |
Uint8 * SDL_GetKeyState (int *numkeys) |
{ |
if ( numkeys != (int *)0 ) |
*numkeys = SDLK_LAST; |
return(SDL_KeyState); |
} |
SDLMod SDL_GetModState (void) |
{ |
return(SDL_ModState); |
} |
void SDL_SetModState (SDLMod modstate) |
{ |
SDL_ModState = modstate; |
} |
char *SDL_GetKeyName(SDLKey key) |
{ |
char *keyname; |
keyname = NULL; |
if ( key < SDLK_LAST ) { |
keyname = keynames[key]; |
} |
if ( keyname == NULL ) { |
keyname = "unknown key"; |
} |
return(keyname); |
} |
/* These are global for SDL_eventloop.c */ |
int SDL_PrivateKeyboard(Uint8 state, SDL_keysym *keysym) |
{ |
SDL_Event event; |
int posted, repeatable; |
Uint16 modstate; |
memset(&event, 0, sizeof(event)); |
/* Set up the keysym */ |
modstate = (Uint16)SDL_ModState; |
repeatable = 0; |
if ( state == SDL_PRESSED ) { |
keysym->mod = (SDLMod)modstate; |
switch (keysym->sym) { |
case SDLK_NUMLOCK: |
modstate ^= KMOD_NUM; |
if ( ! (modstate&KMOD_NUM) ) |
state = SDL_RELEASED; |
keysym->mod = (SDLMod)modstate; |
break; |
case SDLK_CAPSLOCK: |
modstate ^= KMOD_CAPS; |
if ( ! (modstate&KMOD_CAPS) ) |
state = SDL_RELEASED; |
keysym->mod = (SDLMod)modstate; |
break; |
case SDLK_LCTRL: |
modstate |= KMOD_LCTRL; |
break; |
case SDLK_RCTRL: |
modstate |= KMOD_RCTRL; |
break; |
case SDLK_LSHIFT: |
modstate |= KMOD_LSHIFT; |
break; |
case SDLK_RSHIFT: |
modstate |= KMOD_RSHIFT; |
break; |
case SDLK_LALT: |
modstate |= KMOD_LALT; |
break; |
case SDLK_RALT: |
modstate |= KMOD_RALT; |
break; |
case SDLK_LMETA: |
modstate |= KMOD_LMETA; |
break; |
case SDLK_RMETA: |
modstate |= KMOD_RMETA; |
break; |
case SDLK_MODE: |
modstate |= KMOD_MODE; |
break; |
default: |
repeatable = 1; |
break; |
} |
} else { |
switch (keysym->sym) { |
case SDLK_NUMLOCK: |
case SDLK_CAPSLOCK: |
/* Only send keydown events */ |
return(0); |
case SDLK_LCTRL: |
modstate &= ~KMOD_LCTRL; |
break; |
case SDLK_RCTRL: |
modstate &= ~KMOD_RCTRL; |
break; |
case SDLK_LSHIFT: |
modstate &= ~KMOD_LSHIFT; |
break; |
case SDLK_RSHIFT: |
modstate &= ~KMOD_RSHIFT; |
break; |
case SDLK_LALT: |
modstate &= ~KMOD_LALT; |
break; |
case SDLK_RALT: |
modstate &= ~KMOD_RALT; |
break; |
case SDLK_LMETA: |
modstate &= ~KMOD_LMETA; |
break; |
case SDLK_RMETA: |
modstate &= ~KMOD_RMETA; |
break; |
case SDLK_MODE: |
modstate &= ~KMOD_MODE; |
break; |
default: |
break; |
} |
keysym->mod = (SDLMod)modstate; |
} |
/* Figure out what type of event this is */ |
switch (state) { |
case SDL_PRESSED: |
event.type = SDL_KEYDOWN; |
break; |
case SDL_RELEASED: |
event.type = SDL_KEYUP; |
/* |
* jk 991215 - Added |
*/ |
if ( SDL_KeyRepeat.timestamp ) { |
SDL_KeyRepeat.timestamp = 0; |
} |
break; |
default: |
/* Invalid state -- bail */ |
return(0); |
} |
// /* Drop events that don't change state */ |
// if ( SDL_KeyState[keysym->sym] == state ) { |
// return(0); |
// } |
/* Update internal keyboard state */ |
SDL_ModState = (SDLMod)modstate; |
SDL_KeyState[keysym->sym] = state; |
/* Post the event, if desired */ |
posted = 0; |
if ( SDL_ProcessEvents[event.type] == SDL_ENABLE ) { |
event.key.state = state; |
event.key.keysym = *keysym; |
if ( (SDL_EventOK == NULL) || SDL_EventOK(&event) ) { |
posted = 1; |
/* |
* jk 991215 - Added |
*/ |
if (repeatable && (SDL_KeyRepeat.delay != 0)) { |
SDL_KeyRepeat.evt = event; |
SDL_KeyRepeat.firsttime = 1; |
SDL_KeyRepeat.timestamp=SDL_GetTicks(); |
} |
SDL_PushEvent(&event); |
} |
} |
return(posted); |
} |
/* |
* jk 991215 - Added |
*/ |
void SDL_CheckKeyRepeat(void) |
{ |
/* if ( SDL_KeyRepeat.timestamp ) { |
Uint32 now, interval; |
now = SDL_GetTicks(); |
interval = (now - SDL_KeyRepeat.timestamp); |
if ( SDL_KeyRepeat.firsttime ) { |
if ( interval > (Uint32)SDL_KeyRepeat.delay ) { |
SDL_KeyRepeat.timestamp = now; |
SDL_KeyRepeat.firsttime = 0; |
} |
} else { |
if ( interval > (Uint32)SDL_KeyRepeat.interval ) { |
SDL_KeyRepeat.timestamp = now; |
SDL_PushEvent(&SDL_KeyRepeat.evt); |
} |
} |
}*/ |
} |
int SDL_EnableKeyRepeat(int delay, int interval) |
{ |
if ( (delay < 0) || (interval < 0) ) { |
SDL_SetError("keyboard repeat value less than zero"); |
return(-1); |
} |
SDL_KeyRepeat.firsttime = 0; |
SDL_KeyRepeat.delay = delay; |
SDL_KeyRepeat.interval = interval; |
SDL_KeyRepeat.timestamp = 0; |
return(0); |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/events/SDL_mouse.c |
---|
0,0 → 1,246 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* General mouse handling code for SDL */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "SDL_events.h" |
#include "SDL_events_c.h" |
#include "SDL_cursor_c.h" |
#include "SDL_sysvideo.h" |
/* These are static for our mouse handling code */ |
static Sint16 SDL_MouseX = 0; |
static Sint16 SDL_MouseY = 0; |
static Sint16 SDL_DeltaX = 0; |
static Sint16 SDL_DeltaY = 0; |
static Uint8 SDL_ButtonState = 0; |
/* Public functions */ |
int SDL_MouseInit(void) |
{ |
/* The mouse is at (0,0) */ |
SDL_MouseX = 0; |
SDL_MouseY = 0; |
SDL_DeltaX = 0; |
SDL_DeltaY = 0; |
SDL_ButtonState = 0; |
/* That's it! */ |
return(0); |
} |
Uint8 SDL_GetMouseState (int *x, int *y) |
{ |
if ( x ) |
*x = SDL_MouseX; |
if ( y ) |
*y = SDL_MouseY; |
return(SDL_ButtonState); |
} |
Uint8 SDL_GetRelativeMouseState (int *x, int *y) |
{ |
if ( x ) |
*x = SDL_DeltaX; |
if ( y ) |
*y = SDL_DeltaY; |
SDL_DeltaX = 0; |
SDL_DeltaY = 0; |
return(SDL_ButtonState); |
} |
static void ClipOffset(Sint16 *x, Sint16 *y) |
{ |
/* This clips absolute mouse coordinates when the apparent |
display surface is smaller than the real display surface. |
*/ |
if ( SDL_VideoSurface->offset ) { |
*y -= SDL_VideoSurface->offset/SDL_VideoSurface->pitch; |
*x -= (SDL_VideoSurface->offset%SDL_VideoSurface->pitch)/ |
SDL_VideoSurface->format->BytesPerPixel; |
} |
} |
/* These are global for SDL_eventloop.c */ |
int SDL_PrivateMouseMotion(Uint8 buttonstate, int relative, Sint16 x, Sint16 y) |
{ |
int posted; |
Uint16 X, Y; |
Sint16 Xrel; |
Sint16 Yrel; |
/* Don't handle mouse motion if there's no cursor surface */ |
if ( SDL_VideoSurface == NULL ) { |
return(0); |
} |
/* Default buttonstate is the current one */ |
if ( ! buttonstate ) { |
buttonstate = SDL_ButtonState; |
} |
Xrel = x; |
Yrel = y; |
if ( relative ) { |
/* Push the cursor around */ |
x = (SDL_MouseX+x); |
y = (SDL_MouseY+y); |
} else { |
/* Do we need to clip {x,y} ? */ |
ClipOffset(&x, &y); |
} |
/* Mouse coordinates range from 0 - width-1 and 0 - height-1 */ |
if ( x < 0 ) |
X = 0; |
else |
if ( x >= SDL_VideoSurface->w ) |
X = SDL_VideoSurface->w-1; |
else |
X = (Uint16)x; |
if ( y < 0 ) |
Y = 0; |
else |
if ( y >= SDL_VideoSurface->h ) |
Y = SDL_VideoSurface->h-1; |
else |
Y = (Uint16)y; |
/* If not relative mode, generate relative motion from clamped X/Y. |
This prevents lots of extraneous large delta relative motion when |
the screen is windowed mode and the mouse is outside the window. |
*/ |
if ( ! relative ) { |
Xrel = X-SDL_MouseX; |
Yrel = Y-SDL_MouseY; |
} |
/* Update internal mouse state */ |
SDL_ButtonState = buttonstate; |
SDL_MouseX = X; |
SDL_MouseY = Y; |
SDL_DeltaX += Xrel; |
SDL_DeltaY += Yrel; |
SDL_MoveCursor(SDL_MouseX, SDL_MouseY); |
/* Post the event, if desired */ |
posted = 0; |
if ( SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE ) { |
SDL_Event event; |
memset(&event, 0, sizeof(event)); |
event.type = SDL_MOUSEMOTION; |
event.motion.state = buttonstate; |
event.motion.x = X; |
event.motion.y = Y; |
event.motion.xrel = Xrel; |
event.motion.yrel = Yrel; |
if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { |
posted = 1; |
SDL_PushEvent(&event); |
} |
} |
return(posted); |
} |
int SDL_PrivateMouseButton(Uint8 state, Uint8 button, Sint16 x, Sint16 y) |
{ |
SDL_Event event; |
int posted; |
int move_mouse; |
Uint8 buttonstate; |
memset(&event, 0, sizeof(event)); |
/* Check parameters */ |
if ( x || y ) { |
ClipOffset(&x, &y); |
move_mouse = 1; |
/* Mouse coordinates range from 0 - width-1 and 0 - height-1 */ |
if ( x < 0 ) |
x = 0; |
else |
if ( x >= SDL_VideoSurface->w ) |
x = SDL_VideoSurface->w-1; |
if ( y < 0 ) |
y = 0; |
else |
if ( y >= SDL_VideoSurface->h ) |
y = SDL_VideoSurface->h-1; |
} else { |
move_mouse = 0; |
} |
if ( ! x ) |
x = SDL_MouseX; |
if ( ! y ) |
y = SDL_MouseY; |
/* Figure out which event to perform */ |
buttonstate = SDL_ButtonState; |
switch ( state ) { |
case SDL_PRESSED: |
event.type = SDL_MOUSEBUTTONDOWN; |
buttonstate |= SDL_BUTTON(button); |
break; |
case SDL_RELEASED: |
event.type = SDL_MOUSEBUTTONUP; |
buttonstate &= ~SDL_BUTTON(button); |
break; |
default: |
/* Invalid state -- bail */ |
return(0); |
} |
/* Update internal mouse state */ |
SDL_ButtonState = buttonstate; |
if ( move_mouse ) { |
SDL_MouseX = x; |
SDL_MouseY = y; |
/* We don't wan't the cursor because MenuetOS doesn't allow |
hiding mouse cursor */ |
// uncommented for KolibriOS |
SDL_MoveCursor(SDL_MouseX, SDL_MouseY); |
} |
/* Post the event, if desired */ |
posted = 0; |
if ( SDL_ProcessEvents[event.type] == SDL_ENABLE ) { |
event.button.state = state; |
event.button.button = button; |
event.button.x = x; |
event.button.y = y; |
if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { |
posted = 1; |
SDL_PushEvent(&event); |
} |
} |
return(posted); |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/events/SDL_quit.c |
---|
0,0 → 1,79 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* General quit handling code for SDL */ |
#include <stdio.h> |
#ifndef NO_SIGNAL_H |
#include <signal.h> |
#endif |
#include "SDL_events.h" |
#include "SDL_events_c.h" |
#ifndef NO_SIGNAL_H |
static void SDL_HandleSIG(int sig) |
{ |
/* Reset the signal handler */ |
signal(sig, SDL_HandleSIG); |
/* Signal a quit interrupt */ |
SDL_PrivateQuit(); |
} |
#endif /* NO_SIGNAL_H */ |
/* Public functions */ |
int SDL_QuitInit(void) |
{ |
#ifndef NO_SIGNAL_H |
void (*ohandler)(int); |
/* Both SIGINT and SIGTERM are translated into quit interrupts */ |
ohandler = signal(SIGINT, SDL_HandleSIG); |
if ( ohandler != SIG_DFL ) |
signal(SIGINT, ohandler); |
ohandler = signal(SIGTERM, SDL_HandleSIG); |
if ( ohandler != SIG_DFL ) |
signal(SIGTERM, ohandler); |
#endif /* NO_SIGNAL_H */ |
/* That's it! */ |
return(0); |
} |
/* This function returns 1 if it's okay to close the application window */ |
int SDL_PrivateQuit(void) |
{ |
int posted; |
posted = 0; |
if ( SDL_ProcessEvents[SDL_QUIT] == SDL_ENABLE ) { |
SDL_Event event; |
event.type = SDL_QUIT; |
if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { |
posted = 1; |
SDL_PushEvent(&event); |
} |
} |
return(posted); |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/events/SDL_resize.c |
---|
0,0 → 1,72 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* Resize event handling code for SDL */ |
#include "SDL_events.h" |
#include "SDL_events_c.h" |
#include "SDL_sysvideo.h" |
/* Keep the last resize event so we don't post duplicates */ |
static struct { |
int w; |
int h; |
} last_resize; |
/* This is global for SDL_eventloop.c */ |
int SDL_PrivateResize(int w, int h) |
{ |
int posted; |
SDL_Event events[32]; |
/* See if this event would change the video surface */ |
if ( !w || !h || |
((last_resize.w == w) && (last_resize.h == h)) ) { |
return(0); |
} |
last_resize.w = w; |
last_resize.h = h; |
if ( ! SDL_VideoSurface || |
((w == SDL_VideoSurface->w) && (h == SDL_VideoSurface->h)) ) { |
return(0); |
} |
/* Pull out all old resize events */ |
SDL_PeepEvents(events, sizeof(events)/sizeof(events[0]), |
SDL_GETEVENT, SDL_VIDEORESIZEMASK); |
/* Post the event, if desired */ |
posted = 0; |
if ( SDL_ProcessEvents[SDL_VIDEORESIZE] == SDL_ENABLE ) { |
SDL_Event event; |
event.type = SDL_VIDEORESIZE; |
event.resize.w = w; |
event.resize.h = h; |
if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { |
posted = 1; |
SDL_PushEvent(&event); |
} |
} |
return(posted); |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/events/SDL_sysevents.h |
---|
0,0 → 1,46 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_sysevents.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; |
#endif |
#include "SDL_sysvideo.h" |
/* Useful functions and variables from SDL_sysevents.c */ |
#ifdef __BEOS__ /* The Be event loop runs in a separate thread */ |
#define MUST_THREAD_EVENTS |
#endif |
#ifdef WIN32UNDEFINED /* Win32 doesn't allow a separate event thread */ |
#define CANT_THREAD_EVENTS |
#endif |
#ifdef macintosh /* MacOS 7/8 don't support preemptive multi-tasking */ |
#define CANT_THREAD_EVENTS |
#endif |
#ifdef __MENUETOS__ |
#define CANT_THREAD_EVENTS |
#endif |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/file/SDL_rwops.c |
---|
0,0 → 1,207 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* This file provides a general interface for SDL to read and write |
data sources. It can easily be extended to files, memory, etc. |
*/ |
#include <stdlib.h> |
#include <stdio.h> |
#include <string.h> |
#include "SDL_error.h" |
#include "SDL_rwops.h" |
/* Functions to read/write stdio file pointers */ |
static int stdio_seek(SDL_RWops *context, int offset, int whence) |
{ |
if ( fseek(context->hidden.stdio.fp, offset, whence) == 0 ) |
{ |
return(ftell(context->hidden.stdio.fp)); |
} else { |
SDL_Error(SDL_EFSEEK); |
return(-1); |
} |
} |
static int stdio_read(SDL_RWops *context, void *ptr, int size, int maxnum) |
{ |
size_t nread; |
nread = fread(ptr, size, maxnum, context->hidden.stdio.fp); |
if ( nread == 0 && ferror(context->hidden.stdio.fp) ) |
{ |
SDL_Error(SDL_EFREAD); |
} |
return(nread); |
} |
static int stdio_write(SDL_RWops *context, const void *ptr, int size, int num) |
{ |
size_t nwrote; |
nwrote = fwrite(ptr, size, num, context->hidden.stdio.fp); |
if ( nwrote == 0 && ferror(context->hidden.stdio.fp) ) |
{ |
SDL_Error(SDL_EFWRITE); |
} |
return(nwrote); |
} |
static int stdio_close(SDL_RWops *context) |
{ |
if ( context ) |
{ |
if ( context->hidden.stdio.autoclose ) |
{ |
fclose(context->hidden.stdio.fp); |
} |
free(context); |
} |
return(0); |
} |
static int mem_seek(SDL_RWops *context, int offset, int whence) |
{ |
Uint8 *newpos; |
switch (whence) |
{ |
case SEEK_SET: |
newpos = context->hidden.mem.base+offset; |
break; |
case SEEK_CUR: |
newpos = context->hidden.mem.here+offset; |
break; |
case SEEK_END: |
newpos = context->hidden.mem.stop+offset; |
break; |
default: |
SDL_SetError("Unknown value for 'whence'"); |
return(-1); |
} |
if ( newpos < context->hidden.mem.base ) |
{ |
newpos = context->hidden.mem.base; |
} |
if ( newpos > context->hidden.mem.stop ) |
{ |
newpos = context->hidden.mem.stop; |
} |
context->hidden.mem.here = newpos; |
return(context->hidden.mem.here-context->hidden.mem.base); |
} |
static int mem_read(SDL_RWops *context, void *ptr, int size, int maxnum) |
{ |
int num; |
num = maxnum; |
if ( (context->hidden.mem.here + (num*size)) > context->hidden.mem.stop ) |
{ |
num = (context->hidden.mem.stop-context->hidden.mem.here)/size; |
} |
memcpy(ptr, context->hidden.mem.here, num*size); |
context->hidden.mem.here += num*size; |
return(num); |
} |
static int mem_write(SDL_RWops *context, const void *ptr, int size, int num) |
{ |
if ( (context->hidden.mem.here + (num*size)) > context->hidden.mem.stop ) |
{ |
num = (context->hidden.mem.stop-context->hidden.mem.here)/size; |
} |
memcpy(context->hidden.mem.here, ptr, num*size); |
context->hidden.mem.here += num*size; |
return(num); |
} |
static int mem_close(SDL_RWops *context) |
{ |
if ( context ) |
{ |
free(context); |
} |
return(0); |
} |
SDL_RWops *SDL_RWFromFile(const char *file, const char *mode) |
{ |
FILE *fp; |
SDL_RWops *rwops; |
rwops = NULL; |
fp = fopen(file, mode); |
if ( fp == NULL ) |
{ |
SDL_SetError("Couldn't open %s", file); |
} else { |
rwops = SDL_RWFromFP(fp, 1); |
} |
return(rwops); |
} |
SDL_RWops *SDL_RWFromFP(FILE *fp, int autoclose) |
{ |
SDL_RWops *rwops; |
rwops = SDL_AllocRW(); |
if ( rwops != NULL ) |
{ |
rwops->seek = stdio_seek; |
rwops->read = stdio_read; |
rwops->write = stdio_write; |
rwops->close = stdio_close; |
rwops->hidden.stdio.fp = fp; |
rwops->hidden.stdio.autoclose = autoclose; |
} |
return(rwops); |
} |
SDL_RWops *SDL_RWFromMem(void *mem, int size) |
{ |
SDL_RWops *rwops; |
rwops = SDL_AllocRW(); |
if ( rwops != NULL ) |
{ |
rwops->seek = mem_seek; |
rwops->read = mem_read; |
rwops->write = mem_write; |
rwops->close = mem_close; |
rwops->hidden.mem.base = (Uint8 *)mem; |
rwops->hidden.mem.here = rwops->hidden.mem.base; |
rwops->hidden.mem.stop = rwops->hidden.mem.base+size; |
} |
return(rwops); |
} |
SDL_RWops *SDL_AllocRW(void) |
{ |
SDL_RWops *area; |
area = (SDL_RWops *)malloc(sizeof *area); |
if ( area == NULL ) |
{ |
SDL_OutOfMemory(); |
} |
return(area); |
} |
void SDL_FreeRW(SDL_RWops *area) |
{ |
free(area); |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/hermes/HeadMMX.h |
---|
0,0 → 1,101 |
/* |
Header definitions for the MMX routines for the HERMES library |
Copyright (c) 1998 Christian Nentwich (c.nentwich@cs.ucl.ac.uk) |
This source code is licensed under the GNU LGPL |
Please refer to the file COPYING.LIB contained in the distribution for |
licensing conditions |
*/ |
#ifndef __HERMES_HEAD_MMX__ |
#define __HERMES_HEAD_MMX__ |
/* If you cannot stand ifdefs, then please do not look into this file, it's |
going to end your life :) */ |
#ifdef X86_ASSEMBLER |
#ifdef __cplusplus |
extern "C" { |
#endif |
void STACKCALL ConvertMMX(HermesConverterInterface *); |
void STACKCALL ClearMMX_32(HermesClearInterface *); |
void STACKCALL ClearMMX_24(HermesClearInterface *); |
void STACKCALL ClearMMX_16(HermesClearInterface *); |
void STACKCALL ClearMMX_8(HermesClearInterface *); |
void ConvertMMXpII32_24RGB888(); |
void ConvertMMXpII32_16RGB565(); |
void ConvertMMXpII32_16BGR565(); |
void ConvertMMXpII32_16RGB555(); |
void ConvertMMXpII32_16BGR565(); |
void ConvertMMXpII32_16BGR555(); |
void ConvertMMXp32_16RGB555(); |
#ifdef __cplusplus |
} |
#endif |
/* Fix the underscore business with ELF compilers */ |
#if defined(__ELF__) && defined(__GNUC__) |
#ifdef __cplusplus |
extern "C" { |
#endif |
void ConvertMMX(HermesConverterInterface *) __attribute__ ((alias ("_ConvertMMX"))); |
#if 0 |
void ClearMMX_32(HermesClearInterface *) __attribute__ ((alias ("_ClearMMX_32"))); |
void ClearMMX_24(HermesClearInterface *) __attribute__ ((alias ("_ClearMMX_24"))); |
void ClearMMX_16(HermesClearInterface *) __attribute__ ((alias ("_ClearMMX_16"))); |
void ClearMMX_8(HermesClearInterface *) __attribute__ ((alias ("_ClearMMX_8"))); |
void ConvertMMXp32_16RGB555() __attribute__ ((alias ("_ConvertMMXp32_16RGB555"))); |
#endif |
void ConvertMMXpII32_24RGB888() __attribute__ ((alias ("_ConvertMMXpII32_24RGB888"))); |
void ConvertMMXpII32_16RGB565() __attribute__ ((alias ("_ConvertMMXpII32_16RGB565"))); |
void ConvertMMXpII32_16BGR565() __attribute__ ((alias ("_ConvertMMXpII32_16BGR565"))); |
void ConvertMMXpII32_16RGB555() __attribute__ ((alias ("_ConvertMMXpII32_16RGB555"))); |
void ConvertMMXpII32_16BGR555() __attribute__ ((alias ("_ConvertMMXpII32_16BGR555"))); |
#ifdef __cplusplus |
} |
#endif |
#endif /* ELF and GNUC */ |
/* Make it work with Watcom */ |
#ifdef __WATCOMC__ |
#pragma warning 601 9 |
#pragma aux ConvertMMX "_*" modify [EAX EBX ECX EDX ESI EDI] |
#pragma aux ClearMMX_32 "_*" modify [EAX EBX ECX EDX ESI EDI] |
#pragma aux ClearMMX_24 "_*" modify [EAX EBX ECX EDX ESI EDI] |
#pragma aux ClearMMX_16 "_*" modify [EAX EBX ECX EDX ESI EDI] |
#pragma aux ClearMMX_8 "_*" modify [EAX EBX ECX EDX ESI EDI] |
#pragma aux ConvertMMXpII32_24RGB888 "_*" |
#pragma aux ConvertMMXpII32_16RGB565 "_*" |
#pragma aux ConvertMMXpII32_16BGR565 "_*" |
#pragma aux ConvertMMXpII32_16RGB555 "_*" |
#pragma aux ConvertMMXpII32_16BGR555 "_*" |
#pragma aux ConvertMMXp32_16RGB555 "_*" |
#endif /* WATCOM */ |
#endif /* X86_ASSEMBLER */ |
#endif |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/hermes/HeadX86.h |
---|
0,0 → 1,195 |
/* |
Header definitions for the x86 routines for the HERMES library |
Copyright (c) 1998 Christian Nentwich (brn@eleet.mcb.at) |
This source code is licensed under the GNU LGPL |
Please refer to the file COPYING.LIB contained in the distribution for |
licensing conditions |
*/ |
#ifndef __HERMES_HEAD_X86__ |
#define __HERMES_HEAD_X86__ |
#ifdef X86_ASSEMBLER |
/* If you can't stand IFDEFS, then close your eyes now, please :) */ |
/* Ok, we start with normal function definitions */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
void STACKCALL ConvertX86(HermesConverterInterface *); |
void STACKCALL ClearX86_32(HermesClearInterface *); |
void STACKCALL ClearX86_24(HermesClearInterface *); |
void STACKCALL ClearX86_16(HermesClearInterface *); |
void STACKCALL ClearX86_8(HermesClearInterface *); |
int STACKCALL Hermes_X86_CPU(); |
void ConvertX86p32_32BGR888(); |
void ConvertX86p32_32RGBA888(); |
void ConvertX86p32_32BGRA888(); |
void ConvertX86p32_24RGB888(); |
void ConvertX86p32_24BGR888(); |
void ConvertX86p32_16RGB565(); |
void ConvertX86p32_16BGR565(); |
void ConvertX86p32_16RGB555(); |
void ConvertX86p32_16BGR555(); |
void ConvertX86p32_8RGB332(); |
void ConvertX86p16_32RGB888(); |
void ConvertX86p16_32BGR888(); |
void ConvertX86p16_32RGBA888(); |
void ConvertX86p16_32BGRA888(); |
void ConvertX86p16_24RGB888(); |
void ConvertX86p16_24BGR888(); |
void ConvertX86p16_16BGR565(); |
void ConvertX86p16_16RGB555(); |
void ConvertX86p16_16BGR555(); |
void ConvertX86p16_8RGB332(); |
void CopyX86p_4byte(); |
void CopyX86p_3byte(); |
void CopyX86p_2byte(); |
void CopyX86p_1byte(); |
void ConvertX86pI8_32(); |
void ConvertX86pI8_24(); |
void ConvertX86pI8_16(); |
extern int32 ConvertX86p16_32RGB888_LUT_X86[512]; |
extern int32 ConvertX86p16_32BGR888_LUT_X86[512]; |
extern int32 ConvertX86p16_32RGBA888_LUT_X86[512]; |
extern int32 ConvertX86p16_32BGRA888_LUT_X86[512]; |
#ifdef __cplusplus |
} |
#endif |
/* Now fix up the ELF underscore problem */ |
#if defined(__ELF__) && defined(__GNUC__) |
#ifdef __cplusplus |
extern "C" { |
#endif |
int Hermes_X86_CPU() __attribute__ ((alias ("_Hermes_X86_CPU"))); |
void ConvertX86(HermesConverterInterface *) __attribute__ ((alias ("_ConvertX86"))); |
#if 0 |
void ClearX86_32(HermesClearInterface *) __attribute__ ((alias ("_ClearX86_32"))); |
void ClearX86_24(HermesClearInterface *) __attribute__ ((alias ("_ClearX86_24"))); |
void ClearX86_16(HermesClearInterface *) __attribute__ ((alias ("_ClearX86_16"))); |
void ClearX86_8(HermesClearInterface *) __attribute__ ((alias ("_ClearX86_8"))); |
#endif |
void ConvertX86p32_32BGR888() __attribute__ ((alias ("_ConvertX86p32_32BGR888"))); |
void ConvertX86p32_32RGBA888() __attribute__ ((alias ("_ConvertX86p32_32RGBA888"))); |
void ConvertX86p32_32BGRA888() __attribute__ ((alias ("_ConvertX86p32_32BGRA888"))); |
void ConvertX86p32_24RGB888() __attribute__ ((alias ("_ConvertX86p32_24RGB888"))); |
void ConvertX86p32_24BGR888() __attribute__ ((alias ("_ConvertX86p32_24BGR888"))); |
void ConvertX86p32_16RGB565() __attribute__ ((alias ("_ConvertX86p32_16RGB565"))); |
void ConvertX86p32_16BGR565() __attribute__ ((alias ("_ConvertX86p32_16BGR565"))); |
void ConvertX86p32_16RGB555() __attribute__ ((alias ("_ConvertX86p32_16RGB555"))); |
void ConvertX86p32_16BGR555() __attribute__ ((alias ("_ConvertX86p32_16BGR555"))); |
void ConvertX86p32_8RGB332() __attribute__ ((alias ("_ConvertX86p32_8RGB332"))); |
#if 0 |
void ConvertX86p16_32RGB888() __attribute__ ((alias ("_ConvertX86p16_32RGB888"))); |
void ConvertX86p16_32BGR888() __attribute__ ((alias ("_ConvertX86p16_32BGR888"))); |
void ConvertX86p16_32RGBA888() __attribute__ ((alias ("_ConvertX86p16_32RGBA888"))); |
void ConvertX86p16_32BGRA888() __attribute__ ((alias ("_ConvertX86p16_32BGRA888"))); |
void ConvertX86p16_24RGB888() __attribute__ ((alias ("_ConvertX86p16_24RGB888"))); |
void ConvertX86p16_24BGR888() __attribute__ ((alias ("_ConvertX86p16_24BGR888"))); |
#endif |
void ConvertX86p16_16BGR565() __attribute__ ((alias ("_ConvertX86p16_16BGR565"))); |
void ConvertX86p16_16RGB555() __attribute__ ((alias ("_ConvertX86p16_16RGB555"))); |
void ConvertX86p16_16BGR555() __attribute__ ((alias ("_ConvertX86p16_16BGR555"))); |
void ConvertX86p16_8RGB332() __attribute__ ((alias ("_ConvertX86p16_8RGB332"))); |
#if 0 |
void CopyX86p_4byte() __attribute__ ((alias ("_CopyX86p_4byte"))); |
void CopyX86p_3byte() __attribute__ ((alias ("_CopyX86p_3byte"))); |
void CopyX86p_2byte() __attribute__ ((alias ("_CopyX86p_2byte"))); |
void CopyX86p_1byte() __attribute__ ((alias ("_CopyX86p_1byte"))); |
void ConvertX86pI8_32() __attribute__ ((alias ("_ConvertX86pI8_32"))); |
void ConvertX86pI8_24() __attribute__ ((alias ("_ConvertX86pI8_24"))); |
void ConvertX86pI8_16() __attribute__ ((alias ("_ConvertX86pI8_16"))); |
extern int32 ConvertX86p16_32RGB888_LUT_X86[512] __attribute__ ((alias ("_ConvertX86p16_32RGB888_LUT_X86"))); |
extern int32 ConvertX86p16_32BGR888_LUT_X86[512] __attribute__ ((alias ("_ConvertX86p16_32BGR888_LUT_X86"))); |
extern int32 ConvertX86p16_32RGBA888_LUT_X86[512] __attribute__ ((alias ("_ConvertX86p16_32RGBA888_LUT_X86"))); |
extern int32 ConvertX86p16_32BGRA888_LUT_X86[512] __attribute__ ((alias ("_ConvertX86p16_32BGRA888_LUT_X86"))); |
#endif |
#ifdef __cplusplus |
} |
#endif |
#endif /* ELF & GNU */ |
/* Make it run with WATCOM C */ |
#ifdef __WATCOMC__ |
#pragma warning 601 9 |
#pragma aux Hermes_X86_CPU "_*" |
#pragma aux ConvertX86 "_*" modify [EAX EBX ECX EDX ESI EDI] |
#pragma aux ClearX86_32 "_*" modify [EAX EBX ECX EDX ESI EDI] |
#pragma aux ClearX86_24 "_*" modify [EAX EBX ECX EDX ESI EDI] |
#pragma aux ClearX86_16 "_*" modify [EAX EBX ECX EDX ESI EDI] |
#pragma aux ClearX86_8 "_*" modify [EAX EBX ECX EDX ESI EDI] |
#pragma aux ConvertX86p32_32BGR888 "_*" |
#pragma aux ConvertX86p32_32RGBA888 "_*" |
#pragma aux ConvertX86p32_32BGRA888 "_*" |
#pragma aux ConvertX86p32_24RGB888 "_*" |
#pragma aux ConvertX86p32_24BGR888 "_*" |
#pragma aux ConvertX86p32_16RGB565 "_*" |
#pragma aux ConvertX86p32_16BGR565 "_*" |
#pragma aux ConvertX86p32_16RGB555 "_*" |
#pragma aux ConvertX86p32_16BGR555 "_*" |
#pragma aux ConvertX86p32_8RGB332 "_*" |
#pragma aux ConvertX86p16_32RGB888 "_*" |
#pragma aux ConvertX86p16_32BGR888 "_*" |
#pragma aux ConvertX86p16_32RGBA888 "_*" |
#pragma aux ConvertX86p16_32BGRA888 "_*" |
#pragma aux ConvertX86p16_24RGB888 "_*" |
#pragma aux ConvertX86p16_24BGR888 "_*" |
#pragma aux ConvertX86p16_16BGR565 "_*" |
#pragma aux ConvertX86p16_16RGB555 "_*" |
#pragma aux ConvertX86p16_16BGR555 "_*" |
#pragma aux ConvertX86p16_8RGB332 "_*" |
#pragma aux CopyX86p_4byte "_*" |
#pragma aux CopyX86p_3byte "_*" |
#pragma aux CopyX86p_2byte "_*" |
#pragma aux CopyX86p_1byte "_*" |
#pragma aux ConvertX86pI8_32 "_*" |
#pragma aux ConvertX86pI8_24 "_*" |
#pragma aux ConvertX86pI8_16 "_*" |
#pragma aux ConvertX86p16_32RGB888_LUT_X86 "_*" |
#pragma aux ConvertX86p16_32BGR888_LUT_X86 "_*" |
#pragma aux ConvertX86p16_32RGBA888_LUT_X86 "_*" |
#pragma aux ConvertX86p16_32BGRA888_LUT_X86 "_*" |
#endif /* __WATCOMC__ */ |
#endif /* X86_ASSEMBLER */ |
#endif |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/hermes/mmx_main.asm |
---|
0,0 → 1,74 |
; |
; mmx format converter main loops for HERMES |
; Some routines Copyright (c) 1998 Christian Nentwich (c.nentwich@cs.ucl.ac.uk) |
; This source code is licensed under the GNU LGPL |
; |
; Please refer to the file COPYING.LIB contained in the distribution for |
; licensing conditions |
; |
BITS 32 |
GLOBAL _ConvertMMX |
GLOBAL _mmxreturn |
SECTION .text |
;; _ConvertMMX: |
;; [ESP+8] ConverterInfo* |
;; -------------------------------------------------------------------------- |
;; ConverterInfo (ebp+..) |
;; 0: void *s_pixels |
;; 4: int s_width |
;; 8: int s_height |
;; 12: int s_add |
;; 16: void *d_pixels |
;; 20: int d_width |
;; 24: int d_height |
;; 28: int d_add |
;; 32: void (*converter_function)() |
;; 36: int32 *lookup |
_ConvertMMX: |
push ebp |
mov ebp,esp |
; Save the registers used by the blitters, necessary for optimized code |
pusha |
mov eax,[ebp+8] |
cmp dword [eax+4],BYTE 0 |
je endconvert |
mov ebp,eax |
mov esi,[ebp+0] |
mov edi,[ebp+16] |
y_loop: |
mov ecx,[ebp+4] |
jmp [ebp+32] |
_mmxreturn: |
add esi,[ebp+12] |
add edi,[ebp+28] |
dec dword [ebp+8] |
jnz y_loop |
; Restore the registers used by the blitters, necessary for optimized code |
popa |
pop ebp |
endconvert: |
emms |
ret |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/hermes/mmxp2_32.asm |
---|
0,0 → 1,386 |
; |
; pII-optimised MMX format converters for HERMES |
; Copyright (c) 1998 Christian Nentwich (c.nentwich@cs.ucl.ac.uk) |
; and (c) 1999 Jonathan Matthew (jmatthew@uq.net.au) |
; This source code is licensed under the GNU LGPL |
; |
; Please refer to the file COPYING.LIB contained in the distribution for |
; licensing conditions |
; |
; COPYRIGHT NOTICE |
; |
; This file partly contains code that is (c) Intel Corporation, specifically |
; the mode detection routine, and the converter to 15 bit (8 pixel |
; conversion routine from the mmx programming tutorial pages). |
; |
; |
; These routines aren't exactly pII optimised - it's just that as they |
; are, they're terrible on p5 MMXs, but less so on pIIs. Someone needs to |
; optimise them for p5 MMXs.. |
BITS 32 |
GLOBAL _ConvertMMXpII32_24RGB888 |
GLOBAL _ConvertMMXpII32_16RGB565 |
GLOBAL _ConvertMMXpII32_16BGR565 |
GLOBAL _ConvertMMXpII32_16RGB555 |
GLOBAL _ConvertMMXpII32_16BGR555 |
EXTERN _mmxreturn |
SECTION .data |
ALIGN 8 |
;; Constants for conversion routines |
mmx32_rgb888_mask dd 00ffffffh,00ffffffh |
mmx32_rgb565_b dd 000000f8h, 000000f8h |
mmx32_rgb565_g dd 0000fc00h, 0000fc00h |
mmx32_rgb565_r dd 00f80000h, 00f80000h |
mmx32_rgb555_rb dd 00f800f8h,00f800f8h |
mmx32_rgb555_g dd 0000f800h,0000f800h |
mmx32_rgb555_mul dd 20000008h,20000008h |
mmx32_bgr555_mul dd 00082000h,00082000h |
SECTION .text |
_ConvertMMXpII32_24RGB888: |
; set up mm6 as the mask, mm7 as zero |
movq mm6, qword [mmx32_rgb888_mask] |
pxor mm7, mm7 |
mov edx, ecx ; save ecx |
and ecx, 0fffffffch ; clear lower two bits |
jnz .L1 |
jmp .L2 |
.L1: |
movq mm0, [esi] ; A R G B a r g b |
pand mm0, mm6 ; 0 R G B 0 r g b |
movq mm1, [esi+8] ; A R G B a r g b |
pand mm1, mm6 ; 0 R G B 0 r g b |
movq mm2, mm0 ; 0 R G B 0 r g b |
punpckhdq mm2, mm7 ; 0 0 0 0 0 R G B |
punpckldq mm0, mm7 ; 0 0 0 0 0 r g b |
psllq mm2, 24 ; 0 0 R G B 0 0 0 |
por mm0, mm2 ; 0 0 R G B r g b |
movq mm3, mm1 ; 0 R G B 0 r g b |
psllq mm3, 48 ; g b 0 0 0 0 0 0 |
por mm0, mm3 ; g b R G B r g b |
movq mm4, mm1 ; 0 R G B 0 r g b |
punpckhdq mm4, mm7 ; 0 0 0 0 0 R G B |
punpckldq mm1, mm7 ; 0 0 0 0 0 r g b |
psrlq mm1, 16 ; 0 0 0 R G B 0 r |
psllq mm4, 8 ; 0 0 0 0 R G B 0 |
por mm1, mm4 ; 0 0 0 0 R G B r |
movq [edi], mm0 |
add esi, BYTE 16 |
movd [edi+8], mm1 |
add edi, BYTE 12 |
sub ecx, BYTE 4 |
jnz .L1 |
.L2: |
mov ecx, edx |
and ecx, BYTE 3 |
jz .L4 |
.L3: |
mov al, [esi] |
mov bl, [esi+1] |
mov dl, [esi+2] |
mov [edi], al |
mov [edi+1], bl |
mov [edi+2], dl |
add esi, BYTE 4 |
add edi, BYTE 3 |
dec ecx |
jnz .L3 |
.L4: |
jmp _mmxreturn |
_ConvertMMXpII32_16RGB565: |
; set up masks |
movq mm5, [mmx32_rgb565_b] |
movq mm6, [mmx32_rgb565_g] |
movq mm7, [mmx32_rgb565_r] |
mov edx, ecx |
shr ecx, 2 |
jnz .L1 |
jmp .L2 ; not necessary at the moment, but doesn't hurt (much) |
.L1: |
movq mm0, [esi] ; argb |
movq mm1, mm0 ; argb |
pand mm0, mm6 ; 00g0 |
movq mm3, mm1 ; argb |
pand mm1, mm5 ; 000b |
pand mm3, mm7 ; 0r00 |
pslld mm1, 2 ; 0 0 000000bb bbb00000 |
por mm0, mm1 ; 0 0 ggggggbb bbb00000 |
psrld mm0, 5 ; 0 0 00000ggg gggbbbbb |
movq mm4, [esi+8] ; argb |
movq mm2, mm4 ; argb |
pand mm4, mm6 ; 00g0 |
movq mm1, mm2 ; argb |
pand mm2, mm5 ; 000b |
pand mm1, mm7 ; 0r00 |
pslld mm2, 2 ; 0 0 000000bb bbb00000 |
por mm4, mm2 ; 0 0 ggggggbb bbb00000 |
psrld mm4, 5 ; 0 0 00000ggg gggbbbbb |
packuswb mm3, mm1 ; R 0 r 0 |
packssdw mm0, mm4 ; as above.. ish |
por mm0, mm3 ; done. |
movq [edi], mm0 |
add esi, 16 |
add edi, 8 |
dec ecx |
jnz .L1 |
.L2: |
mov ecx, edx |
and ecx, BYTE 3 |
jz .L4 |
.L3: |
mov al, [esi] |
mov bh, [esi+1] |
mov ah, [esi+2] |
shr al, 3 |
and eax, 0F81Fh ; BYTE? |
shr ebx, 5 |
and ebx, 07E0h ; BYTE? |
add eax, ebx |
mov [edi], al |
mov [edi+1], ah |
add esi, BYTE 4 |
add edi, BYTE 2 |
dec ecx |
jnz .L3 |
.L4: |
jmp _mmxreturn |
_ConvertMMXpII32_16BGR565: |
movq mm5, [mmx32_rgb565_r] |
movq mm6, [mmx32_rgb565_g] |
movq mm7, [mmx32_rgb565_b] |
mov edx, ecx |
shr ecx, 2 |
jnz .L1 |
jmp .L2 |
.L1: |
movq mm0, [esi] ; a r g b |
movq mm1, mm0 ; a r g b |
pand mm0, mm6 ; 0 0 g 0 |
movq mm3, mm1 ; a r g b |
pand mm1, mm5 ; 0 r 0 0 |
pand mm3, mm7 ; 0 0 0 b |
psllq mm3, 16 ; 0 b 0 0 |
psrld mm1, 14 ; 0 0 000000rr rrr00000 |
por mm0, mm1 ; 0 0 ggggggrr rrr00000 |
psrld mm0, 5 ; 0 0 00000ggg gggrrrrr |
movq mm4, [esi+8] ; a r g b |
movq mm2, mm4 ; a r g b |
pand mm4, mm6 ; 0 0 g 0 |
movq mm1, mm2 ; a r g b |
pand mm2, mm5 ; 0 r 0 0 |
pand mm1, mm7 ; 0 0 0 b |
psllq mm1, 16 ; 0 b 0 0 |
psrld mm2, 14 ; 0 0 000000rr rrr00000 |
por mm4, mm2 ; 0 0 ggggggrr rrr00000 |
psrld mm4, 5 ; 0 0 00000ggg gggrrrrr |
packuswb mm3, mm1 ; BBBBB000 00000000 bbbbb000 00000000 |
packssdw mm0, mm4 ; 00000GGG GGGRRRRR 00000GGG GGGRRRRR |
por mm0, mm3 ; BBBBBGGG GGGRRRRR bbbbbggg gggrrrrr |
movq [edi], mm0 |
add esi, BYTE 16 |
add edi, BYTE 8 |
dec ecx |
jnz .L1 |
.L2: |
and edx, BYTE 3 |
jz .L4 |
.L3: |
mov al, [esi+2] |
mov bh, [esi+1] |
mov ah, [esi] |
shr al, 3 |
and eax, 0F81Fh ; BYTE ? |
shr ebx, 5 |
and ebx, 07E0h ; BYTE ? |
add eax, ebx |
mov [edi], al |
mov [edi+1], ah |
add esi, BYTE 4 |
add edi, BYTE 2 |
dec edx |
jnz .L3 |
.L4: |
jmp _mmxreturn |
_ConvertMMXpII32_16BGR555: |
; the 16BGR555 converter is identical to the RGB555 one, |
; except it uses a different multiplier for the pmaddwd |
; instruction. cool huh. |
movq mm7, qword [mmx32_bgr555_mul] |
jmp _convert_bgr555_cheat |
; This is the same as the Intel version.. they obviously went to |
; much more trouble to expand/coil the loop than I did, so theirs |
; would almost certainly be faster, even if only a little. |
; I did rename 'mmx32_rgb555_add' to 'mmx32_rgb555_mul', which is |
; (I think) a more accurate name.. |
_ConvertMMXpII32_16RGB555: |
movq mm7,qword [mmx32_rgb555_mul] |
_convert_bgr555_cheat: |
movq mm6,qword [mmx32_rgb555_g] |
mov edx,ecx ; Save ecx |
and ecx,BYTE 0fffffff8h ; clear lower three bits |
jnz .L_OK |
jmp .L2 |
.L_OK: |
movq mm2,[esi+8] |
movq mm0,[esi] |
movq mm3,mm2 |
pand mm3,qword [mmx32_rgb555_rb] |
movq mm1,mm0 |
pand mm1,qword [mmx32_rgb555_rb] |
pmaddwd mm3,mm7 |
pmaddwd mm1,mm7 |
pand mm2,mm6 |
.L1: |
movq mm4,[esi+24] |
pand mm0,mm6 |
movq mm5,[esi+16] |
por mm3,mm2 |
psrld mm3,6 |
por mm1,mm0 |
movq mm0,mm4 |
psrld mm1,6 |
pand mm0,qword [mmx32_rgb555_rb] |
packssdw mm1,mm3 |
movq mm3,mm5 |
pmaddwd mm0,mm7 |
pand mm3,qword [mmx32_rgb555_rb] |
pand mm4,mm6 |
movq [edi],mm1 |
pmaddwd mm3,mm7 |
add esi,BYTE 32 |
por mm4,mm0 |
pand mm5,mm6 |
psrld mm4,6 |
movq mm2,[esi+8] |
por mm5,mm3 |
movq mm0,[esi] |
psrld mm5,6 |
movq mm3,mm2 |
movq mm1,mm0 |
pand mm3,qword [mmx32_rgb555_rb] |
packssdw mm5,mm4 |
pand mm1,qword [mmx32_rgb555_rb] |
pand mm2,mm6 |
movq [edi+8],mm5 |
pmaddwd mm3,mm7 |
pmaddwd mm1,mm7 |
add edi,BYTE 16 |
sub ecx,BYTE 8 |
jz .L2 |
jmp .L1 |
.L2: |
mov ecx,edx |
and ecx,BYTE 7 |
jz .L4 |
.L3: |
mov ebx,[esi] |
add esi,BYTE 4 |
mov eax,ebx |
mov edx,ebx |
shr eax,3 |
shr edx,6 |
and eax,BYTE 0000000000011111b |
and edx, 0000001111100000b |
shr ebx,9 |
or eax,edx |
and ebx, 0111110000000000b |
or eax,ebx |
mov [edi],ax |
add edi,BYTE 2 |
dec ecx |
jnz .L3 |
.L4: |
jmp _mmxreturn |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/hermes/x86_main.asm |
---|
0,0 → 1,126 |
; |
; x86 format converters for HERMES |
; Some routines Copyright (c) 1998 Christian Nentwich (brn@eleet.mcb.at) |
; This source code is licensed under the GNU LGPL |
; |
; Please refer to the file COPYING.LIB contained in the distribution for |
; licensing conditions |
; |
; Most routines are (c) Glenn Fiedler (ptc@gaffer.org), used with permission |
; |
BITS 32 |
GLOBAL _ConvertX86 |
GLOBAL _x86return |
GLOBAL _Hermes_X86_CPU |
SECTION .data |
cpu_flags dd 0 |
SECTION .text |
;; _ConvertX86: |
;; [ESP+8] ConverterInfo* |
;; -------------------------------------------------------------------------- |
;; ConverterInfo (ebp+..) |
;; 0: void *s_pixels |
;; 4: int s_width |
;; 8: int s_height |
;; 12: int s_add |
;; 16: void *d_pixels |
;; 20: int d_width |
;; 24: int d_height |
;; 28: int d_add |
;; 32: void (*converter_function)() |
;; 36: int32 *lookup |
_ConvertX86: |
push ebp |
mov ebp,esp |
; Save the registers used by the blitters, necessary for optimized code |
pusha |
mov eax,[ebp+8] |
cmp dword [eax+4],BYTE 0 |
je endconvert |
mov ebp,eax |
mov esi,[ebp+0] |
mov edi,[ebp+16] |
y_loop: |
mov ecx,[ebp+4] |
jmp [ebp+32] |
_x86return: |
add esi,[ebp+12] |
add edi,[ebp+28] |
dec dword [ebp+8] |
jnz y_loop |
; Restore the registers used by the blitters, necessary for optimized code |
popa |
pop ebp |
endconvert: |
ret |
;; Hermes_X86_CPU returns the CPUID flags in eax |
_Hermes_X86_CPU: |
pushfd |
pop eax |
mov ecx,eax |
xor eax,040000h |
push eax |
popfd |
pushfd |
pop eax |
xor eax,ecx |
jz .L1 ; Processor is 386 |
push ecx |
popfd |
mov eax,ecx |
xor eax,200000h |
push eax |
popfd |
pushfd |
pop eax |
xor eax,ecx |
je .L1 |
pusha |
mov eax,1 |
cpuid |
mov [cpu_flags],edx |
popa |
mov eax,[cpu_flags] |
.L1: |
xor eax,eax |
ret |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/hermes/x86p_16.asm |
---|
0,0 → 1,496 |
; |
; x86 format converters for HERMES |
; Copyright (c) 1998 Glenn Fielder (gaffer@gaffer.org) |
; This source code is licensed under the GNU LGPL |
; |
; Please refer to the file COPYING.LIB contained in the distribution for |
; licensing conditions |
; |
; Routines adjusted for Hermes by Christian Nentwich (brn@eleet.mcb.at) |
; Used with permission. |
; |
BITS 32 |
GLOBAL _ConvertX86p16_32RGB888 |
GLOBAL _ConvertX86p16_32BGR888 |
GLOBAL _ConvertX86p16_32RGBA888 |
GLOBAL _ConvertX86p16_32BGRA888 |
GLOBAL _ConvertX86p16_24RGB888 |
GLOBAL _ConvertX86p16_24BGR888 |
GLOBAL _ConvertX86p16_16BGR565 |
GLOBAL _ConvertX86p16_16RGB555 |
GLOBAL _ConvertX86p16_16BGR555 |
GLOBAL _ConvertX86p16_8RGB332 |
EXTERN _ConvertX86 |
EXTERN _x86return |
SECTION .text |
_ConvertX86p16_16BGR565: |
; check short |
cmp ecx,BYTE 16 |
ja .L3 |
.L1 ; short loop |
mov al,[esi] |
mov ah,[esi+1] |
mov ebx,eax |
mov edx,eax |
shr eax,11 |
and eax,BYTE 11111b |
and ebx,11111100000b |
shl edx,11 |
add eax,ebx |
add eax,edx |
mov [edi],al |
mov [edi+1],ah |
add esi,BYTE 2 |
add edi,BYTE 2 |
dec ecx |
jnz .L1 |
.L2 |
jmp _x86return |
.L3 ; head |
mov eax,edi |
and eax,BYTE 11b |
jz .L4 |
mov al,[esi] |
mov ah,[esi+1] |
mov ebx,eax |
mov edx,eax |
shr eax,11 |
and eax,BYTE 11111b |
and ebx,11111100000b |
shl edx,11 |
add eax,ebx |
add eax,edx |
mov [edi],al |
mov [edi+1],ah |
add esi,BYTE 2 |
add edi,BYTE 2 |
dec ecx |
.L4 ; save count |
push ecx |
; unroll twice |
shr ecx,1 |
; point arrays to end |
lea esi,[esi+ecx*4] |
lea edi,[edi+ecx*4] |
; negative counter |
neg ecx |
jmp SHORT .L6 |
.L5 mov [edi+ecx*4-4],eax |
.L6 mov eax,[esi+ecx*4] |
mov ebx,[esi+ecx*4] |
and eax,07E007E0h |
mov edx,[esi+ecx*4] |
and ebx,0F800F800h |
shr ebx,11 |
and edx,001F001Fh |
shl edx,11 |
add eax,ebx |
add eax,edx |
inc ecx |
jnz .L5 |
mov [edi+ecx*4-4],eax |
; tail |
pop ecx |
and ecx,BYTE 1 |
jz .L7 |
mov al,[esi] |
mov ah,[esi+1] |
mov ebx,eax |
mov edx,eax |
shr eax,11 |
and eax,BYTE 11111b |
and ebx,11111100000b |
shl edx,11 |
add eax,ebx |
add eax,edx |
mov [edi],al |
mov [edi+1],ah |
add esi,BYTE 2 |
add edi,BYTE 2 |
.L7 |
jmp _x86return |
_ConvertX86p16_16RGB555: |
; check short |
cmp ecx,BYTE 32 |
ja .L3 |
.L1 ; short loop |
mov al,[esi] |
mov ah,[esi+1] |
mov ebx,eax |
shr ebx,1 |
and ebx, 0111111111100000b |
and eax,BYTE 0000000000011111b |
add eax,ebx |
mov [edi],al |
mov [edi+1],ah |
add esi,BYTE 2 |
add edi,BYTE 2 |
dec ecx |
jnz .L1 |
.L2 |
jmp _x86return |
.L3 ; head |
mov eax,edi |
and eax,BYTE 11b |
jz .L4 |
mov al,[esi] |
mov ah,[esi+1] |
mov ebx,eax |
shr ebx,1 |
and ebx, 0111111111100000b |
and eax,BYTE 0000000000011111b |
add eax,ebx |
mov [edi],al |
mov [edi+1],ah |
add esi,BYTE 2 |
add edi,BYTE 2 |
dec ecx |
.L4 ; save ebp |
push ebp |
; save count |
push ecx |
; unroll four times |
shr ecx,2 |
; point arrays to end |
lea esi,[esi+ecx*8] |
lea edi,[edi+ecx*8] |
; negative counter |
xor ebp,ebp |
sub ebp,ecx |
.L5 mov eax,[esi+ebp*8] ; agi? |
mov ecx,[esi+ebp*8+4] |
mov ebx,eax |
mov edx,ecx |
and eax,0FFC0FFC0h |
and ecx,0FFC0FFC0h |
shr eax,1 |
and ebx,001F001Fh |
shr ecx,1 |
and edx,001F001Fh |
add eax,ebx |
add ecx,edx |
mov [edi+ebp*8],eax |
mov [edi+ebp*8+4],ecx |
inc ebp |
jnz .L5 |
; tail |
pop ecx |
.L6 and ecx,BYTE 11b |
jz .L7 |
mov al,[esi] |
mov ah,[esi+1] |
mov ebx,eax |
shr ebx,1 |
and ebx, 0111111111100000b |
and eax,BYTE 0000000000011111b |
add eax,ebx |
mov [edi],al |
mov [edi+1],ah |
add esi,BYTE 2 |
add edi,BYTE 2 |
dec ecx |
jmp SHORT .L6 |
.L7 pop ebp |
jmp _x86return |
_ConvertX86p16_16BGR555: |
; check short |
cmp ecx,BYTE 16 |
ja .L3 |
.L1 ; short loop |
mov al,[esi] |
mov ah,[esi+1] |
mov ebx,eax |
mov edx,eax |
shr eax,11 |
and eax,BYTE 11111b |
shr ebx,1 |
and ebx,1111100000b |
shl edx,10 |
and edx,0111110000000000b |
add eax,ebx |
add eax,edx |
mov [edi],al |
mov [edi+1],ah |
add esi,BYTE 2 |
add edi,BYTE 2 |
dec ecx |
jnz .L1 |
.L2 |
jmp _x86return |
.L3 ; head |
mov eax,edi |
and eax,BYTE 11b |
jz .L4 |
mov al,[esi] |
mov ah,[esi+1] |
mov ebx,eax |
mov edx,eax |
shr eax,11 |
and eax,BYTE 11111b |
shr ebx,1 |
and ebx,1111100000b |
shl edx,10 |
and edx,0111110000000000b |
add eax,ebx |
add eax,edx |
mov [edi],al |
mov [edi+1],ah |
add esi,BYTE 2 |
add edi,BYTE 2 |
dec ecx |
.L4 ; save count |
push ecx |
; unroll twice |
shr ecx,1 |
; point arrays to end |
lea esi,[esi+ecx*4] |
lea edi,[edi+ecx*4] |
; negative counter |
neg ecx |
jmp SHORT .L6 |
.L5 mov [edi+ecx*4-4],eax |
.L6 mov eax,[esi+ecx*4] |
shr eax,1 |
mov ebx,[esi+ecx*4] |
and eax,03E003E0h |
mov edx,[esi+ecx*4] |
and ebx,0F800F800h |
shr ebx,11 |
and edx,001F001Fh |
shl edx,10 |
add eax,ebx |
add eax,edx |
inc ecx |
jnz .L5 |
mov [edi+ecx*4-4],eax |
; tail |
pop ecx |
and ecx,BYTE 1 |
jz .L7 |
mov al,[esi] |
mov ah,[esi+1] |
mov ebx,eax |
mov edx,eax |
shr eax,11 |
and eax,BYTE 11111b |
shr ebx,1 |
and ebx,1111100000b |
shl edx,10 |
and edx,0111110000000000b |
add eax,ebx |
add eax,edx |
mov [edi],al |
mov [edi+1],ah |
add esi,BYTE 2 |
add edi,BYTE 2 |
.L7 |
jmp _x86return |
_ConvertX86p16_8RGB332: |
; check short |
cmp ecx,BYTE 16 |
ja .L3 |
.L1 ; short loop |
mov al,[esi+0] |
mov ah,[esi+1] |
mov ebx,eax |
mov edx,eax |
and eax,BYTE 11000b ; blue |
shr eax,3 |
and ebx,11100000000b ; green |
shr ebx,6 |
and edx,1110000000000000b ; red |
shr edx,8 |
add eax,ebx |
add eax,edx |
mov [edi],al |
add esi,BYTE 2 |
inc edi |
dec ecx |
jnz .L1 |
.L2 |
jmp _x86return |
.L3 mov eax,edi |
and eax,BYTE 11b |
jz .L4 |
mov al,[esi+0] |
mov ah,[esi+1] |
mov ebx,eax |
mov edx,eax |
and eax,BYTE 11000b ; blue |
shr eax,3 |
and ebx,11100000000b ; green |
shr ebx,6 |
and edx,1110000000000000b ; red |
shr edx,8 |
add eax,ebx |
add eax,edx |
mov [edi],al |
add esi,BYTE 2 |
inc edi |
dec ecx |
jmp SHORT .L3 |
.L4 ; save ebp |
push ebp |
; save count |
push ecx |
; unroll 4 times |
shr ecx,2 |
; prestep |
mov dl,[esi+0] |
mov bl,[esi+1] |
mov dh,[esi+2] |
.L5 shl edx,16 |
mov bh,[esi+3] |
shl ebx,16 |
mov dl,[esi+4] |
mov dh,[esi+6] |
mov bl,[esi+5] |
and edx,00011000000110000001100000011000b |
mov bh,[esi+7] |
ror edx,16+3 |
mov eax,ebx ; setup eax for reds |
and ebx,00000111000001110000011100000111b |
and eax,11100000111000001110000011100000b ; reds |
ror ebx,16-2 |
add esi,BYTE 8 |
ror eax,16 |
add edi,BYTE 4 |
add eax,ebx |
mov bl,[esi+1] ; greens |
add eax,edx |
mov dl,[esi+0] ; blues |
mov [edi-4],eax |
mov dh,[esi+2] |
dec ecx |
jnz .L5 |
; check tail |
pop ecx |
and ecx,BYTE 11b |
jz .L7 |
.L6 ; tail |
mov al,[esi+0] |
mov ah,[esi+1] |
mov ebx,eax |
mov edx,eax |
and eax,BYTE 11000b ; blue |
shr eax,3 |
and ebx,11100000000b ; green |
shr ebx,6 |
and edx,1110000000000000b ; red |
shr edx,8 |
add eax,ebx |
add eax,edx |
mov [edi],al |
add esi,BYTE 2 |
inc edi |
dec ecx |
jnz .L6 |
.L7 pop ebp |
jmp _x86return |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/hermes/x86p_32.asm |
---|
0,0 → 1,1043 |
; |
; x86 format converters for HERMES |
; Some routines Copyright (c) 1998 Christian Nentwich (brn@eleet.mcb.at) |
; This source code is licensed under the GNU LGPL |
; |
; Please refer to the file COPYING.LIB contained in the distribution for |
; licensing conditions |
; |
; Most routines are (c) Glenn Fiedler (ptc@gaffer.org), used with permission |
; |
BITS 32 |
GLOBAL _ConvertX86p32_32BGR888 |
GLOBAL _ConvertX86p32_32RGBA888 |
GLOBAL _ConvertX86p32_32BGRA888 |
GLOBAL _ConvertX86p32_24RGB888 |
GLOBAL _ConvertX86p32_24BGR888 |
GLOBAL _ConvertX86p32_16RGB565 |
GLOBAL _ConvertX86p32_16BGR565 |
GLOBAL _ConvertX86p32_16RGB555 |
GLOBAL _ConvertX86p32_16BGR555 |
GLOBAL _ConvertX86p32_8RGB332 |
EXTERN _x86return |
SECTION .text |
;; _Convert_* |
;; Paramters: |
;; ESI = source |
;; EDI = dest |
;; ECX = amount (NOT 0!!! (the _ConvertX86 routine checks for that though)) |
;; Destroys: |
;; EAX, EBX, EDX |
_ConvertX86p32_32BGR888: |
; check short |
cmp ecx,BYTE 32 |
ja .L3 |
.L1 ; short loop |
mov edx,[esi] |
bswap edx |
ror edx,8 |
mov [edi],edx |
add esi,BYTE 4 |
add edi,BYTE 4 |
dec ecx |
jnz .L1 |
.L2 |
jmp _x86return |
.L3 ; save ebp |
push ebp |
; unroll four times |
mov ebp,ecx |
shr ebp,2 |
; save count |
push ecx |
.L4 mov eax,[esi] |
mov ebx,[esi+4] |
bswap eax |
bswap ebx |
ror eax,8 |
mov ecx,[esi+8] |
ror ebx,8 |
mov edx,[esi+12] |
bswap ecx |
bswap edx |
ror ecx,8 |
mov [edi+0],eax |
ror edx,8 |
mov [edi+4],ebx |
mov [edi+8],ecx |
mov [edi+12],edx |
add esi,BYTE 16 |
add edi,BYTE 16 |
dec ebp |
jnz .L4 |
; check tail |
pop ecx |
and ecx,BYTE 11b |
jz .L6 |
.L5 ; tail loop |
mov edx,[esi] |
bswap edx |
ror edx,8 |
mov [edi],edx |
add esi,BYTE 4 |
add edi,BYTE 4 |
dec ecx |
jnz .L5 |
.L6 pop ebp |
jmp _x86return |
_ConvertX86p32_32RGBA888: |
; check short |
cmp ecx,BYTE 32 |
ja .L3 |
.L1 ; short loop |
mov edx,[esi] |
rol edx,8 |
mov [edi],edx |
add esi,BYTE 4 |
add edi,BYTE 4 |
dec ecx |
jnz .L1 |
.L2 |
jmp _x86return |
.L3 ; save ebp |
push ebp |
; unroll four times |
mov ebp,ecx |
shr ebp,2 |
; save count |
push ecx |
.L4 mov eax,[esi] |
mov ebx,[esi+4] |
rol eax,8 |
mov ecx,[esi+8] |
rol ebx,8 |
mov edx,[esi+12] |
rol ecx,8 |
mov [edi+0],eax |
rol edx,8 |
mov [edi+4],ebx |
mov [edi+8],ecx |
mov [edi+12],edx |
add esi,BYTE 16 |
add edi,BYTE 16 |
dec ebp |
jnz .L4 |
; check tail |
pop ecx |
and ecx,BYTE 11b |
jz .L6 |
.L5 ; tail loop |
mov edx,[esi] |
rol edx,8 |
mov [edi],edx |
add esi,BYTE 4 |
add edi,BYTE 4 |
dec ecx |
jnz .L5 |
.L6 pop ebp |
jmp _x86return |
_ConvertX86p32_32BGRA888: |
; check short |
cmp ecx,BYTE 32 |
ja .L3 |
.L1 ; short loop |
mov edx,[esi] |
bswap edx |
mov [edi],edx |
add esi,BYTE 4 |
add edi,BYTE 4 |
dec ecx |
jnz .L1 |
.L2 |
jmp _x86return |
.L3 ; save ebp |
push ebp |
; unroll four times |
mov ebp,ecx |
shr ebp,2 |
; save count |
push ecx |
.L4 mov eax,[esi] |
mov ebx,[esi+4] |
mov ecx,[esi+8] |
mov edx,[esi+12] |
bswap eax |
bswap ebx |
bswap ecx |
bswap edx |
mov [edi+0],eax |
mov [edi+4],ebx |
mov [edi+8],ecx |
mov [edi+12],edx |
add esi,BYTE 16 |
add edi,BYTE 16 |
dec ebp |
jnz .L4 |
; check tail |
pop ecx |
and ecx,BYTE 11b |
jz .L6 |
.L5 ; tail loop |
mov edx,[esi] |
bswap edx |
mov [edi],edx |
add esi,BYTE 4 |
add edi,BYTE 4 |
dec ecx |
jnz .L5 |
.L6 pop ebp |
jmp _x86return |
;; 32 bit RGB 888 to 24 BIT RGB 888 |
_ConvertX86p32_24RGB888: |
; check short |
cmp ecx,BYTE 32 |
ja .L3 |
.L1 ; short loop |
mov al,[esi] |
mov bl,[esi+1] |
mov dl,[esi+2] |
mov [edi],al |
mov [edi+1],bl |
mov [edi+2],dl |
add esi,BYTE 4 |
add edi,BYTE 3 |
dec ecx |
jnz .L1 |
.L2 |
jmp _x86return |
.L3 ; head |
mov edx,edi |
and edx,BYTE 11b |
jz .L4 |
mov al,[esi] |
mov bl,[esi+1] |
mov dl,[esi+2] |
mov [edi],al |
mov [edi+1],bl |
mov [edi+2],dl |
add esi,BYTE 4 |
add edi,BYTE 3 |
dec ecx |
jmp SHORT .L3 |
.L4 ; unroll 4 times |
push ebp |
mov ebp,ecx |
shr ebp,2 |
; save count |
push ecx |
.L5 mov eax,[esi] ; first dword eax = [A][R][G][B] |
mov ebx,[esi+4] ; second dword ebx = [a][r][g][b] |
shl eax,8 ; eax = [R][G][B][.] |
mov ecx,[esi+12] ; third dword ecx = [a][r][g][b] |
shl ebx,8 ; ebx = [r][g][b][.] |
mov al,[esi+4] ; eax = [R][G][B][b] |
ror eax,8 ; eax = [b][R][G][B] (done) |
mov bh,[esi+8+1] ; ebx = [r][g][G][.] |
mov [edi],eax |
add edi,BYTE 3*4 |
shl ecx,8 ; ecx = [r][g][b][.] |
mov bl,[esi+8+0] ; ebx = [r][g][G][B] |
rol ebx,16 ; ebx = [G][B][r][g] (done) |
mov cl,[esi+8+2] ; ecx = [r][g][b][R] (done) |
mov [edi+4-3*4],ebx |
add esi,BYTE 4*4 |
mov [edi+8-3*4],ecx |
dec ebp |
jnz .L5 |
; check tail |
pop ecx |
and ecx,BYTE 11b |
jz .L7 |
.L6 ; tail loop |
mov al,[esi] |
mov bl,[esi+1] |
mov dl,[esi+2] |
mov [edi],al |
mov [edi+1],bl |
mov [edi+2],dl |
add esi,BYTE 4 |
add edi,BYTE 3 |
dec ecx |
jnz .L6 |
.L7 pop ebp |
jmp _x86return |
;; 32 bit RGB 888 to 24 bit BGR 888 |
_ConvertX86p32_24BGR888: |
; check short |
cmp ecx,BYTE 32 |
ja .L3 |
.L1 ; short loop |
mov dl,[esi] |
mov bl,[esi+1] |
mov al,[esi+2] |
mov [edi],al |
mov [edi+1],bl |
mov [edi+2],dl |
add esi,BYTE 4 |
add edi,BYTE 3 |
dec ecx |
jnz .L1 |
.L2 |
jmp _x86return |
.L3 ; head |
mov edx,edi |
and edx,BYTE 11b |
jz .L4 |
mov dl,[esi] |
mov bl,[esi+1] |
mov al,[esi+2] |
mov [edi],al |
mov [edi+1],bl |
mov [edi+2],dl |
add esi,BYTE 4 |
add edi,BYTE 3 |
dec ecx |
jmp SHORT .L3 |
.L4 ; unroll 4 times |
push ebp |
mov ebp,ecx |
shr ebp,2 |
; save count |
push ecx |
.L5 |
mov eax,[esi] ; first dword eax = [A][R][G][B] |
mov ebx,[esi+4] ; second dword ebx = [a][r][g][b] |
bswap eax ; eax = [B][G][R][A] |
bswap ebx ; ebx = [b][g][r][a] |
mov al,[esi+4+2] ; eax = [B][G][R][r] |
mov bh,[esi+4+4+1] ; ebx = [b][g][G][a] |
ror eax,8 ; eax = [r][B][G][R] (done) |
mov bl,[esi+4+4+2] ; ebx = [b][g][G][R] |
ror ebx,16 ; ebx = [G][R][b][g] (done) |
mov [edi],eax |
mov [edi+4],ebx |
mov ecx,[esi+12] ; third dword ecx = [a][r][g][b] |
bswap ecx ; ecx = [b][g][r][a] |
mov cl,[esi+8] ; ecx = [b][g][r][B] (done) |
add esi,BYTE 4*4 |
mov [edi+8],ecx |
add edi,BYTE 3*4 |
dec ebp |
jnz .L5 |
; check tail |
pop ecx |
and ecx,BYTE 11b |
jz .L7 |
.L6 ; tail loop |
mov dl,[esi] |
mov bl,[esi+1] |
mov al,[esi+2] |
mov [edi],al |
mov [edi+1],bl |
mov [edi+2],dl |
add esi,BYTE 4 |
add edi,BYTE 3 |
dec ecx |
jnz .L6 |
.L7 |
pop ebp |
jmp _x86return |
;; 32 bit RGB 888 to 16 BIT RGB 565 |
_ConvertX86p32_16RGB565: |
; check short |
cmp ecx,BYTE 16 |
ja .L3 |
.L1 ; short loop |
mov bl,[esi+0] ; blue |
mov al,[esi+1] ; green |
mov ah,[esi+2] ; red |
shr ah,3 |
and al,11111100b |
shl eax,3 |
shr bl,3 |
add al,bl |
mov [edi+0],al |
mov [edi+1],ah |
add esi,BYTE 4 |
add edi,BYTE 2 |
dec ecx |
jnz .L1 |
.L2: ; End of short loop |
jmp _x86return |
.L3 ; head |
mov ebx,edi |
and ebx,BYTE 11b |
jz .L4 |
mov bl,[esi+0] ; blue |
mov al,[esi+1] ; green |
mov ah,[esi+2] ; red |
shr ah,3 |
and al,11111100b |
shl eax,3 |
shr bl,3 |
add al,bl |
mov [edi+0],al |
mov [edi+1],ah |
add esi,BYTE 4 |
add edi,BYTE 2 |
dec ecx |
.L4: |
; save count |
push ecx |
; unroll twice |
shr ecx,1 |
; point arrays to end |
lea esi,[esi+ecx*8] |
lea edi,[edi+ecx*4] |
; negative counter |
neg ecx |
jmp SHORT .L6 |
.L5: |
mov [edi+ecx*4-4],eax |
.L6: |
mov eax,[esi+ecx*8] |
shr ah,2 |
mov ebx,[esi+ecx*8+4] |
shr eax,3 |
mov edx,[esi+ecx*8+4] |
shr bh,2 |
mov dl,[esi+ecx*8+2] |
shl ebx,13 |
and eax,000007FFh |
shl edx,8 |
and ebx,07FF0000h |
and edx,0F800F800h |
add eax,ebx |
add eax,edx |
inc ecx |
jnz .L5 |
mov [edi+ecx*4-4],eax |
; tail |
pop ecx |
test cl,1 |
jz .L7 |
mov bl,[esi+0] ; blue |
mov al,[esi+1] ; green |
mov ah,[esi+2] ; red |
shr ah,3 |
and al,11111100b |
shl eax,3 |
shr bl,3 |
add al,bl |
mov [edi+0],al |
mov [edi+1],ah |
add esi,BYTE 4 |
add edi,BYTE 2 |
.L7: |
jmp _x86return |
;; 32 bit RGB 888 to 16 BIT BGR 565 |
_ConvertX86p32_16BGR565: |
; check short |
cmp ecx,BYTE 16 |
ja .L3 |
.L1 ; short loop |
mov ah,[esi+0] ; blue |
mov al,[esi+1] ; green |
mov bl,[esi+2] ; red |
shr ah,3 |
and al,11111100b |
shl eax,3 |
shr bl,3 |
add al,bl |
mov [edi+0],al |
mov [edi+1],ah |
add esi,BYTE 4 |
add edi,BYTE 2 |
dec ecx |
jnz .L1 |
.L2 |
jmp _x86return |
.L3 ; head |
mov ebx,edi |
and ebx,BYTE 11b |
jz .L4 |
mov ah,[esi+0] ; blue |
mov al,[esi+1] ; green |
mov bl,[esi+2] ; red |
shr ah,3 |
and al,11111100b |
shl eax,3 |
shr bl,3 |
add al,bl |
mov [edi+0],al |
mov [edi+1],ah |
add esi,BYTE 4 |
add edi,BYTE 2 |
dec ecx |
.L4 ; save count |
push ecx |
; unroll twice |
shr ecx,1 |
; point arrays to end |
lea esi,[esi+ecx*8] |
lea edi,[edi+ecx*4] |
; negative count |
neg ecx |
jmp SHORT .L6 |
.L5 |
mov [edi+ecx*4-4],eax |
.L6 |
mov edx,[esi+ecx*8+4] |
mov bh,[esi+ecx*8+4] |
mov ah,[esi+ecx*8] |
shr bh,3 |
mov al,[esi+ecx*8+1] |
shr ah,3 |
mov bl,[esi+ecx*8+5] |
shl eax,3 |
mov dl,[esi+ecx*8+2] |
shl ebx,19 |
and eax,0000FFE0h |
shr edx,3 |
and ebx,0FFE00000h |
and edx,001F001Fh |
add eax,ebx |
add eax,edx |
inc ecx |
jnz .L5 |
mov [edi+ecx*4-4],eax |
; tail |
pop ecx |
and ecx,BYTE 1 |
jz .L7 |
mov ah,[esi+0] ; blue |
mov al,[esi+1] ; green |
mov bl,[esi+2] ; red |
shr ah,3 |
and al,11111100b |
shl eax,3 |
shr bl,3 |
add al,bl |
mov [edi+0],al |
mov [edi+1],ah |
add esi,BYTE 4 |
add edi,BYTE 2 |
.L7 |
jmp _x86return |
;; 32 BIT RGB TO 16 BIT RGB 555 |
_ConvertX86p32_16RGB555: |
; check short |
cmp ecx,BYTE 16 |
ja .L3 |
.L1 ; short loop |
mov bl,[esi+0] ; blue |
mov al,[esi+1] ; green |
mov ah,[esi+2] ; red |
shr ah,3 |
and al,11111000b |
shl eax,2 |
shr bl,3 |
add al,bl |
mov [edi+0],al |
mov [edi+1],ah |
add esi,BYTE 4 |
add edi,BYTE 2 |
dec ecx |
jnz .L1 |
.L2 |
jmp _x86return |
.L3 ; head |
mov ebx,edi |
and ebx,BYTE 11b |
jz .L4 |
mov bl,[esi+0] ; blue |
mov al,[esi+1] ; green |
mov ah,[esi+2] ; red |
shr ah,3 |
and al,11111000b |
shl eax,2 |
shr bl,3 |
add al,bl |
mov [edi+0],al |
mov [edi+1],ah |
add esi,BYTE 4 |
add edi,BYTE 2 |
dec ecx |
.L4 ; save count |
push ecx |
; unroll twice |
shr ecx,1 |
; point arrays to end |
lea esi,[esi+ecx*8] |
lea edi,[edi+ecx*4] |
; negative counter |
neg ecx |
jmp SHORT .L6 |
.L5 |
mov [edi+ecx*4-4],eax |
.L6 |
mov eax,[esi+ecx*8] |
shr ah,3 |
mov ebx,[esi+ecx*8+4] |
shr eax,3 |
mov edx,[esi+ecx*8+4] |
shr bh,3 |
mov dl,[esi+ecx*8+2] |
shl ebx,13 |
and eax,000007FFh |
shl edx,7 |
and ebx,07FF0000h |
and edx,07C007C00h |
add eax,ebx |
add eax,edx |
inc ecx |
jnz .L5 |
mov [edi+ecx*4-4],eax |
; tail |
pop ecx |
and ecx,BYTE 1 |
jz .L7 |
mov bl,[esi+0] ; blue |
mov al,[esi+1] ; green |
mov ah,[esi+2] ; red |
shr ah,3 |
and al,11111000b |
shl eax,2 |
shr bl,3 |
add al,bl |
mov [edi+0],al |
mov [edi+1],ah |
add esi,BYTE 4 |
add edi,BYTE 2 |
.L7 |
jmp _x86return |
;; 32 BIT RGB TO 16 BIT BGR 555 |
_ConvertX86p32_16BGR555: |
; check short |
cmp ecx,BYTE 16 |
ja .L3 |
.L1 ; short loop |
mov ah,[esi+0] ; blue |
mov al,[esi+1] ; green |
mov bl,[esi+2] ; red |
shr ah,3 |
and al,11111000b |
shl eax,2 |
shr bl,3 |
add al,bl |
mov [edi+0],al |
mov [edi+1],ah |
add esi,BYTE 4 |
add edi,BYTE 2 |
dec ecx |
jnz .L1 |
.L2 |
jmp _x86return |
.L3 ; head |
mov ebx,edi |
and ebx,BYTE 11b |
jz .L4 |
mov ah,[esi+0] ; blue |
mov al,[esi+1] ; green |
mov bl,[esi+2] ; red |
shr ah,3 |
and al,11111000b |
shl eax,2 |
shr bl,3 |
add al,bl |
mov [edi+0],al |
mov [edi+1],ah |
add esi,BYTE 4 |
add edi,BYTE 2 |
dec ecx |
.L4 ; save count |
push ecx |
; unroll twice |
shr ecx,1 |
; point arrays to end |
lea esi,[esi+ecx*8] |
lea edi,[edi+ecx*4] |
; negative counter |
neg ecx |
jmp SHORT .L6 |
.L5 |
mov [edi+ecx*4-4],eax |
.L6 |
mov edx,[esi+ecx*8+4] |
mov bh,[esi+ecx*8+4] |
mov ah,[esi+ecx*8] |
shr bh,3 |
mov al,[esi+ecx*8+1] |
shr ah,3 |
mov bl,[esi+ecx*8+5] |
shl eax,2 |
mov dl,[esi+ecx*8+2] |
shl ebx,18 |
and eax,00007FE0h |
shr edx,3 |
and ebx,07FE00000h |
and edx,001F001Fh |
add eax,ebx |
add eax,edx |
inc ecx |
jnz .L5 |
mov [edi+ecx*4-4],eax |
; tail |
pop ecx |
and ecx,BYTE 1 |
jz .L7 |
mov ah,[esi+0] ; blue |
mov al,[esi+1] ; green |
mov bl,[esi+2] ; red |
shr ah,3 |
and al,11111000b |
shl eax,2 |
shr bl,3 |
add al,bl |
mov [edi+0],al |
mov [edi+1],ah |
add esi,BYTE 4 |
add edi,BYTE 2 |
.L7 |
jmp _x86return |
;; FROM 32 BIT RGB to 8 BIT RGB (rrrgggbbb) |
;; This routine writes FOUR pixels at once (dword) and then, if they exist |
;; the trailing three pixels |
_ConvertX86p32_8RGB332: |
.L_ALIGNED |
push ecx |
shr ecx,2 ; We will draw 4 pixels at once |
jnz .L1 |
jmp .L2 ; short jump out of range :( |
.L1: |
mov eax,[esi] ; first pair of pixels |
mov edx,[esi+4] |
shr dl,6 |
mov ebx,eax |
shr al,6 |
and ah,0e0h |
shr ebx,16 |
and dh,0e0h |
shr ah,3 |
and bl,0e0h |
shr dh,3 |
or al,bl |
mov ebx,edx |
or al,ah |
shr ebx,16 |
or dl,dh |
and bl,0e0h |
or dl,bl |
mov ah,dl |
mov ebx,[esi+8] ; second pair of pixels |
mov edx,ebx |
and bh,0e0h |
shr bl,6 |
and edx,0e00000h |
shr edx,16 |
shr bh,3 |
ror eax,16 |
or bl,dl |
mov edx,[esi+12] |
or bl,bh |
mov al,bl |
mov ebx,edx |
and dh,0e0h |
shr dl,6 |
and ebx,0e00000h |
shr dh,3 |
mov ah,dl |
shr ebx,16 |
or ah,dh |
or ah,bl |
rol eax,16 |
add esi,BYTE 16 |
mov [edi],eax |
add edi,BYTE 4 |
dec ecx |
jz .L2 ; L1 out of range for short jump :( |
jmp .L1 |
.L2: |
pop ecx |
and ecx,BYTE 3 ; mask out number of pixels to draw |
jz .L4 ; Nothing to do anymore |
.L3: |
mov eax,[esi] ; single pixel conversion for trailing pixels |
mov ebx,eax |
shr al,6 |
and ah,0e0h |
shr ebx,16 |
shr ah,3 |
and bl,0e0h |
or al,ah |
or al,bl |
mov [edi],al |
inc edi |
add esi,BYTE 4 |
dec ecx |
jnz .L3 |
.L4: |
jmp _x86return |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/joystick/SDL_joystick_c.h |
---|
0,0 → 1,42 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_joystick_c.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; |
#endif |
/* Useful functions and variables from SDL_joystick.c */ |
#include "SDL_joystick.h" |
/* The number of available joysticks on the system */ |
extern Uint8 SDL_numjoysticks; |
/* Internal event queueing functions */ |
extern int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, |
Uint8 axis, Sint16 value); |
extern int SDL_PrivateJoystickBall(SDL_Joystick *joystick, |
Uint8 ball, Sint16 xrel, Sint16 yrel); |
extern int SDL_PrivateJoystickHat(SDL_Joystick *joystick, |
Uint8 hat, Uint8 value); |
extern int SDL_PrivateJoystickButton(SDL_Joystick *joystick, |
Uint8 button, Uint8 state); |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/joystick/SDL_sysjoystick.h |
---|
0,0 → 1,86 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_sysjoystick.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; |
#endif |
/* This is the system specific header for the SDL joystick API */ |
#include "SDL_joystick.h" |
/* The SDL joystick structure */ |
struct _SDL_Joystick { |
Uint8 index; /* Device index */ |
const char *name; /* Joystick name - system dependent */ |
int naxes; /* Number of axis controls on the joystick */ |
Sint16 *axes; /* Current axis states */ |
int nhats; /* Number of hats on the joystick */ |
Uint8 *hats; /* Current hat states */ |
int nballs; /* Number of trackballs on the joystick */ |
struct balldelta { |
int dx; |
int dy; |
} *balls; /* Current ball motion deltas */ |
int nbuttons; /* Number of buttons on the joystick */ |
Uint8 *buttons; /* Current button states */ |
struct joystick_hwdata *hwdata; /* Driver dependent information */ |
int ref_count; /* Reference count for multiple opens */ |
}; |
/* Function to scan the system for joysticks. |
* Joystick 0 should be the system default joystick. |
* This function should return the number of available joysticks, or -1 |
* on an unrecoverable fatal error. |
*/ |
extern int SDL_SYS_JoystickInit(void); |
/* Function to get the device-dependent name of a joystick */ |
extern const char *SDL_SYS_JoystickName(int index); |
/* Function to open a joystick for use. |
The joystick to open is specified by the index field of the joystick. |
This should fill the nbuttons and naxes fields of the joystick structure. |
It returns 0, or -1 if there is an error. |
*/ |
extern int SDL_SYS_JoystickOpen(SDL_Joystick *joystick); |
/* Function to update the state of a joystick - called as a device poll. |
* This function shouldn't update the joystick structure directly, |
* but instead should call SDL_PrivateJoystick*() to deliver events |
* and update joystick device state. |
*/ |
extern void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick); |
/* Function to close a joystick after use */ |
extern void SDL_SYS_JoystickClose(SDL_Joystick *joystick); |
/* Function to perform any system-specific joystick related cleanup */ |
extern void SDL_SYS_JoystickQuit(void); |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/thread/SDL_syscond.c |
---|
0,0 → 1,222 |
/* WARNING: This file was automatically generated! |
* Original: ./src/thread/generic/SDL_syscond.c |
*/ |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* An implementation of condition variables using semaphores and mutexes */ |
/* |
This implementation borrows heavily from the BeOS condition variable |
implementation, written by Christopher Tate and Owen Smith. Thanks! |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include "SDL_error.h" |
#include "SDL_thread.h" |
struct SDL_cond |
{ |
SDL_mutex *lock; |
int waiting; |
int signals; |
SDL_sem *wait_sem; |
SDL_sem *wait_done; |
}; |
/* Create a condition variable */ |
SDL_cond * SDL_CreateCond(void) |
{ |
SDL_cond *cond; |
cond = (SDL_cond *) malloc(sizeof(SDL_cond)); |
if ( cond ) { |
cond->lock = SDL_CreateMutex(); |
cond->wait_sem = SDL_CreateSemaphore(0); |
cond->wait_done = SDL_CreateSemaphore(0); |
cond->waiting = cond->signals = 0; |
if ( ! cond->lock || ! cond->wait_sem || ! cond->wait_done ) { |
SDL_DestroyCond(cond); |
cond = NULL; |
} |
} else { |
SDL_OutOfMemory(); |
} |
return(cond); |
} |
/* Destroy a condition variable */ |
void SDL_DestroyCond(SDL_cond *cond) |
{ |
if ( cond ) { |
if ( cond->wait_sem ) { |
SDL_DestroySemaphore(cond->wait_sem); |
} |
if ( cond->wait_done ) { |
SDL_DestroySemaphore(cond->wait_done); |
} |
if ( cond->lock ) { |
SDL_DestroyMutex(cond->lock); |
} |
free(cond); |
} |
} |
/* Restart one of the threads that are waiting on the condition variable */ |
int SDL_CondSignal(SDL_cond *cond) |
{ |
if ( ! cond ) { |
SDL_SetError("Passed a NULL condition variable"); |
return -1; |
} |
/* If there are waiting threads not already signalled, then |
signal the condition and wait for the thread to respond. |
*/ |
SDL_LockMutex(cond->lock); |
if ( cond->waiting > cond->signals ) { |
++cond->signals; |
SDL_SemPost(cond->wait_sem); |
SDL_UnlockMutex(cond->lock); |
SDL_SemWait(cond->wait_done); |
} else { |
SDL_UnlockMutex(cond->lock); |
} |
return 0; |
} |
/* Restart all threads that are waiting on the condition variable */ |
int SDL_CondBroadcast(SDL_cond *cond) |
{ |
if ( ! cond ) { |
SDL_SetError("Passed a NULL condition variable"); |
return -1; |
} |
/* If there are waiting threads not already signalled, then |
signal the condition and wait for the thread to respond. |
*/ |
SDL_LockMutex(cond->lock); |
if ( cond->waiting > cond->signals ) { |
int i, num_waiting; |
num_waiting = (cond->waiting - cond->signals); |
cond->signals = cond->waiting; |
for ( i=0; i<num_waiting; ++i ) { |
SDL_SemPost(cond->wait_sem); |
} |
/* Now all released threads are blocked here, waiting for us. |
Collect them all (and win fabulous prizes!) :-) |
*/ |
SDL_UnlockMutex(cond->lock); |
for ( i=0; i<num_waiting; ++i ) { |
SDL_SemWait(cond->wait_done); |
} |
} else { |
SDL_UnlockMutex(cond->lock); |
} |
return 0; |
} |
/* Wait on the condition variable for at most 'ms' milliseconds. |
The mutex must be locked before entering this function! |
The mutex is unlocked during the wait, and locked again after the wait. |
Typical use: |
Thread A: |
SDL_LockMutex(lock); |
while ( ! condition ) { |
SDL_CondWait(cond); |
} |
SDL_UnlockMutex(lock); |
Thread B: |
SDL_LockMutex(lock); |
... |
condition = true; |
... |
SDL_UnlockMutex(lock); |
*/ |
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) |
{ |
int retval; |
if ( ! cond ) { |
SDL_SetError("Passed a NULL condition variable"); |
return -1; |
} |
/* Obtain the protection mutex, and increment the number of waiters. |
This allows the signal mechanism to only perform a signal if there |
are waiting threads. |
*/ |
SDL_LockMutex(cond->lock); |
++cond->waiting; |
SDL_UnlockMutex(cond->lock); |
/* Unlock the mutex, as is required by condition variable semantics */ |
SDL_UnlockMutex(mutex); |
/* Wait for a signal */ |
if ( ms == SDL_MUTEX_MAXWAIT ) { |
retval = SDL_SemWait(cond->wait_sem); |
} else { |
retval = SDL_SemWaitTimeout(cond->wait_sem, ms); |
} |
/* Let the signaler know we have completed the wait, otherwise |
the signaler can race ahead and get the condition semaphore |
if we are stopped between the mutex unlock and semaphore wait, |
giving a deadlock. See the following URL for details: |
http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html |
*/ |
SDL_LockMutex(cond->lock); |
if ( cond->signals > 0 ) { |
/* If we timed out, we need to eat a condition signal */ |
if ( retval > 0 ) { |
SDL_SemWait(cond->wait_sem); |
} |
/* We always notify the signal thread that we are done */ |
SDL_SemPost(cond->wait_done); |
/* Signal handshake complete */ |
--cond->signals; |
} |
--cond->waiting; |
SDL_UnlockMutex(cond->lock); |
/* Lock the mutex, as is required by condition variable semantics */ |
SDL_LockMutex(mutex); |
return retval; |
} |
/* Wait on the condition variable forever */ |
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex) |
{ |
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/thread/SDL_syscond_c.h |
---|
0,0 → 1,25 |
/* WARNING: This file was automatically generated! |
* Original: ./src/thread/generic/SDL_syscond_c.h |
*/ |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/thread/SDL_sysmutex.c |
---|
0,0 → 1,136 |
/* WARNING: This file was automatically generated! |
* Original: ./src/thread/generic/SDL_sysmutex.c |
*/ |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* An implementation of mutexes using semaphores */ |
#include <stdio.h> |
#include <stdlib.h> |
#include "SDL_error.h" |
#include "SDL_thread.h" |
#include "SDL_systhread_c.h" |
struct SDL_mutex { |
int recursive; |
Uint32 owner; |
SDL_sem *sem; |
}; |
/* Create a mutex */ |
SDL_mutex *SDL_CreateMutex(void) |
{ |
SDL_mutex *mutex; |
/* Allocate mutex memory */ |
mutex = (SDL_mutex *)malloc(sizeof(*mutex)); |
if ( mutex ) { |
/* Create the mutex semaphore, with initial value 1 */ |
mutex->sem = SDL_CreateSemaphore(1); |
mutex->recursive = 0; |
mutex->owner = 0; |
if ( ! mutex->sem ) { |
free(mutex); |
mutex = NULL; |
} |
} else { |
SDL_OutOfMemory(); |
} |
return mutex; |
} |
/* Free the mutex */ |
void SDL_DestroyMutex(SDL_mutex *mutex) |
{ |
if ( mutex ) { |
if ( mutex->sem ) { |
SDL_DestroySemaphore(mutex->sem); |
} |
free(mutex); |
} |
} |
/* Lock the semaphore */ |
int SDL_mutexP(SDL_mutex *mutex) |
{ |
#ifdef DISABLE_THREADS |
return 0; |
#else |
Uint32 this_thread; |
if ( mutex == NULL ) { |
SDL_SetError("Passed a NULL mutex"); |
return -1; |
} |
this_thread = SDL_ThreadID(); |
if ( mutex->owner == this_thread ) { |
++mutex->recursive; |
} else { |
/* The order of operations is important. |
We set the locking thread id after we obtain the lock |
so unlocks from other threads will fail. |
*/ |
SDL_SemWait(mutex->sem); |
mutex->owner = this_thread; |
mutex->recursive = 0; |
} |
return 0; |
#endif /* DISABLE_THREADS */ |
} |
/* Unlock the mutex */ |
int SDL_mutexV(SDL_mutex *mutex) |
{ |
#ifdef DISABLE_THREADS |
return 0; |
#else |
if ( mutex == NULL ) { |
SDL_SetError("Passed a NULL mutex"); |
return -1; |
} |
/* If we don't own the mutex, we can't unlock it */ |
if ( SDL_ThreadID() != mutex->owner ) { |
SDL_SetError("mutex not owned by this thread"); |
return -1; |
} |
if ( mutex->recursive ) { |
--mutex->recursive; |
} else { |
/* The order of operations is important. |
First reset the owner so another thread doesn't lock |
the mutex and set the ownership before we reset it, |
then release the lock semaphore. |
*/ |
mutex->owner = 0; |
SDL_SemPost(mutex->sem); |
} |
return 0; |
#endif /* DISABLE_THREADS */ |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/thread/SDL_sysmutex_c.h |
---|
0,0 → 1,25 |
/* WARNING: This file was automatically generated! |
* Original: ./src/thread/generic/SDL_sysmutex_c.h |
*/ |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/thread/SDL_syssem.c |
---|
0,0 → 1,213 |
/* WARNING: This file was automatically generated! |
* Original: ./src/thread/generic/SDL_syssem.c |
*/ |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* An implementation of semaphores using mutexes and condition variables */ |
#include <stdlib.h> |
#include "SDL_error.h" |
#include "SDL_timer.h" |
#include "SDL_thread.h" |
#include "SDL_systhread_c.h" |
#ifdef DISABLE_THREADS |
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) |
{ |
SDL_SetError("SDL not configured with thread support"); |
return (SDL_sem *)0; |
} |
void SDL_DestroySemaphore(SDL_sem *sem) |
{ |
return; |
} |
int SDL_SemTryWait(SDL_sem *sem) |
{ |
SDL_SetError("SDL not configured with thread support"); |
return -1; |
} |
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) |
{ |
SDL_SetError("SDL not configured with thread support"); |
return -1; |
} |
int SDL_SemWait(SDL_sem *sem) |
{ |
SDL_SetError("SDL not configured with thread support"); |
return -1; |
} |
Uint32 SDL_SemValue(SDL_sem *sem) |
{ |
return 0; |
} |
int SDL_SemPost(SDL_sem *sem) |
{ |
SDL_SetError("SDL not configured with thread support"); |
return -1; |
} |
#else |
struct SDL_semaphore |
{ |
Uint32 count; |
Uint32 waiters_count; |
SDL_mutex *count_lock; |
SDL_cond *count_nonzero; |
}; |
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) |
{ |
SDL_sem *sem; |
sem = (SDL_sem *)malloc(sizeof(*sem)); |
if ( ! sem ) { |
SDL_OutOfMemory(); |
return(0); |
} |
sem->count = initial_value; |
sem->waiters_count = 0; |
sem->count_lock = SDL_CreateMutex(); |
sem->count_nonzero = SDL_CreateCond(); |
if ( ! sem->count_lock || ! sem->count_nonzero ) { |
SDL_DestroySemaphore(sem); |
return(0); |
} |
return(sem); |
} |
/* WARNING: |
You cannot call this function when another thread is using the semaphore. |
*/ |
void SDL_DestroySemaphore(SDL_sem *sem) |
{ |
if ( sem ) { |
sem->count = 0xFFFFFFFF; |
while ( sem->waiters_count > 0) { |
SDL_CondSignal(sem->count_nonzero); |
SDL_Delay(10); |
} |
SDL_DestroyCond(sem->count_nonzero); |
SDL_mutexP(sem->count_lock); |
SDL_mutexV(sem->count_lock); |
SDL_DestroyMutex(sem->count_lock); |
free(sem); |
} |
} |
int SDL_SemTryWait(SDL_sem *sem) |
{ |
int retval; |
if ( ! sem ) { |
SDL_SetError("Passed a NULL semaphore"); |
return -1; |
} |
retval = SDL_MUTEX_TIMEDOUT; |
SDL_LockMutex(sem->count_lock); |
if ( sem->count > 0 ) { |
--sem->count; |
retval = 0; |
} |
SDL_UnlockMutex(sem->count_lock); |
return retval; |
} |
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) |
{ |
int retval; |
if ( ! sem ) { |
SDL_SetError("Passed a NULL semaphore"); |
return -1; |
} |
/* A timeout of 0 is an easy case */ |
if ( timeout == 0 ) { |
return SDL_SemTryWait(sem); |
} |
SDL_LockMutex(sem->count_lock); |
++sem->waiters_count; |
retval = 0; |
while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) { |
retval = SDL_CondWaitTimeout(sem->count_nonzero, |
sem->count_lock, timeout); |
} |
--sem->waiters_count; |
--sem->count; |
SDL_UnlockMutex(sem->count_lock); |
return retval; |
} |
int SDL_SemWait(SDL_sem *sem) |
{ |
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); |
} |
Uint32 SDL_SemValue(SDL_sem *sem) |
{ |
Uint32 value; |
value = 0; |
if ( sem ) { |
SDL_LockMutex(sem->count_lock); |
value = sem->count; |
SDL_UnlockMutex(sem->count_lock); |
} |
return value; |
} |
int SDL_SemPost(SDL_sem *sem) |
{ |
if ( ! sem ) { |
SDL_SetError("Passed a NULL semaphore"); |
return -1; |
} |
SDL_LockMutex(sem->count_lock); |
if ( sem->waiters_count > 0 ) { |
SDL_CondSignal(sem->count_nonzero); |
} |
++sem->count; |
SDL_UnlockMutex(sem->count_lock); |
return 0; |
} |
#endif /* DISABLE_THREADS */ |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/thread/SDL_syssem_c.h |
---|
0,0 → 1,25 |
/* WARNING: This file was automatically generated! |
* Original: ./src/thread/generic/SDL_syssem_c.h |
*/ |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/thread/SDL_systhread.c |
---|
0,0 → 1,58 |
/* WARNING: This file was automatically generated! |
* Original: ./src/thread/generic/SDL_systhread.c |
*/ |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* Thread management routines for SDL */ |
#include "SDL_error.h" |
#include "SDL_thread.h" |
#include "SDL_systhread.h" |
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) |
{ |
SDL_SetError("Threads are not supported on this platform"); |
return(-1); |
} |
void SDL_SYS_SetupThread(void) |
{ |
return; |
} |
Uint32 SDL_ThreadID(void) |
{ |
return(0); |
} |
void SDL_SYS_WaitThread(SDL_Thread *thread) |
{ |
return; |
} |
void SDL_SYS_KillThread(SDL_Thread *thread) |
{ |
return; |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/thread/SDL_systhread.h |
---|
0,0 → 1,48 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_systhread.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; |
#endif |
/* These are functions that need to be implemented by a port of SDL */ |
#include "SDL_thread_c.h" |
/* This function creates a thread, passing args to SDL_RunThread(), |
saves a system-dependent thread id in thread->id, and returns 0 |
on success. |
*/ |
extern int SDL_SYS_CreateThread(SDL_Thread *thread, void *args); |
/* This function does any necessary setup in the child thread */ |
extern void SDL_SYS_SetupThread(void); |
/* This function waits for the thread to finish and frees any data |
allocated by SDL_SYS_CreateThread() |
*/ |
extern void SDL_SYS_WaitThread(SDL_Thread *thread); |
/* This function kills the thread and returns */ |
extern void SDL_SYS_KillThread(SDL_Thread *thread); |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/thread/SDL_systhread_c.h |
---|
0,0 → 1,29 |
/* WARNING: This file was automatically generated! |
* Original: ./src/thread/generic/SDL_systhread_c.h |
*/ |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* Stub until we implement threads on this platform */ |
typedef int SYS_ThreadHandle; |
#define DISABLE_THREADS |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/thread/SDL_thread.c |
---|
0,0 → 1,296 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* System independent thread management routines for SDL */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "SDL_error.h" |
#include "SDL_mutex.h" |
#include "SDL_thread.h" |
#include "SDL_thread_c.h" |
#include "SDL_systhread.h" |
#define ARRAY_CHUNKSIZE 32 |
/* The array of threads currently active in the application |
(except the main thread) |
The manipulation of an array here is safer than using a linked list. |
*/ |
static int SDL_maxthreads = 0; |
static int SDL_numthreads = 0; |
static SDL_Thread **SDL_Threads = NULL; |
static SDL_mutex *thread_lock = NULL; |
int _creating_thread_lock = 0; |
int SDL_ThreadsInit(void) |
{ |
int retval; |
retval = 0; |
/* Set the thread lock creation flag so that we can reuse an |
existing lock on the system - since this mutex never gets |
destroyed (see SDL_ThreadsQuit()), we want to reuse it. |
*/ |
_creating_thread_lock = 1; |
thread_lock = SDL_CreateMutex(); |
_creating_thread_lock = 0; |
if ( thread_lock == NULL ) { |
retval = -1; |
} |
return(retval); |
} |
/* This should never be called... |
If this is called by SDL_Quit(), we don't know whether or not we should |
clean up threads here. If any threads are still running after this call, |
they will no longer have access to any per-thread data. |
*/ |
void SDL_ThreadsQuit() |
{ |
SDL_mutex *mutex; |
mutex = thread_lock; |
thread_lock = NULL; |
if ( mutex != NULL ) { |
SDL_DestroyMutex(mutex); |
} |
} |
/* Routines for manipulating the thread list */ |
static void SDL_AddThread(SDL_Thread *thread) |
{ |
SDL_Thread **threads; |
/* WARNING: |
If the very first threads are created simultaneously, then |
there could be a race condition causing memory corruption. |
In practice, this isn't a problem because by definition there |
is only one thread running the first time this is called. |
*/ |
if ( thread_lock == NULL ) { |
if ( SDL_ThreadsInit() < 0 ) { |
return; |
} |
} |
SDL_mutexP(thread_lock); |
/* Expand the list of threads, if necessary */ |
#ifdef DEBUG_THREADS |
printf("Adding thread (%d already - %d max)\n", |
SDL_numthreads, SDL_maxthreads); |
#endif |
if ( SDL_numthreads == SDL_maxthreads ) { |
threads=(SDL_Thread **)malloc((SDL_maxthreads+ARRAY_CHUNKSIZE)* |
(sizeof *threads)); |
if ( threads == NULL ) { |
SDL_OutOfMemory(); |
goto done; |
} |
memcpy(threads, SDL_Threads, SDL_numthreads*(sizeof *threads)); |
SDL_maxthreads += ARRAY_CHUNKSIZE; |
if ( SDL_Threads ) { |
free(SDL_Threads); |
} |
SDL_Threads = threads; |
} |
SDL_Threads[SDL_numthreads++] = thread; |
done: |
SDL_mutexV(thread_lock); |
} |
static void SDL_DelThread(SDL_Thread *thread) |
{ |
int i; |
if ( thread_lock ) { |
SDL_mutexP(thread_lock); |
for ( i=0; i<SDL_numthreads; ++i ) { |
if ( thread == SDL_Threads[i] ) { |
break; |
} |
} |
if ( i < SDL_numthreads ) { |
--SDL_numthreads; |
while ( i < SDL_numthreads ) { |
SDL_Threads[i] = SDL_Threads[i+1]; |
++i; |
} |
#ifdef DEBUG_THREADS |
printf("Deleting thread (%d left - %d max)\n", |
SDL_numthreads, SDL_maxthreads); |
#endif |
} |
SDL_mutexV(thread_lock); |
} |
} |
/* The default (non-thread-safe) global error variable */ |
static SDL_error SDL_global_error; |
/* Routine to get the thread-specific error variable */ |
SDL_error *SDL_GetErrBuf(void) |
{ |
SDL_error *errbuf; |
errbuf = &SDL_global_error; |
if ( SDL_Threads ) { |
int i; |
Uint32 this_thread; |
this_thread = SDL_ThreadID(); |
SDL_mutexP(thread_lock); |
for ( i=0; i<SDL_numthreads; ++i ) { |
if ( this_thread == SDL_Threads[i]->threadid ) { |
errbuf = &SDL_Threads[i]->errbuf; |
break; |
} |
} |
SDL_mutexV(thread_lock); |
} |
return(errbuf); |
} |
/* Arguments and callback to setup and run the user thread function */ |
typedef struct { |
int (*func)(void *); |
void *data; |
SDL_Thread *info; |
SDL_sem *wait; |
} thread_args; |
void SDL_RunThread(void *data) |
{ |
thread_args *args; |
int (*userfunc)(void *); |
void *userdata; |
int *statusloc; |
/* Perform any system-dependent setup |
- this function cannot fail, and cannot use SDL_SetError() |
*/ |
SDL_SYS_SetupThread(); |
/* Get the thread id */ |
args = (thread_args *)data; |
args->info->threadid = SDL_ThreadID(); |
/* Figure out what function to run */ |
userfunc = args->func; |
userdata = args->data; |
statusloc = &args->info->status; |
/* Wake up the parent thread */ |
SDL_SemPost(args->wait); |
/* Run the function */ |
*statusloc = userfunc(userdata); |
} |
SDL_Thread *SDL_CreateThread(int (*fn)(void *), void *data) |
{ |
SDL_Thread *thread; |
thread_args *args; |
int ret; |
/* Allocate memory for the thread info structure */ |
thread = (SDL_Thread *)malloc(sizeof(*thread)); |
if ( thread == NULL ) { |
SDL_OutOfMemory(); |
return(NULL); |
} |
memset(thread, 0, (sizeof *thread)); |
thread->status = -1; |
/* Set up the arguments for the thread */ |
args = (thread_args *)malloc(sizeof(*args)); |
if ( args == NULL ) { |
SDL_OutOfMemory(); |
free(thread); |
return(NULL); |
} |
args->func = fn; |
args->data = data; |
args->info = thread; |
args->wait = SDL_CreateSemaphore(0); |
if ( args->wait == NULL ) { |
free(thread); |
free(args); |
return(NULL); |
} |
/* Add the thread to the list of available threads */ |
SDL_AddThread(thread); |
/* Create the thread and go! */ |
ret = SDL_SYS_CreateThread(thread, args); |
if ( ret >= 0 ) { |
/* Wait for the thread function to use arguments */ |
SDL_SemWait(args->wait); |
} else { |
/* Oops, failed. Gotta free everything */ |
SDL_DelThread(thread); |
free(thread); |
thread = NULL; |
} |
SDL_DestroySemaphore(args->wait); |
free(args); |
/* Everything is running now */ |
return(thread); |
} |
void SDL_WaitThread(SDL_Thread *thread, int *status) |
{ |
if ( thread ) { |
SDL_SYS_WaitThread(thread); |
if ( status ) { |
*status = thread->status; |
} |
SDL_DelThread(thread); |
free(thread); |
} |
} |
Uint32 SDL_GetThreadID(SDL_Thread *thread) |
{ |
Uint32 id; |
if ( thread ) { |
id = thread->threadid; |
} else { |
id = SDL_ThreadID(); |
} |
return(id); |
} |
void SDL_KillThread(SDL_Thread *thread) |
{ |
if ( thread ) { |
SDL_SYS_KillThread(thread); |
SDL_WaitThread(thread, NULL); |
} |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/thread/SDL_thread_c.h |
---|
0,0 → 1,44 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifndef _SDL_thread_c_h |
#define _SDL_thread_c_h |
#include "SDL_error_c.h" |
#include "SDL_systhread_c.h" |
/* This is the system-independent thread info structure */ |
struct SDL_Thread { |
Uint32 threadid; |
SYS_ThreadHandle handle; |
int status; |
SDL_error errbuf; |
void *data; |
}; |
/* This is the function called to run a thread */ |
extern void SDL_RunThread(void *data); |
/* Routine to get the thread-specific error variable */ |
extern SDL_error *SDL_GetErrBuf(void); |
#endif /* _SDL_thread_c_h */ |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/timer/SDL_systimer.h |
---|
0,0 → 1,46 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998 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 |
5635-34 Springhouse Dr. |
Pleasanton, CA 94588 (USA) |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_systimer.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; |
#endif |
/* The system dependent timer handling functions */ |
#include "SDL_timer.h" |
#include "SDL_timer_c.h" |
/* Initialize the system dependent timer subsystem */ |
extern int SDL_SYS_TimerInit(void); |
/* Quit the system dependent timer subsystem */ |
extern void SDL_SYS_TimerQuit(void); |
/* Start a timer set up by SDL_SetTimer() */ |
extern int SDL_SYS_StartTimer(void); |
/* Stop a previously started timer */ |
extern void SDL_SYS_StopTimer(void); |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/timer/SDL_timer.c |
---|
0,0 → 1,281 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998 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 |
5635-34 Springhouse Dr. |
Pleasanton, CA 94588 (USA) |
slouken@devolution.com |
*/ |
#include <stdlib.h> |
#include <stdio.h> /* For the definition of NULL */ |
#include "SDL_error.h" |
#include "SDL_timer.h" |
#include "SDL_timer_c.h" |
#include "SDL_mutex.h" |
#include "SDL_systimer.h" |
/* #define DEBUG_TIMERS */ |
int SDL_timer_started = 0; |
int SDL_timer_running = 0; |
/* Data to handle a single periodic alarm */ |
Uint32 SDL_alarm_interval = 0; |
SDL_TimerCallback SDL_alarm_callback; |
static SDL_bool list_changed = SDL_FALSE; |
/* Data used for a thread-based timer */ |
static int SDL_timer_threaded = 0; |
struct _SDL_TimerID { |
Uint32 interval; |
SDL_NewTimerCallback cb; |
void *param; |
Uint32 last_alarm; |
struct _SDL_TimerID *next; |
}; |
static SDL_TimerID SDL_timers = NULL; |
static Uint32 num_timers = 0; |
static SDL_mutex *SDL_timer_mutex; |
/* Set whether or not the timer should use a thread. |
This should not be called while the timer subsystem is running. |
*/ |
int SDL_SetTimerThreaded(int value) |
{ |
int retval; |
if ( SDL_timer_started ) { |
SDL_SetError("Timer already initialized"); |
retval = -1; |
} else { |
retval = 0; |
SDL_timer_threaded = value; |
} |
return retval; |
} |
int SDL_TimerInit(void) |
{ |
int retval; |
SDL_timer_running = 0; |
SDL_SetTimer(0, NULL); |
retval = 0; |
if ( ! SDL_timer_threaded ) { |
retval = SDL_SYS_TimerInit(); |
} |
if ( SDL_timer_threaded ) { |
SDL_timer_mutex = SDL_CreateMutex(); |
} |
SDL_timer_started = 1; |
return(retval); |
} |
void SDL_TimerQuit(void) |
{ |
SDL_SetTimer(0, NULL); |
if ( SDL_timer_threaded < 2 ) { |
SDL_SYS_TimerQuit(); |
} |
if ( SDL_timer_threaded ) { |
SDL_DestroyMutex(SDL_timer_mutex); |
} |
SDL_timer_started = 0; |
SDL_timer_threaded = 0; |
} |
void SDL_ThreadedTimerCheck(void) |
{ |
Uint32 now, ms; |
SDL_TimerID t, prev, next; |
int removed; |
now = SDL_GetTicks(); |
SDL_mutexP(SDL_timer_mutex); |
for ( prev = NULL, t = SDL_timers; t; t = next ) { |
removed = 0; |
ms = t->interval - SDL_TIMESLICE; |
next = t->next; |
if ( (t->last_alarm < now) && ((now - t->last_alarm) > ms) ) { |
if ( (now - t->last_alarm) < t->interval ) { |
t->last_alarm += t->interval; |
} else { |
t->last_alarm = now; |
} |
list_changed = SDL_FALSE; |
#ifdef DEBUG_TIMERS |
printf("Executing timer %p (thread = %d)\n", |
t, SDL_ThreadID()); |
#endif |
SDL_mutexV(SDL_timer_mutex); |
ms = t->cb(t->interval, t->param); |
SDL_mutexP(SDL_timer_mutex); |
if ( list_changed ) { |
/* Abort, list of timers has been modified */ |
break; |
} |
if ( ms != t->interval ) { |
if ( ms ) { |
t->interval = ROUND_RESOLUTION(ms); |
} else { /* Remove the timer from the linked list */ |
#ifdef DEBUG_TIMERS |
printf("SDL: Removing timer %p\n", t); |
#endif |
if ( prev ) { |
prev->next = next; |
} else { |
SDL_timers = next; |
} |
free(t); |
-- num_timers; |
removed = 1; |
} |
} |
} |
/* Don't update prev if the timer has disappeared */ |
if ( ! removed ) { |
prev = t; |
} |
} |
SDL_mutexV(SDL_timer_mutex); |
} |
SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_NewTimerCallback callback, void *param) |
{ |
SDL_TimerID t; |
if ( ! SDL_timer_mutex ) { |
if ( SDL_timer_started ) { |
SDL_SetError("This platform doesn't support multiple timers"); |
} else { |
SDL_SetError("You must call SDL_Init(SDL_INIT_TIMER) first"); |
} |
return NULL; |
} |
if ( ! SDL_timer_threaded ) { |
SDL_SetError("Multiple timers require threaded events!"); |
return NULL; |
} |
SDL_mutexP(SDL_timer_mutex); |
t = (SDL_TimerID) malloc(sizeof(struct _SDL_TimerID)); |
if ( t ) { |
t->interval = ROUND_RESOLUTION(interval); |
t->cb = callback; |
t->param = param; |
t->last_alarm = SDL_GetTicks(); |
t->next = SDL_timers; |
SDL_timers = t; |
++ num_timers; |
list_changed = SDL_TRUE; |
SDL_timer_running = 1; |
} |
#ifdef DEBUG_TIMERS |
printf("SDL_AddTimer(%d) = %08x num_timers = %d\n", interval, (Uint32)t, num_timers); |
#endif |
SDL_mutexV(SDL_timer_mutex); |
return t; |
} |
SDL_bool SDL_RemoveTimer(SDL_TimerID id) |
{ |
SDL_TimerID t, prev = NULL; |
SDL_bool removed; |
removed = SDL_FALSE; |
SDL_mutexP(SDL_timer_mutex); |
/* Look for id in the linked list of timers */ |
for (t = SDL_timers; t; prev=t, t = t->next ) { |
if ( t == id ) { |
if(prev) { |
prev->next = t->next; |
} else { |
SDL_timers = t->next; |
} |
free(t); |
-- num_timers; |
removed = SDL_TRUE; |
list_changed = SDL_TRUE; |
break; |
} |
} |
#ifdef DEBUG_TIMERS |
printf("SDL_RemoveTimer(%08x) = %d num_timers = %d thread = %d\n", (Uint32)id, removed, num_timers, SDL_ThreadID()); |
#endif |
SDL_mutexV(SDL_timer_mutex); |
return removed; |
} |
static void SDL_RemoveAllTimers(SDL_TimerID t) |
{ |
SDL_TimerID freeme; |
/* Changed to non-recursive implementation. |
The recursive implementation is elegant, but subject to |
stack overflow if there are lots and lots of timers. |
*/ |
while ( t ) { |
freeme = t; |
t = t->next; |
free(freeme); |
} |
} |
/* Old style callback functions are wrapped through this */ |
static Uint32 callback_wrapper(Uint32 ms, void *param) |
{ |
SDL_TimerCallback func = (SDL_TimerCallback) param; |
return (*func)(ms); |
} |
int SDL_SetTimer(Uint32 ms, SDL_TimerCallback callback) |
{ |
int retval; |
#ifdef DEBUG_TIMERS |
printf("SDL_SetTimer(%d)\n", ms); |
#endif |
retval = 0; |
if ( SDL_timer_running ) { /* Stop any currently running timer */ |
SDL_timer_running = 0; |
if ( SDL_timer_threaded ) { |
SDL_mutexP(SDL_timer_mutex); |
SDL_RemoveAllTimers(SDL_timers); |
SDL_timers = NULL; |
SDL_mutexV(SDL_timer_mutex); |
} else { |
SDL_SYS_StopTimer(); |
} |
} |
if ( ms ) { |
if ( SDL_timer_threaded ) { |
retval = (SDL_AddTimer(ms, callback_wrapper, |
(void *)callback) != NULL); |
} else { |
SDL_timer_running = 1; |
SDL_alarm_interval = ms; |
SDL_alarm_callback = callback; |
retval = SDL_SYS_StartTimer(); |
} |
} |
return retval; |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/timer/SDL_timer_c.h |
---|
0,0 → 1,52 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998 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 |
5635-34 Springhouse Dr. |
Pleasanton, CA 94588 (USA) |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_timer_c.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; |
#endif |
/* Useful functions and variables from SDL_timer.c */ |
#include "SDL_timer.h" |
#define ROUND_RESOLUTION(X) \ |
(((X+TIMER_RESOLUTION-1)/TIMER_RESOLUTION)*TIMER_RESOLUTION) |
extern int SDL_timer_started; |
extern int SDL_timer_running; |
/* Data to handle a single periodic alarm */ |
extern Uint32 SDL_alarm_interval; |
extern SDL_TimerCallback SDL_alarm_callback; |
/* Set whether or not the timer should use a thread. |
This should be called while the timer subsystem is running. |
*/ |
extern int SDL_SetTimerThreaded(int value); |
extern int SDL_TimerInit(void); |
extern void SDL_TimerQuit(void); |
/* This function is called from the SDL event thread if it is available */ |
extern void SDL_ThreadedTimerCheck(void); |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_RLEaccel.c |
---|
0,0 → 1,1552 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* |
* RLE encoding for software colorkey and alpha-channel acceleration |
* |
* Original version by Sam Lantinga |
* |
* Mattias Engdegård (Yorick): Rewrite. New encoding format, encoder and |
* decoder. Added per-surface alpha blitter. Added per-pixel alpha |
* format, encoder and blitter. |
* |
* Many thanks to Xark and johns for hints, benchmarks and useful comments |
* leading to this code. |
* |
* Welcome to Macro Mayhem. |
*/ |
/* |
* The encoding translates the image data to a stream of segments of the form |
* |
* <skip> <run> <data> |
* |
* where <skip> is the number of transparent pixels to skip, |
* <run> is the number of opaque pixels to blit, |
* and <data> are the pixels themselves. |
* |
* This basic structure is used both for colorkeyed surfaces, used for simple |
* binary transparency and for per-surface alpha blending, and for surfaces |
* with per-pixel alpha. The details differ, however: |
* |
* Encoding of colorkeyed surfaces: |
* |
* Encoded pixels always have the same format as the target surface. |
* <skip> and <run> are unsigned 8 bit integers, except for 32 bit depth |
* where they are 16 bit. This makes the pixel data aligned at all times. |
* Segments never wrap around from one scan line to the next. |
* |
* The end of the sequence is marked by a zero <skip>,<run> pair at the * |
* beginning of a line. |
* |
* Encoding of surfaces with per-pixel alpha: |
* |
* The sequence begins with a struct RLEDestFormat describing the target |
* pixel format, to provide reliable un-encoding. |
* |
* Each scan line is encoded twice: First all completely opaque pixels, |
* encoded in the target format as described above, and then all |
* partially transparent (translucent) pixels (where 1 <= alpha <= 254), |
* in the following 32-bit format: |
* |
* For 32-bit targets, each pixel has the target RGB format but with |
* the alpha value occupying the highest 8 bits. The <skip> and <run> |
* counts are 16 bit. |
* |
* For 16-bit targets, each pixel has the target RGB format, but with |
* the middle component (usually green) shifted 16 steps to the left, |
* and the hole filled with the 5 most significant bits of the alpha value. |
* i.e. if the target has the format rrrrrggggggbbbbb, |
* the encoded pixel will be 00000gggggg00000rrrrr0aaaaabbbbb. |
* The <skip> and <run> counts are 8 bit for the opaque lines, 16 bit |
* for the translucent lines. Two padding bytes may be inserted |
* before each translucent line to keep them 32-bit aligned. |
* |
* The end of the sequence is marked by a zero <skip>,<run> pair at the |
* beginning of an opaque line. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "SDL_types.h" |
#include "SDL_video.h" |
#include "SDL_error.h" |
#include "SDL_sysvideo.h" |
#include "SDL_blit.h" |
#include "SDL_memops.h" |
#include "SDL_RLEaccel_c.h" |
#ifndef MAX |
#define MAX(a, b) ((a) > (b) ? (a) : (b)) |
#endif |
#ifndef MIN |
#define MIN(a, b) ((a) < (b) ? (a) : (b)) |
#endif |
#define PIXEL_COPY(to, from, len, bpp) \ |
do { \ |
if(bpp == 4) { \ |
SDL_memcpy4(to, from, (unsigned)(len)); \ |
} else { \ |
SDL_memcpy(to, from, (unsigned)(len) * (bpp)); \ |
} \ |
} while(0) |
/* |
* Various colorkey blit methods, for opaque and per-surface alpha |
*/ |
#define OPAQUE_BLIT(to, from, length, bpp, alpha) \ |
PIXEL_COPY(to, from, length, bpp) |
/* |
* For 32bpp pixels on the form 0x00rrggbb: |
* If we treat the middle component separately, we can process the two |
* remaining in parallel. This is safe to do because of the gap to the left |
* of each component, so the bits from the multiplication don't collide. |
* This can be used for any RGB permutation of course. |
*/ |
#define ALPHA_BLIT32_888(to, from, length, bpp, alpha) \ |
do { \ |
int i; \ |
Uint32 *src = (Uint32 *)(from); \ |
Uint32 *dst = (Uint32 *)(to); \ |
for(i = 0; i < (int)(length); i++) { \ |
Uint32 s = *src++; \ |
Uint32 d = *dst; \ |
Uint32 s1 = s & 0xff00ff; \ |
Uint32 d1 = d & 0xff00ff; \ |
d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \ |
s &= 0xff00; \ |
d &= 0xff00; \ |
d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ |
*dst++ = d1 | d; \ |
} \ |
} while(0) |
/* |
* For 16bpp pixels we can go a step further: put the middle component |
* in the high 16 bits of a 32 bit word, and process all three RGB |
* components at the same time. Since the smallest gap is here just |
* 5 bits, we have to scale alpha down to 5 bits as well. |
*/ |
#define ALPHA_BLIT16_565(to, from, length, bpp, alpha) \ |
do { \ |
int i; \ |
Uint16 *src = (Uint16 *)(from); \ |
Uint16 *dst = (Uint16 *)(to); \ |
for(i = 0; i < (int)(length); i++) { \ |
Uint32 s = *src++; \ |
Uint32 d = *dst; \ |
s = (s | s << 16) & 0x07e0f81f; \ |
d = (d | d << 16) & 0x07e0f81f; \ |
d += (s - d) * alpha >> 5; \ |
d &= 0x07e0f81f; \ |
*dst++ = d | d >> 16; \ |
} \ |
} while(0) |
#define ALPHA_BLIT16_555(to, from, length, bpp, alpha) \ |
do { \ |
int i; \ |
Uint16 *src = (Uint16 *)(from); \ |
Uint16 *dst = (Uint16 *)(to); \ |
for(i = 0; i < (int)(length); i++) { \ |
Uint32 s = *src++; \ |
Uint32 d = *dst; \ |
s = (s | s << 16) & 0x03e07c1f; \ |
d = (d | d << 16) & 0x03e07c1f; \ |
d += (s - d) * alpha >> 5; \ |
d &= 0x03e07c1f; \ |
*dst++ = d | d >> 16; \ |
} \ |
} while(0) |
/* |
* The general slow catch-all function, for remaining depths and formats |
*/ |
#define ALPHA_BLIT_ANY(to, from, length, bpp, alpha) \ |
do { \ |
int i; \ |
Uint8 *src = from; \ |
Uint8 *dst = to; \ |
for(i = 0; i < (int)(length); i++) { \ |
Uint32 s, d; \ |
unsigned rs, gs, bs, rd, gd, bd; \ |
switch(bpp) { \ |
case 2: \ |
s = *(Uint16 *)src; \ |
d = *(Uint16 *)dst; \ |
break; \ |
case 3: \ |
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ |
s = (src[0] << 16) | (src[1] << 8) | src[2]; \ |
d = (dst[0] << 16) | (dst[1] << 8) | dst[2]; \ |
} else { \ |
s = (src[2] << 16) | (src[1] << 8) | src[0]; \ |
d = (dst[2] << 16) | (dst[1] << 8) | dst[0]; \ |
} \ |
break; \ |
case 4: \ |
s = *(Uint32 *)src; \ |
d = *(Uint32 *)dst; \ |
break; \ |
} \ |
RGB_FROM_PIXEL(s, fmt, rs, gs, bs); \ |
RGB_FROM_PIXEL(d, fmt, rd, gd, bd); \ |
rd += (rs - rd) * alpha >> 8; \ |
gd += (gs - gd) * alpha >> 8; \ |
bd += (bs - bd) * alpha >> 8; \ |
PIXEL_FROM_RGB(d, fmt, rd, gd, bd); \ |
switch(bpp) { \ |
case 2: \ |
*(Uint16 *)dst = d; \ |
break; \ |
case 3: \ |
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ |
dst[0] = d >> 16; \ |
dst[1] = d >> 8; \ |
dst[2] = d; \ |
} else { \ |
dst[0] = d; \ |
dst[1] = d >> 8; \ |
dst[2] = d >> 16; \ |
} \ |
break; \ |
case 4: \ |
*(Uint32 *)dst = d; \ |
break; \ |
} \ |
src += bpp; \ |
dst += bpp; \ |
} \ |
} while(0) |
/* |
* Special case: 50% alpha (alpha=128) |
* This is treated specially because it can be optimized very well, and |
* since it is good for many cases of semi-translucency. |
* The theory is to do all three components at the same time: |
* First zero the lowest bit of each component, which gives us room to |
* add them. Then shift right and add the sum of the lowest bits. |
*/ |
#define ALPHA_BLIT32_888_50(to, from, length, bpp, alpha) \ |
do { \ |
int i; \ |
Uint32 *src = (Uint32 *)(from); \ |
Uint32 *dst = (Uint32 *)(to); \ |
for(i = 0; i < (int)(length); i++) { \ |
Uint32 s = *src++; \ |
Uint32 d = *dst; \ |
*dst++ = (((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) \ |
+ (s & d & 0x00010101); \ |
} \ |
} while(0) |
/* |
* For 16bpp, we can actually blend two pixels in parallel, if we take |
* care to shift before we add, not after. |
*/ |
/* helper: blend a single 16 bit pixel at 50% */ |
#define BLEND16_50(dst, src, mask) \ |
do { \ |
Uint32 s = *src++; \ |
Uint32 d = *dst; \ |
*dst++ = (((s & mask) + (d & mask)) >> 1) \ |
+ (s & d & (~mask & 0xffff)); \ |
} while(0) |
/* basic 16bpp blender. mask is the pixels to keep when adding. */ |
#define ALPHA_BLIT16_50(to, from, length, bpp, alpha, mask) \ |
do { \ |
unsigned n = (length); \ |
Uint16 *src = (Uint16 *)(from); \ |
Uint16 *dst = (Uint16 *)(to); \ |
if(((unsigned long)src ^ (unsigned long)dst) & 3) { \ |
/* source and destination not in phase, blit one by one */ \ |
while(n--) \ |
BLEND16_50(dst, src, mask); \ |
} else { \ |
if((unsigned long)src & 3) { \ |
/* first odd pixel */ \ |
BLEND16_50(dst, src, mask); \ |
n--; \ |
} \ |
for(; n > 1; n -= 2) { \ |
Uint32 s = *(Uint32 *)src; \ |
Uint32 d = *(Uint32 *)dst; \ |
*(Uint32 *)dst = ((s & (mask | mask << 16)) >> 1) \ |
+ ((d & (mask | mask << 16)) >> 1) \ |
+ (s & d & (~(mask | mask << 16))); \ |
src += 2; \ |
dst += 2; \ |
} \ |
if(n) \ |
BLEND16_50(dst, src, mask); /* last odd pixel */ \ |
} \ |
} while(0) |
#define ALPHA_BLIT16_565_50(to, from, length, bpp, alpha) \ |
ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xf7de) |
#define ALPHA_BLIT16_555_50(to, from, length, bpp, alpha) \ |
ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xfbde) |
#define CHOOSE_BLIT(blitter, alpha, fmt) \ |
do { \ |
if(alpha == 255) { \ |
switch(fmt->BytesPerPixel) { \ |
case 1: blitter(1, Uint8, OPAQUE_BLIT); break; \ |
case 2: blitter(2, Uint8, OPAQUE_BLIT); break; \ |
case 3: blitter(3, Uint8, OPAQUE_BLIT); break; \ |
case 4: blitter(4, Uint16, OPAQUE_BLIT); break; \ |
} \ |
} else { \ |
switch(fmt->BytesPerPixel) { \ |
case 1: \ |
/* No 8bpp alpha blitting */ \ |
break; \ |
\ |
case 2: \ |
switch(fmt->Rmask | fmt->Gmask | fmt->Bmask) { \ |
case 0xffff: \ |
if(fmt->Gmask == 0x07e0 \ |
|| fmt->Rmask == 0x07e0 \ |
|| fmt->Bmask == 0x07e0) { \ |
if(alpha == 128) \ |
blitter(2, Uint8, ALPHA_BLIT16_565_50); \ |
else { \ |
alpha >>= 3; /* use 5 bit alpha */ \ |
blitter(2, Uint8, ALPHA_BLIT16_565); \ |
} \ |
} else \ |
goto general16; \ |
break; \ |
\ |
case 0x7fff: \ |
if(fmt->Gmask == 0x03e0 \ |
|| fmt->Rmask == 0x03e0 \ |
|| fmt->Bmask == 0x03e0) { \ |
if(alpha == 128) \ |
blitter(2, Uint8, ALPHA_BLIT16_555_50); \ |
else { \ |
alpha >>= 3; /* use 5 bit alpha */ \ |
blitter(2, Uint8, ALPHA_BLIT16_555); \ |
} \ |
break; \ |
} \ |
/* fallthrough */ \ |
\ |
default: \ |
general16: \ |
blitter(2, Uint8, ALPHA_BLIT_ANY); \ |
} \ |
break; \ |
\ |
case 3: \ |
blitter(3, Uint8, ALPHA_BLIT_ANY); \ |
break; \ |
\ |
case 4: \ |
if((fmt->Rmask | fmt->Gmask | fmt->Bmask) == 0x00ffffff \ |
&& (fmt->Gmask == 0xff00 || fmt->Rmask == 0xff00 \ |
|| fmt->Bmask == 0xff00)) { \ |
if(alpha == 128) \ |
blitter(4, Uint16, ALPHA_BLIT32_888_50); \ |
else \ |
blitter(4, Uint16, ALPHA_BLIT32_888); \ |
} else \ |
blitter(4, Uint16, ALPHA_BLIT_ANY); \ |
break; \ |
} \ |
} \ |
} while(0) |
/* |
* This takes care of the case when the surface is clipped on the left and/or |
* right. Top clipping has already been taken care of. |
*/ |
static void RLEClipBlit(int w, Uint8 *srcbuf, SDL_Surface *dst, |
Uint8 *dstbuf, SDL_Rect *srcrect, unsigned alpha) |
{ |
SDL_PixelFormat *fmt = dst->format; |
#define RLECLIPBLIT(bpp, Type, do_blit) \ |
do { \ |
int linecount = srcrect->h; \ |
int ofs = 0; \ |
int left = srcrect->x; \ |
int right = left + srcrect->w; \ |
dstbuf -= left * bpp; \ |
for(;;) { \ |
int run; \ |
ofs += *(Type *)srcbuf; \ |
run = ((Type *)srcbuf)[1]; \ |
srcbuf += 2 * sizeof(Type); \ |
if(run) { \ |
/* clip to left and right borders */ \ |
if(ofs < right) { \ |
int start = 0; \ |
int len = run; \ |
int startcol; \ |
if(left - ofs > 0) { \ |
start = left - ofs; \ |
len -= start; \ |
if(len <= 0) \ |
goto nocopy ## bpp ## do_blit; \ |
} \ |
startcol = ofs + start; \ |
if(len > right - startcol) \ |
len = right - startcol; \ |
do_blit(dstbuf + startcol * bpp, srcbuf + start * bpp, \ |
len, bpp, alpha); \ |
} \ |
nocopy ## bpp ## do_blit: \ |
srcbuf += run * bpp; \ |
ofs += run; \ |
} else if(!ofs) \ |
break; \ |
if(ofs == w) { \ |
ofs = 0; \ |
dstbuf += dst->pitch; \ |
if(!--linecount) \ |
break; \ |
} \ |
} \ |
} while(0) |
CHOOSE_BLIT(RLECLIPBLIT, alpha, fmt); |
#undef RLECLIPBLIT |
} |
/* blit a colorkeyed RLE surface */ |
int SDL_RLEBlit(SDL_Surface *src, SDL_Rect *srcrect, |
SDL_Surface *dst, SDL_Rect *dstrect) |
{ |
Uint8 *dstbuf; |
Uint8 *srcbuf; |
int x, y; |
int w = src->w; |
unsigned alpha; |
/* Lock the destination if necessary */ |
if ( dst->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
if ( video->LockHWSurface(this, dst) < 0 ) { |
return(-1); |
} |
} |
/* Set up the source and destination pointers */ |
x = dstrect->x; |
y = dstrect->y; |
dstbuf = (Uint8 *)dst->pixels + dst->offset |
+ y * dst->pitch + x * src->format->BytesPerPixel; |
srcbuf = (Uint8 *)src->map->sw_data->aux_data; |
{ |
/* skip lines at the top if neccessary */ |
int vskip = srcrect->y; |
int ofs = 0; |
if(vskip) { |
#define RLESKIP(bpp, Type) \ |
for(;;) { \ |
int run; \ |
ofs += *(Type *)srcbuf; \ |
run = ((Type *)srcbuf)[1]; \ |
srcbuf += sizeof(Type) * 2; \ |
if(run) { \ |
srcbuf += run * bpp; \ |
ofs += run; \ |
} else if(!ofs) \ |
goto done; \ |
if(ofs == w) { \ |
ofs = 0; \ |
if(!--vskip) \ |
break; \ |
} \ |
} |
switch(src->format->BytesPerPixel) { |
case 1: RLESKIP(1, Uint8); break; |
case 2: RLESKIP(2, Uint8); break; |
case 3: RLESKIP(3, Uint8); break; |
case 4: RLESKIP(4, Uint16); break; |
} |
#undef RLESKIP |
} |
} |
alpha = (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA |
? src->format->alpha : 255; |
/* if left or right edge clipping needed, call clip blit */ |
if ( srcrect->x || srcrect->w != src->w ) { |
RLEClipBlit(w, srcbuf, dst, dstbuf, srcrect, alpha); |
} else { |
SDL_PixelFormat *fmt = src->format; |
#define RLEBLIT(bpp, Type, do_blit) \ |
do { \ |
int linecount = srcrect->h; \ |
int ofs = 0; \ |
for(;;) { \ |
unsigned run; \ |
ofs += *(Type *)srcbuf; \ |
run = ((Type *)srcbuf)[1]; \ |
srcbuf += 2 * sizeof(Type); \ |
if(run) { \ |
do_blit(dstbuf + ofs * bpp, srcbuf, run, bpp, alpha); \ |
srcbuf += run * bpp; \ |
ofs += run; \ |
} else if(!ofs) \ |
break; \ |
if(ofs == w) { \ |
ofs = 0; \ |
dstbuf += dst->pitch; \ |
if(!--linecount) \ |
break; \ |
} \ |
} \ |
} while(0) |
CHOOSE_BLIT(RLEBLIT, alpha, fmt); |
#undef RLEBLIT |
} |
done: |
/* Unlock the destination if necessary */ |
if ( dst->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
video->UnlockHWSurface(this, dst); |
} |
return(0); |
} |
#undef OPAQUE_BLIT |
/* |
* Per-pixel blitting macros for translucent pixels: |
* These use the same techniques as the per-surface blitting macros |
*/ |
/* |
* For 32bpp pixels, we have made sure the alpha is stored in the top |
* 8 bits, so proceed as usual |
*/ |
#define BLIT_TRANSL_888(src, dst) \ |
do { \ |
Uint32 s = src; \ |
Uint32 d = dst; \ |
unsigned alpha = s >> 24; \ |
Uint32 s1 = s & 0xff00ff; \ |
Uint32 d1 = d & 0xff00ff; \ |
d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \ |
s &= 0xff00; \ |
d &= 0xff00; \ |
d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ |
dst = d1 | d; \ |
} while(0) |
/* |
* For 16bpp pixels, we have stored the 5 most significant alpha bits in |
* bits 5-10. As before, we can process all 3 RGB components at the same time. |
*/ |
#define BLIT_TRANSL_565(src, dst) \ |
do { \ |
Uint32 s = src; \ |
Uint32 d = dst; \ |
unsigned alpha = (s & 0x3e0) >> 5; \ |
s &= 0x07e0f81f; \ |
d = (d | d << 16) & 0x07e0f81f; \ |
d += (s - d) * alpha >> 5; \ |
d &= 0x07e0f81f; \ |
dst = d | d >> 16; \ |
} while(0) |
#define BLIT_TRANSL_555(src, dst) \ |
do { \ |
Uint32 s = src; \ |
Uint32 d = dst; \ |
unsigned alpha = (s & 0x3e0) >> 5; \ |
s &= 0x03e07c1f; \ |
d = (d | d << 16) & 0x03e07c1f; \ |
d += (s - d) * alpha >> 5; \ |
d &= 0x03e07c1f; \ |
dst = d | d >> 16; \ |
} while(0) |
/* used to save the destination format in the encoding. Designed to be |
macro-compatible with SDL_PixelFormat but without the unneeded fields */ |
typedef struct { |
Uint8 BytesPerPixel; |
Uint8 Rloss; |
Uint8 Gloss; |
Uint8 Bloss; |
Uint8 Rshift; |
Uint8 Gshift; |
Uint8 Bshift; |
Uint8 Ashift; |
Uint32 Rmask; |
Uint32 Gmask; |
Uint32 Bmask; |
Uint32 Amask; |
} RLEDestFormat; |
/* blit a pixel-alpha RLE surface clipped at the right and/or left edges */ |
static void RLEAlphaClipBlit(int w, Uint8 *srcbuf, SDL_Surface *dst, |
Uint8 *dstbuf, SDL_Rect *srcrect) |
{ |
SDL_PixelFormat *df = dst->format; |
/* |
* clipped blitter: Ptype is the destination pixel type, |
* Ctype the translucent count type, and do_blend the macro |
* to blend one pixel. |
*/ |
#define RLEALPHACLIPBLIT(Ptype, Ctype, do_blend) \ |
do { \ |
int linecount = srcrect->h; \ |
int left = srcrect->x; \ |
int right = left + srcrect->w; \ |
dstbuf -= left * sizeof(Ptype); \ |
do { \ |
int ofs = 0; \ |
/* blit opaque pixels on one line */ \ |
do { \ |
unsigned run; \ |
ofs += ((Ctype *)srcbuf)[0]; \ |
run = ((Ctype *)srcbuf)[1]; \ |
srcbuf += 2 * sizeof(Ctype); \ |
if(run) { \ |
/* clip to left and right borders */ \ |
int cofs = ofs; \ |
int crun = run; \ |
if(left - cofs > 0) { \ |
crun -= left - cofs; \ |
cofs = left; \ |
} \ |
if(crun > right - cofs) \ |
crun = right - cofs; \ |
if(crun > 0) \ |
PIXEL_COPY(dstbuf + cofs * sizeof(Ptype), \ |
srcbuf + (cofs - ofs) * sizeof(Ptype), \ |
(unsigned)crun, sizeof(Ptype)); \ |
srcbuf += run * sizeof(Ptype); \ |
ofs += run; \ |
} else if(!ofs) \ |
return; \ |
} while(ofs < w); \ |
/* skip padding if necessary */ \ |
if(sizeof(Ptype) == 2) \ |
srcbuf += (unsigned long)srcbuf & 2; \ |
/* blit translucent pixels on the same line */ \ |
ofs = 0; \ |
do { \ |
unsigned run; \ |
ofs += ((Uint16 *)srcbuf)[0]; \ |
run = ((Uint16 *)srcbuf)[1]; \ |
srcbuf += 4; \ |
if(run) { \ |
/* clip to left and right borders */ \ |
int cofs = ofs; \ |
int crun = run; \ |
if(left - cofs > 0) { \ |
crun -= left - cofs; \ |
cofs = left; \ |
} \ |
if(crun > right - cofs) \ |
crun = right - cofs; \ |
if(crun > 0) { \ |
Ptype *dst = (Ptype *)dstbuf + cofs; \ |
Uint32 *src = (Uint32 *)srcbuf + (cofs - ofs); \ |
int i; \ |
for(i = 0; i < crun; i++) \ |
do_blend(src[i], dst[i]); \ |
} \ |
srcbuf += run * 4; \ |
ofs += run; \ |
} \ |
} while(ofs < w); \ |
dstbuf += dst->pitch; \ |
} while(--linecount); \ |
} while(0) |
switch(df->BytesPerPixel) { |
case 2: |
if(df->Gmask == 0x07e0 || df->Rmask == 0x07e0 |
|| df->Bmask == 0x07e0) |
RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_565); |
else |
RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_555); |
break; |
case 4: |
RLEALPHACLIPBLIT(Uint32, Uint16, BLIT_TRANSL_888); |
break; |
} |
} |
/* blit a pixel-alpha RLE surface */ |
int SDL_RLEAlphaBlit(SDL_Surface *src, SDL_Rect *srcrect, |
SDL_Surface *dst, SDL_Rect *dstrect) |
{ |
int x, y; |
int w = src->w; |
Uint8 *srcbuf, *dstbuf; |
SDL_PixelFormat *df = dst->format; |
/* Lock the destination if necessary */ |
if(dst->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT)) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
if(video->LockHWSurface(this, dst) < 0) { |
return -1; |
} |
} |
x = dstrect->x; |
y = dstrect->y; |
dstbuf = (Uint8 *)dst->pixels + dst->offset |
+ y * dst->pitch + x * df->BytesPerPixel; |
srcbuf = (Uint8 *)src->map->sw_data->aux_data + sizeof(RLEDestFormat); |
{ |
/* skip lines at the top if necessary */ |
int vskip = srcrect->y; |
if(vskip) { |
int ofs; |
if(df->BytesPerPixel == 2) { |
/* the 16/32 interleaved format */ |
do { |
/* skip opaque line */ |
ofs = 0; |
do { |
int run; |
ofs += srcbuf[0]; |
run = srcbuf[1]; |
srcbuf += 2; |
if(run) { |
srcbuf += 2 * run; |
ofs += run; |
} else if(!ofs) |
goto done; |
} while(ofs < w); |
/* skip padding */ |
srcbuf += (unsigned long)srcbuf & 2; |
/* skip translucent line */ |
ofs = 0; |
do { |
int run; |
ofs += ((Uint16 *)srcbuf)[0]; |
run = ((Uint16 *)srcbuf)[1]; |
srcbuf += 4 * (run + 1); |
ofs += run; |
} while(ofs < w); |
} while(--vskip); |
} else { |
/* the 32/32 interleaved format */ |
vskip <<= 1; /* opaque and translucent have same format */ |
do { |
ofs = 0; |
do { |
int run; |
ofs += ((Uint16 *)srcbuf)[0]; |
run = ((Uint16 *)srcbuf)[1]; |
srcbuf += 4; |
if(run) { |
srcbuf += 4 * run; |
ofs += run; |
} else if(!ofs) |
goto done; |
} while(ofs < w); |
} while(--vskip); |
} |
} |
} |
/* if left or right edge clipping needed, call clip blit */ |
if(srcrect->x || srcrect->w != src->w) { |
RLEAlphaClipBlit(w, srcbuf, dst, dstbuf, srcrect); |
} else { |
/* |
* non-clipped blitter. Ptype is the destination pixel type, |
* Ctype the translucent count type, and do_blend the |
* macro to blend one pixel. |
*/ |
#define RLEALPHABLIT(Ptype, Ctype, do_blend) \ |
do { \ |
int linecount = srcrect->h; \ |
do { \ |
int ofs = 0; \ |
/* blit opaque pixels on one line */ \ |
do { \ |
unsigned run; \ |
ofs += ((Ctype *)srcbuf)[0]; \ |
run = ((Ctype *)srcbuf)[1]; \ |
srcbuf += 2 * sizeof(Ctype); \ |
if(run) { \ |
PIXEL_COPY(dstbuf + ofs * sizeof(Ptype), srcbuf, \ |
run, sizeof(Ptype)); \ |
srcbuf += run * sizeof(Ptype); \ |
ofs += run; \ |
} else if(!ofs) \ |
goto done; \ |
} while(ofs < w); \ |
/* skip padding if necessary */ \ |
if(sizeof(Ptype) == 2) \ |
srcbuf += (unsigned long)srcbuf & 2; \ |
/* blit translucent pixels on the same line */ \ |
ofs = 0; \ |
do { \ |
unsigned run; \ |
ofs += ((Uint16 *)srcbuf)[0]; \ |
run = ((Uint16 *)srcbuf)[1]; \ |
srcbuf += 4; \ |
if(run) { \ |
Ptype *dst = (Ptype *)dstbuf + ofs; \ |
unsigned i; \ |
for(i = 0; i < run; i++) { \ |
Uint32 src = *(Uint32 *)srcbuf; \ |
do_blend(src, *dst); \ |
srcbuf += 4; \ |
dst++; \ |
} \ |
ofs += run; \ |
} \ |
} while(ofs < w); \ |
dstbuf += dst->pitch; \ |
} while(--linecount); \ |
} while(0) |
switch(df->BytesPerPixel) { |
case 2: |
if(df->Gmask == 0x07e0 || df->Rmask == 0x07e0 |
|| df->Bmask == 0x07e0) |
RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_565); |
else |
RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_555); |
break; |
case 4: |
RLEALPHABLIT(Uint32, Uint16, BLIT_TRANSL_888); |
break; |
} |
} |
done: |
/* Unlock the destination if necessary */ |
if(dst->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT)) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
video->UnlockHWSurface(this, dst); |
} |
return 0; |
} |
/* |
* Auxiliary functions: |
* The encoding functions take 32bpp rgb + a, and |
* return the number of bytes copied to the destination. |
* The decoding functions copy to 32bpp rgb + a, and |
* return the number of bytes copied from the source. |
* These are only used in the encoder and un-RLE code and are therefore not |
* highly optimised. |
*/ |
/* encode 32bpp rgb + a into 16bpp rgb, losing alpha */ |
static int copy_opaque_16(void *dst, Uint32 *src, int n, |
SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) |
{ |
int i; |
Uint16 *d = dst; |
for(i = 0; i < n; i++) { |
unsigned r, g, b; |
RGB_FROM_PIXEL(*src, sfmt, r, g, b); |
PIXEL_FROM_RGB(*d, dfmt, r, g, b); |
src++; |
d++; |
} |
return n * 2; |
} |
/* decode opaque pixels from 16bpp to 32bpp rgb + a */ |
static int uncopy_opaque_16(Uint32 *dst, void *src, int n, |
RLEDestFormat *sfmt, SDL_PixelFormat *dfmt) |
{ |
int i; |
Uint16 *s = src; |
unsigned alpha = dfmt->Amask ? 255 : 0; |
for(i = 0; i < n; i++) { |
unsigned r, g, b; |
RGB_FROM_PIXEL(*s, sfmt, r, g, b); |
PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, alpha); |
s++; |
dst++; |
} |
return n * 2; |
} |
/* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 565 */ |
static int copy_transl_565(void *dst, Uint32 *src, int n, |
SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) |
{ |
int i; |
Uint32 *d = dst; |
for(i = 0; i < n; i++) { |
unsigned r, g, b, a; |
Uint16 pix; |
RGBA_FROM_8888(*src, sfmt, r, g, b, a); |
PIXEL_FROM_RGB(pix, dfmt, r, g, b); |
*d = ((pix & 0x7e0) << 16) | (pix & 0xf81f) | ((a << 2) & 0x7e0); |
src++; |
d++; |
} |
return n * 4; |
} |
/* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 555 */ |
static int copy_transl_555(void *dst, Uint32 *src, int n, |
SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) |
{ |
int i; |
Uint32 *d = dst; |
for(i = 0; i < n; i++) { |
unsigned r, g, b, a; |
Uint16 pix; |
RGBA_FROM_8888(*src, sfmt, r, g, b, a); |
PIXEL_FROM_RGB(pix, dfmt, r, g, b); |
*d = ((pix & 0x3e0) << 16) | (pix & 0xfc1f) | ((a << 2) & 0x3e0); |
src++; |
d++; |
} |
return n * 4; |
} |
/* decode translucent pixels from 32bpp GORAB to 32bpp rgb + a */ |
static int uncopy_transl_16(Uint32 *dst, void *src, int n, |
RLEDestFormat *sfmt, SDL_PixelFormat *dfmt) |
{ |
int i; |
Uint32 *s = src; |
for(i = 0; i < n; i++) { |
unsigned r, g, b, a; |
Uint32 pix = *s++; |
a = (pix & 0x3e0) >> 2; |
pix = (pix & ~0x3e0) | pix >> 16; |
RGB_FROM_PIXEL(pix, sfmt, r, g, b); |
PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a); |
dst++; |
} |
return n * 4; |
} |
/* encode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */ |
static int copy_32(void *dst, Uint32 *src, int n, |
SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) |
{ |
int i; |
Uint32 *d = dst; |
for(i = 0; i < n; i++) { |
unsigned r, g, b, a; |
Uint32 pixel; |
RGBA_FROM_8888(*src, sfmt, r, g, b, a); |
PIXEL_FROM_RGB(pixel, dfmt, r, g, b); |
*d++ = pixel | a << 24; |
src++; |
} |
return n * 4; |
} |
/* decode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */ |
static int uncopy_32(Uint32 *dst, void *src, int n, |
RLEDestFormat *sfmt, SDL_PixelFormat *dfmt) |
{ |
int i; |
Uint32 *s = src; |
for(i = 0; i < n; i++) { |
unsigned r, g, b, a; |
Uint32 pixel = *s++; |
RGB_FROM_PIXEL(pixel, sfmt, r, g, b); |
a = pixel >> 24; |
PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a); |
dst++; |
} |
return n * 4; |
} |
#define ISOPAQUE(pixel, fmt) ((((pixel) & fmt->Amask) >> fmt->Ashift) == 255) |
#define ISTRANSL(pixel, fmt) \ |
((unsigned)((((pixel) & fmt->Amask) >> fmt->Ashift) - 1U) < 254U) |
/* convert surface to be quickly alpha-blittable onto dest, if possible */ |
static int RLEAlphaSurface(SDL_Surface *surface) |
{ |
SDL_Surface *dest; |
SDL_PixelFormat *df; |
int maxsize = 0; |
int max_opaque_run; |
int max_transl_run = 65535; |
unsigned masksum; |
Uint8 *rlebuf, *dst; |
int (*copy_opaque)(void *, Uint32 *, int, |
SDL_PixelFormat *, SDL_PixelFormat *); |
int (*copy_transl)(void *, Uint32 *, int, |
SDL_PixelFormat *, SDL_PixelFormat *); |
dest = surface->map->dst; |
if(!dest) |
return -1; |
df = dest->format; |
if(surface->format->BitsPerPixel != 32) |
return -1; /* only 32bpp source supported */ |
/* find out whether the destination is one we support, |
and determine the max size of the encoded result */ |
masksum = df->Rmask | df->Gmask | df->Bmask; |
switch(df->BytesPerPixel) { |
case 2: |
/* 16bpp: only support 565 and 555 formats */ |
switch(masksum) { |
case 0xffff: |
if(df->Gmask == 0x07e0 |
|| df->Rmask == 0x07e0 || df->Bmask == 0x07e0) { |
copy_opaque = copy_opaque_16; |
copy_transl = copy_transl_565; |
} else |
return -1; |
break; |
case 0x7fff: |
if(df->Gmask == 0x03e0 |
|| df->Rmask == 0x03e0 || df->Bmask == 0x03e0) { |
copy_opaque = copy_opaque_16; |
copy_transl = copy_transl_555; |
} else |
return -1; |
break; |
default: |
return -1; |
} |
max_opaque_run = 255; /* runs stored as bytes */ |
/* worst case is alternating opaque and translucent pixels, |
with room for alignment padding between lines */ |
maxsize = surface->h * (2 + (4 + 2) * (surface->w + 1)) + 2; |
break; |
case 4: |
if(masksum != 0x00ffffff) |
return -1; /* requires unused high byte */ |
copy_opaque = copy_32; |
copy_transl = copy_32; |
max_opaque_run = 255; /* runs stored as short ints */ |
/* worst case is alternating opaque and translucent pixels */ |
maxsize = surface->h * 2 * 4 * (surface->w + 1) + 4; |
break; |
default: |
return -1; /* anything else unsupported right now */ |
} |
maxsize += sizeof(RLEDestFormat); |
rlebuf = (Uint8 *)malloc(maxsize); |
if(!rlebuf) { |
SDL_OutOfMemory(); |
return -1; |
} |
{ |
/* save the destination format so we can undo the encoding later */ |
RLEDestFormat *r = (RLEDestFormat *)rlebuf; |
r->BytesPerPixel = df->BytesPerPixel; |
r->Rloss = df->Rloss; |
r->Gloss = df->Gloss; |
r->Bloss = df->Bloss; |
r->Rshift = df->Rshift; |
r->Gshift = df->Gshift; |
r->Bshift = df->Bshift; |
r->Ashift = df->Ashift; |
r->Rmask = df->Rmask; |
r->Gmask = df->Gmask; |
r->Bmask = df->Bmask; |
r->Amask = df->Amask; |
} |
dst = rlebuf + sizeof(RLEDestFormat); |
/* Do the actual encoding */ |
{ |
int x, y; |
int h = surface->h, w = surface->w; |
SDL_PixelFormat *sf = surface->format; |
Uint32 *src = (Uint32 *)((Uint8 *)surface->pixels + surface->offset); |
Uint8 *lastline = dst; /* end of last non-blank line */ |
/* opaque counts are 8 or 16 bits, depending on target depth */ |
#define ADD_OPAQUE_COUNTS(n, m) \ |
if(df->BytesPerPixel == 4) { \ |
((Uint16 *)dst)[0] = n; \ |
((Uint16 *)dst)[1] = m; \ |
dst += 4; \ |
} else { \ |
dst[0] = n; \ |
dst[1] = m; \ |
dst += 2; \ |
} |
/* translucent counts are always 16 bit */ |
#define ADD_TRANSL_COUNTS(n, m) \ |
(((Uint16 *)dst)[0] = n, ((Uint16 *)dst)[1] = m, dst += 4) |
for(y = 0; y < h; y++) { |
int runstart, skipstart; |
int blankline = 0; |
/* First encode all opaque pixels of a scan line */ |
x = 0; |
do { |
int run, skip, len; |
skipstart = x; |
while(x < w && !ISOPAQUE(src[x], sf)) |
x++; |
runstart = x; |
while(x < w && ISOPAQUE(src[x], sf)) |
x++; |
skip = runstart - skipstart; |
if(skip == w) |
blankline = 1; |
run = x - runstart; |
while(skip > max_opaque_run) { |
ADD_OPAQUE_COUNTS(max_opaque_run, 0); |
skip -= max_opaque_run; |
} |
len = MIN(run, max_opaque_run); |
ADD_OPAQUE_COUNTS(skip, len); |
dst += copy_opaque(dst, src + runstart, len, sf, df); |
runstart += len; |
run -= len; |
while(run) { |
len = MIN(run, max_opaque_run); |
ADD_OPAQUE_COUNTS(0, len); |
dst += copy_opaque(dst, src + runstart, len, sf, df); |
runstart += len; |
run -= len; |
} |
} while(x < w); |
/* Make sure the next output address is 32-bit aligned */ |
dst += (unsigned long)dst & 2; |
/* Next, encode all translucent pixels of the same scan line */ |
x = 0; |
do { |
int run, skip, len; |
skipstart = x; |
while(x < w && !ISTRANSL(src[x], sf)) |
x++; |
runstart = x; |
while(x < w && ISTRANSL(src[x], sf)) |
x++; |
skip = runstart - skipstart; |
blankline &= (skip == w); |
run = x - runstart; |
while(skip > max_transl_run) { |
ADD_TRANSL_COUNTS(max_transl_run, 0); |
skip -= max_transl_run; |
} |
len = MIN(run, max_transl_run); |
ADD_TRANSL_COUNTS(skip, len); |
dst += copy_transl(dst, src + runstart, len, sf, df); |
runstart += len; |
run -= len; |
while(run) { |
len = MIN(run, max_transl_run); |
ADD_TRANSL_COUNTS(0, len); |
dst += copy_transl(dst, src + runstart, len, sf, df); |
runstart += len; |
run -= len; |
} |
if(!blankline) |
lastline = dst; |
} while(x < w); |
src += surface->pitch >> 2; |
} |
dst = lastline; /* back up past trailing blank lines */ |
ADD_OPAQUE_COUNTS(0, 0); |
} |
#undef ADD_OPAQUE_COUNTS |
#undef ADD_TRANSL_COUNTS |
/* Now that we have it encoded, release the original pixels */ |
if((surface->flags & SDL_PREALLOC) != SDL_PREALLOC |
&& (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) { |
free( surface->pixels ); |
surface->pixels = NULL; |
} |
/* realloc the buffer to release unused memory */ |
{ |
Uint8 *p = realloc(rlebuf, dst - rlebuf); |
if(!p) |
p = rlebuf; |
surface->map->sw_data->aux_data = p; |
} |
return 0; |
} |
static Uint32 getpix_8(Uint8 *srcbuf) |
{ |
return *srcbuf; |
} |
static Uint32 getpix_16(Uint8 *srcbuf) |
{ |
return *(Uint16 *)srcbuf; |
} |
static Uint32 getpix_24(Uint8 *srcbuf) |
{ |
if(SDL_BYTEORDER == SDL_LIL_ENDIAN) |
return srcbuf[0] + (srcbuf[1] << 8) + (srcbuf[2] << 16); |
else |
return (srcbuf[0] << 16) + (srcbuf[1] << 8) + srcbuf[2]; |
} |
static Uint32 getpix_32(Uint8 *srcbuf) |
{ |
return *(Uint32 *)srcbuf; |
} |
typedef Uint32 (*getpix_func)(Uint8 *); |
static getpix_func getpixes[4] = { |
getpix_8, getpix_16, getpix_24, getpix_32 |
}; |
static int RLEColorkeySurface(SDL_Surface *surface) |
{ |
Uint8 *rlebuf, *dst; |
int maxn; |
int y; |
Uint8 *srcbuf, *curbuf, *lastline; |
int maxsize = 0; |
int skip, run; |
int bpp = surface->format->BytesPerPixel; |
getpix_func getpix; |
Uint32 ckey, rgbmask; |
int w, h; |
/* calculate the worst case size for the compressed surface */ |
switch(bpp) { |
case 1: |
/* worst case is alternating opaque and transparent pixels, |
starting with an opaque pixel */ |
maxsize = surface->h * 3 * (surface->w / 2 + 1) + 2; |
break; |
case 2: |
case 3: |
/* worst case is solid runs, at most 255 pixels wide */ |
maxsize = surface->h * (2 * (surface->w / 255 + 1) |
+ surface->w * bpp) + 2; |
break; |
case 4: |
/* worst case is solid runs, at most 65535 pixels wide */ |
maxsize = surface->h * (4 * (surface->w / 65535 + 1) |
+ surface->w * 4) + 4; |
break; |
} |
rlebuf = (Uint8 *)malloc(maxsize); |
if ( rlebuf == NULL ) { |
SDL_OutOfMemory(); |
return(-1); |
} |
/* Set up the conversion */ |
srcbuf = (Uint8 *)surface->pixels+surface->offset; |
curbuf = srcbuf; |
maxn = bpp == 4 ? 65535 : 255; |
skip = run = 0; |
dst = rlebuf; |
rgbmask = ~surface->format->Amask; |
ckey = surface->format->colorkey & rgbmask; |
lastline = dst; |
getpix = getpixes[bpp - 1]; |
w = surface->w; |
h = surface->h; |
#define ADD_COUNTS(n, m) \ |
if(bpp == 4) { \ |
((Uint16 *)dst)[0] = n; \ |
((Uint16 *)dst)[1] = m; \ |
dst += 4; \ |
} else { \ |
dst[0] = n; \ |
dst[1] = m; \ |
dst += 2; \ |
} |
for(y = 0; y < h; y++) { |
int x = 0; |
int blankline = 0; |
do { |
int run, skip, len; |
int runstart; |
int skipstart = x; |
/* find run of transparent, then opaque pixels */ |
while(x < w && (getpix(srcbuf + x * bpp) & rgbmask) == ckey) |
x++; |
runstart = x; |
while(x < w && (getpix(srcbuf + x * bpp) & rgbmask) != ckey) |
x++; |
skip = runstart - skipstart; |
if(skip == w) |
blankline = 1; |
run = x - runstart; |
/* encode segment */ |
while(skip > maxn) { |
ADD_COUNTS(maxn, 0); |
skip -= maxn; |
} |
len = MIN(run, maxn); |
ADD_COUNTS(skip, len); |
memcpy(dst, srcbuf + runstart * bpp, len * bpp); |
dst += len * bpp; |
run -= len; |
runstart += len; |
while(run) { |
len = MIN(run, maxn); |
ADD_COUNTS(0, len); |
memcpy(dst, srcbuf + runstart * bpp, len * bpp); |
dst += len * bpp; |
runstart += len; |
run -= len; |
} |
if(!blankline) |
lastline = dst; |
} while(x < w); |
srcbuf += surface->pitch; |
} |
dst = lastline; /* back up bast trailing blank lines */ |
ADD_COUNTS(0, 0); |
#undef ADD_COUNTS |
/* Now that we have it encoded, release the original pixels */ |
if((surface->flags & SDL_PREALLOC) != SDL_PREALLOC |
&& (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) { |
free( surface->pixels ); |
surface->pixels = NULL; |
} |
/* realloc the buffer to release unused memory */ |
{ |
/* If realloc returns NULL, the original block is left intact */ |
Uint8 *p = realloc(rlebuf, dst - rlebuf); |
if(!p) |
p = rlebuf; |
surface->map->sw_data->aux_data = p; |
} |
return(0); |
} |
int SDL_RLESurface(SDL_Surface *surface) |
{ |
int retcode; |
/* Clear any previous RLE conversion */ |
if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { |
SDL_UnRLESurface(surface, 1); |
} |
/* We don't support RLE encoding of bitmaps */ |
if ( surface->format->BitsPerPixel < 8 ) { |
return(-1); |
} |
/* Lock the surface if it's in hardware */ |
if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
if ( video->LockHWSurface(this, surface) < 0 ) { |
return(-1); |
} |
} |
/* Encode */ |
if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { |
retcode = RLEColorkeySurface(surface); |
} else { |
if((surface->flags & SDL_SRCALPHA) == SDL_SRCALPHA |
&& surface->format->Amask != 0) |
retcode = RLEAlphaSurface(surface); |
else |
retcode = -1; /* no RLE for per-surface alpha sans ckey */ |
} |
/* Unlock the surface if it's in hardware */ |
if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
video->UnlockHWSurface(this, surface); |
} |
if(retcode < 0) |
return -1; |
/* The surface is now accelerated */ |
surface->flags |= SDL_RLEACCEL; |
return(0); |
} |
/* |
* Un-RLE a surface with pixel alpha |
* This may not give back exactly the image before RLE-encoding; all |
* completely transparent pixels will be lost, and colour and alpha depth |
* may have been reduced (when encoding for 16bpp targets). |
*/ |
static void UnRLEAlpha(SDL_Surface *surface) |
{ |
Uint8 *srcbuf; |
Uint32 *dst; |
SDL_PixelFormat *sf = surface->format; |
RLEDestFormat *df = surface->map->sw_data->aux_data; |
int (*uncopy_opaque)(Uint32 *, void *, int, |
RLEDestFormat *, SDL_PixelFormat *); |
int (*uncopy_transl)(Uint32 *, void *, int, |
RLEDestFormat *, SDL_PixelFormat *); |
int w = surface->w; |
int bpp = df->BytesPerPixel; |
if(bpp == 2) { |
uncopy_opaque = uncopy_opaque_16; |
uncopy_transl = uncopy_transl_16; |
} else { |
uncopy_opaque = uncopy_transl = uncopy_32; |
} |
surface->pixels = malloc(surface->h * surface->pitch); |
/* fill background with transparent pixels */ |
memset(surface->pixels, 0, surface->h * surface->pitch); |
dst = surface->pixels; |
srcbuf = (Uint8 *)(df + 1); |
for(;;) { |
/* copy opaque pixels */ |
int ofs = 0; |
do { |
unsigned run; |
if(bpp == 2) { |
ofs += srcbuf[0]; |
run = srcbuf[1]; |
srcbuf += 2; |
} else { |
ofs += ((Uint16 *)srcbuf)[0]; |
run = ((Uint16 *)srcbuf)[1]; |
srcbuf += 4; |
} |
if(run) { |
srcbuf += uncopy_opaque(dst + ofs, srcbuf, run, df, sf); |
ofs += run; |
} else if(!ofs) |
return; |
} while(ofs < w); |
/* skip padding if needed */ |
if(bpp == 2) |
srcbuf += (unsigned long)srcbuf & 2; |
/* copy translucent pixels */ |
ofs = 0; |
do { |
unsigned run; |
ofs += ((Uint16 *)srcbuf)[0]; |
run = ((Uint16 *)srcbuf)[1]; |
srcbuf += 4; |
if(run) { |
srcbuf += uncopy_transl(dst + ofs, srcbuf, run, df, sf); |
ofs += run; |
} |
} while(ofs < w); |
dst += surface->pitch >> 2; |
} |
} |
void SDL_UnRLESurface(SDL_Surface *surface, int recode) |
{ |
if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { |
surface->flags &= ~SDL_RLEACCEL; |
if(recode && (surface->flags & SDL_PREALLOC) != SDL_PREALLOC |
&& (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) { |
if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { |
SDL_Rect full; |
unsigned alpha_flag; |
/* re-create the original surface */ |
surface->pixels = malloc(surface->h * surface->pitch); |
/* fill it with the background colour */ |
SDL_FillRect(surface, NULL, surface->format->colorkey); |
/* now render the encoded surface */ |
full.x = full.y = 0; |
full.w = surface->w; |
full.h = surface->h; |
alpha_flag = surface->flags & SDL_SRCALPHA; |
surface->flags &= ~SDL_SRCALPHA; /* opaque blit */ |
SDL_RLEBlit(surface, &full, surface, &full); |
surface->flags |= alpha_flag; |
} else |
UnRLEAlpha(surface); |
} |
if ( surface->map && surface->map->sw_data->aux_data ) { |
free(surface->map->sw_data->aux_data); |
surface->map->sw_data->aux_data = NULL; |
} |
} |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_RLEaccel_c.h |
---|
0,0 → 1,35 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_RLEaccel_c.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; |
#endif |
/* Useful functions and variables from SDL_RLEaccel.c */ |
extern int SDL_RLESurface(SDL_Surface *surface); |
extern int SDL_RLEBlit(SDL_Surface *src, SDL_Rect *srcrect, |
SDL_Surface *dst, SDL_Rect *dstrect); |
extern int SDL_RLEAlphaBlit(SDL_Surface *src, SDL_Rect *srcrect, |
SDL_Surface *dst, SDL_Rect *dstrect); |
extern void SDL_UnRLESurface(SDL_Surface *surface, int recode); |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_blit.c |
---|
0,0 → 1,289 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "SDL_error.h" |
#include "SDL_video.h" |
#include "SDL_sysvideo.h" |
#include "SDL_blit.h" |
#include "SDL_RLEaccel_c.h" |
#include "SDL_pixels_c.h" |
#include "SDL_memops.h" |
/* The general purpose software blit routine */ |
static int SDL_SoftBlit(SDL_Surface *src, SDL_Rect *srcrect, |
SDL_Surface *dst, SDL_Rect *dstrect) |
{ |
int okay; |
int src_locked; |
int dst_locked; |
/* Everything is okay at the beginning... */ |
okay = 1; |
/* Lock the destination if it's in hardware */ |
dst_locked = 0; |
if ( dst->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
if ( video->LockHWSurface(this, dst) < 0 ) { |
okay = 0; |
} else { |
dst_locked = 1; |
} |
} |
/* Lock the source if it's in hardware */ |
src_locked = 0; |
if ( src->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
if ( video->LockHWSurface(this, src) < 0 ) { |
okay = 0; |
} else { |
src_locked = 1; |
} |
} |
/* Unencode the destination if it's RLE encoded */ |
if ( dst->flags & SDL_RLEACCEL ) { |
SDL_UnRLESurface(dst, 1); |
dst->flags |= SDL_RLEACCEL; /* save accel'd state */ |
} |
/* Set up source and destination buffer pointers, and BLIT! */ |
if ( okay && srcrect->w && srcrect->h ) { |
SDL_BlitInfo info; |
SDL_loblit RunBlit; |
/* Set up the blit information */ |
info.s_pixels = (Uint8 *)src->pixels + src->offset + |
(Uint16)srcrect->y*src->pitch + |
(Uint16)srcrect->x*src->format->BytesPerPixel; |
info.s_width = srcrect->w; |
info.s_height = srcrect->h; |
info.s_skip=src->pitch-info.s_width*src->format->BytesPerPixel; |
info.d_pixels = (Uint8 *)dst->pixels + dst->offset + |
(Uint16)dstrect->y*dst->pitch + |
(Uint16)dstrect->x*dst->format->BytesPerPixel; |
info.d_width = dstrect->w; |
info.d_height = dstrect->h; |
info.d_skip=dst->pitch-info.d_width*dst->format->BytesPerPixel; |
info.aux_data = src->map->sw_data->aux_data; |
info.src = src->format; |
info.table = src->map->table; |
info.dst = dst->format; |
RunBlit = src->map->sw_data->blit; |
/* Run the actual software blit */ |
RunBlit(&info); |
} |
/* Re-encode the destination if it's RLE encoded */ |
if ( dst->flags & SDL_RLEACCEL ) { |
dst->flags &= ~SDL_RLEACCEL; /* stop lying */ |
SDL_RLESurface(dst); |
} |
/* We need to unlock the surfaces if they're locked */ |
if ( dst_locked ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
video->UnlockHWSurface(this, dst); |
} else |
if ( src_locked ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
video->UnlockHWSurface(this, src); |
} |
/* Blit is done! */ |
return(okay ? 0 : -1); |
} |
static void SDL_BlitCopy(SDL_BlitInfo *info) |
{ |
Uint8 *src, *dst; |
int w, h; |
int srcskip, dstskip; |
w = info->d_width*info->dst->BytesPerPixel; |
h = info->d_height; |
src = info->s_pixels; |
dst = info->d_pixels; |
srcskip = w+info->s_skip; |
dstskip = w+info->d_skip; |
while ( h-- ) { |
SDL_memcpy(dst, src, w); |
src += srcskip; |
dst += dstskip; |
} |
} |
static void SDL_BlitCopyOverlap(SDL_BlitInfo *info) |
{ |
Uint8 *src, *dst; |
int w, h; |
int srcskip, dstskip; |
w = info->d_width*info->dst->BytesPerPixel; |
h = info->d_height; |
src = info->s_pixels; |
dst = info->d_pixels; |
srcskip = w+info->s_skip; |
dstskip = w+info->d_skip; |
if ( dst < src ) { |
while ( h-- ) { |
SDL_memcpy(dst, src, w); |
src += srcskip; |
dst += dstskip; |
} |
} else { |
src += ((h-1) * srcskip); |
dst += ((h-1) * dstskip); |
while ( h-- ) { |
SDL_revcpy(dst, src, w); |
src -= srcskip; |
dst -= dstskip; |
} |
} |
} |
/* Figure out which of many blit routines to set up on a surface */ |
int SDL_CalculateBlit(SDL_Surface *surface) |
{ |
int blit_index; |
/* Clean everything out to start */ |
if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { |
SDL_UnRLESurface(surface, 1); |
} |
surface->map->sw_blit = NULL; |
/* Figure out if an accelerated hardware blit is possible */ |
surface->flags &= ~SDL_HWACCEL; |
if ( surface->map->identity ) { |
int hw_blit_ok; |
if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { |
/* We only support accelerated blitting to hardware */ |
if ( surface->map->dst->flags & SDL_HWSURFACE ) { |
hw_blit_ok = current_video->info.blit_hw; |
} else { |
hw_blit_ok = 0; |
} |
if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) { |
hw_blit_ok = current_video->info.blit_hw_CC; |
} |
if ( hw_blit_ok && (surface->flags & SDL_SRCALPHA) ) { |
hw_blit_ok = current_video->info.blit_hw_A; |
} |
} else { |
/* We only support accelerated blitting to hardware */ |
if ( surface->map->dst->flags & SDL_HWSURFACE ) { |
hw_blit_ok = current_video->info.blit_sw; |
} else { |
hw_blit_ok = 0; |
} |
if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) { |
hw_blit_ok = current_video->info.blit_sw_CC; |
} |
if ( hw_blit_ok && (surface->flags & SDL_SRCALPHA) ) { |
hw_blit_ok = current_video->info.blit_sw_A; |
} |
} |
if ( hw_blit_ok ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
video->CheckHWBlit(this, surface, surface->map->dst); |
} |
} |
/* Get the blit function index, based on surface mode */ |
/* { 0 = nothing, 1 = colorkey, 2 = alpha, 3 = colorkey+alpha } */ |
blit_index = 0; |
blit_index |= (!!(surface->flags & SDL_SRCCOLORKEY)) << 0; |
if ( surface->flags & SDL_SRCALPHA |
&& (surface->format->alpha != SDL_ALPHA_OPAQUE |
|| surface->format->Amask) ) { |
blit_index |= 2; |
} |
/* Check for special "identity" case -- copy blit */ |
if ( surface->map->identity && blit_index == 0 ) { |
surface->map->sw_data->blit = SDL_BlitCopy; |
/* Handle overlapping blits on the same surface */ |
if ( surface == surface->map->dst ) { |
surface->map->sw_data->blit = SDL_BlitCopyOverlap; |
} |
} else { |
if ( surface->format->BitsPerPixel < 8 ) { |
surface->map->sw_data->blit = |
SDL_CalculateBlit0(surface, blit_index); |
} else { |
switch ( surface->format->BytesPerPixel ) { |
case 1: |
surface->map->sw_data->blit = |
SDL_CalculateBlit1(surface, blit_index); |
break; |
case 2: |
case 3: |
case 4: |
surface->map->sw_data->blit = |
SDL_CalculateBlitN(surface, blit_index); |
break; |
default: |
surface->map->sw_data->blit = NULL; |
break; |
} |
} |
} |
/* Make sure we have a blit function */ |
if ( surface->map->sw_data->blit == NULL ) { |
SDL_InvalidateMap(surface->map); |
SDL_SetError("Blit combination not supported"); |
return(-1); |
} |
/* Choose software blitting function */ |
if(surface->flags & SDL_RLEACCELOK |
&& (surface->flags & SDL_HWACCEL) != SDL_HWACCEL) { |
if(surface->map->identity |
&& (blit_index == 1 |
|| (blit_index == 3 && !surface->format->Amask))) { |
if ( SDL_RLESurface(surface) == 0 ) |
surface->map->sw_blit = SDL_RLEBlit; |
} else if(blit_index == 2 && surface->format->Amask) { |
if ( SDL_RLESurface(surface) == 0 ) |
surface->map->sw_blit = SDL_RLEAlphaBlit; |
} |
} |
if ( surface->map->sw_blit == NULL ) { |
surface->map->sw_blit = SDL_SoftBlit; |
} |
return(0); |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_blit.h |
---|
0,0 → 1,437 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_blit.h,v 1.3 2001/07/07 20:20:16 hercules Exp $"; |
#endif |
#ifndef _SDL_blit_h |
#define _SDL_blit_h |
#include "SDL_endian.h" |
/* The structure passed to the low level blit functions */ |
typedef struct { |
Uint8 *s_pixels; |
int s_width; |
int s_height; |
int s_skip; |
Uint8 *d_pixels; |
int d_width; |
int d_height; |
int d_skip; |
void *aux_data; |
SDL_PixelFormat *src; |
Uint8 *table; |
SDL_PixelFormat *dst; |
} SDL_BlitInfo; |
/* The type definition for the low level blit functions */ |
typedef void (*SDL_loblit)(SDL_BlitInfo *info); |
/* This is the private info structure for software accelerated blits */ |
struct private_swaccel { |
SDL_loblit blit; |
void *aux_data; |
}; |
/* Blit mapping definition */ |
typedef struct SDL_BlitMap { |
SDL_Surface *dst; |
int identity; |
Uint8 *table; |
SDL_blit hw_blit; |
SDL_blit sw_blit; |
struct private_hwaccel *hw_data; |
struct private_swaccel *sw_data; |
/* the version count matches the destination; mismatch indicates |
an invalid mapping */ |
unsigned int format_version; |
} SDL_BlitMap; |
/* Definitions for special global blit functions */ |
#include "SDL_blit_A.h" |
/* Functions found in SDL_blit.c */ |
extern int SDL_CalculateBlit(SDL_Surface *surface); |
/* Functions found in SDL_blit_{0,1,N,A}.c */ |
extern SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int complex); |
extern SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int complex); |
extern SDL_loblit SDL_CalculateBlitN(SDL_Surface *surface, int complex); |
extern SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int complex); |
/* |
* Useful macros for blitting routines |
*/ |
#define FORMAT_EQUAL(A, B) \ |
((A)->BitsPerPixel == (B)->BitsPerPixel \ |
&& ((A)->Rmask == (B)->Rmask) && ((A)->Amask == (B)->Amask)) |
/* Load pixel of the specified format from a buffer and get its R-G-B values */ |
/* FIXME: rescale values to 0..255 here? */ |
#define RGB_FROM_PIXEL(pixel, fmt, r, g, b) \ |
{ \ |
r = (((pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss); \ |
g = (((pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss); \ |
b = (((pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss); \ |
} |
#define RGB_FROM_RGB565(pixel, r, g, b) \ |
{ \ |
r = (((pixel&0xF800)>>11)<<3); \ |
g = (((pixel&0x07E0)>>5)<<2); \ |
b = ((pixel&0x001F)<<3); \ |
} |
#define RGB_FROM_RGB555(pixel, r, g, b) \ |
{ \ |
r = (((pixel&0x7C00)>>10)<<3); \ |
g = (((pixel&0x03E0)>>5)<<3); \ |
b = ((pixel&0x001F)<<3); \ |
} |
#define RGB_FROM_RGB888(pixel, r, g, b) \ |
{ \ |
r = ((pixel&0xFF0000)>>16); \ |
g = ((pixel&0xFF00)>>8); \ |
b = (pixel&0xFF); \ |
} |
#define RETRIEVE_RGB_PIXEL(buf, bpp, pixel) \ |
do { \ |
switch (bpp) { \ |
case 2: \ |
pixel = *((Uint16 *)(buf)); \ |
break; \ |
\ |
case 3: { \ |
Uint8 *B = (Uint8 *)(buf); \ |
if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ |
pixel = B[0] + (B[1] << 8) + (B[2] << 16); \ |
} else { \ |
pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \ |
} \ |
} \ |
break; \ |
\ |
case 4: \ |
pixel = *((Uint32 *)(buf)); \ |
break; \ |
\ |
default: \ |
pixel = 0; /* appease gcc */ \ |
break; \ |
} \ |
} while(0) |
#define DISEMBLE_RGB(buf, bpp, fmt, pixel, r, g, b) \ |
do { \ |
switch (bpp) { \ |
case 2: \ |
pixel = *((Uint16 *)(buf)); \ |
break; \ |
\ |
case 3: { \ |
Uint8 *B = (Uint8 *)buf; \ |
if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ |
pixel = B[0] + (B[1] << 8) + (B[2] << 16); \ |
} else { \ |
pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \ |
} \ |
} \ |
break; \ |
\ |
case 4: \ |
pixel = *((Uint32 *)(buf)); \ |
break; \ |
\ |
default: \ |
pixel = 0; /* prevent gcc from complaining */ \ |
break; \ |
} \ |
RGB_FROM_PIXEL(pixel, fmt, r, g, b); \ |
} while(0) |
/* Assemble R-G-B values into a specified pixel format and store them */ |
#define PIXEL_FROM_RGB(pixel, fmt, r, g, b) \ |
{ \ |
pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \ |
((g>>fmt->Gloss)<<fmt->Gshift)| \ |
((b>>fmt->Bloss)<<fmt->Bshift); \ |
} |
#define RGB565_FROM_RGB(pixel, r, g, b) \ |
{ \ |
pixel = ((r>>3)<<11)|((g>>2)<<5)|(b>>3); \ |
} |
#define RGB555_FROM_RGB(pixel, r, g, b) \ |
{ \ |
pixel = ((r>>3)<<10)|((g>>3)<<5)|(b>>3); \ |
} |
#define RGB888_FROM_RGB(pixel, r, g, b) \ |
{ \ |
pixel = (r<<16)|(g<<8)|b; \ |
} |
#define ASSEMBLE_RGB(buf, bpp, fmt, r, g, b) \ |
{ \ |
switch (bpp) { \ |
case 2: { \ |
Uint16 pixel; \ |
\ |
PIXEL_FROM_RGB(pixel, fmt, r, g, b); \ |
*((Uint16 *)(buf)) = pixel; \ |
} \ |
break; \ |
\ |
case 3: { \ |
if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ |
*((buf)+fmt->Rshift/8) = r; \ |
*((buf)+fmt->Gshift/8) = g; \ |
*((buf)+fmt->Bshift/8) = b; \ |
} else { \ |
*((buf)+2-fmt->Rshift/8) = r; \ |
*((buf)+2-fmt->Gshift/8) = g; \ |
*((buf)+2-fmt->Bshift/8) = b; \ |
} \ |
} \ |
break; \ |
\ |
case 4: { \ |
Uint32 pixel; \ |
\ |
PIXEL_FROM_RGB(pixel, fmt, r, g, b); \ |
*((Uint32 *)(buf)) = pixel; \ |
} \ |
break; \ |
} \ |
} |
#define ASSEMBLE_RGB_AMASK(buf, bpp, fmt, r, g, b, Amask) \ |
{ \ |
switch (bpp) { \ |
case 2: { \ |
Uint16 *bufp; \ |
Uint16 pixel; \ |
\ |
bufp = (Uint16 *)buf; \ |
PIXEL_FROM_RGB(pixel, fmt, r, g, b); \ |
*bufp = pixel | (*bufp & Amask); \ |
} \ |
break; \ |
\ |
case 3: { \ |
if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ |
*((buf)+fmt->Rshift/8) = r; \ |
*((buf)+fmt->Gshift/8) = g; \ |
*((buf)+fmt->Bshift/8) = b; \ |
} else { \ |
*((buf)+2-fmt->Rshift/8) = r; \ |
*((buf)+2-fmt->Gshift/8) = g; \ |
*((buf)+2-fmt->Bshift/8) = b; \ |
} \ |
} \ |
break; \ |
\ |
case 4: { \ |
Uint32 *bufp; \ |
Uint32 pixel; \ |
\ |
bufp = (Uint32 *)buf; \ |
PIXEL_FROM_RGB(pixel, fmt, r, g, b); \ |
*bufp = pixel | (*bufp & Amask); \ |
} \ |
break; \ |
} \ |
} |
/* FIXME: Should we rescale alpha into 0..255 here? */ |
#define RGBA_FROM_PIXEL(pixel, fmt, r, g, b, a) \ |
{ \ |
r = ((pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss; \ |
g = ((pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss; \ |
b = ((pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss; \ |
a = ((pixel&fmt->Amask)>>fmt->Ashift)<<fmt->Aloss; \ |
} |
#define RGBA_FROM_8888(pixel, fmt, r, g, b, a) \ |
{ \ |
r = (pixel&fmt->Rmask)>>fmt->Rshift; \ |
g = (pixel&fmt->Gmask)>>fmt->Gshift; \ |
b = (pixel&fmt->Bmask)>>fmt->Bshift; \ |
a = (pixel&fmt->Amask)>>fmt->Ashift; \ |
} |
#define RGBA_FROM_RGBA8888(pixel, r, g, b, a) \ |
{ \ |
r = (pixel>>24); \ |
g = ((pixel>>16)&0xFF); \ |
b = ((pixel>>8)&0xFF); \ |
a = (pixel&0xFF); \ |
} |
#define RGBA_FROM_ARGB8888(pixel, r, g, b, a) \ |
{ \ |
r = ((pixel>>16)&0xFF); \ |
g = ((pixel>>8)&0xFF); \ |
b = (pixel&0xFF); \ |
a = (pixel>>24); \ |
} |
#define RGBA_FROM_ABGR8888(pixel, r, g, b, a) \ |
{ \ |
r = (pixel&0xFF); \ |
g = ((pixel>>8)&0xFF); \ |
b = ((pixel>>16)&0xFF); \ |
a = (pixel>>24); \ |
} |
#define DISEMBLE_RGBA(buf, bpp, fmt, pixel, r, g, b, a) \ |
do { \ |
switch (bpp) { \ |
case 2: \ |
pixel = *((Uint16 *)(buf)); \ |
break; \ |
\ |
case 3: {/* FIXME: broken code (no alpha) */ \ |
Uint8 *b = (Uint8 *)buf; \ |
if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ |
pixel = b[0] + (b[1] << 8) + (b[2] << 16); \ |
} else { \ |
pixel = (b[0] << 16) + (b[1] << 8) + b[2]; \ |
} \ |
} \ |
break; \ |
\ |
case 4: \ |
pixel = *((Uint32 *)(buf)); \ |
break; \ |
\ |
default: \ |
pixel = 0; /* stop gcc complaints */ \ |
break; \ |
} \ |
RGBA_FROM_PIXEL(pixel, fmt, r, g, b, a); \ |
pixel &= ~fmt->Amask; \ |
} while(0) |
/* FIXME: this isn't correct, especially for Alpha (maximum != 255) */ |
#define PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a) \ |
{ \ |
pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \ |
((g>>fmt->Gloss)<<fmt->Gshift)| \ |
((b>>fmt->Bloss)<<fmt->Bshift)| \ |
((a<<fmt->Aloss)<<fmt->Ashift); \ |
} |
#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a) \ |
{ \ |
switch (bpp) { \ |
case 2: { \ |
Uint16 pixel; \ |
\ |
PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a); \ |
*((Uint16 *)(buf)) = pixel; \ |
} \ |
break; \ |
\ |
case 3: { /* FIXME: broken code (no alpha) */ \ |
if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ |
*((buf)+fmt->Rshift/8) = r; \ |
*((buf)+fmt->Gshift/8) = g; \ |
*((buf)+fmt->Bshift/8) = b; \ |
} else { \ |
*((buf)+2-fmt->Rshift/8) = r; \ |
*((buf)+2-fmt->Gshift/8) = g; \ |
*((buf)+2-fmt->Bshift/8) = b; \ |
} \ |
} \ |
break; \ |
\ |
case 4: { \ |
Uint32 pixel; \ |
\ |
PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a); \ |
*((Uint32 *)(buf)) = pixel; \ |
} \ |
break; \ |
} \ |
} |
/* Blend the RGB values of two pixels based on a source alpha value */ |
#define ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB) \ |
do { \ |
dR = (((sR-dR)*(A))>>8)+dR; \ |
dG = (((sG-dG)*(A))>>8)+dG; \ |
dB = (((sB-dB)*(A))>>8)+dB; \ |
} while(0) |
/* This is a very useful loop for optimizing blitters */ |
#define USE_DUFFS_LOOP |
#ifdef USE_DUFFS_LOOP |
/* 8-times unrolled loop */ |
#define DUFFS_LOOP8(pixel_copy_increment, width) \ |
{ int n = (width+7)/8; \ |
switch (width & 7) { \ |
case 0: do { pixel_copy_increment; \ |
case 7: pixel_copy_increment; \ |
case 6: pixel_copy_increment; \ |
case 5: pixel_copy_increment; \ |
case 4: pixel_copy_increment; \ |
case 3: pixel_copy_increment; \ |
case 2: pixel_copy_increment; \ |
case 1: pixel_copy_increment; \ |
} while ( --n > 0 ); \ |
} \ |
} |
/* 4-times unrolled loop */ |
#define DUFFS_LOOP4(pixel_copy_increment, width) \ |
{ int n = (width+3)/4; \ |
switch (width & 3) { \ |
case 0: do { pixel_copy_increment; \ |
case 3: pixel_copy_increment; \ |
case 2: pixel_copy_increment; \ |
case 1: pixel_copy_increment; \ |
} while ( --n > 0 ); \ |
} \ |
} |
/* Use the 8-times version of the loop by default */ |
#define DUFFS_LOOP(pixel_copy_increment, width) \ |
DUFFS_LOOP8(pixel_copy_increment, width) |
#else |
/* Don't use Duff's device to unroll loops */ |
#define DUFFS_LOOP(pixel_copy_increment, width) \ |
{ int n; \ |
for ( n=width; n > 0; --n ) { \ |
pixel_copy_increment; \ |
} \ |
} |
#define DUFFS_LOOP8(pixel_copy_increment, width) \ |
DUFFS_LOOP(pixel_copy_increment, width) |
#define DUFFS_LOOP4(pixel_copy_increment, width) \ |
DUFFS_LOOP(pixel_copy_increment, width) |
#endif /* USE_DUFFS_LOOP */ |
/* Prevent Visual C++ 6.0 from printing out stupid warnings */ |
#if defined(_MSC_VER) && (_MSC_VER >= 600) |
#pragma warning(disable: 4550) |
#endif |
#endif /* _SDL_blit_h */ |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_blit_0.c |
---|
0,0 → 1,471 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#include <stdio.h> |
#include <string.h> |
#include "SDL_types.h" |
#include "SDL_video.h" |
#include "SDL_blit.h" |
/* Functions to blit from bitmaps to other surfaces */ |
static void BlitBto1(SDL_BlitInfo *info) |
{ |
int c; |
int width, height; |
Uint8 *src, *map, *dst; |
int srcskip, dstskip; |
/* Set up some basic variables */ |
width = info->d_width; |
height = info->d_height; |
src = info->s_pixels; |
srcskip = info->s_skip; |
dst = info->d_pixels; |
dstskip = info->d_skip; |
map = info->table; |
srcskip += width-(width+7)/8; |
if ( map ) { |
while ( height-- ) { |
Uint8 byte = 0, bit; |
for ( c=0; c<width; ++c ) { |
if ( (c&7) == 0 ) { |
byte = *src++; |
} |
bit = (byte&0x80)>>7; |
if ( 1 ) { |
*dst = map[bit]; |
} |
dst++; |
byte <<= 1; |
} |
src += srcskip; |
dst += dstskip; |
} |
} else { |
while ( height-- ) { |
Uint8 byte = 0, bit; |
for ( c=0; c<width; ++c ) { |
if ( (c&7) == 0 ) { |
byte = *src++; |
} |
bit = (byte&0x80)>>7; |
if ( 1 ) { |
*dst = bit; |
} |
dst++; |
byte <<= 1; |
} |
src += srcskip; |
dst += dstskip; |
} |
} |
} |
static void BlitBto2(SDL_BlitInfo *info) |
{ |
int c; |
int width, height; |
Uint8 *src; |
Uint16 *map, *dst; |
int srcskip, dstskip; |
/* Set up some basic variables */ |
width = info->d_width; |
height = info->d_height; |
src = info->s_pixels; |
srcskip = info->s_skip; |
dst = (Uint16 *)info->d_pixels; |
dstskip = info->d_skip/2; |
map = (Uint16 *)info->table; |
srcskip += width-(width+7)/8; |
while ( height-- ) { |
Uint8 byte = 0, bit; |
for ( c=0; c<width; ++c ) { |
if ( (c&7) == 0 ) { |
byte = *src++; |
} |
bit = (byte&0x80)>>7; |
if ( 1 ) { |
*dst = map[bit]; |
} |
byte <<= 1; |
dst++; |
} |
src += srcskip; |
dst += dstskip; |
} |
} |
static void BlitBto3(SDL_BlitInfo *info) |
{ |
int c, o; |
int width, height; |
Uint8 *src, *map, *dst; |
int srcskip, dstskip; |
/* Set up some basic variables */ |
width = info->d_width; |
height = info->d_height; |
src = info->s_pixels; |
srcskip = info->s_skip; |
dst = info->d_pixels; |
dstskip = info->d_skip; |
map = info->table; |
srcskip += width-(width+7)/8; |
while ( height-- ) { |
Uint8 byte = 0, bit; |
for ( c=0; c<width; ++c ) { |
if ( (c&7) == 0 ) { |
byte = *src++; |
} |
bit = (byte&0x80)>>7; |
if ( 1 ) { |
o = bit * 4; |
dst[0] = map[o++]; |
dst[1] = map[o++]; |
dst[2] = map[o++]; |
} |
byte <<= 1; |
dst += 3; |
} |
src += srcskip; |
dst += dstskip; |
} |
} |
static void BlitBto4(SDL_BlitInfo *info) |
{ |
int width, height; |
Uint8 *src; |
Uint32 *map, *dst; |
int srcskip, dstskip; |
int c; |
/* Set up some basic variables */ |
width = info->d_width; |
height = info->d_height; |
src = info->s_pixels; |
srcskip = info->s_skip; |
dst = (Uint32 *)info->d_pixels; |
dstskip = info->d_skip/4; |
map = (Uint32 *)info->table; |
srcskip += width-(width+7)/8; |
while ( height-- ) { |
Uint8 byte = 0, bit; |
for ( c=0; c<width; ++c ) { |
if ( (c&7) == 0 ) { |
byte = *src++; |
} |
bit = (byte&0x80)>>7; |
if ( 1 ) { |
*dst = map[bit]; |
} |
byte <<= 1; |
dst++; |
} |
src += srcskip; |
dst += dstskip; |
} |
} |
static void BlitBto1Key(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
Uint8 *dst = info->d_pixels; |
int srcskip = info->s_skip; |
int dstskip = info->d_skip; |
Uint32 ckey = info->src->colorkey; |
Uint8 *palmap = info->table; |
int c; |
/* Set up some basic variables */ |
srcskip += width-(width+7)/8; |
if ( palmap ) { |
while ( height-- ) { |
Uint8 byte = 0, bit; |
for ( c=0; c<width; ++c ) { |
if ( (c&7) == 0 ) { |
byte = *src++; |
} |
bit = (byte&0x80)>>7; |
if ( bit != ckey ) { |
*dst = palmap[bit]; |
} |
dst++; |
byte <<= 1; |
} |
src += srcskip; |
dst += dstskip; |
} |
} else { |
while ( height-- ) { |
Uint8 byte = 0, bit; |
for ( c=0; c<width; ++c ) { |
if ( (c&7) == 0 ) { |
byte = *src++; |
} |
bit = (byte&0x80)>>7; |
if ( bit != ckey ) { |
*dst = bit; |
} |
dst++; |
byte <<= 1; |
} |
src += srcskip; |
dst += dstskip; |
} |
} |
} |
static void BlitBto2Key(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
Uint16 *dstp = (Uint16 *)info->d_pixels; |
int srcskip = info->s_skip; |
int dstskip = info->d_skip; |
Uint32 ckey = info->src->colorkey; |
Uint8 *palmap = info->table; |
int c; |
/* Set up some basic variables */ |
srcskip += width-(width+7)/8; |
dstskip /= 2; |
while ( height-- ) { |
Uint8 byte = 0, bit; |
for ( c=0; c<width; ++c ) { |
if ( (c&7) == 0 ) { |
byte = *src++; |
} |
bit = (byte&0x80)>>7; |
if ( bit != ckey ) { |
*dstp=((Uint16 *)palmap)[bit]; |
} |
byte <<= 1; |
dstp++; |
} |
src += srcskip; |
dstp += dstskip; |
} |
} |
static void BlitBto3Key(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
Uint8 *dst = info->d_pixels; |
int srcskip = info->s_skip; |
int dstskip = info->d_skip; |
Uint32 ckey = info->src->colorkey; |
Uint8 *palmap = info->table; |
int c; |
/* Set up some basic variables */ |
srcskip += width-(width+7)/8; |
while ( height-- ) { |
Uint8 byte = 0, bit; |
for ( c=0; c<width; ++c ) { |
if ( (c&7) == 0 ) { |
byte = *src++; |
} |
bit = (byte&0x80)>>7; |
if ( bit != ckey ) { |
memcpy(dst, &palmap[bit*4], 3); |
} |
byte <<= 1; |
dst += 3; |
} |
src += srcskip; |
dst += dstskip; |
} |
} |
static void BlitBto4Key(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
Uint32 *dstp = (Uint32 *)info->d_pixels; |
int srcskip = info->s_skip; |
int dstskip = info->d_skip; |
Uint32 ckey = info->src->colorkey; |
Uint8 *palmap = info->table; |
int c; |
/* Set up some basic variables */ |
srcskip += width-(width+7)/8; |
dstskip /= 4; |
while ( height-- ) { |
Uint8 byte = 0, bit; |
for ( c=0; c<width; ++c ) { |
if ( (c&7) == 0 ) { |
byte = *src++; |
} |
bit = (byte&0x80)>>7; |
if ( bit != ckey ) { |
*dstp=((Uint32 *)palmap)[bit]; |
} |
byte <<= 1; |
dstp++; |
} |
src += srcskip; |
dstp += dstskip; |
} |
} |
static void BlitBtoNAlpha(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
Uint8 *dst = info->d_pixels; |
int srcskip = info->s_skip; |
int dstskip = info->d_skip; |
const SDL_Color *srcpal = info->src->palette->colors; |
SDL_PixelFormat *dstfmt = info->dst; |
int dstbpp; |
int c; |
const int A = info->src->alpha; |
/* Set up some basic variables */ |
dstbpp = dstfmt->BytesPerPixel; |
srcskip += width-(width+7)/8; |
while ( height-- ) { |
Uint8 byte = 0, bit; |
for ( c=0; c<width; ++c ) { |
if ( (c&7) == 0 ) { |
byte = *src++; |
} |
bit = (byte&0x80)>>7; |
if ( 1 ) { |
Uint32 pixel; |
unsigned sR, sG, sB; |
unsigned dR, dG, dB; |
sR = srcpal[bit].r; |
sG = srcpal[bit].g; |
sB = srcpal[bit].b; |
DISEMBLE_RGB(dst, dstbpp, dstfmt, |
pixel, dR, dG, dB); |
ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); |
ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); |
} |
byte <<= 1; |
dst += dstbpp; |
} |
src += srcskip; |
dst += dstskip; |
} |
} |
static void BlitBtoNAlphaKey(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
Uint8 *dst = info->d_pixels; |
int srcskip = info->s_skip; |
int dstskip = info->d_skip; |
SDL_PixelFormat *srcfmt = info->src; |
SDL_PixelFormat *dstfmt = info->dst; |
const SDL_Color *srcpal = srcfmt->palette->colors; |
int dstbpp; |
int c; |
const int A = srcfmt->alpha; |
Uint32 ckey = srcfmt->colorkey; |
/* Set up some basic variables */ |
dstbpp = dstfmt->BytesPerPixel; |
srcskip += width-(width+7)/8; |
while ( height-- ) { |
Uint8 byte = 0, bit; |
for ( c=0; c<width; ++c ) { |
if ( (c&7) == 0 ) { |
byte = *src++; |
} |
bit = (byte&0x80)>>7; |
if ( bit != ckey ) { |
int sR, sG, sB; |
int dR, dG, dB; |
Uint32 pixel; |
sR = srcpal[bit].r; |
sG = srcpal[bit].g; |
sB = srcpal[bit].b; |
DISEMBLE_RGB(dst, dstbpp, dstfmt, |
pixel, dR, dG, dB); |
ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); |
ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); |
} |
byte <<= 1; |
dst += dstbpp; |
} |
src += srcskip; |
dst += dstskip; |
} |
} |
static SDL_loblit bitmap_blit[] = { |
NULL, BlitBto1, BlitBto2, BlitBto3, BlitBto4 |
}; |
static SDL_loblit colorkey_blit[] = { |
NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key |
}; |
SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int blit_index) |
{ |
int which; |
if ( surface->map->dst->format->BitsPerPixel < 8 ) { |
which = 0; |
} else { |
which = surface->map->dst->format->BytesPerPixel; |
} |
switch(blit_index) { |
case 0: /* copy */ |
return bitmap_blit[which]; |
case 1: /* colorkey */ |
return colorkey_blit[which]; |
case 2: /* alpha */ |
return which >= 2 ? BlitBtoNAlpha : NULL; |
case 4: /* alpha + colorkey */ |
return which >= 2 ? BlitBtoNAlphaKey : NULL; |
} |
return NULL; |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_blit_1.c |
---|
0,0 → 1,526 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#include <stdio.h> |
#include "SDL_types.h" |
#include "SDL_video.h" |
#include "SDL_blit.h" |
#include "SDL_sysvideo.h" |
#include "SDL_endian.h" |
/* Functions to blit from 8-bit surfaces to other surfaces */ |
static void Blit1to1(SDL_BlitInfo *info) |
{ |
#ifndef USE_DUFFS_LOOP |
int c; |
#endif |
int width, height; |
Uint8 *src, *map, *dst; |
int srcskip, dstskip; |
/* Set up some basic variables */ |
width = info->d_width; |
height = info->d_height; |
src = info->s_pixels; |
srcskip = info->s_skip; |
dst = info->d_pixels; |
dstskip = info->d_skip; |
map = info->table; |
while ( height-- ) { |
#ifdef USE_DUFFS_LOOP |
DUFFS_LOOP( |
{ |
*dst = map[*src]; |
} |
dst++; |
src++; |
, width); |
#else |
for ( c=width; c; --c ) { |
*dst = map[*src]; |
dst++; |
src++; |
} |
#endif |
src += srcskip; |
dst += dstskip; |
} |
} |
/* 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 |
static void Blit1to2(SDL_BlitInfo *info) |
{ |
#ifndef USE_DUFFS_LOOP |
int c; |
#endif |
int width, height; |
Uint8 *src, *dst; |
Uint16 *map; |
int srcskip, dstskip; |
/* Set up some basic variables */ |
width = info->d_width; |
height = info->d_height; |
src = info->s_pixels; |
srcskip = info->s_skip; |
dst = info->d_pixels; |
dstskip = info->d_skip; |
map = (Uint16 *)info->table; |
#ifdef USE_DUFFS_LOOP |
while ( height-- ) { |
DUFFS_LOOP( |
{ |
*(Uint16 *)dst = map[*src++]; |
dst += 2; |
}, |
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 */ |
*(Uint16 *)dst = map[*src++]; |
dst += 2; |
/* Copy in 4 pixel chunks */ |
for ( c=width/4; c; --c ) { |
*(Uint32 *)dst = |
(map[src[HI]]<<16)|(map[src[LO]]); |
src += 2; |
dst += 4; |
*(Uint32 *)dst = |
(map[src[HI]]<<16)|(map[src[LO]]); |
src += 2; |
dst += 4; |
} |
/* Get any leftovers */ |
switch (width & 3) { |
case 3: |
*(Uint16 *)dst = map[*src++]; |
dst += 2; |
case 2: |
*(Uint32 *)dst = |
(map[src[HI]]<<16)|(map[src[LO]]); |
src += 2; |
dst += 4; |
break; |
case 1: |
*(Uint16 *)dst = map[*src++]; |
dst += 2; |
break; |
} |
src += srcskip; |
dst += dstskip; |
} |
} else { |
while ( height-- ) { |
/* Copy in 4 pixel chunks */ |
for ( c=width/4; c; --c ) { |
*(Uint32 *)dst = |
(map[src[HI]]<<16)|(map[src[LO]]); |
src += 2; |
dst += 4; |
*(Uint32 *)dst = |
(map[src[HI]]<<16)|(map[src[LO]]); |
src += 2; |
dst += 4; |
} |
/* Get any leftovers */ |
switch (width & 3) { |
case 3: |
*(Uint16 *)dst = map[*src++]; |
dst += 2; |
case 2: |
*(Uint32 *)dst = |
(map[src[HI]]<<16)|(map[src[LO]]); |
src += 2; |
dst += 4; |
break; |
case 1: |
*(Uint16 *)dst = map[*src++]; |
dst += 2; |
break; |
} |
src += srcskip; |
dst += dstskip; |
} |
} |
#endif /* USE_DUFFS_LOOP */ |
} |
static void Blit1to3(SDL_BlitInfo *info) |
{ |
#ifndef USE_DUFFS_LOOP |
int c; |
#endif |
int o; |
int width, height; |
Uint8 *src, *map, *dst; |
int srcskip, dstskip; |
/* Set up some basic variables */ |
width = info->d_width; |
height = info->d_height; |
src = info->s_pixels; |
srcskip = info->s_skip; |
dst = info->d_pixels; |
dstskip = info->d_skip; |
map = info->table; |
while ( height-- ) { |
#ifdef USE_DUFFS_LOOP |
DUFFS_LOOP( |
{ |
o = *src * 4; |
dst[0] = map[o++]; |
dst[1] = map[o++]; |
dst[2] = map[o++]; |
} |
src++; |
dst += 3; |
, width); |
#else |
for ( c=width; c; --c ) { |
o = *src * 4; |
dst[0] = map[o++]; |
dst[1] = map[o++]; |
dst[2] = map[o++]; |
src++; |
dst += 3; |
} |
#endif /* USE_DUFFS_LOOP */ |
src += srcskip; |
dst += dstskip; |
} |
} |
static void Blit1to4(SDL_BlitInfo *info) |
{ |
#ifndef USE_DUFFS_LOOP |
int c; |
#endif |
int width, height; |
Uint8 *src; |
Uint32 *map, *dst; |
int srcskip, dstskip; |
/* Set up some basic variables */ |
width = info->d_width; |
height = info->d_height; |
src = info->s_pixels; |
srcskip = info->s_skip; |
dst = (Uint32 *)info->d_pixels; |
dstskip = info->d_skip/4; |
map = (Uint32 *)info->table; |
while ( height-- ) { |
#ifdef USE_DUFFS_LOOP |
DUFFS_LOOP( |
*dst++ = map[*src++]; |
, width); |
#else |
for ( c=width/4; c; --c ) { |
*dst++ = map[*src++]; |
*dst++ = map[*src++]; |
*dst++ = map[*src++]; |
*dst++ = map[*src++]; |
} |
switch ( width & 3 ) { |
case 3: |
*dst++ = map[*src++]; |
case 2: |
*dst++ = map[*src++]; |
case 1: |
*dst++ = map[*src++]; |
} |
#endif /* USE_DUFFS_LOOP */ |
src += srcskip; |
dst += dstskip; |
} |
} |
static void Blit1to1Key(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint8 *dst = info->d_pixels; |
int dstskip = info->d_skip; |
Uint8 *palmap = info->table; |
Uint32 ckey = info->src->colorkey; |
if ( palmap ) { |
while ( height-- ) { |
DUFFS_LOOP( |
{ |
if ( *src != ckey ) { |
*dst = palmap[*src]; |
} |
dst++; |
src++; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} else { |
while ( height-- ) { |
DUFFS_LOOP( |
{ |
if ( *src != ckey ) { |
*dst = *src; |
} |
dst++; |
src++; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} |
} |
static void Blit1to2Key(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint16 *dstp = (Uint16 *)info->d_pixels; |
int dstskip = info->d_skip; |
Uint16 *palmap = (Uint16 *)info->table; |
Uint32 ckey = info->src->colorkey; |
/* Set up some basic variables */ |
dstskip /= 2; |
while ( height-- ) { |
DUFFS_LOOP( |
{ |
if ( *src != ckey ) { |
*dstp=palmap[*src]; |
} |
src++; |
dstp++; |
}, |
width); |
src += srcskip; |
dstp += dstskip; |
} |
} |
static void Blit1to3Key(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint8 *dst = info->d_pixels; |
int dstskip = info->d_skip; |
Uint8 *palmap = info->table; |
Uint32 ckey = info->src->colorkey; |
int o; |
while ( height-- ) { |
DUFFS_LOOP( |
{ |
if ( *src != ckey ) { |
o = *src * 4; |
dst[0] = palmap[o++]; |
dst[1] = palmap[o++]; |
dst[2] = palmap[o++]; |
} |
src++; |
dst += 3; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} |
static void Blit1to4Key(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint32 *dstp = (Uint32 *)info->d_pixels; |
int dstskip = info->d_skip; |
Uint32 *palmap = (Uint32 *)info->table; |
Uint32 ckey = info->src->colorkey; |
/* Set up some basic variables */ |
dstskip /= 4; |
while ( height-- ) { |
DUFFS_LOOP( |
{ |
if ( *src != ckey ) { |
*dstp = palmap[*src]; |
} |
src++; |
dstp++; |
}, |
width); |
src += srcskip; |
dstp += dstskip; |
} |
} |
static void Blit1toNAlpha(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint8 *dst = info->d_pixels; |
int dstskip = info->d_skip; |
SDL_PixelFormat *dstfmt = info->dst; |
const SDL_Color *srcpal = info->src->palette->colors; |
int dstbpp; |
const int A = info->src->alpha; |
/* Set up some basic variables */ |
dstbpp = dstfmt->BytesPerPixel; |
while ( height-- ) { |
int sR, sG, sB; |
int dR, dG, dB; |
DUFFS_LOOP4( |
{ |
Uint32 pixel; |
sR = srcpal[*src].r; |
sG = srcpal[*src].g; |
sB = srcpal[*src].b; |
DISEMBLE_RGB(dst, dstbpp, dstfmt, |
pixel, dR, dG, dB); |
ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); |
ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); |
src++; |
dst += dstbpp; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} |
static void Blit1toNAlphaKey(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint8 *dst = info->d_pixels; |
int dstskip = info->d_skip; |
SDL_PixelFormat *srcfmt = info->src; |
SDL_PixelFormat *dstfmt = info->dst; |
const SDL_Color *srcpal = info->src->palette->colors; |
Uint32 ckey = srcfmt->colorkey; |
int dstbpp; |
const int A = srcfmt->alpha; |
/* Set up some basic variables */ |
dstbpp = dstfmt->BytesPerPixel; |
while ( height-- ) { |
int sR, sG, sB; |
int dR, dG, dB; |
DUFFS_LOOP( |
{ |
if ( *src != ckey ) { |
Uint32 pixel; |
sR = srcpal[*src].r; |
sG = srcpal[*src].g; |
sB = srcpal[*src].b; |
DISEMBLE_RGB(dst, dstbpp, dstfmt, |
pixel, dR, dG, dB); |
ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); |
ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); |
} |
src++; |
dst += dstbpp; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} |
static SDL_loblit one_blit[] = { |
NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4 |
}; |
static SDL_loblit one_blitkey[] = { |
NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key |
}; |
SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int blit_index) |
{ |
int which; |
SDL_PixelFormat *dstfmt; |
dstfmt = surface->map->dst->format; |
if ( dstfmt->BitsPerPixel < 8 ) { |
which = 0; |
} else { |
which = dstfmt->BytesPerPixel; |
} |
switch(blit_index) { |
case 0: /* copy */ |
return one_blit[which]; |
case 1: /* colorkey */ |
return one_blitkey[which]; |
case 2: /* alpha */ |
/* Supporting 8bpp->8bpp alpha is doable but requires lots of |
tables which consume space and takes time to precompute, |
so is better left to the user */ |
return which >= 2 ? Blit1toNAlpha : NULL; |
case 3: /* alpha + colorkey */ |
return which >= 2 ? Blit1toNAlphaKey : NULL; |
} |
return NULL; |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_blit_A.c |
---|
0,0 → 1,772 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#include <stdio.h> |
#include "SDL_types.h" |
#include "SDL_video.h" |
#include "SDL_blit.h" |
/* Functions to perform alpha blended blitting */ |
/* N->1 blending with per-surface alpha */ |
static void BlitNto1SurfaceAlpha(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint8 *dst = info->d_pixels; |
int dstskip = info->d_skip; |
Uint8 *palmap = info->table; |
SDL_PixelFormat *srcfmt = info->src; |
SDL_PixelFormat *dstfmt = info->dst; |
int srcbpp = srcfmt->BytesPerPixel; |
const unsigned A = srcfmt->alpha; |
while ( height-- ) { |
DUFFS_LOOP4( |
{ |
Uint32 pixel; |
unsigned sR; |
unsigned sG; |
unsigned sB; |
unsigned dR; |
unsigned dG; |
unsigned dB; |
DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB); |
dR = dstfmt->palette->colors[*dst].r; |
dG = dstfmt->palette->colors[*dst].g; |
dB = dstfmt->palette->colors[*dst].b; |
ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); |
dR &= 0xff; |
dG &= 0xff; |
dB &= 0xff; |
/* Pack RGB into 8bit pixel */ |
if ( palmap == NULL ) { |
*dst =((dR>>5)<<(3+2))| |
((dG>>5)<<(2))| |
((dB>>6)<<(0)); |
} else { |
*dst = palmap[((dR>>5)<<(3+2))| |
((dG>>5)<<(2)) | |
((dB>>6)<<(0))]; |
} |
dst++; |
src += srcbpp; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} |
/* N->1 blending with pixel alpha */ |
static void BlitNto1PixelAlpha(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint8 *dst = info->d_pixels; |
int dstskip = info->d_skip; |
Uint8 *palmap = info->table; |
SDL_PixelFormat *srcfmt = info->src; |
SDL_PixelFormat *dstfmt = info->dst; |
int srcbpp = srcfmt->BytesPerPixel; |
/* FIXME: fix alpha bit field expansion here too? */ |
while ( height-- ) { |
DUFFS_LOOP4( |
{ |
Uint32 pixel; |
unsigned sR; |
unsigned sG; |
unsigned sB; |
unsigned sA; |
unsigned dR; |
unsigned dG; |
unsigned dB; |
DISEMBLE_RGBA(src,srcbpp,srcfmt,pixel,sR,sG,sB,sA); |
dR = dstfmt->palette->colors[*dst].r; |
dG = dstfmt->palette->colors[*dst].g; |
dB = dstfmt->palette->colors[*dst].b; |
ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); |
dR &= 0xff; |
dG &= 0xff; |
dB &= 0xff; |
/* Pack RGB into 8bit pixel */ |
if ( palmap == NULL ) { |
*dst =((dR>>5)<<(3+2))| |
((dG>>5)<<(2))| |
((dB>>6)<<(0)); |
} else { |
*dst = palmap[((dR>>5)<<(3+2))| |
((dG>>5)<<(2)) | |
((dB>>6)<<(0)) ]; |
} |
dst++; |
src += srcbpp; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} |
/* colorkeyed N->1 blending with per-surface alpha */ |
static void BlitNto1SurfaceAlphaKey(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint8 *dst = info->d_pixels; |
int dstskip = info->d_skip; |
Uint8 *palmap = info->table; |
SDL_PixelFormat *srcfmt = info->src; |
SDL_PixelFormat *dstfmt = info->dst; |
int srcbpp = srcfmt->BytesPerPixel; |
Uint32 ckey = srcfmt->colorkey; |
const int A = srcfmt->alpha; |
while ( height-- ) { |
DUFFS_LOOP( |
{ |
Uint32 pixel; |
unsigned sR; |
unsigned sG; |
unsigned sB; |
unsigned dR; |
unsigned dG; |
unsigned dB; |
DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB); |
if ( pixel != ckey ) { |
dR = dstfmt->palette->colors[*dst].r; |
dG = dstfmt->palette->colors[*dst].g; |
dB = dstfmt->palette->colors[*dst].b; |
ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); |
dR &= 0xff; |
dG &= 0xff; |
dB &= 0xff; |
/* Pack RGB into 8bit pixel */ |
if ( palmap == NULL ) { |
*dst =((dR>>5)<<(3+2))| |
((dG>>5)<<(2)) | |
((dB>>6)<<(0)); |
} else { |
*dst = palmap[((dR>>5)<<(3+2))| |
((dG>>5)<<(2)) | |
((dB>>6)<<(0)) ]; |
} |
} |
dst++; |
src += srcbpp; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} |
/* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */ |
static void BlitRGBtoRGBSurfaceAlpha128(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint32 *srcp = (Uint32 *)info->s_pixels; |
int srcskip = info->s_skip >> 2; |
Uint32 *dstp = (Uint32 *)info->d_pixels; |
int dstskip = info->d_skip >> 2; |
while(height--) { |
DUFFS_LOOP4({ |
Uint32 s = *srcp++; |
Uint32 d = *dstp; |
*dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) |
+ (s & d & 0x00010101)) | 0xff000000; |
}, width); |
srcp += srcskip; |
dstp += dstskip; |
} |
} |
/* fast RGB888->(A)RGB888 blending with surface alpha */ |
static void BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo *info) |
{ |
unsigned alpha = info->src->alpha; |
if(alpha == 128) { |
BlitRGBtoRGBSurfaceAlpha128(info); |
} else { |
int width = info->d_width; |
int height = info->d_height; |
Uint32 *srcp = (Uint32 *)info->s_pixels; |
int srcskip = info->s_skip >> 2; |
Uint32 *dstp = (Uint32 *)info->d_pixels; |
int dstskip = info->d_skip >> 2; |
while(height--) { |
DUFFS_LOOP4({ |
Uint32 s; |
Uint32 d; |
Uint32 s1; |
Uint32 d1; |
s = *srcp; |
d = *dstp; |
s1 = s & 0xff00ff; |
d1 = d & 0xff00ff; |
d1 = (d1 + ((s1 - d1) * alpha >> 8)) |
& 0xff00ff; |
s &= 0xff00; |
d &= 0xff00; |
d = (d + ((s - d) * alpha >> 8)) & 0xff00; |
*dstp = d1 | d | 0xff000000; |
++srcp; |
++dstp; |
}, width); |
srcp += srcskip; |
dstp += dstskip; |
} |
} |
} |
/* fast ARGB888->(A)RGB888 blending with pixel alpha */ |
static void BlitRGBtoRGBPixelAlpha(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint32 *srcp = (Uint32 *)info->s_pixels; |
int srcskip = info->s_skip >> 2; |
Uint32 *dstp = (Uint32 *)info->d_pixels; |
int dstskip = info->d_skip >> 2; |
while(height--) { |
DUFFS_LOOP4({ |
Uint32 dalpha; |
Uint32 d; |
Uint32 s1; |
Uint32 d1; |
Uint32 s = *srcp; |
Uint32 alpha = s >> 24; |
/* FIXME: Here we special-case opaque alpha since the |
compositioning used (>>8 instead of /255) doesn't handle |
it correctly. Also special-case alpha=0 for speed? |
Benchmark this! */ |
if(alpha == SDL_ALPHA_OPAQUE) { |
*dstp = (s & 0x00ffffff) | (*dstp & 0xff000000); |
} else { |
/* |
* take out the middle component (green), and process |
* the other two in parallel. One multiply less. |
*/ |
d = *dstp; |
dalpha = d & 0xff000000; |
s1 = s & 0xff00ff; |
d1 = d & 0xff00ff; |
d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; |
s &= 0xff00; |
d &= 0xff00; |
d = (d + ((s - d) * alpha >> 8)) & 0xff00; |
*dstp = d1 | d | dalpha; |
} |
++srcp; |
++dstp; |
}, width); |
srcp += srcskip; |
dstp += dstskip; |
} |
} |
/* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel */ |
/* blend a single 16 bit pixel at 50% */ |
#define BLEND16_50(d, s, mask) \ |
((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff))) |
/* blend two 16 bit pixels at 50% */ |
#define BLEND2x16_50(d, s, mask) \ |
(((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \ |
+ (s & d & (~(mask | mask << 16)))) |
static void Blit16to16SurfaceAlpha128(SDL_BlitInfo *info, Uint16 mask) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint16 *srcp = (Uint16 *)info->s_pixels; |
int srcskip = info->s_skip >> 1; |
Uint16 *dstp = (Uint16 *)info->d_pixels; |
int dstskip = info->d_skip >> 1; |
while(height--) { |
if(((unsigned long)srcp ^ (unsigned long)dstp) & 2) { |
/* |
* Source and destination not aligned, pipeline it. |
* This is mostly a win for big blits but no loss for |
* small ones |
*/ |
Uint32 prev_sw; |
int w = width; |
/* handle odd destination */ |
if((unsigned long)dstp & 2) { |
Uint16 d = *dstp, s = *srcp; |
*dstp = BLEND16_50(d, s, mask); |
dstp++; |
srcp++; |
w--; |
} |
srcp++; /* srcp is now 32-bit aligned */ |
/* bootstrap pipeline with first halfword */ |
prev_sw = ((Uint32 *)srcp)[-1]; |
while(w > 1) { |
Uint32 sw, dw, s; |
sw = *(Uint32 *)srcp; |
dw = *(Uint32 *)dstp; |
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) |
s = (prev_sw << 16) + (sw >> 16); |
else |
s = (prev_sw >> 16) + (sw << 16); |
prev_sw = sw; |
*(Uint32 *)dstp = BLEND2x16_50(dw, s, mask); |
dstp += 2; |
srcp += 2; |
w -= 2; |
} |
/* final pixel if any */ |
if(w) { |
Uint16 d = *dstp, s; |
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) |
s = prev_sw; |
else |
s = prev_sw >> 16; |
*dstp = BLEND16_50(d, s, mask); |
srcp++; |
dstp++; |
} |
srcp += srcskip - 1; |
dstp += dstskip; |
} else { |
/* source and destination are aligned */ |
int w = width; |
/* first odd pixel? */ |
if((unsigned long)srcp & 2) { |
Uint16 d = *dstp, s = *srcp; |
*dstp = BLEND16_50(d, s, mask); |
srcp++; |
dstp++; |
w--; |
} |
/* srcp and dstp are now 32-bit aligned */ |
while(w > 1) { |
Uint32 sw = *(Uint32 *)srcp; |
Uint32 dw = *(Uint32 *)dstp; |
*(Uint32 *)dstp = BLEND2x16_50(dw, sw, mask); |
srcp += 2; |
dstp += 2; |
w -= 2; |
} |
/* last odd pixel? */ |
if(w) { |
Uint16 d = *dstp, s = *srcp; |
*dstp = BLEND16_50(d, s, mask); |
srcp++; |
dstp++; |
} |
srcp += srcskip; |
dstp += dstskip; |
} |
} |
} |
/* fast RGB565->RGB565 blending with surface alpha */ |
static void Blit565to565SurfaceAlpha(SDL_BlitInfo *info) |
{ |
unsigned alpha = info->src->alpha; |
if(alpha == 128) { |
Blit16to16SurfaceAlpha128(info, 0xf7de); |
} else { |
int width = info->d_width; |
int height = info->d_height; |
Uint16 *srcp = (Uint16 *)info->s_pixels; |
int srcskip = info->s_skip >> 1; |
Uint16 *dstp = (Uint16 *)info->d_pixels; |
int dstskip = info->d_skip >> 1; |
alpha >>= 3; /* downscale alpha to 5 bits */ |
while(height--) { |
DUFFS_LOOP4({ |
Uint32 s = *srcp++; |
Uint32 d = *dstp; |
/* |
* shift out the middle component (green) to |
* the high 16 bits, and process all three RGB |
* components at the same time. |
*/ |
s = (s | s << 16) & 0x07e0f81f; |
d = (d | d << 16) & 0x07e0f81f; |
d += (s - d) * alpha >> 5; |
d &= 0x07e0f81f; |
*dstp++ = d | d >> 16; |
}, width); |
srcp += srcskip; |
dstp += dstskip; |
} |
} |
} |
/* fast RGB555->RGB555 blending with surface alpha */ |
static void Blit555to555SurfaceAlpha(SDL_BlitInfo *info) |
{ |
unsigned alpha = info->src->alpha; /* downscale alpha to 5 bits */ |
if(alpha == 128) { |
Blit16to16SurfaceAlpha128(info, 0xfbde); |
} else { |
int width = info->d_width; |
int height = info->d_height; |
Uint16 *srcp = (Uint16 *)info->s_pixels; |
int srcskip = info->s_skip >> 1; |
Uint16 *dstp = (Uint16 *)info->d_pixels; |
int dstskip = info->d_skip >> 1; |
alpha >>= 3; /* downscale alpha to 5 bits */ |
while(height--) { |
DUFFS_LOOP4({ |
Uint32 s = *srcp++; |
Uint32 d = *dstp; |
/* |
* shift out the middle component (green) to |
* the high 16 bits, and process all three RGB |
* components at the same time. |
*/ |
s = (s | s << 16) & 0x03e07c1f; |
d = (d | d << 16) & 0x03e07c1f; |
d += (s - d) * alpha >> 5; |
d &= 0x03e07c1f; |
*dstp++ = d | d >> 16; |
}, width); |
srcp += srcskip; |
dstp += dstskip; |
} |
} |
} |
/* fast ARGB8888->RGB565 blending with pixel alpha */ |
static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint32 *srcp = (Uint32 *)info->s_pixels; |
int srcskip = info->s_skip >> 2; |
Uint16 *dstp = (Uint16 *)info->d_pixels; |
int dstskip = info->d_skip >> 1; |
while(height--) { |
DUFFS_LOOP4({ |
Uint32 s = *srcp; |
unsigned alpha = s >> 27; /* downscale alpha to 5 bits */ |
/* FIXME: Here we special-case opaque alpha since the |
compositioning used (>>8 instead of /255) doesn't handle |
it correctly. Also special-case alpha=0 for speed? |
Benchmark this! */ |
if(alpha == (SDL_ALPHA_OPAQUE >> 3)) { |
*dstp = (s >> 8 & 0xf800) + (s >> 5 & 0x7e0) |
+ (s >> 3 & 0x1f); |
} else { |
Uint32 d = *dstp; |
/* |
* convert source and destination to G0RAB65565 |
* and blend all components at the same time |
*/ |
s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800) |
+ (s >> 3 & 0x1f); |
d = (d | d << 16) & 0x07e0f81f; |
d += (s - d) * alpha >> 5; |
d &= 0x07e0f81f; |
*dstp = d | d >> 16; |
} |
srcp++; |
dstp++; |
}, width); |
srcp += srcskip; |
dstp += dstskip; |
} |
} |
/* fast ARGB8888->RGB555 blending with pixel alpha */ |
static void BlitARGBto555PixelAlpha(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint32 *srcp = (Uint32 *)info->s_pixels; |
int srcskip = info->s_skip >> 2; |
Uint16 *dstp = (Uint16 *)info->d_pixels; |
int dstskip = info->d_skip >> 1; |
while(height--) { |
DUFFS_LOOP4({ |
unsigned alpha; |
Uint32 s = *srcp; |
alpha = s >> 27; /* downscale alpha to 5 bits */ |
/* FIXME: Here we special-case opaque alpha since the |
compositioning used (>>8 instead of /255) doesn't handle |
it correctly. Also special-case alpha=0 for speed? |
Benchmark this! */ |
if(alpha == (SDL_ALPHA_OPAQUE >> 3)) { |
*dstp = (s >> 9 & 0x7c00) + (s >> 6 & 0x3e0) |
+ (s >> 3 & 0x1f); |
} else { |
Uint32 d = *dstp; |
/* |
* convert source and destination to G0RAB65565 |
* and blend all components at the same time |
*/ |
s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00) |
+ (s >> 3 & 0x1f); |
d = (d | d << 16) & 0x03e07c1f; |
d += (s - d) * alpha >> 5; |
d &= 0x03e07c1f; |
*dstp = d | d >> 16; |
} |
srcp++; |
dstp++; |
}, width); |
srcp += srcskip; |
dstp += dstskip; |
} |
} |
/* General (slow) N->N blending with per-surface alpha */ |
static void BlitNtoNSurfaceAlpha(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint8 *dst = info->d_pixels; |
int dstskip = info->d_skip; |
SDL_PixelFormat *srcfmt = info->src; |
SDL_PixelFormat *dstfmt = info->dst; |
int srcbpp = srcfmt->BytesPerPixel; |
int dstbpp = dstfmt->BytesPerPixel; |
unsigned sA = srcfmt->alpha; |
unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; |
while ( height-- ) { |
DUFFS_LOOP4( |
{ |
Uint32 pixel; |
unsigned sR; |
unsigned sG; |
unsigned sB; |
unsigned dR; |
unsigned dG; |
unsigned dB; |
DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB); |
DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB); |
ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); |
ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); |
src += srcbpp; |
dst += dstbpp; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} |
/* General (slow) colorkeyed N->N blending with per-surface alpha */ |
static void BlitNtoNSurfaceAlphaKey(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint8 *dst = info->d_pixels; |
int dstskip = info->d_skip; |
SDL_PixelFormat *srcfmt = info->src; |
SDL_PixelFormat *dstfmt = info->dst; |
Uint32 ckey = srcfmt->colorkey; |
int srcbpp = srcfmt->BytesPerPixel; |
int dstbpp = dstfmt->BytesPerPixel; |
unsigned sA = srcfmt->alpha; |
unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; |
while ( height-- ) { |
DUFFS_LOOP4( |
{ |
Uint32 pixel; |
unsigned sR; |
unsigned sG; |
unsigned sB; |
unsigned dR; |
unsigned dG; |
unsigned dB; |
RETRIEVE_RGB_PIXEL(src, srcbpp, pixel); |
if(pixel != ckey) { |
RGB_FROM_PIXEL(pixel, srcfmt, sR, sG, sB); |
DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB); |
ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); |
ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); |
} |
src += srcbpp; |
dst += dstbpp; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} |
/* General (slow) N->N blending with pixel alpha */ |
static void BlitNtoNPixelAlpha(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint8 *dst = info->d_pixels; |
int dstskip = info->d_skip; |
SDL_PixelFormat *srcfmt = info->src; |
SDL_PixelFormat *dstfmt = info->dst; |
int srcbpp; |
int dstbpp; |
/* Set up some basic variables */ |
srcbpp = srcfmt->BytesPerPixel; |
dstbpp = dstfmt->BytesPerPixel; |
/* FIXME: for 8bpp source alpha, this doesn't get opaque values |
quite right. for <8bpp source alpha, it gets them very wrong |
(check all macros!) |
It is unclear whether there is a good general solution that doesn't |
need a branch (or a divide). */ |
while ( height-- ) { |
DUFFS_LOOP4( |
{ |
Uint32 pixel; |
unsigned sR; |
unsigned sG; |
unsigned sB; |
unsigned dR; |
unsigned dG; |
unsigned dB; |
unsigned sA; |
unsigned dA; |
DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB, sA); |
DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA); |
ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); |
ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); |
src += srcbpp; |
dst += dstbpp; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} |
SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int blit_index) |
{ |
SDL_PixelFormat *sf = surface->format; |
SDL_PixelFormat *df = surface->map->dst->format; |
if(sf->Amask == 0) { |
if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { |
if(df->BytesPerPixel == 1) |
return BlitNto1SurfaceAlphaKey; |
else |
return BlitNtoNSurfaceAlphaKey; |
} else { |
/* Per-surface alpha blits */ |
switch(df->BytesPerPixel) { |
case 1: |
return BlitNto1SurfaceAlpha; |
case 2: |
if(surface->map->identity) { |
if(df->Gmask == 0x7e0) |
return Blit565to565SurfaceAlpha; |
else if(df->Gmask == 0x3e0) |
return Blit555to555SurfaceAlpha; |
} |
return BlitNtoNSurfaceAlpha; |
case 4: |
if(sf->Rmask == df->Rmask |
&& sf->Gmask == df->Gmask |
&& sf->Bmask == df->Bmask |
&& (sf->Rmask | sf->Gmask | sf->Bmask) == 0xffffff |
&& sf->BytesPerPixel == 4) |
return BlitRGBtoRGBSurfaceAlpha; |
else |
return BlitNtoNSurfaceAlpha; |
case 3: |
default: |
return BlitNtoNSurfaceAlpha; |
} |
} |
} else { |
/* Per-pixel alpha blits */ |
switch(df->BytesPerPixel) { |
case 1: |
return BlitNto1PixelAlpha; |
case 2: |
if(sf->BytesPerPixel == 4 && sf->Amask == 0xff000000 |
&& sf->Gmask == 0xff00 |
&& ((sf->Rmask == 0xff && df->Rmask == 0x1f) |
|| (sf->Bmask == 0xff && df->Bmask == 0x1f))) { |
if(df->Gmask == 0x7e0) |
return BlitARGBto565PixelAlpha; |
else if(df->Gmask == 0x3e0) |
return BlitARGBto555PixelAlpha; |
} |
return BlitNtoNPixelAlpha; |
case 4: |
if(sf->Amask == 0xff000000 |
&& sf->Rmask == df->Rmask |
&& sf->Gmask == df->Gmask |
&& sf->Bmask == df->Bmask |
&& sf->BytesPerPixel == 4) |
return BlitRGBtoRGBPixelAlpha; |
return BlitNtoNPixelAlpha; |
case 3: |
default: |
return BlitNtoNPixelAlpha; |
} |
} |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_blit_A.h |
---|
0,0 → 1,30 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_blit_A.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; |
#endif |
/* Functions from SDL_blitalpha.c */ |
extern void SDL_BlitAlpha(SDL_BlitInfo *info); |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_blit_N.c |
---|
0,0 → 1,1607 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#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; |
break; |
} |
src += srcskip; |
dst += dstskip; |
} |
} |
#endif /* USE_DUFFS_LOOP */ |
} |
#endif /* USE_ASMBLIT */ |
/* Special optimized blit for RGB 5-6-5 --> 32-bit RGB surfaces */ |
#if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) |
#define RGB565_32(dst, src, map) (map[src[0]*2] + map[src[1]*2+1]) |
#else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */ |
#define RGB565_32(dst, src, map) (map[src[1]*2] + map[src[0]*2+1]) |
#endif |
static void Blit_RGB565_32(SDL_BlitInfo *info, const Uint32 *map) |
{ |
#ifndef USE_DUFFS_LOOP |
int c; |
#endif |
int width, height; |
Uint8 *src; |
Uint32 *dst; |
int srcskip, dstskip; |
/* Set up some basic variables */ |
width = info->d_width; |
height = info->d_height; |
src = (Uint8 *)info->s_pixels; |
srcskip = info->s_skip; |
dst = (Uint32 *)info->d_pixels; |
dstskip = info->d_skip/4; |
#ifdef USE_DUFFS_LOOP |
while ( height-- ) { |
DUFFS_LOOP( |
{ |
*dst++ = RGB565_32(dst, src, map); |
src += 2; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
#else |
while ( height-- ) { |
/* Copy in 4 pixel chunks */ |
for ( c=width/4; c; --c ) { |
*dst++ = RGB565_32(dst, src, map); |
src += 2; |
*dst++ = RGB565_32(dst, src, map); |
src += 2; |
*dst++ = RGB565_32(dst, src, map); |
src += 2; |
*dst++ = RGB565_32(dst, src, map); |
src += 2; |
} |
/* Get any leftovers */ |
switch (width & 3) { |
case 3: |
*dst++ = RGB565_32(dst, src, map); |
src += 2; |
case 2: |
*dst++ = RGB565_32(dst, src, map); |
src += 2; |
case 1: |
*dst++ = RGB565_32(dst, src, map); |
src += 2; |
break; |
} |
src += srcskip; |
dst += dstskip; |
} |
#endif /* USE_DUFFS_LOOP */ |
} |
/* Special optimized blit for RGB 5-6-5 --> ARGB 8-8-8-8 */ |
static const Uint32 RGB565_ARGB8888_LUT[512] = { |
0x00000000, 0xff000000, 0x00000008, 0xff002000, |
0x00000010, 0xff004000, 0x00000018, 0xff006100, |
0x00000020, 0xff008100, 0x00000029, 0xff00a100, |
0x00000031, 0xff00c200, 0x00000039, 0xff00e200, |
0x00000041, 0xff080000, 0x0000004a, 0xff082000, |
0x00000052, 0xff084000, 0x0000005a, 0xff086100, |
0x00000062, 0xff088100, 0x0000006a, 0xff08a100, |
0x00000073, 0xff08c200, 0x0000007b, 0xff08e200, |
0x00000083, 0xff100000, 0x0000008b, 0xff102000, |
0x00000094, 0xff104000, 0x0000009c, 0xff106100, |
0x000000a4, 0xff108100, 0x000000ac, 0xff10a100, |
0x000000b4, 0xff10c200, 0x000000bd, 0xff10e200, |
0x000000c5, 0xff180000, 0x000000cd, 0xff182000, |
0x000000d5, 0xff184000, 0x000000de, 0xff186100, |
0x000000e6, 0xff188100, 0x000000ee, 0xff18a100, |
0x000000f6, 0xff18c200, 0x000000ff, 0xff18e200, |
0x00000400, 0xff200000, 0x00000408, 0xff202000, |
0x00000410, 0xff204000, 0x00000418, 0xff206100, |
0x00000420, 0xff208100, 0x00000429, 0xff20a100, |
0x00000431, 0xff20c200, 0x00000439, 0xff20e200, |
0x00000441, 0xff290000, 0x0000044a, 0xff292000, |
0x00000452, 0xff294000, 0x0000045a, 0xff296100, |
0x00000462, 0xff298100, 0x0000046a, 0xff29a100, |
0x00000473, 0xff29c200, 0x0000047b, 0xff29e200, |
0x00000483, 0xff310000, 0x0000048b, 0xff312000, |
0x00000494, 0xff314000, 0x0000049c, 0xff316100, |
0x000004a4, 0xff318100, 0x000004ac, 0xff31a100, |
0x000004b4, 0xff31c200, 0x000004bd, 0xff31e200, |
0x000004c5, 0xff390000, 0x000004cd, 0xff392000, |
0x000004d5, 0xff394000, 0x000004de, 0xff396100, |
0x000004e6, 0xff398100, 0x000004ee, 0xff39a100, |
0x000004f6, 0xff39c200, 0x000004ff, 0xff39e200, |
0x00000800, 0xff410000, 0x00000808, 0xff412000, |
0x00000810, 0xff414000, 0x00000818, 0xff416100, |
0x00000820, 0xff418100, 0x00000829, 0xff41a100, |
0x00000831, 0xff41c200, 0x00000839, 0xff41e200, |
0x00000841, 0xff4a0000, 0x0000084a, 0xff4a2000, |
0x00000852, 0xff4a4000, 0x0000085a, 0xff4a6100, |
0x00000862, 0xff4a8100, 0x0000086a, 0xff4aa100, |
0x00000873, 0xff4ac200, 0x0000087b, 0xff4ae200, |
0x00000883, 0xff520000, 0x0000088b, 0xff522000, |
0x00000894, 0xff524000, 0x0000089c, 0xff526100, |
0x000008a4, 0xff528100, 0x000008ac, 0xff52a100, |
0x000008b4, 0xff52c200, 0x000008bd, 0xff52e200, |
0x000008c5, 0xff5a0000, 0x000008cd, 0xff5a2000, |
0x000008d5, 0xff5a4000, 0x000008de, 0xff5a6100, |
0x000008e6, 0xff5a8100, 0x000008ee, 0xff5aa100, |
0x000008f6, 0xff5ac200, 0x000008ff, 0xff5ae200, |
0x00000c00, 0xff620000, 0x00000c08, 0xff622000, |
0x00000c10, 0xff624000, 0x00000c18, 0xff626100, |
0x00000c20, 0xff628100, 0x00000c29, 0xff62a100, |
0x00000c31, 0xff62c200, 0x00000c39, 0xff62e200, |
0x00000c41, 0xff6a0000, 0x00000c4a, 0xff6a2000, |
0x00000c52, 0xff6a4000, 0x00000c5a, 0xff6a6100, |
0x00000c62, 0xff6a8100, 0x00000c6a, 0xff6aa100, |
0x00000c73, 0xff6ac200, 0x00000c7b, 0xff6ae200, |
0x00000c83, 0xff730000, 0x00000c8b, 0xff732000, |
0x00000c94, 0xff734000, 0x00000c9c, 0xff736100, |
0x00000ca4, 0xff738100, 0x00000cac, 0xff73a100, |
0x00000cb4, 0xff73c200, 0x00000cbd, 0xff73e200, |
0x00000cc5, 0xff7b0000, 0x00000ccd, 0xff7b2000, |
0x00000cd5, 0xff7b4000, 0x00000cde, 0xff7b6100, |
0x00000ce6, 0xff7b8100, 0x00000cee, 0xff7ba100, |
0x00000cf6, 0xff7bc200, 0x00000cff, 0xff7be200, |
0x00001000, 0xff830000, 0x00001008, 0xff832000, |
0x00001010, 0xff834000, 0x00001018, 0xff836100, |
0x00001020, 0xff838100, 0x00001029, 0xff83a100, |
0x00001031, 0xff83c200, 0x00001039, 0xff83e200, |
0x00001041, 0xff8b0000, 0x0000104a, 0xff8b2000, |
0x00001052, 0xff8b4000, 0x0000105a, 0xff8b6100, |
0x00001062, 0xff8b8100, 0x0000106a, 0xff8ba100, |
0x00001073, 0xff8bc200, 0x0000107b, 0xff8be200, |
0x00001083, 0xff940000, 0x0000108b, 0xff942000, |
0x00001094, 0xff944000, 0x0000109c, 0xff946100, |
0x000010a4, 0xff948100, 0x000010ac, 0xff94a100, |
0x000010b4, 0xff94c200, 0x000010bd, 0xff94e200, |
0x000010c5, 0xff9c0000, 0x000010cd, 0xff9c2000, |
0x000010d5, 0xff9c4000, 0x000010de, 0xff9c6100, |
0x000010e6, 0xff9c8100, 0x000010ee, 0xff9ca100, |
0x000010f6, 0xff9cc200, 0x000010ff, 0xff9ce200, |
0x00001400, 0xffa40000, 0x00001408, 0xffa42000, |
0x00001410, 0xffa44000, 0x00001418, 0xffa46100, |
0x00001420, 0xffa48100, 0x00001429, 0xffa4a100, |
0x00001431, 0xffa4c200, 0x00001439, 0xffa4e200, |
0x00001441, 0xffac0000, 0x0000144a, 0xffac2000, |
0x00001452, 0xffac4000, 0x0000145a, 0xffac6100, |
0x00001462, 0xffac8100, 0x0000146a, 0xffaca100, |
0x00001473, 0xffacc200, 0x0000147b, 0xfface200, |
0x00001483, 0xffb40000, 0x0000148b, 0xffb42000, |
0x00001494, 0xffb44000, 0x0000149c, 0xffb46100, |
0x000014a4, 0xffb48100, 0x000014ac, 0xffb4a100, |
0x000014b4, 0xffb4c200, 0x000014bd, 0xffb4e200, |
0x000014c5, 0xffbd0000, 0x000014cd, 0xffbd2000, |
0x000014d5, 0xffbd4000, 0x000014de, 0xffbd6100, |
0x000014e6, 0xffbd8100, 0x000014ee, 0xffbda100, |
0x000014f6, 0xffbdc200, 0x000014ff, 0xffbde200, |
0x00001800, 0xffc50000, 0x00001808, 0xffc52000, |
0x00001810, 0xffc54000, 0x00001818, 0xffc56100, |
0x00001820, 0xffc58100, 0x00001829, 0xffc5a100, |
0x00001831, 0xffc5c200, 0x00001839, 0xffc5e200, |
0x00001841, 0xffcd0000, 0x0000184a, 0xffcd2000, |
0x00001852, 0xffcd4000, 0x0000185a, 0xffcd6100, |
0x00001862, 0xffcd8100, 0x0000186a, 0xffcda100, |
0x00001873, 0xffcdc200, 0x0000187b, 0xffcde200, |
0x00001883, 0xffd50000, 0x0000188b, 0xffd52000, |
0x00001894, 0xffd54000, 0x0000189c, 0xffd56100, |
0x000018a4, 0xffd58100, 0x000018ac, 0xffd5a100, |
0x000018b4, 0xffd5c200, 0x000018bd, 0xffd5e200, |
0x000018c5, 0xffde0000, 0x000018cd, 0xffde2000, |
0x000018d5, 0xffde4000, 0x000018de, 0xffde6100, |
0x000018e6, 0xffde8100, 0x000018ee, 0xffdea100, |
0x000018f6, 0xffdec200, 0x000018ff, 0xffdee200, |
0x00001c00, 0xffe60000, 0x00001c08, 0xffe62000, |
0x00001c10, 0xffe64000, 0x00001c18, 0xffe66100, |
0x00001c20, 0xffe68100, 0x00001c29, 0xffe6a100, |
0x00001c31, 0xffe6c200, 0x00001c39, 0xffe6e200, |
0x00001c41, 0xffee0000, 0x00001c4a, 0xffee2000, |
0x00001c52, 0xffee4000, 0x00001c5a, 0xffee6100, |
0x00001c62, 0xffee8100, 0x00001c6a, 0xffeea100, |
0x00001c73, 0xffeec200, 0x00001c7b, 0xffeee200, |
0x00001c83, 0xfff60000, 0x00001c8b, 0xfff62000, |
0x00001c94, 0xfff64000, 0x00001c9c, 0xfff66100, |
0x00001ca4, 0xfff68100, 0x00001cac, 0xfff6a100, |
0x00001cb4, 0xfff6c200, 0x00001cbd, 0xfff6e200, |
0x00001cc5, 0xffff0000, 0x00001ccd, 0xffff2000, |
0x00001cd5, 0xffff4000, 0x00001cde, 0xffff6100, |
0x00001ce6, 0xffff8100, 0x00001cee, 0xffffa100, |
0x00001cf6, 0xffffc200, 0x00001cff, 0xffffe200 |
}; |
static void Blit_RGB565_ARGB8888(SDL_BlitInfo *info) |
{ |
Blit_RGB565_32(info, RGB565_ARGB8888_LUT); |
} |
/* Special optimized blit for RGB 5-6-5 --> ABGR 8-8-8-8 */ |
static const Uint32 RGB565_ABGR8888_LUT[512] = { |
0xff000000, 0x00000000, 0xff080000, 0x00002000, |
0xff100000, 0x00004000, 0xff180000, 0x00006100, |
0xff200000, 0x00008100, 0xff290000, 0x0000a100, |
0xff310000, 0x0000c200, 0xff390000, 0x0000e200, |
0xff410000, 0x00000008, 0xff4a0000, 0x00002008, |
0xff520000, 0x00004008, 0xff5a0000, 0x00006108, |
0xff620000, 0x00008108, 0xff6a0000, 0x0000a108, |
0xff730000, 0x0000c208, 0xff7b0000, 0x0000e208, |
0xff830000, 0x00000010, 0xff8b0000, 0x00002010, |
0xff940000, 0x00004010, 0xff9c0000, 0x00006110, |
0xffa40000, 0x00008110, 0xffac0000, 0x0000a110, |
0xffb40000, 0x0000c210, 0xffbd0000, 0x0000e210, |
0xffc50000, 0x00000018, 0xffcd0000, 0x00002018, |
0xffd50000, 0x00004018, 0xffde0000, 0x00006118, |
0xffe60000, 0x00008118, 0xffee0000, 0x0000a118, |
0xfff60000, 0x0000c218, 0xffff0000, 0x0000e218, |
0xff000400, 0x00000020, 0xff080400, 0x00002020, |
0xff100400, 0x00004020, 0xff180400, 0x00006120, |
0xff200400, 0x00008120, 0xff290400, 0x0000a120, |
0xff310400, 0x0000c220, 0xff390400, 0x0000e220, |
0xff410400, 0x00000029, 0xff4a0400, 0x00002029, |
0xff520400, 0x00004029, 0xff5a0400, 0x00006129, |
0xff620400, 0x00008129, 0xff6a0400, 0x0000a129, |
0xff730400, 0x0000c229, 0xff7b0400, 0x0000e229, |
0xff830400, 0x00000031, 0xff8b0400, 0x00002031, |
0xff940400, 0x00004031, 0xff9c0400, 0x00006131, |
0xffa40400, 0x00008131, 0xffac0400, 0x0000a131, |
0xffb40400, 0x0000c231, 0xffbd0400, 0x0000e231, |
0xffc50400, 0x00000039, 0xffcd0400, 0x00002039, |
0xffd50400, 0x00004039, 0xffde0400, 0x00006139, |
0xffe60400, 0x00008139, 0xffee0400, 0x0000a139, |
0xfff60400, 0x0000c239, 0xffff0400, 0x0000e239, |
0xff000800, 0x00000041, 0xff080800, 0x00002041, |
0xff100800, 0x00004041, 0xff180800, 0x00006141, |
0xff200800, 0x00008141, 0xff290800, 0x0000a141, |
0xff310800, 0x0000c241, 0xff390800, 0x0000e241, |
0xff410800, 0x0000004a, 0xff4a0800, 0x0000204a, |
0xff520800, 0x0000404a, 0xff5a0800, 0x0000614a, |
0xff620800, 0x0000814a, 0xff6a0800, 0x0000a14a, |
0xff730800, 0x0000c24a, 0xff7b0800, 0x0000e24a, |
0xff830800, 0x00000052, 0xff8b0800, 0x00002052, |
0xff940800, 0x00004052, 0xff9c0800, 0x00006152, |
0xffa40800, 0x00008152, 0xffac0800, 0x0000a152, |
0xffb40800, 0x0000c252, 0xffbd0800, 0x0000e252, |
0xffc50800, 0x0000005a, 0xffcd0800, 0x0000205a, |
0xffd50800, 0x0000405a, 0xffde0800, 0x0000615a, |
0xffe60800, 0x0000815a, 0xffee0800, 0x0000a15a, |
0xfff60800, 0x0000c25a, 0xffff0800, 0x0000e25a, |
0xff000c00, 0x00000062, 0xff080c00, 0x00002062, |
0xff100c00, 0x00004062, 0xff180c00, 0x00006162, |
0xff200c00, 0x00008162, 0xff290c00, 0x0000a162, |
0xff310c00, 0x0000c262, 0xff390c00, 0x0000e262, |
0xff410c00, 0x0000006a, 0xff4a0c00, 0x0000206a, |
0xff520c00, 0x0000406a, 0xff5a0c00, 0x0000616a, |
0xff620c00, 0x0000816a, 0xff6a0c00, 0x0000a16a, |
0xff730c00, 0x0000c26a, 0xff7b0c00, 0x0000e26a, |
0xff830c00, 0x00000073, 0xff8b0c00, 0x00002073, |
0xff940c00, 0x00004073, 0xff9c0c00, 0x00006173, |
0xffa40c00, 0x00008173, 0xffac0c00, 0x0000a173, |
0xffb40c00, 0x0000c273, 0xffbd0c00, 0x0000e273, |
0xffc50c00, 0x0000007b, 0xffcd0c00, 0x0000207b, |
0xffd50c00, 0x0000407b, 0xffde0c00, 0x0000617b, |
0xffe60c00, 0x0000817b, 0xffee0c00, 0x0000a17b, |
0xfff60c00, 0x0000c27b, 0xffff0c00, 0x0000e27b, |
0xff001000, 0x00000083, 0xff081000, 0x00002083, |
0xff101000, 0x00004083, 0xff181000, 0x00006183, |
0xff201000, 0x00008183, 0xff291000, 0x0000a183, |
0xff311000, 0x0000c283, 0xff391000, 0x0000e283, |
0xff411000, 0x0000008b, 0xff4a1000, 0x0000208b, |
0xff521000, 0x0000408b, 0xff5a1000, 0x0000618b, |
0xff621000, 0x0000818b, 0xff6a1000, 0x0000a18b, |
0xff731000, 0x0000c28b, 0xff7b1000, 0x0000e28b, |
0xff831000, 0x00000094, 0xff8b1000, 0x00002094, |
0xff941000, 0x00004094, 0xff9c1000, 0x00006194, |
0xffa41000, 0x00008194, 0xffac1000, 0x0000a194, |
0xffb41000, 0x0000c294, 0xffbd1000, 0x0000e294, |
0xffc51000, 0x0000009c, 0xffcd1000, 0x0000209c, |
0xffd51000, 0x0000409c, 0xffde1000, 0x0000619c, |
0xffe61000, 0x0000819c, 0xffee1000, 0x0000a19c, |
0xfff61000, 0x0000c29c, 0xffff1000, 0x0000e29c, |
0xff001400, 0x000000a4, 0xff081400, 0x000020a4, |
0xff101400, 0x000040a4, 0xff181400, 0x000061a4, |
0xff201400, 0x000081a4, 0xff291400, 0x0000a1a4, |
0xff311400, 0x0000c2a4, 0xff391400, 0x0000e2a4, |
0xff411400, 0x000000ac, 0xff4a1400, 0x000020ac, |
0xff521400, 0x000040ac, 0xff5a1400, 0x000061ac, |
0xff621400, 0x000081ac, 0xff6a1400, 0x0000a1ac, |
0xff731400, 0x0000c2ac, 0xff7b1400, 0x0000e2ac, |
0xff831400, 0x000000b4, 0xff8b1400, 0x000020b4, |
0xff941400, 0x000040b4, 0xff9c1400, 0x000061b4, |
0xffa41400, 0x000081b4, 0xffac1400, 0x0000a1b4, |
0xffb41400, 0x0000c2b4, 0xffbd1400, 0x0000e2b4, |
0xffc51400, 0x000000bd, 0xffcd1400, 0x000020bd, |
0xffd51400, 0x000040bd, 0xffde1400, 0x000061bd, |
0xffe61400, 0x000081bd, 0xffee1400, 0x0000a1bd, |
0xfff61400, 0x0000c2bd, 0xffff1400, 0x0000e2bd, |
0xff001800, 0x000000c5, 0xff081800, 0x000020c5, |
0xff101800, 0x000040c5, 0xff181800, 0x000061c5, |
0xff201800, 0x000081c5, 0xff291800, 0x0000a1c5, |
0xff311800, 0x0000c2c5, 0xff391800, 0x0000e2c5, |
0xff411800, 0x000000cd, 0xff4a1800, 0x000020cd, |
0xff521800, 0x000040cd, 0xff5a1800, 0x000061cd, |
0xff621800, 0x000081cd, 0xff6a1800, 0x0000a1cd, |
0xff731800, 0x0000c2cd, 0xff7b1800, 0x0000e2cd, |
0xff831800, 0x000000d5, 0xff8b1800, 0x000020d5, |
0xff941800, 0x000040d5, 0xff9c1800, 0x000061d5, |
0xffa41800, 0x000081d5, 0xffac1800, 0x0000a1d5, |
0xffb41800, 0x0000c2d5, 0xffbd1800, 0x0000e2d5, |
0xffc51800, 0x000000de, 0xffcd1800, 0x000020de, |
0xffd51800, 0x000040de, 0xffde1800, 0x000061de, |
0xffe61800, 0x000081de, 0xffee1800, 0x0000a1de, |
0xfff61800, 0x0000c2de, 0xffff1800, 0x0000e2de, |
0xff001c00, 0x000000e6, 0xff081c00, 0x000020e6, |
0xff101c00, 0x000040e6, 0xff181c00, 0x000061e6, |
0xff201c00, 0x000081e6, 0xff291c00, 0x0000a1e6, |
0xff311c00, 0x0000c2e6, 0xff391c00, 0x0000e2e6, |
0xff411c00, 0x000000ee, 0xff4a1c00, 0x000020ee, |
0xff521c00, 0x000040ee, 0xff5a1c00, 0x000061ee, |
0xff621c00, 0x000081ee, 0xff6a1c00, 0x0000a1ee, |
0xff731c00, 0x0000c2ee, 0xff7b1c00, 0x0000e2ee, |
0xff831c00, 0x000000f6, 0xff8b1c00, 0x000020f6, |
0xff941c00, 0x000040f6, 0xff9c1c00, 0x000061f6, |
0xffa41c00, 0x000081f6, 0xffac1c00, 0x0000a1f6, |
0xffb41c00, 0x0000c2f6, 0xffbd1c00, 0x0000e2f6, |
0xffc51c00, 0x000000ff, 0xffcd1c00, 0x000020ff, |
0xffd51c00, 0x000040ff, 0xffde1c00, 0x000061ff, |
0xffe61c00, 0x000081ff, 0xffee1c00, 0x0000a1ff, |
0xfff61c00, 0x0000c2ff, 0xffff1c00, 0x0000e2ff |
}; |
static void Blit_RGB565_ABGR8888(SDL_BlitInfo *info) |
{ |
Blit_RGB565_32(info, RGB565_ABGR8888_LUT); |
} |
/* Special optimized blit for RGB 5-6-5 --> RGBA 8-8-8-8 */ |
static const Uint32 RGB565_RGBA8888_LUT[512] = { |
0x000000ff, 0x00000000, 0x000008ff, 0x00200000, |
0x000010ff, 0x00400000, 0x000018ff, 0x00610000, |
0x000020ff, 0x00810000, 0x000029ff, 0x00a10000, |
0x000031ff, 0x00c20000, 0x000039ff, 0x00e20000, |
0x000041ff, 0x08000000, 0x00004aff, 0x08200000, |
0x000052ff, 0x08400000, 0x00005aff, 0x08610000, |
0x000062ff, 0x08810000, 0x00006aff, 0x08a10000, |
0x000073ff, 0x08c20000, 0x00007bff, 0x08e20000, |
0x000083ff, 0x10000000, 0x00008bff, 0x10200000, |
0x000094ff, 0x10400000, 0x00009cff, 0x10610000, |
0x0000a4ff, 0x10810000, 0x0000acff, 0x10a10000, |
0x0000b4ff, 0x10c20000, 0x0000bdff, 0x10e20000, |
0x0000c5ff, 0x18000000, 0x0000cdff, 0x18200000, |
0x0000d5ff, 0x18400000, 0x0000deff, 0x18610000, |
0x0000e6ff, 0x18810000, 0x0000eeff, 0x18a10000, |
0x0000f6ff, 0x18c20000, 0x0000ffff, 0x18e20000, |
0x000400ff, 0x20000000, 0x000408ff, 0x20200000, |
0x000410ff, 0x20400000, 0x000418ff, 0x20610000, |
0x000420ff, 0x20810000, 0x000429ff, 0x20a10000, |
0x000431ff, 0x20c20000, 0x000439ff, 0x20e20000, |
0x000441ff, 0x29000000, 0x00044aff, 0x29200000, |
0x000452ff, 0x29400000, 0x00045aff, 0x29610000, |
0x000462ff, 0x29810000, 0x00046aff, 0x29a10000, |
0x000473ff, 0x29c20000, 0x00047bff, 0x29e20000, |
0x000483ff, 0x31000000, 0x00048bff, 0x31200000, |
0x000494ff, 0x31400000, 0x00049cff, 0x31610000, |
0x0004a4ff, 0x31810000, 0x0004acff, 0x31a10000, |
0x0004b4ff, 0x31c20000, 0x0004bdff, 0x31e20000, |
0x0004c5ff, 0x39000000, 0x0004cdff, 0x39200000, |
0x0004d5ff, 0x39400000, 0x0004deff, 0x39610000, |
0x0004e6ff, 0x39810000, 0x0004eeff, 0x39a10000, |
0x0004f6ff, 0x39c20000, 0x0004ffff, 0x39e20000, |
0x000800ff, 0x41000000, 0x000808ff, 0x41200000, |
0x000810ff, 0x41400000, 0x000818ff, 0x41610000, |
0x000820ff, 0x41810000, 0x000829ff, 0x41a10000, |
0x000831ff, 0x41c20000, 0x000839ff, 0x41e20000, |
0x000841ff, 0x4a000000, 0x00084aff, 0x4a200000, |
0x000852ff, 0x4a400000, 0x00085aff, 0x4a610000, |
0x000862ff, 0x4a810000, 0x00086aff, 0x4aa10000, |
0x000873ff, 0x4ac20000, 0x00087bff, 0x4ae20000, |
0x000883ff, 0x52000000, 0x00088bff, 0x52200000, |
0x000894ff, 0x52400000, 0x00089cff, 0x52610000, |
0x0008a4ff, 0x52810000, 0x0008acff, 0x52a10000, |
0x0008b4ff, 0x52c20000, 0x0008bdff, 0x52e20000, |
0x0008c5ff, 0x5a000000, 0x0008cdff, 0x5a200000, |
0x0008d5ff, 0x5a400000, 0x0008deff, 0x5a610000, |
0x0008e6ff, 0x5a810000, 0x0008eeff, 0x5aa10000, |
0x0008f6ff, 0x5ac20000, 0x0008ffff, 0x5ae20000, |
0x000c00ff, 0x62000000, 0x000c08ff, 0x62200000, |
0x000c10ff, 0x62400000, 0x000c18ff, 0x62610000, |
0x000c20ff, 0x62810000, 0x000c29ff, 0x62a10000, |
0x000c31ff, 0x62c20000, 0x000c39ff, 0x62e20000, |
0x000c41ff, 0x6a000000, 0x000c4aff, 0x6a200000, |
0x000c52ff, 0x6a400000, 0x000c5aff, 0x6a610000, |
0x000c62ff, 0x6a810000, 0x000c6aff, 0x6aa10000, |
0x000c73ff, 0x6ac20000, 0x000c7bff, 0x6ae20000, |
0x000c83ff, 0x73000000, 0x000c8bff, 0x73200000, |
0x000c94ff, 0x73400000, 0x000c9cff, 0x73610000, |
0x000ca4ff, 0x73810000, 0x000cacff, 0x73a10000, |
0x000cb4ff, 0x73c20000, 0x000cbdff, 0x73e20000, |
0x000cc5ff, 0x7b000000, 0x000ccdff, 0x7b200000, |
0x000cd5ff, 0x7b400000, 0x000cdeff, 0x7b610000, |
0x000ce6ff, 0x7b810000, 0x000ceeff, 0x7ba10000, |
0x000cf6ff, 0x7bc20000, 0x000cffff, 0x7be20000, |
0x001000ff, 0x83000000, 0x001008ff, 0x83200000, |
0x001010ff, 0x83400000, 0x001018ff, 0x83610000, |
0x001020ff, 0x83810000, 0x001029ff, 0x83a10000, |
0x001031ff, 0x83c20000, 0x001039ff, 0x83e20000, |
0x001041ff, 0x8b000000, 0x00104aff, 0x8b200000, |
0x001052ff, 0x8b400000, 0x00105aff, 0x8b610000, |
0x001062ff, 0x8b810000, 0x00106aff, 0x8ba10000, |
0x001073ff, 0x8bc20000, 0x00107bff, 0x8be20000, |
0x001083ff, 0x94000000, 0x00108bff, 0x94200000, |
0x001094ff, 0x94400000, 0x00109cff, 0x94610000, |
0x0010a4ff, 0x94810000, 0x0010acff, 0x94a10000, |
0x0010b4ff, 0x94c20000, 0x0010bdff, 0x94e20000, |
0x0010c5ff, 0x9c000000, 0x0010cdff, 0x9c200000, |
0x0010d5ff, 0x9c400000, 0x0010deff, 0x9c610000, |
0x0010e6ff, 0x9c810000, 0x0010eeff, 0x9ca10000, |
0x0010f6ff, 0x9cc20000, 0x0010ffff, 0x9ce20000, |
0x001400ff, 0xa4000000, 0x001408ff, 0xa4200000, |
0x001410ff, 0xa4400000, 0x001418ff, 0xa4610000, |
0x001420ff, 0xa4810000, 0x001429ff, 0xa4a10000, |
0x001431ff, 0xa4c20000, 0x001439ff, 0xa4e20000, |
0x001441ff, 0xac000000, 0x00144aff, 0xac200000, |
0x001452ff, 0xac400000, 0x00145aff, 0xac610000, |
0x001462ff, 0xac810000, 0x00146aff, 0xaca10000, |
0x001473ff, 0xacc20000, 0x00147bff, 0xace20000, |
0x001483ff, 0xb4000000, 0x00148bff, 0xb4200000, |
0x001494ff, 0xb4400000, 0x00149cff, 0xb4610000, |
0x0014a4ff, 0xb4810000, 0x0014acff, 0xb4a10000, |
0x0014b4ff, 0xb4c20000, 0x0014bdff, 0xb4e20000, |
0x0014c5ff, 0xbd000000, 0x0014cdff, 0xbd200000, |
0x0014d5ff, 0xbd400000, 0x0014deff, 0xbd610000, |
0x0014e6ff, 0xbd810000, 0x0014eeff, 0xbda10000, |
0x0014f6ff, 0xbdc20000, 0x0014ffff, 0xbde20000, |
0x001800ff, 0xc5000000, 0x001808ff, 0xc5200000, |
0x001810ff, 0xc5400000, 0x001818ff, 0xc5610000, |
0x001820ff, 0xc5810000, 0x001829ff, 0xc5a10000, |
0x001831ff, 0xc5c20000, 0x001839ff, 0xc5e20000, |
0x001841ff, 0xcd000000, 0x00184aff, 0xcd200000, |
0x001852ff, 0xcd400000, 0x00185aff, 0xcd610000, |
0x001862ff, 0xcd810000, 0x00186aff, 0xcda10000, |
0x001873ff, 0xcdc20000, 0x00187bff, 0xcde20000, |
0x001883ff, 0xd5000000, 0x00188bff, 0xd5200000, |
0x001894ff, 0xd5400000, 0x00189cff, 0xd5610000, |
0x0018a4ff, 0xd5810000, 0x0018acff, 0xd5a10000, |
0x0018b4ff, 0xd5c20000, 0x0018bdff, 0xd5e20000, |
0x0018c5ff, 0xde000000, 0x0018cdff, 0xde200000, |
0x0018d5ff, 0xde400000, 0x0018deff, 0xde610000, |
0x0018e6ff, 0xde810000, 0x0018eeff, 0xdea10000, |
0x0018f6ff, 0xdec20000, 0x0018ffff, 0xdee20000, |
0x001c00ff, 0xe6000000, 0x001c08ff, 0xe6200000, |
0x001c10ff, 0xe6400000, 0x001c18ff, 0xe6610000, |
0x001c20ff, 0xe6810000, 0x001c29ff, 0xe6a10000, |
0x001c31ff, 0xe6c20000, 0x001c39ff, 0xe6e20000, |
0x001c41ff, 0xee000000, 0x001c4aff, 0xee200000, |
0x001c52ff, 0xee400000, 0x001c5aff, 0xee610000, |
0x001c62ff, 0xee810000, 0x001c6aff, 0xeea10000, |
0x001c73ff, 0xeec20000, 0x001c7bff, 0xeee20000, |
0x001c83ff, 0xf6000000, 0x001c8bff, 0xf6200000, |
0x001c94ff, 0xf6400000, 0x001c9cff, 0xf6610000, |
0x001ca4ff, 0xf6810000, 0x001cacff, 0xf6a10000, |
0x001cb4ff, 0xf6c20000, 0x001cbdff, 0xf6e20000, |
0x001cc5ff, 0xff000000, 0x001ccdff, 0xff200000, |
0x001cd5ff, 0xff400000, 0x001cdeff, 0xff610000, |
0x001ce6ff, 0xff810000, 0x001ceeff, 0xffa10000, |
0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000, |
}; |
static void Blit_RGB565_RGBA8888(SDL_BlitInfo *info) |
{ |
Blit_RGB565_32(info, RGB565_RGBA8888_LUT); |
} |
/* Special optimized blit for RGB 5-6-5 --> BGRA 8-8-8-8 */ |
static const Uint32 RGB565_BGRA8888_LUT[512] = { |
0x00000000, 0x000000ff, 0x08000000, 0x002000ff, |
0x10000000, 0x004000ff, 0x18000000, 0x006100ff, |
0x20000000, 0x008100ff, 0x29000000, 0x00a100ff, |
0x31000000, 0x00c200ff, 0x39000000, 0x00e200ff, |
0x41000000, 0x000008ff, 0x4a000000, 0x002008ff, |
0x52000000, 0x004008ff, 0x5a000000, 0x006108ff, |
0x62000000, 0x008108ff, 0x6a000000, 0x00a108ff, |
0x73000000, 0x00c208ff, 0x7b000000, 0x00e208ff, |
0x83000000, 0x000010ff, 0x8b000000, 0x002010ff, |
0x94000000, 0x004010ff, 0x9c000000, 0x006110ff, |
0xa4000000, 0x008110ff, 0xac000000, 0x00a110ff, |
0xb4000000, 0x00c210ff, 0xbd000000, 0x00e210ff, |
0xc5000000, 0x000018ff, 0xcd000000, 0x002018ff, |
0xd5000000, 0x004018ff, 0xde000000, 0x006118ff, |
0xe6000000, 0x008118ff, 0xee000000, 0x00a118ff, |
0xf6000000, 0x00c218ff, 0xff000000, 0x00e218ff, |
0x00040000, 0x000020ff, 0x08040000, 0x002020ff, |
0x10040000, 0x004020ff, 0x18040000, 0x006120ff, |
0x20040000, 0x008120ff, 0x29040000, 0x00a120ff, |
0x31040000, 0x00c220ff, 0x39040000, 0x00e220ff, |
0x41040000, 0x000029ff, 0x4a040000, 0x002029ff, |
0x52040000, 0x004029ff, 0x5a040000, 0x006129ff, |
0x62040000, 0x008129ff, 0x6a040000, 0x00a129ff, |
0x73040000, 0x00c229ff, 0x7b040000, 0x00e229ff, |
0x83040000, 0x000031ff, 0x8b040000, 0x002031ff, |
0x94040000, 0x004031ff, 0x9c040000, 0x006131ff, |
0xa4040000, 0x008131ff, 0xac040000, 0x00a131ff, |
0xb4040000, 0x00c231ff, 0xbd040000, 0x00e231ff, |
0xc5040000, 0x000039ff, 0xcd040000, 0x002039ff, |
0xd5040000, 0x004039ff, 0xde040000, 0x006139ff, |
0xe6040000, 0x008139ff, 0xee040000, 0x00a139ff, |
0xf6040000, 0x00c239ff, 0xff040000, 0x00e239ff, |
0x00080000, 0x000041ff, 0x08080000, 0x002041ff, |
0x10080000, 0x004041ff, 0x18080000, 0x006141ff, |
0x20080000, 0x008141ff, 0x29080000, 0x00a141ff, |
0x31080000, 0x00c241ff, 0x39080000, 0x00e241ff, |
0x41080000, 0x00004aff, 0x4a080000, 0x00204aff, |
0x52080000, 0x00404aff, 0x5a080000, 0x00614aff, |
0x62080000, 0x00814aff, 0x6a080000, 0x00a14aff, |
0x73080000, 0x00c24aff, 0x7b080000, 0x00e24aff, |
0x83080000, 0x000052ff, 0x8b080000, 0x002052ff, |
0x94080000, 0x004052ff, 0x9c080000, 0x006152ff, |
0xa4080000, 0x008152ff, 0xac080000, 0x00a152ff, |
0xb4080000, 0x00c252ff, 0xbd080000, 0x00e252ff, |
0xc5080000, 0x00005aff, 0xcd080000, 0x00205aff, |
0xd5080000, 0x00405aff, 0xde080000, 0x00615aff, |
0xe6080000, 0x00815aff, 0xee080000, 0x00a15aff, |
0xf6080000, 0x00c25aff, 0xff080000, 0x00e25aff, |
0x000c0000, 0x000062ff, 0x080c0000, 0x002062ff, |
0x100c0000, 0x004062ff, 0x180c0000, 0x006162ff, |
0x200c0000, 0x008162ff, 0x290c0000, 0x00a162ff, |
0x310c0000, 0x00c262ff, 0x390c0000, 0x00e262ff, |
0x410c0000, 0x00006aff, 0x4a0c0000, 0x00206aff, |
0x520c0000, 0x00406aff, 0x5a0c0000, 0x00616aff, |
0x620c0000, 0x00816aff, 0x6a0c0000, 0x00a16aff, |
0x730c0000, 0x00c26aff, 0x7b0c0000, 0x00e26aff, |
0x830c0000, 0x000073ff, 0x8b0c0000, 0x002073ff, |
0x940c0000, 0x004073ff, 0x9c0c0000, 0x006173ff, |
0xa40c0000, 0x008173ff, 0xac0c0000, 0x00a173ff, |
0xb40c0000, 0x00c273ff, 0xbd0c0000, 0x00e273ff, |
0xc50c0000, 0x00007bff, 0xcd0c0000, 0x00207bff, |
0xd50c0000, 0x00407bff, 0xde0c0000, 0x00617bff, |
0xe60c0000, 0x00817bff, 0xee0c0000, 0x00a17bff, |
0xf60c0000, 0x00c27bff, 0xff0c0000, 0x00e27bff, |
0x00100000, 0x000083ff, 0x08100000, 0x002083ff, |
0x10100000, 0x004083ff, 0x18100000, 0x006183ff, |
0x20100000, 0x008183ff, 0x29100000, 0x00a183ff, |
0x31100000, 0x00c283ff, 0x39100000, 0x00e283ff, |
0x41100000, 0x00008bff, 0x4a100000, 0x00208bff, |
0x52100000, 0x00408bff, 0x5a100000, 0x00618bff, |
0x62100000, 0x00818bff, 0x6a100000, 0x00a18bff, |
0x73100000, 0x00c28bff, 0x7b100000, 0x00e28bff, |
0x83100000, 0x000094ff, 0x8b100000, 0x002094ff, |
0x94100000, 0x004094ff, 0x9c100000, 0x006194ff, |
0xa4100000, 0x008194ff, 0xac100000, 0x00a194ff, |
0xb4100000, 0x00c294ff, 0xbd100000, 0x00e294ff, |
0xc5100000, 0x00009cff, 0xcd100000, 0x00209cff, |
0xd5100000, 0x00409cff, 0xde100000, 0x00619cff, |
0xe6100000, 0x00819cff, 0xee100000, 0x00a19cff, |
0xf6100000, 0x00c29cff, 0xff100000, 0x00e29cff, |
0x00140000, 0x0000a4ff, 0x08140000, 0x0020a4ff, |
0x10140000, 0x0040a4ff, 0x18140000, 0x0061a4ff, |
0x20140000, 0x0081a4ff, 0x29140000, 0x00a1a4ff, |
0x31140000, 0x00c2a4ff, 0x39140000, 0x00e2a4ff, |
0x41140000, 0x0000acff, 0x4a140000, 0x0020acff, |
0x52140000, 0x0040acff, 0x5a140000, 0x0061acff, |
0x62140000, 0x0081acff, 0x6a140000, 0x00a1acff, |
0x73140000, 0x00c2acff, 0x7b140000, 0x00e2acff, |
0x83140000, 0x0000b4ff, 0x8b140000, 0x0020b4ff, |
0x94140000, 0x0040b4ff, 0x9c140000, 0x0061b4ff, |
0xa4140000, 0x0081b4ff, 0xac140000, 0x00a1b4ff, |
0xb4140000, 0x00c2b4ff, 0xbd140000, 0x00e2b4ff, |
0xc5140000, 0x0000bdff, 0xcd140000, 0x0020bdff, |
0xd5140000, 0x0040bdff, 0xde140000, 0x0061bdff, |
0xe6140000, 0x0081bdff, 0xee140000, 0x00a1bdff, |
0xf6140000, 0x00c2bdff, 0xff140000, 0x00e2bdff, |
0x00180000, 0x0000c5ff, 0x08180000, 0x0020c5ff, |
0x10180000, 0x0040c5ff, 0x18180000, 0x0061c5ff, |
0x20180000, 0x0081c5ff, 0x29180000, 0x00a1c5ff, |
0x31180000, 0x00c2c5ff, 0x39180000, 0x00e2c5ff, |
0x41180000, 0x0000cdff, 0x4a180000, 0x0020cdff, |
0x52180000, 0x0040cdff, 0x5a180000, 0x0061cdff, |
0x62180000, 0x0081cdff, 0x6a180000, 0x00a1cdff, |
0x73180000, 0x00c2cdff, 0x7b180000, 0x00e2cdff, |
0x83180000, 0x0000d5ff, 0x8b180000, 0x0020d5ff, |
0x94180000, 0x0040d5ff, 0x9c180000, 0x0061d5ff, |
0xa4180000, 0x0081d5ff, 0xac180000, 0x00a1d5ff, |
0xb4180000, 0x00c2d5ff, 0xbd180000, 0x00e2d5ff, |
0xc5180000, 0x0000deff, 0xcd180000, 0x0020deff, |
0xd5180000, 0x0040deff, 0xde180000, 0x0061deff, |
0xe6180000, 0x0081deff, 0xee180000, 0x00a1deff, |
0xf6180000, 0x00c2deff, 0xff180000, 0x00e2deff, |
0x001c0000, 0x0000e6ff, 0x081c0000, 0x0020e6ff, |
0x101c0000, 0x0040e6ff, 0x181c0000, 0x0061e6ff, |
0x201c0000, 0x0081e6ff, 0x291c0000, 0x00a1e6ff, |
0x311c0000, 0x00c2e6ff, 0x391c0000, 0x00e2e6ff, |
0x411c0000, 0x0000eeff, 0x4a1c0000, 0x0020eeff, |
0x521c0000, 0x0040eeff, 0x5a1c0000, 0x0061eeff, |
0x621c0000, 0x0081eeff, 0x6a1c0000, 0x00a1eeff, |
0x731c0000, 0x00c2eeff, 0x7b1c0000, 0x00e2eeff, |
0x831c0000, 0x0000f6ff, 0x8b1c0000, 0x0020f6ff, |
0x941c0000, 0x0040f6ff, 0x9c1c0000, 0x0061f6ff, |
0xa41c0000, 0x0081f6ff, 0xac1c0000, 0x00a1f6ff, |
0xb41c0000, 0x00c2f6ff, 0xbd1c0000, 0x00e2f6ff, |
0xc51c0000, 0x0000ffff, 0xcd1c0000, 0x0020ffff, |
0xd51c0000, 0x0040ffff, 0xde1c0000, 0x0061ffff, |
0xe61c0000, 0x0081ffff, 0xee1c0000, 0x00a1ffff, |
0xf61c0000, 0x00c2ffff, 0xff1c0000, 0x00e2ffff |
}; |
static void Blit_RGB565_BGRA8888(SDL_BlitInfo *info) |
{ |
Blit_RGB565_32(info, RGB565_BGRA8888_LUT); |
} |
/* Special optimized blit for RGB 8-8-8 --> RGB 3-3-2 */ |
#ifndef RGB888_RGB332 |
#define RGB888_RGB332(dst, src) { \ |
dst = (((src)&0x00E00000)>>16)| \ |
(((src)&0x0000E000)>>11)| \ |
(((src)&0x000000C0)>>6); \ |
} |
#endif |
static void Blit_RGB888_index8_map(SDL_BlitInfo *info) |
{ |
#ifndef USE_DUFFS_LOOP |
int c; |
#endif |
int pixel; |
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; |
#ifdef USE_DUFFS_LOOP |
while ( height-- ) { |
DUFFS_LOOP( |
RGB888_RGB332(pixel, *src); |
*dst++ = map[pixel]; |
++src; |
, width); |
src += srcskip; |
dst += dstskip; |
} |
#else |
while ( height-- ) { |
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; |
} |
src += srcskip; |
dst += dstskip; |
} |
#endif /* USE_DUFFS_LOOP */ |
} |
static void BlitNto1(SDL_BlitInfo *info) |
{ |
#ifndef USE_DUFFS_LOOP |
int c; |
#endif |
int width, height; |
Uint8 *src; |
const Uint8 *map; |
Uint8 *dst; |
int srcskip, dstskip; |
int srcbpp; |
Uint32 pixel; |
int sR, sG, sB; |
SDL_PixelFormat *srcfmt; |
/* Set up some basic variables */ |
width = info->d_width; |
height = info->d_height; |
src = info->s_pixels; |
srcskip = info->s_skip; |
dst = info->d_pixels; |
dstskip = info->d_skip; |
map = info->table; |
srcfmt = info->src; |
srcbpp = srcfmt->BytesPerPixel; |
if ( map == NULL ) { |
while ( height-- ) { |
#ifdef USE_DUFFS_LOOP |
DUFFS_LOOP( |
DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, |
sR, sG, sB); |
if ( 1 ) { |
/* Pack RGB into 8bit pixel */ |
*dst = ((sR>>5)<<(3+2))| |
((sG>>5)<<(2)) | |
((sB>>6)<<(0)) ; |
} |
dst++; |
src += srcbpp; |
, width); |
#else |
for ( c=width; c; --c ) { |
DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, |
sR, sG, sB); |
if ( 1 ) { |
/* Pack RGB into 8bit pixel */ |
*dst = ((sR>>5)<<(3+2))| |
((sG>>5)<<(2)) | |
((sB>>6)<<(0)) ; |
} |
dst++; |
src += srcbpp; |
} |
#endif |
src += srcskip; |
dst += dstskip; |
} |
} else { |
while ( height-- ) { |
#ifdef USE_DUFFS_LOOP |
DUFFS_LOOP( |
DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, |
sR, sG, sB); |
if ( 1 ) { |
/* Pack RGB into 8bit pixel */ |
*dst = map[((sR>>5)<<(3+2))| |
((sG>>5)<<(2)) | |
((sB>>6)<<(0)) ]; |
} |
dst++; |
src += srcbpp; |
, width); |
#else |
for ( c=width; c; --c ) { |
DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, |
sR, sG, sB); |
if ( 1 ) { |
/* Pack RGB into 8bit pixel */ |
*dst = map[((sR>>5)<<(3+2))| |
((sG>>5)<<(2)) | |
((sB>>6)<<(0)) ]; |
} |
dst++; |
src += srcbpp; |
} |
#endif /* USE_DUFFS_LOOP */ |
src += srcskip; |
dst += dstskip; |
} |
} |
} |
static void BlitNtoN(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint8 *dst = info->d_pixels; |
int dstskip = info->d_skip; |
SDL_PixelFormat *srcfmt = info->src; |
int srcbpp = srcfmt->BytesPerPixel; |
SDL_PixelFormat *dstfmt = info->dst; |
int dstbpp = dstfmt->BytesPerPixel; |
unsigned alpha = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; |
while ( height-- ) { |
DUFFS_LOOP( |
{ |
Uint32 pixel; |
unsigned sR; |
unsigned sG; |
unsigned sB; |
DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB); |
ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha); |
dst += dstbpp; |
src += srcbpp; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} |
static void BlitNtoNCopyAlpha(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint8 *dst = info->d_pixels; |
int dstskip = info->d_skip; |
SDL_PixelFormat *srcfmt = info->src; |
int srcbpp = srcfmt->BytesPerPixel; |
SDL_PixelFormat *dstfmt = info->dst; |
int dstbpp = dstfmt->BytesPerPixel; |
int c; |
/* FIXME: should map alpha to [0..255] correctly! */ |
while ( height-- ) { |
for ( c=width; c; --c ) { |
Uint32 pixel; |
unsigned sR, sG, sB, sA; |
DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, |
sR, sG, sB, sA); |
ASSEMBLE_RGBA(dst, dstbpp, dstfmt, |
sR, sG, sB, sA); |
dst += dstbpp; |
src += srcbpp; |
} |
src += srcskip; |
dst += dstskip; |
} |
} |
static void BlitNto1Key(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint8 *dst = info->d_pixels; |
int dstskip = info->d_skip; |
SDL_PixelFormat *srcfmt = info->src; |
const Uint8 *palmap = info->table; |
Uint32 ckey = srcfmt->colorkey; |
Uint32 rgbmask = ~srcfmt->Amask; |
int srcbpp; |
Uint32 pixel; |
Uint8 sR, sG, sB; |
/* Set up some basic variables */ |
srcbpp = srcfmt->BytesPerPixel; |
ckey &= rgbmask; |
if ( palmap == NULL ) { |
while ( height-- ) { |
DUFFS_LOOP( |
{ |
DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, |
sR, sG, sB); |
if ( (pixel & rgbmask) != ckey ) { |
/* Pack RGB into 8bit pixel */ |
*dst = ((sR>>5)<<(3+2))| |
((sG>>5)<<(2)) | |
((sB>>6)<<(0)) ; |
} |
dst++; |
src += srcbpp; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} else { |
while ( height-- ) { |
DUFFS_LOOP( |
{ |
DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, |
sR, sG, sB); |
if ( (pixel & rgbmask) != ckey ) { |
/* Pack RGB into 8bit pixel */ |
*dst = palmap[((sR>>5)<<(3+2))| |
((sG>>5)<<(2)) | |
((sB>>6)<<(0)) ]; |
} |
dst++; |
src += srcbpp; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} |
} |
static void Blit2to2Key(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint16 *srcp = (Uint16 *)info->s_pixels; |
int srcskip = info->s_skip; |
Uint16 *dstp = (Uint16 *)info->d_pixels; |
int dstskip = info->d_skip; |
Uint32 ckey = info->src->colorkey; |
Uint32 rgbmask = ~info->src->Amask; |
/* Set up some basic variables */ |
srcskip /= 2; |
dstskip /= 2; |
ckey &= rgbmask; |
while ( height-- ) { |
DUFFS_LOOP( |
{ |
if ( (*srcp & rgbmask) != ckey ) { |
*dstp = *srcp; |
} |
dstp++; |
srcp++; |
}, |
width); |
srcp += srcskip; |
dstp += dstskip; |
} |
} |
static void BlitNtoNKey(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint8 *dst = info->d_pixels; |
int dstskip = info->d_skip; |
Uint32 ckey = info->src->colorkey; |
SDL_PixelFormat *srcfmt = info->src; |
SDL_PixelFormat *dstfmt = info->dst; |
int srcbpp = srcfmt->BytesPerPixel; |
int dstbpp = dstfmt->BytesPerPixel; |
unsigned alpha = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; |
while ( height-- ) { |
DUFFS_LOOP( |
{ |
Uint32 pixel; |
unsigned sR; |
unsigned sG; |
unsigned sB; |
RETRIEVE_RGB_PIXEL(src, srcbpp, pixel); |
if ( pixel != ckey ) { |
RGB_FROM_PIXEL(pixel, srcfmt, sR, sG, sB); |
ASSEMBLE_RGBA(dst, dstbpp, dstfmt, |
sR, sG, sB, alpha); |
} |
dst += dstbpp; |
src += srcbpp; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} |
static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo *info) |
{ |
int width = info->d_width; |
int height = info->d_height; |
Uint8 *src = info->s_pixels; |
int srcskip = info->s_skip; |
Uint8 *dst = info->d_pixels; |
int dstskip = info->d_skip; |
Uint32 ckey = info->src->colorkey; |
SDL_PixelFormat *srcfmt = info->src; |
SDL_PixelFormat *dstfmt = info->dst; |
Uint32 rgbmask = ~srcfmt->Amask; |
Uint8 srcbpp; |
Uint8 dstbpp; |
Uint32 pixel; |
Uint8 sR, sG, sB, sA; |
/* Set up some basic variables */ |
srcbpp = srcfmt->BytesPerPixel; |
dstbpp = dstfmt->BytesPerPixel; |
ckey &= rgbmask; |
/* FIXME: should map alpha to [0..255] correctly! */ |
while ( height-- ) { |
DUFFS_LOOP( |
{ |
DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, |
sR, sG, sB, sA); |
if ( (pixel & rgbmask) != ckey ) { |
ASSEMBLE_RGBA(dst, dstbpp, dstfmt, |
sR, sG, sB, sA); |
} |
dst += dstbpp; |
src += srcbpp; |
}, |
width); |
src += srcskip; |
dst += dstskip; |
} |
} |
/* Normal N to N optimized blitters */ |
struct blit_table { |
Uint32 srcR, srcG, srcB; |
int dstbpp; |
Uint32 dstR, dstG, dstB; |
Uint32 cpu_flags; |
void *aux_data; |
SDL_loblit blitfunc; |
enum { NO_ALPHA, SET_ALPHA, COPY_ALPHA } alpha; |
}; |
static const struct blit_table normal_blit_1[] = { |
/* Default for 8-bit RGB source, an invalid combination */ |
{ 0,0,0, 0, 0,0,0, 0, NULL, NULL }, |
}; |
static const struct blit_table normal_blit_2[] = { |
#ifdef USE_ASMBLIT |
{ 0x0000F800,0x000007E0,0x0000001F, 2, 0x0000001F,0x000007E0,0x0000F800, |
0, ConvertX86p16_16BGR565, ConvertX86, NO_ALPHA }, |
{ 0x0000F800,0x000007E0,0x0000001F, 2, 0x00007C00,0x000003E0,0x0000001F, |
0, ConvertX86p16_16RGB555, ConvertX86, NO_ALPHA }, |
{ 0x0000F800,0x000007E0,0x0000001F, 2, 0x0000001F,0x000003E0,0x00007C00, |
0, ConvertX86p16_16BGR555, ConvertX86, NO_ALPHA }, |
#endif |
{ 0x0000F800,0x000007E0,0x0000001F, 4, 0x00FF0000,0x0000FF00,0x000000FF, |
0, NULL, Blit_RGB565_ARGB8888, SET_ALPHA }, |
{ 0x0000F800,0x000007E0,0x0000001F, 4, 0x000000FF,0x0000FF00,0x00FF0000, |
0, NULL, Blit_RGB565_ABGR8888, SET_ALPHA }, |
{ 0x0000F800,0x000007E0,0x0000001F, 4, 0xFF000000,0x00FF0000,0x0000FF00, |
0, NULL, Blit_RGB565_RGBA8888, SET_ALPHA }, |
{ 0x0000F800,0x000007E0,0x0000001F, 4, 0x0000FF00,0x00FF0000,0xFF000000, |
0, NULL, Blit_RGB565_BGRA8888, SET_ALPHA }, |
/* Default for 16-bit RGB source, used if no other blitter matches */ |
{ 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 } |
}; |
static const struct blit_table normal_blit_3[] = { |
/* Default for 24-bit RGB source, never optimized */ |
{ 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 } |
}; |
static const struct blit_table normal_blit_4[] = { |
#ifdef USE_ASMBLIT |
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F, |
MMX_CPU, ConvertMMXpII32_16RGB565, ConvertMMX, NO_ALPHA }, |
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F, |
0, ConvertX86p32_16RGB565, ConvertX86, NO_ALPHA }, |
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800, |
MMX_CPU, ConvertMMXpII32_16BGR565, ConvertMMX, NO_ALPHA }, |
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800, |
0, ConvertX86p32_16BGR565, ConvertX86, NO_ALPHA }, |
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F, |
MMX_CPU, ConvertMMXpII32_16RGB555, ConvertMMX, NO_ALPHA }, |
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F, |
0, ConvertX86p32_16RGB555, ConvertX86, NO_ALPHA }, |
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00, |
MMX_CPU, ConvertMMXpII32_16BGR555, ConvertMMX, NO_ALPHA }, |
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00, |
0, ConvertX86p32_16BGR555, ConvertX86, NO_ALPHA }, |
{ 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x00FF0000,0x0000FF00,0x000000FF, |
0, ConvertX86p32_24RGB888, ConvertX86, NO_ALPHA }, |
{ 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x000000FF,0x0000FF00,0x00FF0000, |
0, ConvertX86p32_24BGR888, ConvertX86, NO_ALPHA }, |
{ 0x00FF0000,0x0000FF00,0x000000FF, 4, 0x000000FF,0x0000FF00,0x00FF0000, |
0, ConvertX86p32_32BGR888, ConvertX86, NO_ALPHA }, |
{ 0x00FF0000,0x0000FF00,0x000000FF, 4, 0xFF000000,0x00FF0000,0x0000FF00, |
0, ConvertX86p32_32RGBA888, ConvertX86, NO_ALPHA }, |
{ 0x00FF0000,0x0000FF00,0x000000FF, 4, 0x0000FF00,0x00FF0000,0xFF000000, |
0, ConvertX86p32_32BGRA888, ConvertX86, NO_ALPHA }, |
#else |
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F, |
0, NULL, Blit_RGB888_RGB565, NO_ALPHA }, |
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F, |
0, NULL, Blit_RGB888_RGB555, NO_ALPHA }, |
#endif |
/* Default for 32-bit RGB source, used if no other blitter matches */ |
{ 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 } |
}; |
static const struct blit_table *normal_blit[] = { |
normal_blit_1, normal_blit_2, normal_blit_3, normal_blit_4 |
}; |
SDL_loblit SDL_CalculateBlitN(SDL_Surface *surface, int blit_index) |
{ |
struct private_swaccel *sdata; |
SDL_PixelFormat *srcfmt; |
SDL_PixelFormat *dstfmt; |
const struct blit_table *table; |
int which; |
SDL_loblit blitfun; |
/* Set up data for choosing the blit */ |
sdata = surface->map->sw_data; |
srcfmt = surface->format; |
dstfmt = surface->map->dst->format; |
if ( blit_index & 2 ) { |
/* alpha or alpha+colorkey */ |
return SDL_CalculateAlphaBlit(surface, blit_index); |
} |
/* We don't support destinations less than 8-bits */ |
if ( dstfmt->BitsPerPixel < 8 ) { |
return(NULL); |
} |
if(blit_index == 1) { |
/* colorkey blit: Here we don't have too many options, mostly |
because RLE is the preferred fast way to deal with this. |
If a particular case turns out to be useful we'll add it. */ |
if(srcfmt->BytesPerPixel == 2 |
&& surface->map->identity) |
return Blit2to2Key; |
else if(dstfmt->BytesPerPixel == 1) |
return BlitNto1Key; |
else { |
if(srcfmt->Amask && dstfmt->Amask) |
return BlitNtoNKeyCopyAlpha; |
else |
return BlitNtoNKey; |
} |
} |
blitfun = NULL; |
if ( dstfmt->BitsPerPixel == 8 ) { |
/* We assume 8-bit destinations are palettized */ |
if ( (srcfmt->BytesPerPixel == 4) && |
(srcfmt->Rmask == 0x00FF0000) && |
(srcfmt->Gmask == 0x0000FF00) && |
(srcfmt->Bmask == 0x000000FF) ) { |
if ( surface->map->table ) { |
blitfun = Blit_RGB888_index8_map; |
} else { |
#ifdef USE_ASMBLIT |
sdata->aux_data = ConvertX86p32_8RGB332; |
blitfun = ConvertX86; |
#else |
blitfun = Blit_RGB888_index8; |
#endif |
} |
} else { |
blitfun = BlitNto1; |
} |
} else { |
/* Now the meat, choose the blitter we want */ |
int a_need = 0; |
if(dstfmt->Amask) |
a_need = srcfmt->Amask ? COPY_ALPHA : SET_ALPHA; |
table = normal_blit[srcfmt->BytesPerPixel-1]; |
for ( which=0; table[which].srcR; ++which ) { |
if ( srcfmt->Rmask == table[which].srcR && |
srcfmt->Gmask == table[which].srcG && |
srcfmt->Bmask == table[which].srcB && |
dstfmt->BytesPerPixel == table[which].dstbpp && |
dstfmt->Rmask == table[which].dstR && |
dstfmt->Gmask == table[which].dstG && |
dstfmt->Bmask == table[which].dstB && |
(a_need & table[which].alpha) == a_need && |
(CPU_Flags()&table[which].cpu_flags) == |
table[which].cpu_flags ) |
break; |
} |
sdata->aux_data = table[which].aux_data; |
blitfun = table[which].blitfunc; |
if(a_need == COPY_ALPHA && blitfun == BlitNtoN) |
blitfun = BlitNtoNCopyAlpha; |
} |
#ifdef DEBUG_ASM |
#ifdef USE_ASMBLIT |
if ( blitfun == ConvertMMX ) |
SDL_printf("Using mmx blit\n"); |
else |
if ( blitfun == ConvertX86 ) |
SDL_printf("Using asm blit\n"); |
else |
#endif |
if ( (blitfun == SDL_BlitNtoN) || (blitfun == SDL_BlitNto1) ) |
fprintf(stderr, "Using C blit\n"); |
else |
fprintf(stderr, "Using optimized C blit\n"); |
#endif /* DEBUG_ASM */ |
return(blitfun); |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_bmp.c |
---|
0,0 → 1,523 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifndef DISABLE_FILE |
/* |
Code to load and save surfaces in Windows BMP format. |
Why support BMP format? Well, it's a native format for Windows, and |
most image processing programs can read and write it. It would be nice |
to be able to have at least one image format that we can natively load |
and save, and since PNG is so complex that it would bloat the library, |
BMP is a good alternative. |
This code currently supports Win32 DIBs in uncompressed 8 and 24 bpp. |
*/ |
#include <string.h> |
#include "SDL_error.h" |
#include "SDL_video.h" |
#include "SDL_endian.h" |
/* Compression encodings for BMP files */ |
#ifndef BI_RGB |
#define BI_RGB 0 |
#define BI_RLE8 1 |
#define BI_RLE4 2 |
#define BI_BITFIELDS 3 |
#endif |
SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) |
{ |
int was_error; |
long fp_offset; |
int bmpPitch; |
int i, pad; |
SDL_Surface *surface; |
Uint32 Rmask; |
Uint32 Gmask; |
Uint32 Bmask; |
SDL_Palette *palette; |
Uint8 *bits; |
int ExpandBMP; |
/* The Win32 BMP file header (14 bytes) */ |
char magic[2]; |
Uint32 bfSize; |
Uint16 bfReserved1; |
Uint16 bfReserved2; |
Uint32 bfOffBits; |
/* The Win32 BITMAPINFOHEADER struct (40 bytes) */ |
Uint32 biSize; |
Sint32 biWidth; |
Sint32 biHeight; |
Uint16 biPlanes; |
Uint16 biBitCount; |
Uint32 biCompression; |
Uint32 biSizeImage; |
Sint32 biXPelsPerMeter; |
Sint32 biYPelsPerMeter; |
Uint32 biClrUsed; |
Uint32 biClrImportant; |
/* Make sure we are passed a valid data source */ |
surface = NULL; |
was_error = 0; |
if ( src == NULL ) { |
was_error = 1; |
goto done; |
} |
/* Read in the BMP file header */ |
fp_offset = SDL_RWtell(src); |
SDL_ClearError(); |
if ( SDL_RWread(src, magic, 1, 2) != 2 ) { |
SDL_Error(SDL_EFREAD); |
was_error = 1; |
goto done; |
} |
if ( strncmp(magic, "BM", 2) != 0 ) { |
SDL_SetError("File is not a Windows BMP file"); |
was_error = 1; |
goto done; |
} |
bfSize = SDL_ReadLE32(src); |
bfReserved1 = SDL_ReadLE16(src); |
bfReserved2 = SDL_ReadLE16(src); |
bfOffBits = SDL_ReadLE32(src); |
/* Read the Win32 BITMAPINFOHEADER */ |
biSize = SDL_ReadLE32(src); |
if ( biSize == 12 ) { |
biWidth = (Uint32)SDL_ReadLE16(src); |
biHeight = (Uint32)SDL_ReadLE16(src); |
biPlanes = SDL_ReadLE16(src); |
biBitCount = SDL_ReadLE16(src); |
biCompression = BI_RGB; |
biSizeImage = 0; |
biXPelsPerMeter = 0; |
biYPelsPerMeter = 0; |
biClrUsed = 0; |
biClrImportant = 0; |
} else { |
biWidth = SDL_ReadLE32(src); |
biHeight = SDL_ReadLE32(src); |
biPlanes = SDL_ReadLE16(src); |
biBitCount = SDL_ReadLE16(src); |
biCompression = SDL_ReadLE32(src); |
biSizeImage = SDL_ReadLE32(src); |
biXPelsPerMeter = SDL_ReadLE32(src); |
biYPelsPerMeter = SDL_ReadLE32(src); |
biClrUsed = SDL_ReadLE32(src); |
biClrImportant = SDL_ReadLE32(src); |
} |
/* Check for read error */ |
if ( strcmp(SDL_GetError(), "") != 0 ) { |
was_error = 1; |
goto done; |
} |
/* Expand 1 and 4 bit bitmaps to 8 bits per pixel */ |
switch (biBitCount) { |
case 1: |
case 4: |
ExpandBMP = biBitCount; |
biBitCount = 8; |
break; |
default: |
ExpandBMP = 0; |
break; |
} |
/* We don't support any BMP compression right now */ |
Rmask = Gmask = Bmask = 0; |
switch (biCompression) { |
case BI_RGB: |
/* If there are no masks, use the defaults */ |
if ( bfOffBits == (14+biSize) ) { |
/* Default values for the BMP format */ |
switch (biBitCount) { |
case 15: |
case 16: |
Rmask = 0x7C00; |
Gmask = 0x03E0; |
Bmask = 0x001F; |
break; |
case 24: |
#if SDL_BYTEORDER == SDL_BIG_ENDIAN |
Rmask = 0x000000FF; |
Gmask = 0x0000FF00; |
Bmask = 0x00FF0000; |
break; |
#endif |
case 32: |
Rmask = 0x00FF0000; |
Gmask = 0x0000FF00; |
Bmask = 0x000000FF; |
break; |
default: |
break; |
} |
break; |
} |
/* Fall through -- read the RGB masks */ |
case BI_BITFIELDS: |
switch (biBitCount) { |
case 15: |
case 16: |
case 32: |
Rmask = SDL_ReadLE32(src); |
Gmask = SDL_ReadLE32(src); |
Bmask = SDL_ReadLE32(src); |
break; |
default: |
break; |
} |
break; |
default: |
SDL_SetError("Compressed BMP files not supported"); |
was_error = 1; |
goto done; |
} |
/* Create a compatible surface, note that the colors are RGB ordered */ |
surface = SDL_CreateRGBSurface(SDL_SWSURFACE, |
biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, 0); |
if ( surface == NULL ) { |
was_error = 1; |
goto done; |
} |
/* Load the palette, if any */ |
palette = (surface->format)->palette; |
if ( palette ) { |
if ( biClrUsed == 0 ) { |
biClrUsed = 1 << biBitCount; |
} |
if ( biSize == 12 ) { |
for ( i = 0; i < (int)biClrUsed; ++i ) { |
SDL_RWread(src, &palette->colors[i].b, 1, 1); |
SDL_RWread(src, &palette->colors[i].g, 1, 1); |
SDL_RWread(src, &palette->colors[i].r, 1, 1); |
palette->colors[i].unused = 0; |
} |
} else { |
for ( i = 0; i < (int)biClrUsed; ++i ) { |
SDL_RWread(src, &palette->colors[i].b, 1, 1); |
SDL_RWread(src, &palette->colors[i].g, 1, 1); |
SDL_RWread(src, &palette->colors[i].r, 1, 1); |
SDL_RWread(src, &palette->colors[i].unused, 1, 1); |
} |
} |
palette->ncolors = biClrUsed; |
} |
/* Read the surface pixels. Note that the bmp image is upside down */ |
if ( SDL_RWseek(src, fp_offset+bfOffBits, SEEK_SET) < 0 ) { |
SDL_Error(SDL_EFSEEK); |
was_error = 1; |
goto done; |
} |
bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch); |
switch (ExpandBMP) { |
case 1: |
bmpPitch = (biWidth + 7) >> 3; |
pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0); |
break; |
case 4: |
bmpPitch = (biWidth + 1) >> 1; |
pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0); |
break; |
default: |
pad = ((surface->pitch%4) ? |
(4-(surface->pitch%4)) : 0); |
break; |
} |
while ( bits > (Uint8 *)surface->pixels ) { |
bits -= surface->pitch; |
switch (ExpandBMP) { |
case 1: |
case 4: { |
Uint8 pixel = 0; |
int shift = (8-ExpandBMP); |
for ( i=0; i<surface->w; ++i ) { |
if ( i%(8/ExpandBMP) == 0 ) { |
if ( !SDL_RWread(src, &pixel, 1, 1) ) { |
SDL_SetError( |
"Error reading from BMP"); |
was_error = 1; |
goto done; |
} |
} |
*(bits+i) = (pixel>>shift); |
pixel <<= ExpandBMP; |
} } |
break; |
default: |
if ( SDL_RWread(src, bits, 1, surface->pitch) |
!= surface->pitch ) { |
SDL_Error(SDL_EFREAD); |
was_error = 1; |
goto done; |
} |
#if SDL_BYTEORDER == SDL_BIG_ENDIAN |
/* Byte-swap the pixels if needed. Note that the 24bpp |
case has already been taken care of above. */ |
switch(biBitCount) { |
case 15: |
case 16: { |
Uint16 *pix = (Uint16 *)bits; |
for(i = 0; i < surface->w; i++) |
pix[i] = SDL_Swap16(pix[i]); |
break; |
} |
case 32: { |
Uint32 *pix = (Uint32 *)bits; |
for(i = 0; i < surface->w; i++) |
pix[i] = SDL_Swap32(pix[i]); |
break; |
} |
} |
#endif |
break; |
} |
/* Skip padding bytes, ugh */ |
if ( pad ) { |
Uint8 padbyte; |
for ( i=0; i<pad; ++i ) { |
SDL_RWread(src, &padbyte, 1, 1); |
} |
} |
} |
done: |
if ( was_error ) { |
if ( surface ) { |
SDL_FreeSurface(surface); |
} |
surface = NULL; |
} |
if ( freesrc && src ) { |
SDL_RWclose(src); |
} |
return(surface); |
} |
int SDL_SaveBMP_RW (SDL_Surface *saveme, SDL_RWops *dst, int freedst) |
{ |
long fp_offset; |
int i, pad; |
SDL_Surface *surface; |
Uint8 *bits; |
/* The Win32 BMP file header (14 bytes) */ |
char magic[2] = { 'B', 'M' }; |
Uint32 bfSize; |
Uint16 bfReserved1; |
Uint16 bfReserved2; |
Uint32 bfOffBits; |
/* The Win32 BITMAPINFOHEADER struct (40 bytes) */ |
Uint32 biSize; |
Sint32 biWidth; |
Sint32 biHeight; |
Uint16 biPlanes; |
Uint16 biBitCount; |
Uint32 biCompression; |
Uint32 biSizeImage; |
Sint32 biXPelsPerMeter; |
Sint32 biYPelsPerMeter; |
Uint32 biClrUsed; |
Uint32 biClrImportant; |
/* Make sure we have somewhere to save */ |
surface = NULL; |
if ( dst ) { |
if ( saveme->format->palette ) { |
if ( saveme->format->BitsPerPixel == 8 ) { |
surface = saveme; |
} else { |
SDL_SetError("%d bpp BMP files not supported", |
saveme->format->BitsPerPixel); |
} |
} |
else if ( (saveme->format->BitsPerPixel == 24) && |
#if SDL_BYTEORDER == SDL_LIL_ENDIAN |
(saveme->format->Rmask == 0x00FF0000) && |
(saveme->format->Gmask == 0x0000FF00) && |
(saveme->format->Bmask == 0x000000FF) |
#else |
(saveme->format->Rmask == 0x000000FF) && |
(saveme->format->Gmask == 0x0000FF00) && |
(saveme->format->Bmask == 0x00FF0000) |
#endif |
) { |
surface = saveme; |
} else { |
SDL_Rect bounds; |
/* Convert to 24 bits per pixel */ |
surface = SDL_CreateRGBSurface(SDL_SWSURFACE, |
saveme->w, saveme->h, 24, |
#if SDL_BYTEORDER == SDL_LIL_ENDIAN |
0x00FF0000, 0x0000FF00, 0x000000FF, |
#else |
0x000000FF, 0x0000FF00, 0x00FF0000, |
#endif |
0); |
if ( surface != NULL ) { |
bounds.x = 0; |
bounds.y = 0; |
bounds.w = saveme->w; |
bounds.h = saveme->h; |
if ( SDL_LowerBlit(saveme, &bounds, surface, |
&bounds) < 0 ) { |
SDL_FreeSurface(surface); |
SDL_SetError( |
"Couldn't convert image to 24 bpp"); |
surface = NULL; |
} |
} |
} |
} |
if ( surface && (SDL_LockSurface(surface) == 0) ) { |
/* Set the BMP file header values */ |
bfSize = 0; /* We'll write this when we're done */ |
bfReserved1 = 0; |
bfReserved2 = 0; |
bfOffBits = 0; /* We'll write this when we're done */ |
/* Write the BMP file header values */ |
fp_offset = SDL_RWtell(dst); |
SDL_ClearError(); |
SDL_RWwrite(dst, magic, 2, 1); |
SDL_WriteLE32(dst, bfSize); |
SDL_WriteLE16(dst, bfReserved1); |
SDL_WriteLE16(dst, bfReserved2); |
SDL_WriteLE32(dst, bfOffBits); |
/* Set the BMP info values */ |
biSize = 40; |
biWidth = surface->w; |
biHeight = surface->h; |
biPlanes = 1; |
biBitCount = surface->format->BitsPerPixel; |
biCompression = BI_RGB; |
biSizeImage = surface->h*surface->pitch; |
biXPelsPerMeter = 0; |
biYPelsPerMeter = 0; |
if ( surface->format->palette ) { |
biClrUsed = surface->format->palette->ncolors; |
} else { |
biClrUsed = 0; |
} |
biClrImportant = 0; |
/* Write the BMP info values */ |
SDL_WriteLE32(dst, biSize); |
SDL_WriteLE32(dst, biWidth); |
SDL_WriteLE32(dst, biHeight); |
SDL_WriteLE16(dst, biPlanes); |
SDL_WriteLE16(dst, biBitCount); |
SDL_WriteLE32(dst, biCompression); |
SDL_WriteLE32(dst, biSizeImage); |
SDL_WriteLE32(dst, biXPelsPerMeter); |
SDL_WriteLE32(dst, biYPelsPerMeter); |
SDL_WriteLE32(dst, biClrUsed); |
SDL_WriteLE32(dst, biClrImportant); |
/* Write the palette (in BGR color order) */ |
if ( surface->format->palette ) { |
SDL_Color *colors; |
int ncolors; |
colors = surface->format->palette->colors; |
ncolors = surface->format->palette->ncolors; |
for ( i=0; i<ncolors; ++i ) { |
SDL_RWwrite(dst, &colors[i].b, 1, 1); |
SDL_RWwrite(dst, &colors[i].g, 1, 1); |
SDL_RWwrite(dst, &colors[i].r, 1, 1); |
SDL_RWwrite(dst, &colors[i].unused, 1, 1); |
} |
} |
/* Write the bitmap offset */ |
bfOffBits = SDL_RWtell(dst)-fp_offset; |
if ( SDL_RWseek(dst, fp_offset+10, SEEK_SET) < 0 ) { |
SDL_Error(SDL_EFSEEK); |
} |
SDL_WriteLE32(dst, bfOffBits); |
if ( SDL_RWseek(dst, fp_offset+bfOffBits, SEEK_SET) < 0 ) { |
SDL_Error(SDL_EFSEEK); |
} |
/* Write the bitmap image upside down */ |
bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch); |
pad = ((surface->pitch%4) ? (4-(surface->pitch%4)) : 0); |
while ( bits > (Uint8 *)surface->pixels ) { |
bits -= surface->pitch; |
if ( SDL_RWwrite(dst, bits, 1, surface->pitch) |
!= surface->pitch) { |
SDL_Error(SDL_EFWRITE); |
break; |
} |
if ( pad ) { |
const Uint8 padbyte = 0; |
for ( i=0; i<pad; ++i ) { |
SDL_RWwrite(dst, &padbyte, 1, 1); |
} |
} |
} |
/* Write the BMP file size */ |
bfSize = SDL_RWtell(dst)-fp_offset; |
if ( SDL_RWseek(dst, fp_offset+2, SEEK_SET) < 0 ) { |
SDL_Error(SDL_EFSEEK); |
} |
SDL_WriteLE32(dst, bfSize); |
if ( SDL_RWseek(dst, fp_offset+bfSize, SEEK_SET) < 0 ) { |
SDL_Error(SDL_EFSEEK); |
} |
/* Close it up.. */ |
SDL_UnlockSurface(surface); |
if ( surface != saveme ) { |
SDL_FreeSurface(surface); |
} |
} |
if ( freedst && dst ) { |
SDL_RWclose(dst); |
} |
return((strcmp(SDL_GetError(), "") == 0) ? 0 : -1); |
} |
#endif /* ENABLE_FILE */ |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_cursor.c |
---|
0,0 → 1,742 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* General cursor handling code for SDL */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "SDL_mutex.h" |
#include "SDL_error.h" |
#include "SDL_video.h" |
#include "SDL_mouse.h" |
#include "SDL_blit.h" |
#include "SDL_events_c.h" |
#include "SDL_sysvideo.h" |
#include "SDL_sysevents.h" |
#include "SDL_cursor_c.h" |
#include "SDL_pixels_c.h" |
#include "default_cursor.h" |
/* These are static for our cursor handling code */ |
volatile int SDL_cursorstate = 0; |
SDL_Cursor *SDL_cursor = NULL; |
static SDL_Cursor *SDL_defcursor = NULL; |
SDL_mutex *SDL_cursorlock = NULL; |
/* Public functions */ |
void SDL_CursorQuit(void) |
{ |
if ( SDL_cursor != NULL ) { |
SDL_Cursor *cursor; |
SDL_cursorstate &= ~CURSOR_VISIBLE; |
if ( SDL_cursor != SDL_defcursor ) { |
SDL_FreeCursor(SDL_cursor); |
} |
SDL_cursor = NULL; |
if ( SDL_defcursor != NULL ) { |
cursor = SDL_defcursor; |
SDL_defcursor = NULL; |
SDL_FreeCursor(cursor); |
} |
} |
if ( SDL_cursorlock != NULL ) { |
SDL_DestroyMutex(SDL_cursorlock); |
SDL_cursorlock = NULL; |
} |
} |
int SDL_CursorInit(Uint32 multithreaded) |
{ |
/* We don't have mouse focus, and the cursor isn't drawn yet */ |
SDL_cursorstate = CURSOR_VISIBLE; |
/* Create the default cursor */ |
if ( SDL_defcursor == NULL ) { |
SDL_defcursor = SDL_CreateCursor(default_cdata, default_cmask, |
DEFAULT_CWIDTH, DEFAULT_CHEIGHT, |
DEFAULT_CHOTX, DEFAULT_CHOTY); |
SDL_SetCursor(SDL_defcursor); |
} |
/* Create a lock if necessary */ |
if ( multithreaded ) { |
SDL_cursorlock = SDL_CreateMutex(); |
} |
/* That's it! */ |
return(0); |
} |
/* Multi-thread support for cursors */ |
#ifndef SDL_LockCursor |
void SDL_LockCursor(void) |
{ |
if ( SDL_cursorlock ) { |
SDL_mutexP(SDL_cursorlock); |
} |
} |
#endif |
#ifndef SDL_UnlockCursor |
void SDL_UnlockCursor(void) |
{ |
if ( SDL_cursorlock ) { |
SDL_mutexV(SDL_cursorlock); |
} |
} |
#endif |
/* Software cursor drawing support */ |
SDL_Cursor * SDL_CreateCursor (Uint8 *data, Uint8 *mask, |
int w, int h, int hot_x, int hot_y) |
{ |
SDL_VideoDevice *video = current_video; |
int savelen; |
int i; |
SDL_Cursor *cursor; |
/* Make sure the width is a multiple of 8 */ |
w = ((w+7)&~7); |
/* Sanity check the hot spot */ |
if ( (hot_x < 0) || (hot_y < 0) || (hot_x >= w) || (hot_y >= h) ) { |
SDL_SetError("Cursor hot spot doesn't lie within cursor"); |
return(NULL); |
} |
/* Allocate memory for the cursor */ |
cursor = (SDL_Cursor *)malloc(sizeof *cursor); |
if ( cursor == NULL ) { |
SDL_OutOfMemory(); |
return(NULL); |
} |
savelen = (w*4)*h; |
cursor->area.x = 0; |
cursor->area.y = 0; |
cursor->area.w = w; |
cursor->area.h = h; |
cursor->hot_x = hot_x; |
cursor->hot_y = hot_y; |
cursor->data = (Uint8 *)malloc((w/8)*h*2); |
cursor->mask = cursor->data+((w/8)*h); |
cursor->save[0] = (Uint8 *)malloc(savelen*2); |
cursor->save[1] = cursor->save[0] + savelen; |
cursor->wm_cursor = NULL; |
if ( ! cursor->data || ! cursor->save[0] ) { |
SDL_FreeCursor(cursor); |
SDL_OutOfMemory(); |
return(NULL); |
} |
for ( i=((w/8)*h)-1; i>=0; --i ) { |
cursor->data[i] = data[i]; |
cursor->mask[i] = mask[i] | data[i]; |
} |
memset(cursor->save[0], 0, savelen*2); |
/* If the window manager gives us a good cursor, we're done! */ |
if ( video->CreateWMCursor ) { |
cursor->wm_cursor = video->CreateWMCursor(video, data, mask, |
w, h, hot_x, hot_y); |
} else { |
cursor->wm_cursor = NULL; |
} |
return(cursor); |
} |
/* SDL_SetCursor(NULL) can be used to force the cursor redraw, |
if this is desired for any reason. This is used when setting |
the video mode and when the SDL window gains the mouse focus. |
*/ |
void SDL_SetCursor (SDL_Cursor *cursor) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
/* Make sure that the video subsystem has been initialized */ |
if ( ! video ) { |
return; |
} |
/* Prevent the event thread from moving the mouse */ |
SDL_LockCursor(); |
/* Set the new cursor */ |
if ( cursor && (cursor != SDL_cursor) ) { |
/* Erase the current mouse position */ |
if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { |
SDL_EraseCursor(SDL_VideoSurface); |
} else if ( video->MoveWMCursor ) { |
/* If the video driver is moving the cursor directly, |
it needs to hide the old cursor before (possibly) |
showing the new one. (But don't erase NULL cursor) |
*/ |
if ( SDL_cursor ) { |
video->ShowWMCursor(this, NULL); |
} |
} |
SDL_cursor = cursor; |
} |
/* Draw the new mouse cursor */ |
if ( SDL_cursor && (SDL_cursorstate&CURSOR_VISIBLE) ) { |
/* Use window manager cursor if possible */ |
if ( SDL_cursor->wm_cursor && |
video->ShowWMCursor(this, SDL_cursor->wm_cursor) ) |
SDL_cursorstate &= ~CURSOR_USINGSW; |
else { |
SDL_cursorstate |= CURSOR_USINGSW; |
if ( video->ShowWMCursor ) { |
video->ShowWMCursor(this, NULL); |
} |
{ int x, y; |
SDL_GetMouseState(&x, &y); |
SDL_cursor->area.x = (x - SDL_cursor->hot_x); |
SDL_cursor->area.y = (y - SDL_cursor->hot_y); |
} |
SDL_DrawCursor(SDL_VideoSurface); |
} |
} else { |
/* Erase window manager mouse (cursor not visible) */ |
if ( SDL_cursor && (SDL_cursorstate & CURSOR_USINGSW) ) { |
SDL_EraseCursor(SDL_VideoSurface); |
} else { |
if ( video ) { |
video->ShowWMCursor(this, NULL); |
} |
} |
} |
SDL_UnlockCursor(); |
} |
SDL_Cursor * SDL_GetCursor (void) |
{ |
return(SDL_cursor); |
} |
void SDL_FreeCursor (SDL_Cursor *cursor) |
{ |
if ( cursor ) { |
if ( cursor == SDL_cursor ) { |
SDL_SetCursor(SDL_defcursor); |
} |
if ( cursor != SDL_defcursor ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
if ( cursor->data ) { |
free(cursor->data); |
} |
if ( cursor->save[0] ) { |
free(cursor->save[0]); |
} |
if ( video && cursor->wm_cursor ) { |
video->FreeWMCursor(this, cursor->wm_cursor); |
} |
free(cursor); |
} |
} |
} |
int SDL_ShowCursor (int toggle) |
{ |
int showing; |
showing = (SDL_cursorstate & CURSOR_VISIBLE); |
if ( toggle >= 0 ) { |
SDL_LockCursor(); |
if ( toggle ) { |
SDL_cursorstate |= CURSOR_VISIBLE; |
} else { |
SDL_cursorstate &= ~CURSOR_VISIBLE; |
} |
SDL_UnlockCursor(); |
if ( (SDL_cursorstate & CURSOR_VISIBLE) != showing ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
SDL_SetCursor(NULL); |
if ( video && video->CheckMouseMode ) { |
video->CheckMouseMode(this); |
} |
} |
} else { |
/* Query current state */ ; |
} |
return(showing ? 1 : 0); |
} |
void SDL_WarpMouse (Uint16 x, Uint16 y) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
/* This generates a mouse motion event */ |
if ( video->WarpWMCursor ) { |
video->WarpWMCursor(this, x, y); |
} else { |
x += (this->screen->offset % this->screen->pitch) / |
this->screen->format->BytesPerPixel; |
y += (this->screen->offset / this->screen->pitch); |
SDL_PrivateMouseMotion(0, 0, x, y); |
} |
} |
void SDL_MoveCursor(int x, int y) |
{ |
SDL_VideoDevice *video = current_video; |
/* Erase and update the current mouse position */ |
if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { |
/* Erase and redraw mouse cursor in new position */ |
SDL_LockCursor(); |
SDL_EraseCursor(SDL_VideoSurface); |
SDL_cursor->area.x = (x - SDL_cursor->hot_x); |
SDL_cursor->area.y = (y - SDL_cursor->hot_y); |
SDL_DrawCursor(SDL_VideoSurface); |
SDL_UnlockCursor(); |
} else if ( video->MoveWMCursor ) { |
video->MoveWMCursor(video, x, y); |
} |
} |
/* Keep track of the current cursor colors */ |
static int palette_changed = 1; |
static Uint32 pixels8[2]; |
void SDL_CursorPaletteChanged(void) |
{ |
palette_changed = 1; |
} |
void SDL_MouseRect(SDL_Rect *area) |
{ |
int clip_diff; |
*area = SDL_cursor->area; |
if ( area->x < 0 ) { |
area->w += area->x; |
area->x = 0; |
} |
if ( area->y < 0 ) { |
area->h += area->y; |
area->y = 0; |
} |
clip_diff = (area->x+area->w)-SDL_VideoSurface->w; |
if ( clip_diff > 0 ) { |
area->w = area->w < clip_diff ? 0 : area->w-clip_diff; |
} |
clip_diff = (area->y+area->h)-SDL_VideoSurface->h; |
if ( clip_diff > 0 ) { |
area->h = area->h < clip_diff ? 0 : area->h-clip_diff; |
} |
} |
static void SDL_DrawCursorFast(SDL_Surface *screen, SDL_Rect *area) |
{ |
const Uint32 pixels[2] = { 0xFFFFFFFF, 0x00000000 }; |
int i, w, h; |
Uint8 *data, datab; |
Uint8 *mask, maskb; |
data = SDL_cursor->data + area->y * SDL_cursor->area.w/8; |
mask = SDL_cursor->mask + area->y * SDL_cursor->area.w/8; |
switch (screen->format->BytesPerPixel) { |
case 1: { |
Uint8 *dst; |
int dstskip; |
if ( palette_changed ) { |
pixels8[0] = SDL_MapRGB(screen->format, 255, 255, 255); |
pixels8[1] = SDL_MapRGB(screen->format, 0, 0, 0); |
palette_changed = 0; |
} |
dst = (Uint8 *)screen->pixels + |
(SDL_cursor->area.y+area->y)*screen->pitch + |
SDL_cursor->area.x; |
dstskip = screen->pitch-area->w; |
for ( h=area->h; h; h-- ) { |
for ( w=area->w/8; w; w-- ) { |
maskb = *mask++; |
datab = *data++; |
for ( i=0; i<8; ++i ) { |
if ( maskb & 0x80 ) { |
*dst = pixels8[datab>>7]; |
} |
maskb <<= 1; |
datab <<= 1; |
dst++; |
} |
} |
dst += dstskip; |
} |
} |
break; |
case 2: { |
Uint16 *dst; |
int dstskip; |
dst = (Uint16 *)screen->pixels + |
(SDL_cursor->area.y+area->y)*screen->pitch/2 + |
SDL_cursor->area.x; |
dstskip = (screen->pitch/2)-area->w; |
for ( h=area->h; h; h-- ) { |
for ( w=area->w/8; w; w-- ) { |
maskb = *mask++; |
datab = *data++; |
for ( i=0; i<8; ++i ) { |
if ( maskb & 0x80 ) { |
*dst = pixels[datab>>7]; |
} |
maskb <<= 1; |
datab <<= 1; |
dst++; |
} |
} |
dst += dstskip; |
} |
} |
break; |
case 3: { |
Uint8 *dst; |
int dstskip; |
dst = (Uint8 *)screen->pixels + |
(SDL_cursor->area.y+area->y)*screen->pitch + |
SDL_cursor->area.x*3; |
dstskip = screen->pitch-area->w*3; |
for ( h=area->h; h; h-- ) { |
for ( w=area->w/8; w; w-- ) { |
maskb = *mask++; |
datab = *data++; |
for ( i=0; i<8; ++i ) { |
if ( maskb & 0x80 ) { |
memset(dst,pixels[datab>>7],3); |
} |
maskb <<= 1; |
datab <<= 1; |
dst += 3; |
} |
} |
dst += dstskip; |
} |
} |
break; |
case 4: { |
Uint32 *dst; |
int dstskip; |
dst = (Uint32 *)screen->pixels + |
(SDL_cursor->area.y+area->y)*screen->pitch/4 + |
SDL_cursor->area.x; |
dstskip = (screen->pitch/4)-area->w; |
for ( h=area->h; h; h-- ) { |
for ( w=area->w/8; w; w-- ) { |
maskb = *mask++; |
datab = *data++; |
for ( i=0; i<8; ++i ) { |
if ( maskb & 0x80 ) { |
*dst = pixels[datab>>7]; |
} |
maskb <<= 1; |
datab <<= 1; |
dst++; |
} |
} |
dst += dstskip; |
} |
} |
break; |
} |
} |
static void SDL_DrawCursorSlow(SDL_Surface *screen, SDL_Rect *area) |
{ |
const Uint32 pixels[2] = { 0xFFFFFF, 0x000000 }; |
int h; |
int x, minx, maxx; |
Uint8 *data, datab = 0; |
Uint8 *mask, maskb = 0; |
Uint8 *dst; |
int dstbpp, dstskip; |
data = SDL_cursor->data + area->y * SDL_cursor->area.w/8; |
mask = SDL_cursor->mask + area->y * SDL_cursor->area.w/8; |
dstbpp = screen->format->BytesPerPixel; |
dst = (Uint8 *)screen->pixels + |
(SDL_cursor->area.y+area->y)*screen->pitch + |
SDL_cursor->area.x*dstbpp; |
dstskip = screen->pitch-SDL_cursor->area.w*dstbpp; |
minx = area->x; |
maxx = area->x+area->w; |
if ( screen->format->BytesPerPixel == 1 ) { |
if ( palette_changed ) { |
pixels8[0] = SDL_MapRGB(screen->format, 255, 255, 255); |
pixels8[1] = SDL_MapRGB(screen->format, 0, 0, 0); |
palette_changed = 0; |
} |
for ( h=area->h; h; h-- ) { |
for ( x=0; x<SDL_cursor->area.w; ++x ) { |
if ( (x%8) == 0 ) { |
maskb = *mask++; |
datab = *data++; |
} |
if ( (x >= minx) && (x < maxx) ) { |
if ( maskb & 0x80 ) { |
memset(dst, pixels8[datab>>7], dstbpp); |
} |
} |
maskb <<= 1; |
datab <<= 1; |
dst += dstbpp; |
} |
dst += dstskip; |
} |
} else { |
for ( h=area->h; h; h-- ) { |
for ( x=0; x<SDL_cursor->area.w; ++x ) { |
if ( (x%8) == 0 ) { |
maskb = *mask++; |
datab = *data++; |
} |
if ( (x >= minx) && (x < maxx) ) { |
if ( maskb & 0x80 ) { |
memset(dst, pixels[datab>>7], dstbpp); |
} |
} |
maskb <<= 1; |
datab <<= 1; |
dst += dstbpp; |
} |
dst += dstskip; |
} |
} |
} |
/* This handles the ugly work of converting the saved cursor background from |
the pixel format of the shadow surface to that of the video surface. |
This is only necessary when blitting from a shadow surface of a different |
pixel format than the video surface, and using a software rendered cursor. |
*/ |
static void SDL_ConvertCursorSave(SDL_Surface *screen, int w, int h) |
{ |
SDL_BlitInfo info; |
SDL_loblit RunBlit; |
/* Make sure we can steal the blit mapping */ |
if ( screen->map->dst != SDL_VideoSurface ) { |
return; |
} |
/* Set up the blit information */ |
info.s_pixels = SDL_cursor->save[1]; |
info.s_width = w; |
info.s_height = h; |
info.s_skip = 0; |
info.d_pixels = SDL_cursor->save[0]; |
info.d_width = w; |
info.d_height = h; |
info.d_skip = 0; |
info.aux_data = screen->map->sw_data->aux_data; |
info.src = screen->format; |
info.table = screen->map->table; |
info.dst = SDL_VideoSurface->format; |
RunBlit = screen->map->sw_data->blit; |
/* Run the actual software blit */ |
RunBlit(&info); |
} |
void SDL_DrawCursorNoLock(SDL_Surface *screen) |
{ |
SDL_Rect area; |
/* Get the mouse rectangle, clipped to the screen */ |
SDL_MouseRect(&area); |
if ( (area.w == 0) || (area.h == 0) ) { |
return; |
} |
/* Copy mouse background */ |
{ int w, h, screenbpp; |
Uint8 *src, *dst; |
/* Set up the copy pointers */ |
screenbpp = screen->format->BytesPerPixel; |
if ( (screen == SDL_VideoSurface) || |
FORMAT_EQUAL(screen->format, SDL_VideoSurface->format) ) { |
dst = SDL_cursor->save[0]; |
} else { |
dst = SDL_cursor->save[1]; |
} |
src = (Uint8 *)screen->pixels + area.y * screen->pitch + |
area.x * screenbpp; |
/* Perform the copy */ |
w = area.w*screenbpp; |
h = area.h; |
while ( h-- ) { |
memcpy(dst, src, w); |
dst += w; |
src += screen->pitch; |
} |
} |
/* Draw the mouse cursor */ |
area.x -= SDL_cursor->area.x; |
area.y -= SDL_cursor->area.y; |
if ( (area.x == 0) && (area.w == SDL_cursor->area.w) ) { |
SDL_DrawCursorFast(screen, &area); |
} else { |
SDL_DrawCursorSlow(screen, &area); |
} |
} |
void SDL_DrawCursor(SDL_Surface *screen) |
{ |
/* Lock the screen if necessary */ |
if ( screen == NULL ) { |
return; |
} |
if ( SDL_MUSTLOCK(screen) ) { |
if ( SDL_LockSurface(screen) < 0 ) { |
return; |
} |
} |
SDL_DrawCursorNoLock(screen); |
/* Unlock the screen and update if necessary */ |
if ( SDL_MUSTLOCK(screen) ) { |
SDL_UnlockSurface(screen); |
} |
if ( (screen == SDL_VideoSurface) && |
((screen->flags & SDL_HWSURFACE) != SDL_HWSURFACE) ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
SDL_Rect area; |
SDL_MouseRect(&area); |
/* This can be called before a video mode is set */ |
if ( video->UpdateRects ) { |
video->UpdateRects(this, 1, &area); |
} |
} |
} |
void SDL_EraseCursorNoLock(SDL_Surface *screen) |
{ |
SDL_Rect area; |
/* Get the mouse rectangle, clipped to the screen */ |
SDL_MouseRect(&area); |
if ( (area.w == 0) || (area.h == 0) ) { |
return; |
} |
/* Copy mouse background */ |
{ int w, h, screenbpp; |
Uint8 *src, *dst; |
/* Set up the copy pointers */ |
screenbpp = screen->format->BytesPerPixel; |
if ( (screen == SDL_VideoSurface) || |
FORMAT_EQUAL(screen->format, SDL_VideoSurface->format) ) { |
src = SDL_cursor->save[0]; |
} else { |
src = SDL_cursor->save[1]; |
} |
dst = (Uint8 *)screen->pixels + area.y * screen->pitch + |
area.x * screenbpp; |
/* Perform the copy */ |
w = area.w*screenbpp; |
h = area.h; |
while ( h-- ) { |
memcpy(dst, src, w); |
src += w; |
dst += screen->pitch; |
} |
/* Perform pixel conversion on cursor background */ |
if ( src > SDL_cursor->save[1] ) { |
SDL_ConvertCursorSave(screen, area.w, area.h); |
} |
} |
} |
void SDL_EraseCursor(SDL_Surface *screen) |
{ |
/* Lock the screen if necessary */ |
if ( screen == NULL ) { |
return; |
} |
if ( SDL_MUSTLOCK(screen) ) { |
if ( SDL_LockSurface(screen) < 0 ) { |
return; |
} |
} |
SDL_EraseCursorNoLock(screen); |
/* Unlock the screen and update if necessary */ |
if ( SDL_MUSTLOCK(screen) ) { |
SDL_UnlockSurface(screen); |
} |
if ( (screen == SDL_VideoSurface) && |
((screen->flags & SDL_HWSURFACE) != SDL_HWSURFACE) ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
SDL_Rect area; |
SDL_MouseRect(&area); |
if ( video->UpdateRects ) { |
video->UpdateRects(this, 1, &area); |
} |
} |
} |
/* Reset the cursor on video mode change |
FIXME: Keep track of all cursors, and reset them all. |
*/ |
void SDL_ResetCursor(void) |
{ |
int savelen; |
if ( SDL_cursor ) { |
savelen = SDL_cursor->area.w*4*SDL_cursor->area.h; |
SDL_cursor->area.x = 0; |
SDL_cursor->area.y = 0; |
memset(SDL_cursor->save[0], 0, savelen); |
} |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_cursor_c.h |
---|
0,0 → 1,77 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_cursor_c.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; |
#endif |
/* Useful variables and functions from SDL_cursor.c */ |
#include "SDL_mouse.h" |
extern int SDL_CursorInit(Uint32 flags); |
extern void SDL_CursorPaletteChanged(void); |
extern void SDL_DrawCursor(SDL_Surface *screen); |
extern void SDL_DrawCursorNoLock(SDL_Surface *screen); |
extern void SDL_EraseCursor(SDL_Surface *screen); |
extern void SDL_EraseCursorNoLock(SDL_Surface *screen); |
extern void SDL_UpdateCursor(SDL_Surface *screen); |
extern void SDL_ResetCursor(void); |
extern void SDL_MoveCursor(int x, int y); |
extern void SDL_CursorQuit(void); |
#define INLINE_MOUSELOCK |
#ifdef INLINE_MOUSELOCK |
/* Inline (macro) versions of the mouse lock functions */ |
#include "SDL_mutex.h" |
extern SDL_mutex *SDL_cursorlock; |
#define SDL_LockCursor() \ |
do { \ |
if ( SDL_cursorlock ) { \ |
SDL_mutexP(SDL_cursorlock); \ |
} \ |
} while ( 0 ) |
#define SDL_UnlockCursor() \ |
do { \ |
if ( SDL_cursorlock ) { \ |
SDL_mutexV(SDL_cursorlock); \ |
} \ |
} while ( 0 ) |
#else |
extern void SDL_LockCursor(void); |
extern void SDL_UnlockCursor(void); |
#endif /* INLINE_MOUSELOCK */ |
/* Only for low-level mouse cursor drawing */ |
extern SDL_Cursor *SDL_cursor; |
extern void SDL_MouseRect(SDL_Rect *area); |
/* State definitions for the SDL cursor */ |
#define CURSOR_VISIBLE 0x01 |
#define CURSOR_USINGSW 0x10 |
#define SHOULD_DRAWCURSOR(X) \ |
(((X)&(CURSOR_VISIBLE|CURSOR_USINGSW)) == \ |
(CURSOR_VISIBLE|CURSOR_USINGSW)) |
extern volatile int SDL_cursorstate; |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_gamma.c |
---|
0,0 → 1,238 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* Gamma correction support */ |
#define USE_MATH_H /* Used for calculating gamma ramps */ |
#ifdef USE_MATH_H |
#include <math.h> |
#endif |
#include <stdlib.h> |
#include "SDL_error.h" |
#include "SDL_sysvideo.h" |
#ifdef USE_MATH_H |
static void CalculateGammaRamp(float gamma, Uint16 *ramp) |
{ |
int i; |
/* 0.0 gamma is all black */ |
if ( gamma <= 0.0 ) { |
for ( i=0; i<256; ++i ) { |
ramp[i] = 0; |
} |
return; |
} else |
/* 1.0 gamma is identity */ |
if ( gamma == 1.0 ) { |
for ( i=0; i<256; ++i ) { |
ramp[i] = (i << 8) | i; |
} |
return; |
} else |
/* Calculate a real gamma ramp */ |
{ int value; |
gamma = 1.0f / gamma; |
for ( i=0; i<256; ++i ) { |
value = (int)(pow((double)i/256.0, gamma)*65535.0+0.5); |
if ( value > 65535 ) { |
value = 65535; |
} |
ramp[i] = (Uint16)value; |
} |
} |
} |
static void CalculateGammaFromRamp(float *gamma, Uint16 *ramp) |
{ |
/* The following is adapted from a post by Garrett Bass on OpenGL |
Gamedev list, March 4, 2000. |
*/ |
float sum = 0.0; |
int i, count = 0; |
*gamma = 1.0; |
for ( i = 1; i < 256; ++i ) { |
if ( (ramp[i] != 0) && (ramp[i] != 65535) ) { |
double B = (double)i / 256.0; |
double A = ramp[i] / 65535.0; |
sum += (float) ( log(A) / log(B) ); |
count++; |
} |
} |
if ( count && sum ) { |
*gamma = 1.0f / (sum / count); |
} |
} |
#endif /* USE_MATH_H */ |
int SDL_SetGamma(float red, float green, float blue) |
{ |
int succeeded; |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
succeeded = -1; |
#ifdef USE_MATH_H |
/* Prefer using SetGammaRamp(), as it's more flexible */ |
{ |
Uint16 ramp[3][256]; |
CalculateGammaRamp(red, ramp[0]); |
CalculateGammaRamp(green, ramp[1]); |
CalculateGammaRamp(blue, ramp[2]); |
succeeded = SDL_SetGammaRamp(ramp[0], ramp[1], ramp[2]); |
} |
#else |
SDL_SetError("Gamma correction not supported"); |
#endif |
if ( (succeeded < 0) && video->SetGamma ) { |
SDL_ClearError(); |
succeeded = video->SetGamma(this, red, green, blue); |
} |
return succeeded; |
} |
/* Calculating the gamma by integrating the gamma ramps isn't exact, |
so this function isn't officially supported. |
*/ |
int SDL_GetGamma(float *red, float *green, float *blue) |
{ |
int succeeded; |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
succeeded = -1; |
#ifdef USE_MATH_H |
/* Prefer using GetGammaRamp(), as it's more flexible */ |
{ |
Uint16 ramp[3][256]; |
succeeded = SDL_GetGammaRamp(ramp[0], ramp[1], ramp[2]); |
if ( succeeded >= 0 ) { |
CalculateGammaFromRamp(red, ramp[0]); |
CalculateGammaFromRamp(green, ramp[1]); |
CalculateGammaFromRamp(blue, ramp[2]); |
} |
} |
#else |
SDL_SetError("Gamma correction not supported"); |
#endif |
if ( (succeeded < 0) && video->GetGamma ) { |
SDL_ClearError(); |
succeeded = video->GetGamma(this, red, green, blue); |
} |
return succeeded; |
} |
int SDL_SetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue) |
{ |
int succeeded; |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
SDL_Surface *screen = SDL_PublicSurface; |
/* Verify the screen parameter */ |
if ( !screen ) { |
SDL_SetError("No video mode has been set"); |
return -1; |
} |
/* Lazily allocate the gamma tables */ |
if ( ! video->gamma ) { |
SDL_GetGammaRamp(0, 0, 0); |
} |
/* Fill the gamma table with the new values */ |
if ( red ) { |
memcpy(&video->gamma[0*256], red, 256*sizeof(*video->gamma)); |
} |
if ( green ) { |
memcpy(&video->gamma[1*256], green, 256*sizeof(*video->gamma)); |
} |
if ( blue ) { |
memcpy(&video->gamma[2*256], blue, 256*sizeof(*video->gamma)); |
} |
/* Gamma correction always possible on split palettes */ |
if ( (screen->flags & SDL_HWPALETTE) == SDL_HWPALETTE ) { |
SDL_Palette *pal = screen->format->palette; |
/* If physical palette has been set independently, use it */ |
if(video->physpal) |
pal = video->physpal; |
SDL_SetPalette(screen, SDL_PHYSPAL, |
pal->colors, 0, pal->ncolors); |
return 0; |
} |
/* Try to set the gamma ramp in the driver */ |
succeeded = -1; |
if ( video->SetGammaRamp ) { |
succeeded = video->SetGammaRamp(this, video->gamma); |
} else { |
SDL_SetError("Gamma ramp manipulation not supported"); |
} |
return succeeded; |
} |
int SDL_GetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
/* Lazily allocate the gamma table */ |
if ( ! video->gamma ) { |
video->gamma = malloc(3*256*sizeof(*video->gamma)); |
if ( ! video->gamma ) { |
SDL_OutOfMemory(); |
return -1; |
} |
if ( video->GetGammaRamp ) { |
/* Get the real hardware gamma */ |
video->GetGammaRamp(this, video->gamma); |
} else { |
/* Assume an identity gamma */ |
int i; |
for ( i=0; i<256; ++i ) { |
video->gamma[0*256+i] = (i << 8) | i; |
video->gamma[1*256+i] = (i << 8) | i; |
video->gamma[2*256+i] = (i << 8) | i; |
} |
} |
} |
/* Just copy from our internal table */ |
if ( red ) { |
memcpy(red, &video->gamma[0*256], 256*sizeof(*red)); |
} |
if ( green ) { |
memcpy(green, &video->gamma[1*256], 256*sizeof(*green)); |
} |
if ( blue ) { |
memcpy(blue, &video->gamma[2*256], 256*sizeof(*blue)); |
} |
return 0; |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_glfuncs.h |
---|
0,0 → 1,341 |
/* list of OpenGL functions sorted alphabetically |
If you need to use a GL function from the SDL video subsystem, |
change it's entry from SDL_PROC_UNUSED to SDL_PROC and rebuild. |
*/ |
#define SDL_PROC_UNUSED(ret,func,params) |
SDL_PROC_UNUSED(void,glAccum,(GLenum,GLfloat)) |
SDL_PROC_UNUSED(void,glAlphaFunc,(GLenum,GLclampf)) |
SDL_PROC_UNUSED(GLboolean,glAreTexturesResident,(GLsizei,const GLuint*,GLboolean*)) |
SDL_PROC_UNUSED(void,glArrayElement,(GLint)) |
SDL_PROC(void,glBegin,(GLenum)) |
SDL_PROC(void,glBindTexture,(GLenum,GLuint)) |
SDL_PROC_UNUSED(void,glBitmap,(GLsizei,GLsizei,GLfloat,GLfloat,GLfloat,GLfloat,const GLubyte*)) |
SDL_PROC(void,glBlendFunc,(GLenum,GLenum)) |
SDL_PROC_UNUSED(void,glCallList,(GLuint)) |
SDL_PROC_UNUSED(void,glCallLists,(GLsizei,GLenum,const GLvoid*)) |
SDL_PROC_UNUSED(void,glClear,(GLbitfield)) |
SDL_PROC_UNUSED(void,glClearAccum,(GLfloat,GLfloat,GLfloat,GLfloat)) |
SDL_PROC_UNUSED(void,glClearColor,(GLclampf,GLclampf,GLclampf,GLclampf)) |
SDL_PROC_UNUSED(void,glClearDepth,(GLclampd)) |
SDL_PROC_UNUSED(void,glClearIndex,(GLfloat)) |
SDL_PROC_UNUSED(void,glClearStencil,(GLint)) |
SDL_PROC_UNUSED(void,glClipPlane,(GLenum,const GLdouble*)) |
SDL_PROC_UNUSED(void,glColor3b,(GLbyte,GLbyte,GLbyte)) |
SDL_PROC_UNUSED(void,glColor3bv,(const GLbyte*)) |
SDL_PROC_UNUSED(void,glColor3d,(GLdouble,GLdouble,GLdouble)) |
SDL_PROC_UNUSED(void,glColor3dv,(const GLdouble*)) |
SDL_PROC_UNUSED(void,glColor3f,(GLfloat,GLfloat,GLfloat)) |
SDL_PROC_UNUSED(void,glColor3fv,(const GLfloat*)) |
SDL_PROC_UNUSED(void,glColor3i,(GLint,GLint,GLint)) |
SDL_PROC_UNUSED(void,glColor3iv,(const GLint*)) |
SDL_PROC_UNUSED(void,glColor3s,(GLshort,GLshort,GLshort)) |
SDL_PROC_UNUSED(void,glColor3sv,(const GLshort*)) |
SDL_PROC_UNUSED(void,glColor3ub,(GLubyte,GLubyte,GLubyte)) |
SDL_PROC_UNUSED(void,glColor3ubv,(const GLubyte*)) |
SDL_PROC_UNUSED(void,glColor3ui,(GLuint,GLuint,GLuint)) |
SDL_PROC_UNUSED(void,glColor3uiv,(const GLuint*)) |
SDL_PROC_UNUSED(void,glColor3us,(GLushort,GLushort,GLushort)) |
SDL_PROC_UNUSED(void,glColor3usv,(const GLushort*)) |
SDL_PROC_UNUSED(void,glColor4b,(GLbyte,GLbyte,GLbyte,GLbyte)) |
SDL_PROC_UNUSED(void,glColor4bv,(const GLbyte*)) |
SDL_PROC_UNUSED(void,glColor4d,(GLdouble,GLdouble,GLdouble,GLdouble)) |
SDL_PROC_UNUSED(void,glColor4dv,(const GLdouble*)) |
SDL_PROC(void,glColor4f,(GLfloat,GLfloat,GLfloat,GLfloat)) |
SDL_PROC_UNUSED(void,glColor4fv,(const GLfloat*)) |
SDL_PROC_UNUSED(void,glColor4i,(GLint,GLint,GLint,GLint)) |
SDL_PROC_UNUSED(void,glColor4iv,(const GLint*)) |
SDL_PROC_UNUSED(void,glColor4s,(GLshort,GLshort,GLshort,GLshort)) |
SDL_PROC_UNUSED(void,glColor4sv,(const GLshort*)) |
SDL_PROC_UNUSED(void,glColor4ub,(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)) |
SDL_PROC_UNUSED(void,glColor4ubv,(const GLubyte *v)) |
SDL_PROC_UNUSED(void,glColor4ui,(GLuint red, GLuint green, GLuint blue, GLuint alpha)) |
SDL_PROC_UNUSED(void,glColor4uiv,(const GLuint *v)) |
SDL_PROC_UNUSED(void,glColor4us,(GLushort red, GLushort green, GLushort blue, GLushort alpha)) |
SDL_PROC_UNUSED(void,glColor4usv,(const GLushort *v)) |
SDL_PROC_UNUSED(void,glColorMask,(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) |
SDL_PROC_UNUSED(void,glColorMaterial,(GLenum face, GLenum mode)) |
SDL_PROC_UNUSED(void,glColorPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) |
SDL_PROC_UNUSED(void,glCopyPixels,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)) |
SDL_PROC(void,glCopyTexImage1D,(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)) |
SDL_PROC_UNUSED(void,glCopyTexImage2D,(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)) |
SDL_PROC_UNUSED(void,glCopyTexSubImage1D,(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)) |
SDL_PROC_UNUSED(void,glCopyTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)) |
SDL_PROC_UNUSED(void,glCullFace,(GLenum mode)) |
SDL_PROC_UNUSED(void,glDeleteLists,(GLuint list, GLsizei range)) |
SDL_PROC_UNUSED(void,glDeleteTextures,(GLsizei n, const GLuint *textures)) |
SDL_PROC_UNUSED(void,glDepthFunc,(GLenum func)) |
SDL_PROC_UNUSED(void,glDepthMask,(GLboolean flag)) |
SDL_PROC_UNUSED(void,glDepthRange,(GLclampd zNear, GLclampd zFar)) |
SDL_PROC(void,glDisable,(GLenum cap)) |
SDL_PROC_UNUSED(void,glDisableClientState,(GLenum array)) |
SDL_PROC_UNUSED(void,glDrawArrays,(GLenum mode, GLint first, GLsizei count)) |
SDL_PROC_UNUSED(void,glDrawBuffer,(GLenum mode)) |
SDL_PROC_UNUSED(void,glDrawElements,(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)) |
SDL_PROC_UNUSED(void,glDrawPixels,(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)) |
SDL_PROC_UNUSED(void,glEdgeFlag,(GLboolean flag)) |
SDL_PROC_UNUSED(void,glEdgeFlagPointer,(GLsizei stride, const GLvoid *pointer)) |
SDL_PROC_UNUSED(void,glEdgeFlagv,(const GLboolean *flag)) |
SDL_PROC(void,glEnable,(GLenum cap)) |
SDL_PROC_UNUSED(void,glEnableClientState,(GLenum array)) |
SDL_PROC(void,glEnd,(void)) |
SDL_PROC_UNUSED(void,glEndList,(void)) |
SDL_PROC_UNUSED(void,glEvalCoord1d,(GLdouble u)) |
SDL_PROC_UNUSED(void,glEvalCoord1dv,(const GLdouble *u)) |
SDL_PROC_UNUSED(void,glEvalCoord1f,(GLfloat u)) |
SDL_PROC_UNUSED(void,glEvalCoord1fv,(const GLfloat *u)) |
SDL_PROC_UNUSED(void,glEvalCoord2d,(GLdouble u, GLdouble v)) |
SDL_PROC_UNUSED(void,glEvalCoord2dv,(const GLdouble *u)) |
SDL_PROC_UNUSED(void,glEvalCoord2f,(GLfloat u, GLfloat v)) |
SDL_PROC_UNUSED(void,glEvalCoord2fv,(const GLfloat *u)) |
SDL_PROC_UNUSED(void,glEvalMesh1,(GLenum mode, GLint i1, GLint i2)) |
SDL_PROC_UNUSED(void,glEvalMesh2,(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)) |
SDL_PROC_UNUSED(void,glEvalPoint1,(GLint i)) |
SDL_PROC_UNUSED(void,glEvalPoint2,(GLint i, GLint j)) |
SDL_PROC_UNUSED(void,glFeedbackBuffer,(GLsizei size, GLenum type, GLfloat *buffer)) |
SDL_PROC_UNUSED(void,glFinish,(void)) |
SDL_PROC(void,glFlush,(void)) |
SDL_PROC_UNUSED(void,glFogf,(GLenum pname, GLfloat param)) |
SDL_PROC_UNUSED(void,glFogfv,(GLenum pname, const GLfloat *params)) |
SDL_PROC_UNUSED(void,glFogi,(GLenum pname, GLint param)) |
SDL_PROC_UNUSED(void,glFogiv,(GLenum pname, const GLint *params)) |
SDL_PROC_UNUSED(void,glFrontFace,(GLenum mode)) |
SDL_PROC_UNUSED(void,glFrustum,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)) |
SDL_PROC_UNUSED(GLuint,glGenLists,(GLsizei range)) |
SDL_PROC(void,glGenTextures,(GLsizei n, GLuint *textures)) |
SDL_PROC_UNUSED(void,glGetBooleanv,(GLenum pname, GLboolean *params)) |
SDL_PROC_UNUSED(void,glGetClipPlane,(GLenum plane, GLdouble *equation)) |
SDL_PROC_UNUSED(void,glGetDoublev,(GLenum pname, GLdouble *params)) |
SDL_PROC_UNUSED(GLenum,glGetError,(void)) |
SDL_PROC_UNUSED(void,glGetFloatv,(GLenum pname, GLfloat *params)) |
SDL_PROC_UNUSED(void,glGetIntegerv,(GLenum pname, GLint *params)) |
SDL_PROC_UNUSED(void,glGetLightfv,(GLenum light, GLenum pname, GLfloat *params)) |
SDL_PROC_UNUSED(void,glGetLightiv,(GLenum light, GLenum pname, GLint *params)) |
SDL_PROC_UNUSED(void,glGetMapdv,(GLenum target, GLenum query, GLdouble *v)) |
SDL_PROC_UNUSED(void,glGetMapfv,(GLenum target, GLenum query, GLfloat *v)) |
SDL_PROC_UNUSED(void,glGetMapiv,(GLenum target, GLenum query, GLint *v)) |
SDL_PROC_UNUSED(void,glGetMaterialfv,(GLenum face, GLenum pname, GLfloat *params)) |
SDL_PROC_UNUSED(void,glGetMaterialiv,(GLenum face, GLenum pname, GLint *params)) |
SDL_PROC_UNUSED(void,glGetPixelMapfv,(GLenum map, GLfloat *values)) |
SDL_PROC_UNUSED(void,glGetPixelMapuiv,(GLenum map, GLuint *values)) |
SDL_PROC_UNUSED(void,glGetPixelMapusv,(GLenum map, GLushort *values)) |
SDL_PROC_UNUSED(void,glGetPointerv,(GLenum pname, GLvoid* *params)) |
SDL_PROC_UNUSED(void,glGetPolygonStipple,(GLubyte *mask)) |
SDL_PROC(const GLubyte *,glGetString,(GLenum name)) |
SDL_PROC_UNUSED(void,glGetTexEnvfv,(GLenum target, GLenum pname, GLfloat *params)) |
SDL_PROC_UNUSED(void,glGetTexEnviv,(GLenum target, GLenum pname, GLint *params)) |
SDL_PROC_UNUSED(void,glGetTexGendv,(GLenum coord, GLenum pname, GLdouble *params)) |
SDL_PROC_UNUSED(void,glGetTexGenfv,(GLenum coord, GLenum pname, GLfloat *params)) |
SDL_PROC_UNUSED(void,glGetTexGeniv,(GLenum coord, GLenum pname, GLint *params)) |
SDL_PROC_UNUSED(void,glGetTexImage,(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)) |
SDL_PROC_UNUSED(void,glGetTexLevelParameterfv,(GLenum target, GLint level, GLenum pname, GLfloat *params)) |
SDL_PROC_UNUSED(void,glGetTexLevelParameteriv,(GLenum target, GLint level, GLenum pname, GLint *params)) |
SDL_PROC_UNUSED(void,glGetTexParameterfv,(GLenum target, GLenum pname, GLfloat *params)) |
SDL_PROC_UNUSED(void,glGetTexParameteriv,(GLenum target, GLenum pname, GLint *params)) |
SDL_PROC_UNUSED(void,glHint,(GLenum target, GLenum mode)) |
SDL_PROC_UNUSED(void,glIndexMask,(GLuint mask)) |
SDL_PROC_UNUSED(void,glIndexPointer,(GLenum type, GLsizei stride, const GLvoid *pointer)) |
SDL_PROC_UNUSED(void,glIndexd,(GLdouble c)) |
SDL_PROC_UNUSED(void,glIndexdv,(const GLdouble *c)) |
SDL_PROC_UNUSED(void,glIndexf,(GLfloat c)) |
SDL_PROC_UNUSED(void,glIndexfv,(const GLfloat *c)) |
SDL_PROC_UNUSED(void,glIndexi,(GLint c)) |
SDL_PROC_UNUSED(void,glIndexiv,(const GLint *c)) |
SDL_PROC_UNUSED(void,glIndexs,(GLshort c)) |
SDL_PROC_UNUSED(void,glIndexsv,(const GLshort *c)) |
SDL_PROC_UNUSED(void,glIndexub,(GLubyte c)) |
SDL_PROC_UNUSED(void,glIndexubv,(const GLubyte *c)) |
SDL_PROC_UNUSED(void,glInitNames,(void)) |
SDL_PROC_UNUSED(void,glInterleavedArrays,(GLenum format, GLsizei stride, const GLvoid *pointer)) |
SDL_PROC_UNUSED(GLboolean,glIsEnabled,(GLenum cap)) |
SDL_PROC_UNUSED(GLboolean,glIsList,(GLuint list)) |
SDL_PROC_UNUSED(GLboolean,glIsTexture,(GLuint texture)) |
SDL_PROC_UNUSED(void,glLightModelf,(GLenum pname, GLfloat param)) |
SDL_PROC_UNUSED(void,glLightModelfv,(GLenum pname, const GLfloat *params)) |
SDL_PROC_UNUSED(void,glLightModeli,(GLenum pname, GLint param)) |
SDL_PROC_UNUSED(void,glLightModeliv,(GLenum pname, const GLint *params)) |
SDL_PROC_UNUSED(void,glLightf,(GLenum light, GLenum pname, GLfloat param)) |
SDL_PROC_UNUSED(void,glLightfv,(GLenum light, GLenum pname, const GLfloat *params)) |
SDL_PROC_UNUSED(void,glLighti,(GLenum light, GLenum pname, GLint param)) |
SDL_PROC_UNUSED(void,glLightiv,(GLenum light, GLenum pname, const GLint *params)) |
SDL_PROC_UNUSED(void,glLineStipple,(GLint factor, GLushort pattern)) |
SDL_PROC_UNUSED(void,glLineWidth,(GLfloat width)) |
SDL_PROC_UNUSED(void,glListBase,(GLuint base)) |
SDL_PROC(void,glLoadIdentity,(void)) |
SDL_PROC_UNUSED(void,glLoadMatrixd,(const GLdouble *m)) |
SDL_PROC_UNUSED(void,glLoadMatrixf,(const GLfloat *m)) |
SDL_PROC_UNUSED(void,glLoadName,(GLuint name)) |
SDL_PROC_UNUSED(void,glLogicOp,(GLenum opcode)) |
SDL_PROC_UNUSED(void,glMap1d,(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)) |
SDL_PROC_UNUSED(void,glMap1f,(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)) |
SDL_PROC_UNUSED(void,glMap2d,(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)) |
SDL_PROC_UNUSED(void,glMap2f,(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)) |
SDL_PROC_UNUSED(void,glMapGrid1d,(GLint un, GLdouble u1, GLdouble u2)) |
SDL_PROC_UNUSED(void,glMapGrid1f,(GLint un, GLfloat u1, GLfloat u2)) |
SDL_PROC_UNUSED(void,glMapGrid2d,(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)) |
SDL_PROC_UNUSED(void,glMapGrid2f,(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)) |
SDL_PROC_UNUSED(void,glMaterialf,(GLenum face, GLenum pname, GLfloat param)) |
SDL_PROC_UNUSED(void,glMaterialfv,(GLenum face, GLenum pname, const GLfloat *params)) |
SDL_PROC_UNUSED(void,glMateriali,(GLenum face, GLenum pname, GLint param)) |
SDL_PROC_UNUSED(void,glMaterialiv,(GLenum face, GLenum pname, const GLint *params)) |
SDL_PROC(void,glMatrixMode,(GLenum mode)) |
SDL_PROC_UNUSED(void,glMultMatrixd,(const GLdouble *m)) |
SDL_PROC_UNUSED(void,glMultMatrixf,(const GLfloat *m)) |
SDL_PROC_UNUSED(void,glNewList,(GLuint list, GLenum mode)) |
SDL_PROC_UNUSED(void,glNormal3b,(GLbyte nx, GLbyte ny, GLbyte nz)) |
SDL_PROC_UNUSED(void,glNormal3bv,(const GLbyte *v)) |
SDL_PROC_UNUSED(void,glNormal3d,(GLdouble nx, GLdouble ny, GLdouble nz)) |
SDL_PROC_UNUSED(void,glNormal3dv,(const GLdouble *v)) |
SDL_PROC_UNUSED(void,glNormal3f,(GLfloat nx, GLfloat ny, GLfloat nz)) |
SDL_PROC_UNUSED(void,glNormal3fv,(const GLfloat *v)) |
SDL_PROC_UNUSED(void,glNormal3i,(GLint nx, GLint ny, GLint nz)) |
SDL_PROC_UNUSED(void,glNormal3iv,(const GLint *v)) |
SDL_PROC_UNUSED(void,glNormal3s,(GLshort nx, GLshort ny, GLshort nz)) |
SDL_PROC_UNUSED(void,glNormal3sv,(const GLshort *v)) |
SDL_PROC_UNUSED(void,glNormalPointer,(GLenum type, GLsizei stride, const GLvoid *pointer)) |
SDL_PROC(void,glOrtho,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)) |
SDL_PROC_UNUSED(void,glPassThrough,(GLfloat token)) |
SDL_PROC_UNUSED(void,glPixelMapfv,(GLenum map, GLsizei mapsize, const GLfloat *values)) |
SDL_PROC_UNUSED(void,glPixelMapuiv,(GLenum map, GLsizei mapsize, const GLuint *values)) |
SDL_PROC_UNUSED(void,glPixelMapusv,(GLenum map, GLsizei mapsize, const GLushort *values)) |
SDL_PROC_UNUSED(void,glPixelStoref,(GLenum pname, GLfloat param)) |
SDL_PROC(void,glPixelStorei,(GLenum pname, GLint param)) |
SDL_PROC_UNUSED(void,glPixelTransferf,(GLenum pname, GLfloat param)) |
SDL_PROC_UNUSED(void,glPixelTransferi,(GLenum pname, GLint param)) |
SDL_PROC_UNUSED(void,glPixelZoom,(GLfloat xfactor, GLfloat yfactor)) |
SDL_PROC_UNUSED(void,glPointSize,(GLfloat size)) |
SDL_PROC_UNUSED(void,glPolygonMode,(GLenum face, GLenum mode)) |
SDL_PROC_UNUSED(void,glPolygonOffset,(GLfloat factor, GLfloat units)) |
SDL_PROC_UNUSED(void,glPolygonStipple,(const GLubyte *mask)) |
SDL_PROC(void,glPopAttrib,(void)) |
SDL_PROC(void,glPopClientAttrib,(void)) |
SDL_PROC(void,glPopMatrix,(void)) |
SDL_PROC_UNUSED(void,glPopName,(void)) |
SDL_PROC_UNUSED(void,glPrioritizeTextures,(GLsizei n, const GLuint *textures, const GLclampf *priorities)) |
SDL_PROC(void,glPushAttrib,(GLbitfield mask)) |
SDL_PROC(void,glPushClientAttrib,(GLbitfield mask)) |
SDL_PROC(void,glPushMatrix,(void)) |
SDL_PROC_UNUSED(void,glPushName,(GLuint name)) |
SDL_PROC_UNUSED(void,glRasterPos2d,(GLdouble x, GLdouble y)) |
SDL_PROC_UNUSED(void,glRasterPos2dv,(const GLdouble *v)) |
SDL_PROC_UNUSED(void,glRasterPos2f,(GLfloat x, GLfloat y)) |
SDL_PROC_UNUSED(void,glRasterPos2fv,(const GLfloat *v)) |
SDL_PROC_UNUSED(void,glRasterPos2i,(GLint x, GLint y)) |
SDL_PROC_UNUSED(void,glRasterPos2iv,(const GLint *v)) |
SDL_PROC_UNUSED(void,glRasterPos2s,(GLshort x, GLshort y)) |
SDL_PROC_UNUSED(void,glRasterPos2sv,(const GLshort *v)) |
SDL_PROC_UNUSED(void,glRasterPos3d,(GLdouble x, GLdouble y, GLdouble z)) |
SDL_PROC_UNUSED(void,glRasterPos3dv,(const GLdouble *v)) |
SDL_PROC_UNUSED(void,glRasterPos3f,(GLfloat x, GLfloat y, GLfloat z)) |
SDL_PROC_UNUSED(void,glRasterPos3fv,(const GLfloat *v)) |
SDL_PROC_UNUSED(void,glRasterPos3i,(GLint x, GLint y, GLint z)) |
SDL_PROC_UNUSED(void,glRasterPos3iv,(const GLint *v)) |
SDL_PROC_UNUSED(void,glRasterPos3s,(GLshort x, GLshort y, GLshort z)) |
SDL_PROC_UNUSED(void,glRasterPos3sv,(const GLshort *v)) |
SDL_PROC_UNUSED(void,glRasterPos4d,(GLdouble x, GLdouble y, GLdouble z, GLdouble w)) |
SDL_PROC_UNUSED(void,glRasterPos4dv,(const GLdouble *v)) |
SDL_PROC_UNUSED(void,glRasterPos4f,(GLfloat x, GLfloat y, GLfloat z, GLfloat w)) |
SDL_PROC_UNUSED(void,glRasterPos4fv,(const GLfloat *v)) |
SDL_PROC_UNUSED(void,glRasterPos4i,(GLint x, GLint y, GLint z, GLint w)) |
SDL_PROC_UNUSED(void,glRasterPos4iv,(const GLint *v)) |
SDL_PROC_UNUSED(void,glRasterPos4s,(GLshort x, GLshort y, GLshort z, GLshort w)) |
SDL_PROC_UNUSED(void,glRasterPos4sv,(const GLshort *v)) |
SDL_PROC_UNUSED(void,glReadBuffer,(GLenum mode)) |
SDL_PROC_UNUSED(void,glReadPixels,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)) |
SDL_PROC_UNUSED(void,glRectd,(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)) |
SDL_PROC_UNUSED(void,glRectdv,(const GLdouble *v1, const GLdouble *v2)) |
SDL_PROC_UNUSED(void,glRectf,(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)) |
SDL_PROC_UNUSED(void,glRectfv,(const GLfloat *v1, const GLfloat *v2)) |
SDL_PROC_UNUSED(void,glRecti,(GLint x1, GLint y1, GLint x2, GLint y2)) |
SDL_PROC_UNUSED(void,glRectiv,(const GLint *v1, const GLint *v2)) |
SDL_PROC_UNUSED(void,glRects,(GLshort x1, GLshort y1, GLshort x2, GLshort y2)) |
SDL_PROC_UNUSED(void,glRectsv,(const GLshort *v1, const GLshort *v2)) |
SDL_PROC_UNUSED(GLint,glRenderMode,(GLenum mode)) |
SDL_PROC_UNUSED(void,glRotated,(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)) |
SDL_PROC_UNUSED(void,glRotatef,(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) |
SDL_PROC_UNUSED(void,glScaled,(GLdouble x, GLdouble y, GLdouble z)) |
SDL_PROC_UNUSED(void,glScalef,(GLfloat x, GLfloat y, GLfloat z)) |
SDL_PROC_UNUSED(void,glScissor,(GLint x, GLint y, GLsizei width, GLsizei height)) |
SDL_PROC_UNUSED(void,glSelectBuffer,(GLsizei size, GLuint *buffer)) |
SDL_PROC_UNUSED(void,glShadeModel,(GLenum mode)) |
SDL_PROC_UNUSED(void,glStencilFunc,(GLenum func, GLint ref, GLuint mask)) |
SDL_PROC_UNUSED(void,glStencilMask,(GLuint mask)) |
SDL_PROC_UNUSED(void,glStencilOp,(GLenum fail, GLenum zfail, GLenum zpass)) |
SDL_PROC_UNUSED(void,glTexCoord1d,(GLdouble s)) |
SDL_PROC_UNUSED(void,glTexCoord1dv,(const GLdouble *v)) |
SDL_PROC_UNUSED(void,glTexCoord1f,(GLfloat s)) |
SDL_PROC_UNUSED(void,glTexCoord1fv,(const GLfloat *v)) |
SDL_PROC_UNUSED(void,glTexCoord1i,(GLint s)) |
SDL_PROC_UNUSED(void,glTexCoord1iv,(const GLint *v)) |
SDL_PROC_UNUSED(void,glTexCoord1s,(GLshort s)) |
SDL_PROC_UNUSED(void,glTexCoord1sv,(const GLshort *v)) |
SDL_PROC_UNUSED(void,glTexCoord2d,(GLdouble s, GLdouble t)) |
SDL_PROC_UNUSED(void,glTexCoord2dv,(const GLdouble *v)) |
SDL_PROC(void,glTexCoord2f,(GLfloat s, GLfloat t)) |
SDL_PROC_UNUSED(void,glTexCoord2fv,(const GLfloat *v)) |
SDL_PROC_UNUSED(void,glTexCoord2i,(GLint s, GLint t)) |
SDL_PROC_UNUSED(void,glTexCoord2iv,(const GLint *v)) |
SDL_PROC_UNUSED(void,glTexCoord2s,(GLshort s, GLshort t)) |
SDL_PROC_UNUSED(void,glTexCoord2sv,(const GLshort *v)) |
SDL_PROC_UNUSED(void,glTexCoord3d,(GLdouble s, GLdouble t, GLdouble r)) |
SDL_PROC_UNUSED(void,glTexCoord3dv,(const GLdouble *v)) |
SDL_PROC_UNUSED(void,glTexCoord3f,(GLfloat s, GLfloat t, GLfloat r)) |
SDL_PROC_UNUSED(void,glTexCoord3fv,(const GLfloat *v)) |
SDL_PROC_UNUSED(void,glTexCoord3i,(GLint s, GLint t, GLint r)) |
SDL_PROC_UNUSED(void,glTexCoord3iv,(const GLint *v)) |
SDL_PROC_UNUSED(void,glTexCoord3s,(GLshort s, GLshort t, GLshort r)) |
SDL_PROC_UNUSED(void,glTexCoord3sv,(const GLshort *v)) |
SDL_PROC_UNUSED(void,glTexCoord4d,(GLdouble s, GLdouble t, GLdouble r, GLdouble q)) |
SDL_PROC_UNUSED(void,glTexCoord4dv,(const GLdouble *v)) |
SDL_PROC_UNUSED(void,glTexCoord4f,(GLfloat s, GLfloat t, GLfloat r, GLfloat q)) |
SDL_PROC_UNUSED(void,glTexCoord4fv,(const GLfloat *v)) |
SDL_PROC_UNUSED(void,glTexCoord4i,(GLint s, GLint t, GLint r, GLint q)) |
SDL_PROC_UNUSED(void,glTexCoord4iv,(const GLint *v)) |
SDL_PROC_UNUSED(void,glTexCoord4s,(GLshort s, GLshort t, GLshort r, GLshort q)) |
SDL_PROC_UNUSED(void,glTexCoord4sv,(const GLshort *v)) |
SDL_PROC_UNUSED(void,glTexCoordPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) |
SDL_PROC(void,glTexEnvf,(GLenum target, GLenum pname, GLfloat param)) |
SDL_PROC_UNUSED(void,glTexEnvfv,(GLenum target, GLenum pname, const GLfloat *params)) |
SDL_PROC_UNUSED(void,glTexEnvi,(GLenum target, GLenum pname, GLint param)) |
SDL_PROC_UNUSED(void,glTexEnviv,(GLenum target, GLenum pname, const GLint *params)) |
SDL_PROC_UNUSED(void,glTexGend,(GLenum coord, GLenum pname, GLdouble param)) |
SDL_PROC_UNUSED(void,glTexGendv,(GLenum coord, GLenum pname, const GLdouble *params)) |
SDL_PROC_UNUSED(void,glTexGenf,(GLenum coord, GLenum pname, GLfloat param)) |
SDL_PROC_UNUSED(void,glTexGenfv,(GLenum coord, GLenum pname, const GLfloat *params)) |
SDL_PROC_UNUSED(void,glTexGeni,(GLenum coord, GLenum pname, GLint param)) |
SDL_PROC_UNUSED(void,glTexGeniv,(GLenum coord, GLenum pname, const GLint *params)) |
SDL_PROC_UNUSED(void,glTexImage1D,(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) |
SDL_PROC(void,glTexImage2D,(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) |
SDL_PROC_UNUSED(void,glTexParameterf,(GLenum target, GLenum pname, GLfloat param)) |
SDL_PROC_UNUSED(void,glTexParameterfv,(GLenum target, GLenum pname, const GLfloat *params)) |
SDL_PROC(void,glTexParameteri,(GLenum target, GLenum pname, GLint param)) |
SDL_PROC_UNUSED(void,glTexParameteriv,(GLenum target, GLenum pname, const GLint *params)) |
SDL_PROC_UNUSED(void,glTexSubImage1D,(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)) |
SDL_PROC(void,glTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)) |
SDL_PROC_UNUSED(void,glTranslated,(GLdouble x, GLdouble y, GLdouble z)) |
SDL_PROC_UNUSED(void,glTranslatef,(GLfloat x, GLfloat y, GLfloat z)) |
SDL_PROC_UNUSED(void,glVertex2d,(GLdouble x, GLdouble y)) |
SDL_PROC_UNUSED(void,glVertex2dv,(const GLdouble *v)) |
SDL_PROC_UNUSED(void,glVertex2f,(GLfloat x, GLfloat y)) |
SDL_PROC_UNUSED(void,glVertex2fv,(const GLfloat *v)) |
SDL_PROC(void,glVertex2i,(GLint x, GLint y)) |
SDL_PROC_UNUSED(void,glVertex2iv,(const GLint *v)) |
SDL_PROC_UNUSED(void,glVertex2s,(GLshort x, GLshort y)) |
SDL_PROC_UNUSED(void,glVertex2sv,(const GLshort *v)) |
SDL_PROC_UNUSED(void,glVertex3d,(GLdouble x, GLdouble y, GLdouble z)) |
SDL_PROC_UNUSED(void,glVertex3dv,(const GLdouble *v)) |
SDL_PROC_UNUSED(void,glVertex3f,(GLfloat x, GLfloat y, GLfloat z)) |
SDL_PROC_UNUSED(void,glVertex3fv,(const GLfloat *v)) |
SDL_PROC_UNUSED(void,glVertex3i,(GLint x, GLint y, GLint z)) |
SDL_PROC_UNUSED(void,glVertex3iv,(const GLint *v)) |
SDL_PROC_UNUSED(void,glVertex3s,(GLshort x, GLshort y, GLshort z)) |
SDL_PROC_UNUSED(void,glVertex3sv,(const GLshort *v)) |
SDL_PROC_UNUSED(void,glVertex4d,(GLdouble x, GLdouble y, GLdouble z, GLdouble w)) |
SDL_PROC_UNUSED(void,glVertex4dv,(const GLdouble *v)) |
SDL_PROC_UNUSED(void,glVertex4f,(GLfloat x, GLfloat y, GLfloat z, GLfloat w)) |
SDL_PROC_UNUSED(void,glVertex4fv,(const GLfloat *v)) |
SDL_PROC_UNUSED(void,glVertex4i,(GLint x, GLint y, GLint z, GLint w)) |
SDL_PROC_UNUSED(void,glVertex4iv,(const GLint *v)) |
SDL_PROC_UNUSED(void,glVertex4s,(GLshort x, GLshort y, GLshort z, GLshort w)) |
SDL_PROC_UNUSED(void,glVertex4sv,(const GLshort *v)) |
SDL_PROC_UNUSED(void,glVertexPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) |
SDL_PROC(void,glViewport,(GLint x, GLint y, GLsizei width, GLsizei height)) |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_leaks.h |
---|
0,0 → 1,35 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_leaks.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; |
#endif |
/* Define this if you want surface leak detection code enabled */ |
/*#define CHECK_LEAKS*/ |
/* Global variables used to check leaks in code using SDL */ |
#ifdef CHECK_LEAKS |
extern int surfaces_allocated; |
#endif |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_memops.h |
---|
0,0 → 1,144 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_memops.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; |
#endif |
#ifndef _SDL_memops_h |
#define _SDL_memops_h |
/* System dependent optimized memory manipulation routines: |
*/ |
#include <string.h> |
#if defined(__GNUC__) && defined(i386) |
/* Thanks to Brennan "Bas" Underwood, for the inspiration. :) |
*/ |
#define SDL_memcpy(dst, src, len) \ |
do { \ |
int u0, u1, u2; \ |
__asm__ __volatile__ ( \ |
"cld\n\t" \ |
"rep ; movsl\n\t" \ |
"testb $2,%b4\n\t" \ |
"je 1f\n\t" \ |
"movsw\n" \ |
"1:\ttestb $1,%b4\n\t" \ |
"je 2f\n\t" \ |
"movsb\n" \ |
"2:" \ |
: "=&c" (u0), "=&D" (u1), "=&S" (u2) \ |
: "0" ((unsigned)(len)/4), "q" (len), "1" (dst),"2" (src) \ |
: "memory" ); \ |
} while(0) |
#define SDL_memcpy4(dst, src, len) \ |
do { \ |
int ecx, edi, esi; \ |
__asm__ __volatile__ ( \ |
"cld\n\t" \ |
"rep ; movsl" \ |
: "=&c" (ecx), "=&D" (edi), "=&S" (esi) \ |
: "0" ((unsigned)(len)), "1" (dst), "2" (src) \ |
: "memory" ); \ |
} while(0) |
#define SDL_revcpy(dst, src, len) \ |
do { \ |
int u0, u1, u2; \ |
char *dstp = (char *)(dst); \ |
char *srcp = (char *)(src); \ |
int n = (len); \ |
if ( n >= 4 ) { \ |
__asm__ __volatile__ ( \ |
"std\n\t" \ |
"rep ; movsl\n\t" \ |
: "=&c" (u0), "=&D" (u1), "=&S" (u2) \ |
: "0" (n >> 2), \ |
"1" (dstp+(n-4)), "2" (srcp+(n-4)) \ |
: "memory" ); \ |
} \ |
switch (n & 3) { \ |
case 3: dstp[2] = srcp[2]; \ |
case 2: dstp[1] = srcp[1]; \ |
case 1: dstp[0] = srcp[0]; \ |
break; \ |
default: \ |
break; \ |
} \ |
} while(0) |
#define SDL_memmove(dst, src, len) \ |
do { \ |
if ( (dst) < (src) ) { \ |
SDL_memcpy((dst), (src), (len)); \ |
} else { \ |
SDL_revcpy((dst), (src), (len)); \ |
} \ |
} while(0) |
#define SDL_memset4(dst, val, len) \ |
do { \ |
int u0, u1, u2; \ |
__asm__ __volatile__ ( \ |
"cld\n\t" \ |
"rep ; stosl\n\t" \ |
: "=&D" (u0), "=&a" (u1), "=&c" (u2) \ |
: "0" (dst), "1" (val), "2" ((Uint32)(len)) \ |
: "memory" ); \ |
} while(0) |
#endif /* GNU C and x86 */ |
/* If there are no optimized versions, define the normal versions */ |
#ifndef SDL_memcpy |
#define SDL_memcpy(dst, src, len) memcpy(dst, src, len) |
#endif |
#ifndef SDL_memcpy4 |
#define SDL_memcpy4(dst, src, len) memcpy(dst, src, (len) << 2) |
#endif |
#ifndef SDL_revcpy |
#define SDL_revcpy(dst, src, len) memmove(dst, src, len) |
#endif |
#ifndef SDL_memset4 |
#define SDL_memset4(dst, val, len) \ |
do { \ |
unsigned _count = (len); \ |
unsigned _n = (_count + 3) / 4; \ |
Uint32 *_p = (Uint32 *)(dst); \ |
Uint32 _val = (val); \ |
switch (_count % 4) { \ |
case 0: do { *_p++ = _val; \ |
case 3: *_p++ = _val; \ |
case 2: *_p++ = _val; \ |
case 1: *_p++ = _val; \ |
} while ( --_n ); \ |
} \ |
} while(0) |
#endif |
#endif /* _SDL_memops_h */ |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_pixels.c |
---|
0,0 → 1,615 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* General (mostly internal) pixel/color manipulation routines for SDL */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "SDL_error.h" |
#include "SDL_endian.h" |
#include "SDL_video.h" |
#include "SDL_sysvideo.h" |
#include "SDL_blit.h" |
#include "SDL_pixels_c.h" |
#include "SDL_RLEaccel_c.h" |
/* Helper functions */ |
/* |
* Allocate a pixel format structure and fill it according to the given info. |
*/ |
SDL_PixelFormat *SDL_AllocFormat(int bpp, |
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) |
{ |
SDL_PixelFormat *format; |
Uint32 mask; |
/* Allocate an empty pixel format structure */ |
format = malloc(sizeof(*format)); |
if ( format == NULL ) { |
SDL_OutOfMemory(); |
return(NULL); |
} |
memset(format, 0, sizeof(*format)); |
format->alpha = SDL_ALPHA_OPAQUE; |
/* Set up the format */ |
format->BitsPerPixel = bpp; |
format->BytesPerPixel = (bpp+7)/8; |
switch (bpp) { |
case 1: |
/* Create the 2 color black-white palette */ |
format->palette = (SDL_Palette *)malloc( |
sizeof(SDL_Palette)); |
if ( format->palette == NULL ) { |
SDL_FreeFormat(format); |
SDL_OutOfMemory(); |
return(NULL); |
} |
(format->palette)->ncolors = 2; |
(format->palette)->colors = (SDL_Color *)malloc( |
(format->palette)->ncolors*sizeof(SDL_Color)); |
if ( (format->palette)->colors == NULL ) { |
SDL_FreeFormat(format); |
SDL_OutOfMemory(); |
return(NULL); |
} |
format->palette->colors[0].r = 0xFF; |
format->palette->colors[0].g = 0xFF; |
format->palette->colors[0].b = 0xFF; |
format->palette->colors[1].r = 0x00; |
format->palette->colors[1].g = 0x00; |
format->palette->colors[1].b = 0x00; |
format->Rloss = 8; |
format->Gloss = 8; |
format->Bloss = 8; |
format->Aloss = 8; |
format->Rshift = 0; |
format->Gshift = 0; |
format->Bshift = 0; |
format->Ashift = 0; |
format->Rmask = 0; |
format->Gmask = 0; |
format->Bmask = 0; |
format->Amask = 0; |
break; |
case 4: |
/* Create the 16 color VGA palette */ |
format->palette = (SDL_Palette *)malloc( |
sizeof(SDL_Palette)); |
if ( format->palette == NULL ) { |
SDL_FreeFormat(format); |
SDL_OutOfMemory(); |
return(NULL); |
} |
(format->palette)->ncolors = 16; |
(format->palette)->colors = (SDL_Color *)malloc( |
(format->palette)->ncolors*sizeof(SDL_Color)); |
if ( (format->palette)->colors == NULL ) { |
SDL_FreeFormat(format); |
SDL_OutOfMemory(); |
return(NULL); |
} |
/* Punt for now, will this ever be used? */ |
memset((format->palette)->colors, 0, |
(format->palette)->ncolors*sizeof(SDL_Color)); |
/* Palettized formats have no mask info */ |
format->Rloss = 8; |
format->Gloss = 8; |
format->Bloss = 8; |
format->Aloss = 8; |
format->Rshift = 0; |
format->Gshift = 0; |
format->Bshift = 0; |
format->Ashift = 0; |
format->Rmask = 0; |
format->Gmask = 0; |
format->Bmask = 0; |
format->Amask = 0; |
break; |
case 8: |
/* Create an empty 256 color palette */ |
format->palette = (SDL_Palette *)malloc( |
sizeof(SDL_Palette)); |
if ( format->palette == NULL ) { |
SDL_FreeFormat(format); |
SDL_OutOfMemory(); |
return(NULL); |
} |
(format->palette)->ncolors = 256; |
(format->palette)->colors = (SDL_Color *)malloc( |
(format->palette)->ncolors*sizeof(SDL_Color)); |
if ( (format->palette)->colors == NULL ) { |
SDL_FreeFormat(format); |
SDL_OutOfMemory(); |
return(NULL); |
} |
memset((format->palette)->colors, 0, |
(format->palette)->ncolors*sizeof(SDL_Color)); |
/* Palettized formats have no mask info */ |
format->Rloss = 8; |
format->Gloss = 8; |
format->Bloss = 8; |
format->Aloss = 8; |
format->Rshift = 0; |
format->Gshift = 0; |
format->Bshift = 0; |
format->Ashift = 0; |
format->Rmask = 0; |
format->Gmask = 0; |
format->Bmask = 0; |
format->Amask = 0; |
break; |
default: |
/* No palette, just packed pixel info */ |
format->palette = NULL; |
format->Rshift = 0; |
format->Rloss = 8; |
if ( Rmask ) { |
for ( mask = Rmask; !(mask&0x01); mask >>= 1 ) |
++format->Rshift; |
for ( ; (mask&0x01); mask >>= 1 ) |
--format->Rloss; |
} |
format->Gshift = 0; |
format->Gloss = 8; |
if ( Gmask ) { |
for ( mask = Gmask; !(mask&0x01); mask >>= 1 ) |
++format->Gshift; |
for ( ; (mask&0x01); mask >>= 1 ) |
--format->Gloss; |
} |
format->Bshift = 0; |
format->Bloss = 8; |
if ( Bmask ) { |
for ( mask = Bmask; !(mask&0x01); mask >>= 1 ) |
++format->Bshift; |
for ( ; (mask&0x01); mask >>= 1 ) |
--format->Bloss; |
} |
format->Ashift = 0; |
format->Aloss = 8; |
if ( Amask ) { |
for ( mask = Amask; !(mask&0x01); mask >>= 1 ) |
++format->Ashift; |
for ( ; (mask&0x01); mask >>= 1 ) |
--format->Aloss; |
} |
format->Rmask = Rmask; |
format->Gmask = Gmask; |
format->Bmask = Bmask; |
format->Amask = Amask; |
break; |
} |
/* Calculate some standard bitmasks, if necessary |
* Note: This could conflict with an alpha mask, if given. |
*/ |
if ( (bpp > 8) && !format->Rmask && !format->Gmask && !format->Bmask ) { |
/* R-G-B */ |
if ( bpp > 24 ) |
bpp = 24; |
format->Rloss = 8-(bpp/3); |
format->Gloss = 8-(bpp/3)-(bpp%3); |
format->Bloss = 8-(bpp/3); |
format->Rshift = ((bpp/3)+(bpp%3))+(bpp/3); |
format->Gshift = (bpp/3); |
format->Bshift = 0; |
format->Rmask = ((0xFF>>format->Rloss)<<format->Rshift); |
format->Gmask = ((0xFF>>format->Gloss)<<format->Gshift); |
format->Bmask = ((0xFF>>format->Bloss)<<format->Bshift); |
} |
return(format); |
} |
SDL_PixelFormat *SDL_ReallocFormat(SDL_Surface *surface, int bpp, |
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) |
{ |
if ( surface->format ) { |
SDL_FreeFormat(surface->format); |
SDL_FormatChanged(surface); |
} |
surface->format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); |
return surface->format; |
} |
/* |
* Change any previous mappings from/to the new surface format |
*/ |
void SDL_FormatChanged(SDL_Surface *surface) |
{ |
surface->format_version++; |
SDL_InvalidateMap(surface->map); |
} |
/* |
* Free a previously allocated format structure |
*/ |
void SDL_FreeFormat(SDL_PixelFormat *format) |
{ |
if ( format ) { |
if ( format->palette ) { |
if ( format->palette->colors ) { |
free(format->palette->colors); |
} |
free(format->palette); |
} |
free(format); |
} |
} |
/* |
* Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors |
*/ |
void SDL_DitherColors(SDL_Color *colors, int bpp) |
{ |
int i; |
if(bpp != 8) |
return; /* only 8bpp supported right now */ |
for(i = 0; i < 256; i++) { |
int r, g, b; |
/* map each bit field to the full [0, 255] interval, |
so 0 is mapped to (0, 0, 0) and 255 to (255, 255, 255) */ |
r = i & 0xe0; |
r |= r >> 3 | r >> 6; |
colors[i].r = r; |
g = (i << 3) & 0xe0; |
g |= g >> 3 | g >> 6; |
colors[i].g = g; |
b = i & 0x3; |
b |= b << 2; |
b |= b << 4; |
colors[i].b = b; |
} |
} |
/* |
* Calculate the pad-aligned scanline width of a surface |
*/ |
Uint16 SDL_CalculatePitch(SDL_Surface *surface) |
{ |
Uint16 pitch; |
/* Surface should be 4-byte aligned for speed */ |
pitch = surface->w*surface->format->BytesPerPixel; |
switch (surface->format->BitsPerPixel) { |
case 1: |
pitch = (pitch+7)/8; |
break; |
case 4: |
pitch = (pitch+1)/2; |
break; |
default: |
break; |
} |
pitch = (pitch + 3) & ~3; /* 4-byte aligning */ |
return(pitch); |
} |
/* |
* Match an RGB value to a particular palette index |
*/ |
Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b) |
{ |
/* Do colorspace distance matching */ |
unsigned int smallest; |
unsigned int distance; |
int rd, gd, bd; |
int i; |
Uint8 pixel=0; |
smallest = ~0; |
for ( i=0; i<pal->ncolors; ++i ) { |
rd = pal->colors[i].r - r; |
gd = pal->colors[i].g - g; |
bd = pal->colors[i].b - b; |
distance = (rd*rd)+(gd*gd)+(bd*bd); |
if ( distance < smallest ) { |
pixel = i; |
if ( distance == 0 ) { /* Perfect match! */ |
break; |
} |
smallest = distance; |
} |
} |
return(pixel); |
} |
/* Find the opaque pixel value corresponding to an RGB triple */ |
Uint32 SDL_MapRGB(SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b) |
{ |
if ( format->palette == NULL ) { |
return (r >> format->Rloss) << format->Rshift |
| (g >> format->Gloss) << format->Gshift |
| (b >> format->Bloss) << format->Bshift |
| format->Amask; |
} else { |
return SDL_FindColor(format->palette, r, g, b); |
} |
} |
/* Find the pixel value corresponding to an RGBA quadruple */ |
Uint32 SDL_MapRGBA(SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b, Uint8 a) |
{ |
if ( format->palette == NULL ) { |
return (r >> format->Rloss) << format->Rshift |
| (g >> format->Gloss) << format->Gshift |
| (b >> format->Bloss) << format->Bshift |
| ((a >> format->Aloss) << format->Ashift & format->Amask); |
} else { |
return SDL_FindColor(format->palette, r, g, b); |
} |
} |
void SDL_GetRGBA(Uint32 pixel, SDL_PixelFormat *fmt, |
Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a) |
{ |
if ( fmt->palette == NULL ) { |
/* |
* This makes sure that the result is mapped to the |
* interval [0..255], and the maximum value for each |
* component is 255. This is important to make sure |
* that white is indeed reported as (255, 255, 255), |
* and that opaque alpha is 255. |
* This only works for RGB bit fields at least 4 bit |
* wide, which is almost always the case. |
*/ |
unsigned rv, gv, bv, av; |
rv = (pixel & fmt->Rmask) >> fmt->Rshift; |
*r = (rv << fmt->Rloss) + (rv >> (8 - fmt->Rloss)); |
gv = (pixel & fmt->Gmask) >> fmt->Gshift; |
*g = (gv << fmt->Gloss) + (gv >> (8 - fmt->Gloss)); |
bv = (pixel & fmt->Bmask) >> fmt->Bshift; |
*b = (bv << fmt->Bloss) + (bv >> (8 - fmt->Bloss)); |
if(fmt->Amask) { |
av = (pixel & fmt->Amask) >> fmt->Ashift; |
*a = (av << fmt->Aloss) + (av >> (8 - fmt->Aloss)); |
} else |
*a = SDL_ALPHA_OPAQUE; |
} else { |
*r = fmt->palette->colors[pixel].r; |
*g = fmt->palette->colors[pixel].g; |
*b = fmt->palette->colors[pixel].b; |
*a = SDL_ALPHA_OPAQUE; |
} |
} |
void SDL_GetRGB(Uint32 pixel, SDL_PixelFormat *fmt, Uint8 *r,Uint8 *g,Uint8 *b) |
{ |
if ( fmt->palette == NULL ) { |
/* the note for SDL_GetRGBA above applies here too */ |
unsigned rv, gv, bv; |
rv = (pixel & fmt->Rmask) >> fmt->Rshift; |
*r = (rv << fmt->Rloss) + (rv >> (8 - fmt->Rloss)); |
gv = (pixel & fmt->Gmask) >> fmt->Gshift; |
*g = (gv << fmt->Gloss) + (gv >> (8 - fmt->Gloss)); |
bv = (pixel & fmt->Bmask) >> fmt->Bshift; |
*b = (bv << fmt->Bloss) + (bv >> (8 - fmt->Bloss)); |
} else { |
*r = fmt->palette->colors[pixel].r; |
*g = fmt->palette->colors[pixel].g; |
*b = fmt->palette->colors[pixel].b; |
} |
} |
/* Apply gamma to a set of colors - this is easy. :) */ |
void SDL_ApplyGamma(Uint16 *gamma, SDL_Color *colors, SDL_Color *output, |
int ncolors) |
{ |
int i; |
for ( i=0; i<ncolors; ++i ) { |
output[i].r = gamma[0*256 + colors[i].r] >> 8; |
output[i].g = gamma[1*256 + colors[i].g] >> 8; |
output[i].b = gamma[2*256 + colors[i].b] >> 8; |
} |
} |
/* Map from Palette to Palette */ |
static Uint8 *Map1to1(SDL_Palette *src, SDL_Palette *dst, int *identical) |
{ |
Uint8 *map; |
int i; |
if ( identical ) { |
if ( src->ncolors <= dst->ncolors ) { |
/* If an identical palette, no need to map */ |
if ( memcmp(src->colors, dst->colors, src->ncolors* |
sizeof(SDL_Color)) == 0 ) { |
*identical = 1; |
return(NULL); |
} |
} |
*identical = 0; |
} |
map = (Uint8 *)malloc(src->ncolors); |
if ( map == NULL ) { |
SDL_OutOfMemory(); |
return(NULL); |
} |
for ( i=0; i<src->ncolors; ++i ) { |
map[i] = SDL_FindColor(dst, |
src->colors[i].r, src->colors[i].g, src->colors[i].b); |
} |
return(map); |
} |
/* Map from Palette to BitField */ |
static Uint8 *Map1toN(SDL_Palette *src, SDL_PixelFormat *dst) |
{ |
Uint8 *map; |
int i; |
int bpp; |
unsigned alpha; |
bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel); |
map = (Uint8 *)malloc(src->ncolors*bpp); |
if ( map == NULL ) { |
SDL_OutOfMemory(); |
return(NULL); |
} |
alpha = dst->Amask ? SDL_ALPHA_OPAQUE : 0; |
/* We memory copy to the pixel map so the endianness is preserved */ |
for ( i=0; i<src->ncolors; ++i ) { |
ASSEMBLE_RGBA(&map[i*bpp], dst->BytesPerPixel, dst, |
src->colors[i].r, src->colors[i].g, |
src->colors[i].b, alpha); |
} |
return(map); |
} |
/* Map from BitField to Dithered-Palette to Palette */ |
static Uint8 *MapNto1(SDL_PixelFormat *src, SDL_Palette *dst, int *identical) |
{ |
/* Generate a 256 color dither palette */ |
SDL_Palette dithered; |
SDL_Color colors[256]; |
dithered.ncolors = 256; |
SDL_DitherColors(colors, 8); |
dithered.colors = colors; |
return(Map1to1(&dithered, dst, identical)); |
} |
SDL_BlitMap *SDL_AllocBlitMap(void) |
{ |
SDL_BlitMap *map; |
/* Allocate the empty map */ |
map = (SDL_BlitMap *)malloc(sizeof(*map)); |
if ( map == NULL ) { |
SDL_OutOfMemory(); |
return(NULL); |
} |
memset(map, 0, sizeof(*map)); |
/* Allocate the software blit data */ |
map->sw_data = (struct private_swaccel *)malloc(sizeof(*map->sw_data)); |
if ( map->sw_data == NULL ) { |
SDL_FreeBlitMap(map); |
SDL_OutOfMemory(); |
return(NULL); |
} |
memset(map->sw_data, 0, sizeof(*map->sw_data)); |
/* It's ready to go */ |
return(map); |
} |
void SDL_InvalidateMap(SDL_BlitMap *map) |
{ |
if ( ! map ) { |
return; |
} |
map->dst = NULL; |
map->format_version = (unsigned int)-1; |
if ( map->table ) { |
free(map->table); |
map->table = NULL; |
} |
} |
int SDL_MapSurface (SDL_Surface *src, SDL_Surface *dst) |
{ |
SDL_PixelFormat *srcfmt; |
SDL_PixelFormat *dstfmt; |
SDL_BlitMap *map; |
/* Clear out any previous mapping */ |
map = src->map; |
if ( (src->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { |
SDL_UnRLESurface(src, 1); |
} |
SDL_InvalidateMap(map); |
/* Figure out what kind of mapping we're doing */ |
map->identity = 0; |
srcfmt = src->format; |
dstfmt = dst->format; |
switch (srcfmt->BytesPerPixel) { |
case 1: |
switch (dstfmt->BytesPerPixel) { |
case 1: |
/* Palette --> Palette */ |
/* If both SDL_HWSURFACE, assume have same palette */ |
if ( ((src->flags & SDL_HWSURFACE) == SDL_HWSURFACE) && |
((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) ) { |
map->identity = 1; |
} else { |
map->table = Map1to1(srcfmt->palette, |
dstfmt->palette, &map->identity); |
} |
if ( ! map->identity ) { |
if ( map->table == NULL ) { |
return(-1); |
} |
} |
if (srcfmt->BitsPerPixel!=dstfmt->BitsPerPixel) |
map->identity = 0; |
break; |
default: |
/* Palette --> BitField */ |
map->table = Map1toN(srcfmt->palette, dstfmt); |
if ( map->table == NULL ) { |
return(-1); |
} |
break; |
} |
break; |
default: |
switch (dstfmt->BytesPerPixel) { |
case 1: |
/* BitField --> Palette */ |
map->table = MapNto1(srcfmt, |
dstfmt->palette, &map->identity); |
if ( ! map->identity ) { |
if ( map->table == NULL ) { |
return(-1); |
} |
} |
map->identity = 0; /* Don't optimize to copy */ |
break; |
default: |
/* BitField --> BitField */ |
if ( FORMAT_EQUAL(srcfmt, dstfmt) ) |
map->identity = 1; |
break; |
} |
break; |
} |
map->dst = dst; |
map->format_version = dst->format_version; |
/* Choose your blitters wisely */ |
return(SDL_CalculateBlit(src)); |
} |
void SDL_FreeBlitMap(SDL_BlitMap *map) |
{ |
if ( map ) { |
SDL_InvalidateMap(map); |
if ( map->sw_data != NULL ) { |
free(map->sw_data); |
} |
free(map); |
} |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_pixels_c.h |
---|
0,0 → 1,50 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_pixels_c.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; |
#endif |
/* Useful functions and variables from SDL_pixel.c */ |
#include "SDL_blit.h" |
/* Pixel format functions */ |
extern SDL_PixelFormat *SDL_AllocFormat(int bpp, |
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); |
extern SDL_PixelFormat *SDL_ReallocFormat(SDL_Surface *surface, int bpp, |
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); |
extern void SDL_FormatChanged(SDL_Surface *surface); |
extern void SDL_FreeFormat(SDL_PixelFormat *format); |
/* Blit mapping functions */ |
extern SDL_BlitMap *SDL_AllocBlitMap(void); |
extern void SDL_InvalidateMap(SDL_BlitMap *map); |
extern int SDL_MapSurface (SDL_Surface *src, SDL_Surface *dst); |
extern void SDL_FreeBlitMap(SDL_BlitMap *map); |
/* Miscellaneous functions */ |
extern Uint16 SDL_CalculatePitch(SDL_Surface *surface); |
extern void SDL_DitherColors(SDL_Color *colors, int bpp); |
extern Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b); |
extern void SDL_ApplyGamma(Uint16 *gamma, SDL_Color *colors, SDL_Color *output, int ncolors); |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_stretch.c |
---|
0,0 → 1,305 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* This a stretch blit implementation based on ideas given to me by |
Tomasz Cejner - thanks! :) |
April 27, 2000 - Sam Lantinga |
*/ |
#include "SDL_error.h" |
#include "SDL_video.h" |
#include "SDL_blit.h" |
/* This isn't ready for general consumption yet - it should be folded |
into the general blitting mechanism. |
*/ |
#if (defined(WIN32UNDEFINED) && !defined(_M_ALPHA) && !defined(_WIN32_WCE)) || \ |
defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) |
#define USE_ASM_STRETCH |
#endif |
#ifdef USE_ASM_STRETCH |
#if defined(WIN32UNDEFINED) || defined(i386) |
#define PREFIX16 0x66 |
#define STORE_BYTE 0xAA |
#define STORE_WORD 0xAB |
#define LOAD_BYTE 0xAC |
#define LOAD_WORD 0xAD |
#define RETURN 0xC3 |
#else |
#error Need assembly opcodes for this architecture |
#endif |
#if defined(__ELF__) && defined(__GNUC__) |
extern unsigned char _copy_row[4096] __attribute__ ((alias ("copy_row"))); |
#endif |
static unsigned char copy_row[4096]; |
static int generate_rowbytes(int src_w, int dst_w, int bpp) |
{ |
static struct { |
int bpp; |
int src_w; |
int dst_w; |
} last; |
int i; |
int pos, inc; |
unsigned char *eip; |
unsigned char load, store; |
/* See if we need to regenerate the copy buffer */ |
if ( (src_w == last.src_w) && |
(dst_w == last.src_w) && (bpp == last.bpp) ) { |
return(0); |
} |
last.bpp = bpp; |
last.src_w = src_w; |
last.dst_w = dst_w; |
switch (bpp) { |
case 1: |
load = LOAD_BYTE; |
store = STORE_BYTE; |
break; |
case 2: |
case 4: |
load = LOAD_WORD; |
store = STORE_WORD; |
break; |
default: |
SDL_SetError("ASM stretch of %d bytes isn't supported\n", bpp); |
return(-1); |
} |
pos = 0x10000; |
inc = (src_w << 16) / dst_w; |
eip = copy_row; |
for ( i=0; i<dst_w; ++i ) { |
while ( pos >= 0x10000L ) { |
if ( bpp == 2 ) { |
*eip++ = PREFIX16; |
} |
*eip++ = load; |
pos -= 0x10000L; |
} |
if ( bpp == 2 ) { |
*eip++ = PREFIX16; |
} |
*eip++ = store; |
pos += inc; |
} |
*eip++ = RETURN; |
/* Verify that we didn't overflow (too late) */ |
if ( eip > (copy_row+sizeof(copy_row)) ) { |
SDL_SetError("Copy buffer overflow"); |
return(-1); |
} |
return(0); |
} |
#else |
#define DEFINE_COPY_ROW(name, type) \ |
void name(type *src, int src_w, type *dst, int dst_w) \ |
{ \ |
int i; \ |
int pos, inc; \ |
type pixel = 0; \ |
\ |
pos = 0x10000; \ |
inc = (src_w << 16) / dst_w; \ |
for ( i=dst_w; i>0; --i ) { \ |
while ( pos >= 0x10000L ) { \ |
pixel = *src++; \ |
pos -= 0x10000L; \ |
} \ |
*dst++ = pixel; \ |
pos += inc; \ |
} \ |
} |
DEFINE_COPY_ROW(copy_row1, Uint8) |
DEFINE_COPY_ROW(copy_row2, Uint16) |
DEFINE_COPY_ROW(copy_row4, Uint32) |
#endif /* USE_ASM_STRETCH */ |
/* The ASM code doesn't handle 24-bpp stretch blits */ |
void copy_row3(Uint8 *src, int src_w, Uint8 *dst, int dst_w) |
{ |
int i; |
int pos, inc; |
Uint8 pixel[3]; |
pos = 0x10000; |
inc = (src_w << 16) / dst_w; |
for ( i=dst_w; i>0; --i ) { |
while ( pos >= 0x10000L ) { |
pixel[0] = *src++; |
pixel[1] = *src++; |
pixel[2] = *src++; |
pos -= 0x10000L; |
} |
*dst++ = pixel[0]; |
*dst++ = pixel[1]; |
*dst++ = pixel[2]; |
pos += inc; |
} |
} |
/* Perform a stretch blit between two surfaces of the same format. |
NOTE: This function is not safe to call from multiple threads! |
*/ |
int SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect, |
SDL_Surface *dst, SDL_Rect *dstrect) |
{ |
int pos, inc; |
int dst_width; |
int dst_maxrow; |
int src_row, dst_row; |
Uint8 *srcp = NULL; |
Uint8 *dstp; |
SDL_Rect full_src; |
SDL_Rect full_dst; |
#if defined(USE_ASM_STRETCH) && defined(__GNUC__) |
int u1, u2; |
#endif |
const int bpp = dst->format->BytesPerPixel; |
if ( src->format->BitsPerPixel != dst->format->BitsPerPixel ) { |
SDL_SetError("Only works with same format surfaces"); |
return(-1); |
} |
/* Verify the blit rectangles */ |
if ( srcrect ) { |
if ( (srcrect->x < 0) || (srcrect->y < 0) || |
((srcrect->x+srcrect->w) > src->w) || |
((srcrect->y+srcrect->h) > src->h) ) { |
SDL_SetError("Invalid source blit rectangle"); |
return(-1); |
} |
} else { |
full_src.x = 0; |
full_src.y = 0; |
full_src.w = src->w; |
full_src.h = src->h; |
srcrect = &full_src; |
} |
if ( dstrect ) { |
if ( (dstrect->x < 0) || (dstrect->y < 0) || |
((dstrect->x+dstrect->w) > dst->w) || |
((dstrect->y+dstrect->h) > dst->h) ) { |
SDL_SetError("Invalid destination blit rectangle"); |
return(-1); |
} |
} else { |
full_dst.x = 0; |
full_dst.y = 0; |
full_dst.w = dst->w; |
full_dst.h = dst->h; |
dstrect = &full_dst; |
} |
/* Set up the data... */ |
pos = 0x10000; |
inc = (srcrect->h << 16) / dstrect->h; |
src_row = srcrect->y; |
dst_row = dstrect->y; |
dst_width = dstrect->w*bpp; |
#ifdef USE_ASM_STRETCH |
/* Write the opcodes for this stretch */ |
if ( (bpp != 3) && |
(generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0) ) { |
return(-1); |
} |
#endif |
/* Perform the stretch blit */ |
for ( dst_maxrow = dst_row+dstrect->h; dst_row<dst_maxrow; ++dst_row ) { |
dstp = (Uint8 *)dst->pixels + (dst_row*dst->pitch) |
+ (dstrect->x*bpp); |
while ( pos >= 0x10000L ) { |
srcp = (Uint8 *)src->pixels + (src_row*src->pitch) |
+ (srcrect->x*bpp); |
++src_row; |
pos -= 0x10000L; |
} |
#ifdef USE_ASM_STRETCH |
switch (bpp) { |
case 3: |
copy_row3(srcp, srcrect->w, dstp, dstrect->w); |
break; |
default: |
#ifdef __GNUC__ |
__asm__ __volatile__ ("call _copy_row" |
: "=&D" (u1), "=&S" (u2) |
: "0" (dstp), "1" (srcp) |
: "memory" ); |
#else |
#ifdef WIN32UNDEFINED |
{ void *code = ©_row; |
__asm { |
push edi |
push esi |
mov edi, dstp |
mov esi, srcp |
call dword ptr code |
pop esi |
pop edi |
} |
} |
#else |
#error Need inline assembly for this compiler |
#endif |
#endif /* __GNUC__ */ |
break; |
} |
#else |
switch (bpp) { |
case 1: |
copy_row1(srcp, srcrect->w, dstp, dstrect->w); |
break; |
case 2: |
copy_row2((Uint16 *)srcp, srcrect->w, |
(Uint16 *)dstp, dstrect->w); |
break; |
case 3: |
copy_row3(srcp, srcrect->w, dstp, dstrect->w); |
break; |
case 4: |
copy_row4((Uint32 *)srcp, srcrect->w, |
(Uint32 *)dstp, dstrect->w); |
break; |
} |
#endif |
pos += inc; |
} |
return(0); |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_stretch_c.h |
---|
0,0 → 1,33 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_stretch_c.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; |
#endif |
/* Perform a stretch blit between two surfaces of the same format. |
NOTE: This function is not safe to call from multiple threads! |
*/ |
extern int SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect, |
SDL_Surface *dst, SDL_Rect *dstrect); |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_surface.c |
---|
0,0 → 1,816 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "SDL_error.h" |
#include "SDL_video.h" |
#include "SDL_sysvideo.h" |
#include "SDL_cursor_c.h" |
#include "SDL_blit.h" |
#include "SDL_RLEaccel_c.h" |
#include "SDL_pixels_c.h" |
#include "SDL_memops.h" |
#include "SDL_leaks.h" |
/* Public routines */ |
/* |
* Create an empty RGB surface of the appropriate depth |
*/ |
SDL_Surface * SDL_CreateRGBSurface (Uint32 flags, |
int width, int height, int depth, |
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
SDL_Surface *screen; |
SDL_Surface *surface; |
/* Check to see if we desire the surface in video memory */ |
if ( video ) { |
screen = SDL_PublicSurface; |
} else { |
screen = NULL; |
} |
if ( screen && ((screen->flags&SDL_HWSURFACE) == SDL_HWSURFACE) ) { |
if ( (flags&(SDL_SRCCOLORKEY|SDL_SRCALPHA)) != 0 ) { |
flags |= SDL_HWSURFACE; |
} |
if ( (flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { |
if ( ! current_video->info.blit_hw_CC ) { |
flags &= ~SDL_HWSURFACE; |
} |
} |
if ( (flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { |
if ( ! current_video->info.blit_hw_A ) { |
flags &= ~SDL_HWSURFACE; |
} |
} |
} else { |
flags &= ~SDL_HWSURFACE; |
} |
/* Allocate the surface */ |
surface = (SDL_Surface *)malloc(sizeof(*surface)); |
if ( surface == NULL ) { |
SDL_OutOfMemory(); |
return(NULL); |
} |
surface->flags = SDL_SWSURFACE; |
if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { |
depth = screen->format->BitsPerPixel; |
Rmask = screen->format->Rmask; |
Gmask = screen->format->Gmask; |
Bmask = screen->format->Bmask; |
Amask = screen->format->Amask; |
} |
surface->format = SDL_AllocFormat(depth, Rmask, Gmask, Bmask, Amask); |
if ( surface->format == NULL ) { |
free(surface); |
return(NULL); |
} |
if ( Amask ) { |
surface->flags |= SDL_SRCALPHA; |
} |
surface->w = width; |
surface->h = height; |
surface->pitch = SDL_CalculatePitch(surface); |
surface->pixels = NULL; |
surface->offset = 0; |
surface->hwdata = NULL; |
surface->locked = 0; |
surface->map = NULL; |
surface->format_version = 0; |
SDL_SetClipRect(surface, NULL); |
/* Get the pixels */ |
if ( ((flags&SDL_HWSURFACE) == SDL_SWSURFACE) || |
(video->AllocHWSurface(this, surface) < 0) ) { |
if ( surface->w && surface->h ) { |
surface->pixels = malloc(surface->h*surface->pitch); |
if ( surface->pixels == NULL ) { |
SDL_FreeSurface(surface); |
SDL_OutOfMemory(); |
return(NULL); |
} |
/* This is important for bitmaps */ |
memset(surface->pixels, 0, surface->h*surface->pitch); |
} |
} |
/* Allocate an empty mapping */ |
surface->map = SDL_AllocBlitMap(); |
if ( surface->map == NULL ) { |
SDL_FreeSurface(surface); |
return(NULL); |
} |
/* The surface is ready to go */ |
surface->refcount = 1; |
#ifdef CHECK_LEAKS |
++surfaces_allocated; |
#endif |
return(surface); |
} |
/* |
* Create an RGB surface from an existing memory buffer |
*/ |
SDL_Surface * SDL_CreateRGBSurfaceFrom (void *pixels, |
int width, int height, int depth, int pitch, |
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) |
{ |
SDL_Surface *surface; |
surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, depth, |
Rmask, Gmask, Bmask, Amask); |
if ( surface != NULL ) { |
surface->flags |= SDL_PREALLOC; |
surface->pixels = pixels; |
surface->w = width; |
surface->h = height; |
surface->pitch = pitch; |
SDL_SetClipRect(surface, NULL); |
} |
return(surface); |
} |
/* |
* Set the color key in a blittable surface |
*/ |
int SDL_SetColorKey (SDL_Surface *surface, Uint32 flag, Uint32 key) |
{ |
/* Sanity check the flag as it gets passed in */ |
if ( flag & SDL_SRCCOLORKEY ) { |
if ( flag & (SDL_RLEACCEL|SDL_RLEACCELOK) ) { |
flag = (SDL_SRCCOLORKEY | SDL_RLEACCELOK); |
} else { |
flag = SDL_SRCCOLORKEY; |
} |
} else { |
flag = 0; |
} |
/* Optimize away operations that don't change anything */ |
if ( (flag == (surface->flags & (SDL_SRCCOLORKEY|SDL_RLEACCELOK))) && |
(key == surface->format->colorkey) ) { |
return(0); |
} |
/* UnRLE surfaces before we change the colorkey */ |
if ( surface->flags & SDL_RLEACCEL ) { |
SDL_UnRLESurface(surface, 1); |
} |
if ( flag ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
surface->flags |= SDL_SRCCOLORKEY; |
surface->format->colorkey = key; |
if ( (surface->flags & SDL_HWACCEL) == SDL_HWACCEL ) { |
if ( (video->SetHWColorKey == NULL) || |
(video->SetHWColorKey(this, surface, key) < 0) ) { |
surface->flags &= ~SDL_HWACCEL; |
} |
} |
if ( flag & SDL_RLEACCELOK ) { |
surface->flags |= SDL_RLEACCELOK; |
} else { |
surface->flags &= ~SDL_RLEACCELOK; |
} |
} else { |
surface->flags &= ~(SDL_SRCCOLORKEY|SDL_RLEACCELOK); |
surface->format->colorkey = 0; |
} |
SDL_InvalidateMap(surface->map); |
return(0); |
} |
int SDL_SetAlpha (SDL_Surface *surface, Uint32 flag, Uint8 value) |
{ |
Uint32 oldflags = surface->flags; |
Uint32 oldalpha = surface->format->alpha; |
/* Sanity check the flag as it gets passed in */ |
if ( flag & SDL_SRCALPHA ) { |
if ( flag & (SDL_RLEACCEL|SDL_RLEACCELOK) ) { |
flag = (SDL_SRCALPHA | SDL_RLEACCELOK); |
} else { |
flag = SDL_SRCALPHA; |
} |
} else { |
flag = 0; |
} |
/* Optimize away operations that don't change anything */ |
if ( (flag == (surface->flags & (SDL_SRCALPHA|SDL_RLEACCELOK))) && |
(!flag || value == oldalpha) ) { |
return(0); |
} |
if(!(flag & SDL_RLEACCELOK) && (surface->flags & SDL_RLEACCEL)) |
SDL_UnRLESurface(surface, 1); |
if ( flag ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
surface->flags |= SDL_SRCALPHA; |
surface->format->alpha = value; |
if ( (surface->flags & SDL_HWACCEL) == SDL_HWACCEL ) { |
if ( (video->SetHWAlpha == NULL) || |
(video->SetHWAlpha(this, surface, value) < 0) ) { |
surface->flags &= ~SDL_HWACCEL; |
} |
} |
if ( flag & SDL_RLEACCELOK ) { |
surface->flags |= SDL_RLEACCELOK; |
} else { |
surface->flags &= ~SDL_RLEACCELOK; |
} |
} else { |
surface->flags &= ~SDL_SRCALPHA; |
surface->format->alpha = SDL_ALPHA_OPAQUE; |
} |
/* |
* The representation for software surfaces is independent of |
* per-surface alpha, so no need to invalidate the blit mapping |
* if just the alpha value was changed. (If either is 255, we still |
* need to invalidate.) |
*/ |
if((surface->flags & SDL_HWACCEL) == SDL_HWACCEL |
|| oldflags != surface->flags |
|| (((oldalpha + 1) ^ (value + 1)) & 0x100)) |
SDL_InvalidateMap(surface->map); |
return(0); |
} |
/* |
* A function to calculate the intersection of two rectangles: |
* return true if the rectangles intersect, false otherwise |
*/ |
static __inline__ |
SDL_bool SDL_IntersectRect(SDL_Rect *A, SDL_Rect *B, SDL_Rect *intersection) |
{ |
int Amin, Amax, Bmin, Bmax; |
/* Horizontal intersection */ |
Amin = A->x; |
Amax = Amin + A->w; |
Bmin = B->x; |
Bmax = Bmin + B->w; |
if(Bmin > Amin) |
Amin = Bmin; |
intersection->x = Amin; |
if(Bmax < Amax) |
Amax = Bmax; |
intersection->w = Amax - Amin > 0 ? Amax - Amin : 0; |
/* Vertical intersection */ |
Amin = A->y; |
Amax = Amin + A->h; |
Bmin = B->y; |
Bmax = Bmin + B->h; |
if(Bmin > Amin) |
Amin = Bmin; |
intersection->y = Amin; |
if(Bmax < Amax) |
Amax = Bmax; |
intersection->h = Amax - Amin > 0 ? Amax - Amin : 0; |
return (intersection->w && intersection->h); |
} |
/* |
* Set the clipping rectangle for a blittable surface |
*/ |
SDL_bool SDL_SetClipRect(SDL_Surface *surface, SDL_Rect *rect) |
{ |
SDL_Rect full_rect; |
/* Don't do anything if there's no surface to act on */ |
if ( ! surface ) { |
return SDL_FALSE; |
} |
/* Set up the full surface rectangle */ |
full_rect.x = 0; |
full_rect.y = 0; |
full_rect.w = surface->w; |
full_rect.h = surface->h; |
/* Set the clipping rectangle */ |
if ( ! rect ) { |
surface->clip_rect = full_rect; |
return 1; |
} |
return SDL_IntersectRect(rect, &full_rect, &surface->clip_rect); |
} |
void SDL_GetClipRect(SDL_Surface *surface, SDL_Rect *rect) |
{ |
if ( surface && rect ) { |
*rect = surface->clip_rect; |
} |
} |
/* |
* Set up a blit between two surfaces -- split into three parts: |
* The upper part, SDL_UpperBlit(), performs clipping and rectangle |
* verification. The lower part is a pointer to a low level |
* accelerated blitting function. |
* |
* These parts are separated out and each used internally by this |
* library in the optimimum places. They are exported so that if |
* you know exactly what you are doing, you can optimize your code |
* by calling the one(s) you need. |
*/ |
int SDL_LowerBlit (SDL_Surface *src, SDL_Rect *srcrect, |
SDL_Surface *dst, SDL_Rect *dstrect) |
{ |
SDL_blit do_blit; |
/* Check to make sure the blit mapping is valid */ |
if ( (src->map->dst != dst) || |
(src->map->dst->format_version != src->map->format_version) ) { |
if ( SDL_MapSurface(src, dst) < 0 ) { |
return(-1); |
} |
} |
/* Figure out which blitter to use */ |
if ( (src->flags & SDL_HWACCEL) == SDL_HWACCEL ) { |
do_blit = src->map->hw_blit; |
} else { |
do_blit = src->map->sw_blit; |
} |
return(do_blit(src, srcrect, dst, dstrect)); |
} |
int SDL_UpperBlit (SDL_Surface *src, SDL_Rect *srcrect, |
SDL_Surface *dst, SDL_Rect *dstrect) |
{ |
SDL_Rect fulldst; |
int srcx, srcy, w, h; |
/* Make sure the surfaces aren't locked */ |
if ( ! src || ! dst ) { |
SDL_SetError("SDL_UpperBlit: passed a NULL surface"); |
return(-1); |
} |
if ( src->locked || dst->locked ) { |
SDL_SetError("Surfaces must not be locked during blit"); |
return(-1); |
} |
/* If the destination rectangle is NULL, use the entire dest surface */ |
if ( dstrect == NULL ) { |
fulldst.x = fulldst.y = 0; |
dstrect = &fulldst; |
} |
/* clip the source rectangle to the source surface */ |
if(srcrect) { |
int maxw, maxh; |
srcx = srcrect->x; |
w = srcrect->w; |
if(srcx < 0) { |
w += srcx; |
dstrect->x -= srcx; |
srcx = 0; |
} |
maxw = src->w - srcx; |
if(maxw < w) |
w = maxw; |
srcy = srcrect->y; |
h = srcrect->h; |
if(srcy < 0) { |
h += srcy; |
dstrect->y -= srcy; |
srcy = 0; |
} |
maxh = src->h - srcy; |
if(maxh < h) |
h = maxh; |
} else { |
srcx = srcy = 0; |
w = src->w; |
h = src->h; |
} |
/* clip the destination rectangle against the clip rectangle */ |
{ |
SDL_Rect *clip = &dst->clip_rect; |
int dx, dy; |
dx = clip->x - dstrect->x; |
if(dx > 0) { |
w -= dx; |
dstrect->x += dx; |
srcx += dx; |
} |
dx = dstrect->x + w - clip->x - clip->w; |
if(dx > 0) |
w -= dx; |
dy = clip->y - dstrect->y; |
if(dy > 0) { |
h -= dy; |
dstrect->y += dy; |
srcy += dy; |
} |
dy = dstrect->y + h - clip->y - clip->h; |
if(dy > 0) |
h -= dy; |
} |
if(w > 0 && h > 0) { |
SDL_Rect sr; |
sr.x = srcx; |
sr.y = srcy; |
sr.w = dstrect->w = w; |
sr.h = dstrect->h = h; |
return SDL_LowerBlit(src, &sr, dst, dstrect); |
} |
dstrect->w = dstrect->h = 0; |
return 0; |
} |
/* |
* This function performs a fast fill of the given rectangle with 'color' |
*/ |
int SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
int x, y; |
Uint8 *row; |
/* If 'dstrect' == NULL, then fill the whole surface */ |
if ( dstrect ) { |
/* Perform clipping */ |
if ( !SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect) ) { |
return(0); |
} |
} else { |
dstrect = &dst->clip_rect; |
} |
/* Check for hardware acceleration */ |
if ( ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) && |
video->info.blit_fill ) { |
return(video->FillHWRect(this, dst, dstrect, color)); |
} |
/* Perform software fill */ |
if ( SDL_LockSurface(dst) != 0 ) { |
return(-1); |
} |
row = (Uint8 *)dst->pixels+dstrect->y*dst->pitch+ |
dstrect->x*dst->format->BytesPerPixel; |
if ( dst->format->palette || (color == 0) ) { |
x = dstrect->w*dst->format->BytesPerPixel; |
if ( !color && !((long)row&3) && !(x&3) && !(dst->pitch&3) ) { |
int n = x >> 2; |
for ( y=dstrect->h; y; --y ) { |
SDL_memset4(row, 0, n); |
row += dst->pitch; |
} |
} else { |
#ifdef __powerpc__ |
/* |
* memset() on PPC (both glibc and codewarrior) uses |
* the dcbz (Data Cache Block Zero) instruction, which |
* causes an alignment exception if the destination is |
* uncachable, so only use it on software surfaces |
*/ |
if((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) { |
if(dstrect->w >= 8) { |
/* |
* 64-bit stores are probably most |
* efficient to uncached video memory |
*/ |
double fill; |
memset(&fill, color, (sizeof fill)); |
for(y = dstrect->h; y; y--) { |
Uint8 *d = row; |
unsigned n = x; |
unsigned nn; |
Uint8 c = color; |
double f = fill; |
while((unsigned long)d |
& (sizeof(double) - 1)) { |
*d++ = c; |
n--; |
} |
nn = n / (sizeof(double) * 4); |
while(nn) { |
((double *)d)[0] = f; |
((double *)d)[1] = f; |
((double *)d)[2] = f; |
((double *)d)[3] = f; |
d += 4*sizeof(double); |
nn--; |
} |
n &= ~(sizeof(double) * 4 - 1); |
nn = n / sizeof(double); |
while(nn) { |
*(double *)d = f; |
d += sizeof(double); |
nn--; |
} |
n &= ~(sizeof(double) - 1); |
while(n) { |
*d++ = c; |
n--; |
} |
row += dst->pitch; |
} |
} else { |
/* narrow boxes */ |
for(y = dstrect->h; y; y--) { |
Uint8 *d = row; |
Uint8 c = color; |
int n = x; |
while(n) { |
*d++ = c; |
n--; |
} |
row += dst->pitch; |
} |
} |
} else |
#endif /* __powerpc__ */ |
{ |
for(y = dstrect->h; y; y--) { |
memset(row, color, x); |
row += dst->pitch; |
} |
} |
} |
} else { |
switch (dst->format->BytesPerPixel) { |
case 2: |
for ( y=dstrect->h; y; --y ) { |
Uint16 *pixels = (Uint16 *)row; |
Uint16 c = color; |
Uint32 cc = (Uint32)c << 16 | c; |
int n = dstrect->w; |
if((unsigned long)pixels & 3) { |
*pixels++ = c; |
n--; |
} |
if(n >> 1) |
SDL_memset4(pixels, cc, n >> 1); |
if(n & 1) |
pixels[n - 1] = c; |
row += dst->pitch; |
} |
break; |
case 3: |
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) |
color <<= 8; |
for ( y=dstrect->h; y; --y ) { |
Uint8 *pixels = row; |
for ( x=dstrect->w; x; --x ) { |
memcpy(pixels, &color, 3); |
pixels += 3; |
} |
row += dst->pitch; |
} |
break; |
case 4: |
for(y = dstrect->h; y; --y) { |
SDL_memset4(row, color, dstrect->w); |
row += dst->pitch; |
} |
break; |
} |
} |
SDL_UnlockSurface(dst); |
/* We're done! */ |
return(0); |
} |
/* |
* Lock a surface to directly access the pixels |
* -- Do not call this from any blit function, as SDL_DrawCursor() may recurse |
* Instead, use: |
* if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) |
* video->LockHWSurface(video, surface); |
*/ |
int SDL_LockSurface (SDL_Surface *surface) |
{ |
if ( ! surface->locked ) { |
/* Perform the lock */ |
if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
if ( video->LockHWSurface(this, surface) < 0 ) { |
return(-1); |
} |
} |
if ( surface->flags & SDL_RLEACCEL ) { |
SDL_UnRLESurface(surface, 1); |
surface->flags |= SDL_RLEACCEL; /* save accel'd state */ |
} |
/* This needs to be done here in case pixels changes value */ |
surface->pixels = (Uint8 *)surface->pixels + surface->offset; |
} |
/* Increment the surface lock count, for recursive locks */ |
++surface->locked; |
/* Ready to go.. */ |
return(0); |
} |
/* |
* Unlock a previously locked surface |
* -- Do not call this from any blit function, as SDL_DrawCursor() may recurse |
* Instead, use: |
* if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) |
* video->UnlockHWSurface(video, surface); |
*/ |
void SDL_UnlockSurface (SDL_Surface *surface) |
{ |
/* Only perform an unlock if we are locked */ |
if ( ! surface->locked || (--surface->locked > 0) ) { |
return; |
} |
/* Perform the unlock */ |
surface->pixels = (Uint8 *)surface->pixels - surface->offset; |
/* Unlock hardware or accelerated surfaces */ |
if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
video->UnlockHWSurface(this, surface); |
} else { |
/* Update RLE encoded surface with new data */ |
if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { |
surface->flags &= ~SDL_RLEACCEL; /* stop lying */ |
SDL_RLESurface(surface); |
} |
} |
} |
/* |
* Convert a surface into the specified pixel format. |
*/ |
SDL_Surface * SDL_ConvertSurface (SDL_Surface *surface, |
SDL_PixelFormat *format, Uint32 flags) |
{ |
SDL_Surface *convert; |
Uint32 colorkey = 0; |
Uint8 alpha = 0; |
Uint32 surface_flags; |
SDL_Rect bounds; |
/* Check for empty destination palette! (results in empty image) */ |
if ( format->palette != NULL ) { |
int i; |
for ( i=0; i<format->palette->ncolors; ++i ) { |
if ( (format->palette->colors[i].r != 0) || |
(format->palette->colors[i].g != 0) || |
(format->palette->colors[i].b != 0) ) |
break; |
} |
if ( i == format->palette->ncolors ) { |
SDL_SetError("Empty destination palette"); |
return(NULL); |
} |
} |
/* Create a new surface with the desired format */ |
convert = SDL_CreateRGBSurface(flags, |
surface->w, surface->h, format->BitsPerPixel, |
format->Rmask, format->Gmask, format->Bmask, format->Amask); |
if ( convert == NULL ) { |
return(NULL); |
} |
/* Copy the palette if any */ |
if ( format->palette && convert->format->palette ) { |
memcpy(convert->format->palette->colors, |
format->palette->colors, |
format->palette->ncolors*sizeof(SDL_Color)); |
convert->format->palette->ncolors = format->palette->ncolors; |
} |
/* Save the original surface color key and alpha */ |
surface_flags = surface->flags; |
if ( (surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { |
/* Convert colourkeyed surfaces to RGBA if requested */ |
if((flags & SDL_SRCCOLORKEY) != SDL_SRCCOLORKEY |
&& format->Amask) { |
surface_flags &= ~SDL_SRCCOLORKEY; |
} else { |
colorkey = surface->format->colorkey; |
SDL_SetColorKey(surface, 0, 0); |
} |
} |
if ( (surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { |
alpha = surface->format->alpha; |
SDL_SetAlpha(surface, 0, 0); |
} |
/* Copy over the image data */ |
bounds.x = 0; |
bounds.y = 0; |
bounds.w = surface->w; |
bounds.h = surface->h; |
SDL_LowerBlit(surface, &bounds, convert, &bounds); |
/* Clean up the original surface, and update converted surface */ |
if ( convert != NULL ) { |
SDL_SetClipRect(convert, &surface->clip_rect); |
} |
if ( (surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { |
Uint32 cflags = surface_flags&(SDL_SRCCOLORKEY|SDL_RLEACCELOK); |
if ( convert != NULL ) { |
Uint8 keyR, keyG, keyB; |
SDL_GetRGB(colorkey,surface->format,&keyR,&keyG,&keyB); |
SDL_SetColorKey(convert, cflags|(flags&SDL_RLEACCELOK), |
SDL_MapRGB(convert->format, keyR, keyG, keyB)); |
} |
SDL_SetColorKey(surface, cflags, colorkey); |
} |
if ( (surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { |
Uint32 aflags = surface_flags&(SDL_SRCALPHA|SDL_RLEACCELOK); |
if ( convert != NULL ) { |
SDL_SetAlpha(convert, aflags|(flags&SDL_RLEACCELOK), |
alpha); |
} |
SDL_SetAlpha(surface, aflags, alpha); |
} |
/* We're ready to go! */ |
return(convert); |
} |
/* |
* Free a surface created by the above function. |
*/ |
void SDL_FreeSurface (SDL_Surface *surface) |
{ |
/* Free anything that's not NULL, and not the screen surface */ |
if ((surface == NULL) || |
(current_video && |
((surface == SDL_ShadowSurface)||(surface == SDL_VideoSurface)))) { |
return; |
} |
if ( --surface->refcount > 0 ) { |
return; |
} |
if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { |
SDL_UnRLESurface(surface, 0); |
} |
if ( surface->format ) { |
SDL_FreeFormat(surface->format); |
surface->format = NULL; |
} |
if ( surface->map != NULL ) { |
SDL_FreeBlitMap(surface->map); |
surface->map = NULL; |
} |
if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
video->FreeHWSurface(this, surface); |
} |
if ( surface->pixels && |
((surface->flags & SDL_PREALLOC) != SDL_PREALLOC) ) { |
free(surface->pixels); |
} |
free(surface); |
#ifdef CHECK_LEAKS |
--surfaces_allocated; |
#endif |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_sysvideo.h |
---|
0,0 → 1,399 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_sysvideo.h,v 1.6 2001/06/19 13:33:53 hercules Exp $"; |
#endif |
#ifndef _SDL_sysvideo_h |
#define _SDL_sysvideo_h |
#include "SDL_mouse.h" |
#define SDL_PROTOTYPES_ONLY |
#include "SDL_syswm.h" |
#undef SDL_PROTOTYPES_ONLY |
/* This file prototypes the video driver implementation. |
This is designed to be easily converted to C++ in the future. |
*/ |
/* OpenGL is pretty much available on all Windows systems */ |
#ifdef WIN32UNDEFINED |
#ifndef _WIN32_WCE |
#define HAVE_OPENGL |
#endif |
#include <windows.h> |
#endif |
#ifdef HAVE_OPENGL |
#ifdef MACOSX |
#include <OpenGL/gl.h> /* OpenGL.framework */ |
#else |
#include <GL/gl.h> |
#endif /* MACOSX */ |
#endif /* HAVE_OPENGL */ |
/* The SDL video driver */ |
typedef struct SDL_VideoDevice SDL_VideoDevice; |
/* Define the SDL video driver structure */ |
#define _THIS SDL_VideoDevice *_this |
#ifndef _STATUS |
#define _STATUS SDL_status *status |
#endif |
struct SDL_VideoDevice { |
/* * * */ |
/* The name of this video driver */ |
const char *name; |
/* * * */ |
/* Initialization/Query functions */ |
/* Initialize the native video subsystem, filling 'vformat' with the |
"best" display pixel format, returning 0 or -1 if there's an error. |
*/ |
int (*VideoInit)(_THIS, SDL_PixelFormat *vformat); |
/* List the available video modes for the given pixel format, sorted |
from largest to smallest. |
*/ |
SDL_Rect **(*ListModes)(_THIS, SDL_PixelFormat *format, Uint32 flags); |
/* Set the requested video mode, returning a surface which will be |
set to the SDL_VideoSurface. The width and height will already |
be verified by ListModes(), and the video subsystem is free to |
set the mode to a supported bit depth different from the one |
specified -- the desired bpp will be emulated with a shadow |
surface if necessary. If a new mode is returned, this function |
should take care of cleaning up the current mode. |
*/ |
SDL_Surface *(*SetVideoMode)(_THIS, SDL_Surface *current, |
int width, int height, int bpp, Uint32 flags); |
/* Toggle the fullscreen mode */ |
int (*ToggleFullScreen)(_THIS, int on); |
/* This is called after the video mode has been set, to get the |
initial mouse state. It should queue events as necessary to |
properly represent the current mouse focus and position. |
*/ |
void (*UpdateMouse)(_THIS); |
/* Create a YUV video surface (possibly overlay) of the given |
format. The hardware should be able to perform at least 2x |
scaling on display. |
*/ |
SDL_Overlay *(*CreateYUVOverlay)(_THIS, int width, int height, |
Uint32 format, SDL_Surface *display); |
/* Sets the color entries { firstcolor .. (firstcolor+ncolors-1) } |
of the physical palette to those in 'colors'. If the device is |
using a software palette (SDL_HWPALETTE not set), then the |
changes are reflected in the logical palette of the screen |
as well. |
The return value is 1 if all entries could be set properly |
or 0 otherwise. |
*/ |
int (*SetColors)(_THIS, int firstcolor, int ncolors, |
SDL_Color *colors); |
/* This pointer should exist in the native video subsystem and should |
point to an appropriate update function for the current video mode |
*/ |
void (*UpdateRects)(_THIS, int numrects, SDL_Rect *rects); |
/* Reverse the effects VideoInit() -- called if VideoInit() fails |
or if the application is shutting down the video subsystem. |
*/ |
void (*VideoQuit)(_THIS); |
/* * * */ |
/* Hardware acceleration functions */ |
/* Information about the video hardware */ |
SDL_VideoInfo info; |
/* Allocates a surface in video memory */ |
int (*AllocHWSurface)(_THIS, SDL_Surface *surface); |
/* Sets the hardware accelerated blit function, if any, based |
on the current flags of the surface (colorkey, alpha, etc.) |
*/ |
int (*CheckHWBlit)(_THIS, SDL_Surface *src, SDL_Surface *dst); |
/* Fills a surface rectangle with the given color */ |
int (*FillHWRect)(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color); |
/* Sets video mem colorkey and accelerated blit function */ |
int (*SetHWColorKey)(_THIS, SDL_Surface *surface, Uint32 key); |
/* Sets per surface hardware alpha value */ |
int (*SetHWAlpha)(_THIS, SDL_Surface *surface, Uint8 value); |
/* Returns a readable/writable surface */ |
int (*LockHWSurface)(_THIS, SDL_Surface *surface); |
void (*UnlockHWSurface)(_THIS, SDL_Surface *surface); |
/* Performs hardware flipping */ |
int (*FlipHWSurface)(_THIS, SDL_Surface *surface); |
/* Frees a previously allocated video surface */ |
void (*FreeHWSurface)(_THIS, SDL_Surface *surface); |
/* * * */ |
/* Gamma support */ |
Uint16 *gamma; |
/* Set the gamma correction directly (emulated with gamma ramps) */ |
int (*SetGamma)(_THIS, float red, float green, float blue); |
/* Get the gamma correction directly (emulated with gamma ramps) */ |
int (*GetGamma)(_THIS, float *red, float *green, float *blue); |
/* Set the gamma ramp */ |
int (*SetGammaRamp)(_THIS, Uint16 *ramp); |
/* Get the gamma ramp */ |
int (*GetGammaRamp)(_THIS, Uint16 *ramp); |
/* * * */ |
/* OpenGL support */ |
/* Sets the dll to use for OpenGL and loads it */ |
int (*GL_LoadLibrary)(_THIS, const char *path); |
/* Retrieves the address of a function in the gl library */ |
void* (*GL_GetProcAddress)(_THIS, const char *proc); |
/* Get attribute information from the windowing system. */ |
int (*GL_GetAttribute)(_THIS, SDL_GLattr attrib, int* value); |
/* Make the context associated with this driver current */ |
int (*GL_MakeCurrent)(_THIS); |
/* Swap the current buffers in double buffer mode. */ |
void (*GL_SwapBuffers)(_THIS); |
/* OpenGL functions for SDL_OPENGLBLIT */ |
#ifdef HAVE_OPENGL |
#ifndef WIN32UNDEFINED |
#define WINAPI |
#endif |
#define SDL_PROC(ret,func,params) ret (WINAPI *func) params; |
#include "SDL_glfuncs.h" |
#undef SDL_PROC |
/* Texture id */ |
GLuint texture; |
#endif |
int is_32bit; |
/* * * */ |
/* Window manager functions */ |
/* Set the title and icon text */ |
void (*SetCaption)(_THIS, const char *title, const char *icon); |
/* Set the window icon image */ |
void (*SetIcon)(_THIS, SDL_Surface *icon, Uint8 *mask); |
/* Iconify the window. |
This function returns 1 if there is a window manager and the |
window was actually iconified, it returns 0 otherwise. |
*/ |
int (*IconifyWindow)(_THIS); |
/* Grab or ungrab keyboard and mouse input */ |
SDL_GrabMode (*GrabInput)(_THIS, SDL_GrabMode mode); |
/* Get some platform dependent window information */ |
int (*GetWMInfo)(_THIS, SDL_SysWMinfo *info); |
/* * * */ |
/* Cursor manager functions */ |
/* Free a window manager cursor |
This function can be NULL if CreateWMCursor is also NULL. |
*/ |
void (*FreeWMCursor)(_THIS, WMcursor *cursor); |
/* If not NULL, create a black/white window manager cursor */ |
WMcursor *(*CreateWMCursor)(_THIS, |
Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); |
/* Show the specified cursor, or hide if cursor is NULL */ |
int (*ShowWMCursor)(_THIS, WMcursor *cursor); |
/* Warp the window manager cursor to (x,y) |
If NULL, a mouse motion event is posted internally. |
*/ |
void (*WarpWMCursor)(_THIS, Uint16 x, Uint16 y); |
/* If not NULL, this is called when a mouse motion event occurs */ |
void (*MoveWMCursor)(_THIS, int x, int y); |
/* Determine whether the mouse should be in relative mode or not. |
This function is called when the input grab state or cursor |
visibility state changes. |
If the cursor is not visible, and the input is grabbed, the |
driver can place the mouse in relative mode, which may result |
in higher accuracy sampling of the pointer motion. |
*/ |
void (*CheckMouseMode)(_THIS); |
/* * * */ |
/* Event manager functions */ |
/* Initialize keyboard mapping for this driver */ |
void (*InitOSKeymap)(_THIS); |
/* Handle any queued OS events */ |
void (*PumpEvents)(_THIS); |
/* * * */ |
/* Data common to all drivers */ |
SDL_Surface *screen; |
SDL_Surface *shadow; |
SDL_Surface *visible; |
SDL_Palette *physpal; /* physical palette, if != logical palette */ |
SDL_Color *gammacols; /* gamma-corrected colours, or NULL */ |
char *wm_title; |
char *wm_icon; |
int offset_x; |
int offset_y; |
SDL_GrabMode input_grab; |
/* Driver information flags */ |
int handles_any_size; /* Driver handles any size video mode */ |
/* * * */ |
/* Data used by the GL drivers */ |
struct { |
int red_size; |
int green_size; |
int blue_size; |
int alpha_size; |
int depth_size; |
int buffer_size; |
int stencil_size; |
int double_buffer; |
int accum_red_size; |
int accum_green_size; |
int accum_blue_size; |
int accum_alpha_size; |
int driver_loaded; |
char driver_path[256]; |
void* dll_handle; |
} gl_config; |
/* * * */ |
/* Data private to this driver */ |
struct SDL_PrivateVideoData *hidden; |
struct SDL_PrivateGLData *gl_data; |
/* * * */ |
/* The function used to dispose of this structure */ |
void (*free)(_THIS); |
}; |
#undef _THIS |
typedef struct VideoBootStrap { |
const char *name; |
const char *desc; |
int (*available)(void); |
SDL_VideoDevice *(*create)(int devindex); |
} VideoBootStrap; |
#ifdef ENABLE_X11 |
extern VideoBootStrap X11_bootstrap; |
#endif |
#ifdef ENABLE_DGA |
extern VideoBootStrap DGA_bootstrap; |
#endif |
#ifdef ENABLE_NANOX |
extern VideoBootStrap NX_bootstrap; |
#endif |
#ifdef ENABLE_FBCON |
extern VideoBootStrap FBCON_bootstrap; |
#endif |
#ifdef ENABLE_PS2GS |
extern VideoBootStrap PS2GS_bootstrap; |
#endif |
#ifdef ENABLE_GGI |
extern VideoBootStrap GGI_bootstrap; |
#endif |
#ifdef ENABLE_VGL |
extern VideoBootStrap VGL_bootstrap; |
#endif |
#ifdef ENABLE_SVGALIB |
extern VideoBootStrap SVGALIB_bootstrap; |
#endif |
#ifdef ENABLE_AALIB |
extern VideoBootStrap AALIB_bootstrap; |
#endif |
#ifdef ENABLE_WINDIB |
extern VideoBootStrap WINDIB_bootstrap; |
#endif |
#ifdef ENABLE_DIRECTX |
extern VideoBootStrap DIRECTX_bootstrap; |
#endif |
#ifdef ENABLE_BWINDOW |
extern VideoBootStrap BWINDOW_bootstrap; |
#endif |
#ifdef ENABLE_DUMMYVIDEO |
extern VideoBootStrap DUMMY_bootstrap; |
#endif |
#ifdef ENABLE_PHOTON |
extern VideoBootStrap ph_bootstrap; |
#endif |
/* MacOS X gets the proper defines from configure */ |
#if defined(macintosh) && !defined(MACOSX) |
#define ENABLE_TOOLBOX |
#if !TARGET_API_MAC_CARBON |
#define ENABLE_DRAWSPROCKET |
#endif |
#endif |
#ifdef ENABLE_TOOLBOX |
extern VideoBootStrap TOOLBOX_bootstrap; |
#endif |
#ifdef ENABLE_DRAWSPROCKET |
extern VideoBootStrap DSp_bootstrap; |
#endif |
#ifdef ENABLE_QUARTZ |
extern VideoBootStrap QZ_bootstrap; |
#endif |
#ifdef ENABLE_CYBERGRAPHICS |
extern VideoBootStrap CGX_bootstrap; |
#endif |
#ifdef ENABLE_MENUETOS |
extern VideoBootStrap mosvideo_bootstrab; |
#endif |
/* This is the current video device */ |
extern SDL_VideoDevice *current_video; |
#define SDL_VideoSurface (current_video->screen) |
#define SDL_ShadowSurface (current_video->shadow) |
#define SDL_PublicSurface (current_video->visible) |
#endif /* _SDL_sysvideo_h */ |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_video.c |
---|
0,0 → 1,1802 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* The high-level video driver subsystem */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "SDL.h" |
#include "SDL_error.h" |
#include "SDL_video.h" |
#include "SDL_events.h" |
#include "SDL_mutex.h" |
#include "SDL_sysvideo.h" |
#include "SDL_sysevents.h" |
#include "SDL_blit.h" |
#include "SDL_pixels_c.h" |
#include "SDL_events_c.h" |
#include "SDL_cursor_c.h" |
/* Available video drivers */ |
static VideoBootStrap *bootstrap[] = { |
#ifdef ENABLE_X11 |
&X11_bootstrap, |
#endif |
#ifdef ENABLE_DGA |
&DGA_bootstrap, |
#endif |
#ifdef ENABLE_NANOX |
&NX_bootstrap, |
#endif |
#ifdef ENABLE_FBCON |
&FBCON_bootstrap, |
#endif |
#ifdef ENABLE_PS2GS |
&PS2GS_bootstrap, |
#endif |
#ifdef ENABLE_GGI |
&GGI_bootstrap, |
#endif |
#ifdef ENABLE_VGL |
&VGL_bootstrap, |
#endif |
#ifdef ENABLE_SVGALIB |
&SVGALIB_bootstrap, |
#endif |
#ifdef ENABLE_AALIB |
&AALIB_bootstrap, |
#endif |
#ifdef ENABLE_DIRECTX |
&DIRECTX_bootstrap, |
#endif |
#ifdef ENABLE_WINDIB |
&WINDIB_bootstrap, |
#endif |
#ifdef ENABLE_BWINDOW |
&BWINDOW_bootstrap, |
#endif |
#ifdef ENABLE_TOOLBOX |
&TOOLBOX_bootstrap, |
#endif |
#ifdef ENABLE_DRAWSPROCKET |
&DSp_bootstrap, |
#endif |
#ifdef ENABLE_QUARTZ |
&QZ_bootstrap, |
#endif |
#ifdef ENABLE_CYBERGRAPHICS |
&CGX_bootstrap, |
#endif |
#ifdef ENABLE_DUMMYVIDEO |
&DUMMY_bootstrap, |
#endif |
#ifdef ENABLE_PHOTON |
&ph_bootstrap, |
#endif |
#ifdef ENABLE_MENUETOS |
&mosvideo_bootstrab, |
#endif |
NULL |
}; |
SDL_VideoDevice *current_video = NULL; |
/* Various local functions */ |
int SDL_VideoInit(const char *driver_name, Uint32 flags); |
void SDL_VideoQuit(void); |
void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect* rects); |
static SDL_GrabMode SDL_WM_GrabInputOff(void); |
#ifdef HAVE_OPENGL |
static int lock_count = 0; |
#endif |
/* |
* Initialize the video and event subsystems -- determine native pixel format |
*/ |
int SDL_VideoInit (const char *driver_name, Uint32 flags) |
{ |
SDL_VideoDevice *video; |
int index; |
int i; |
SDL_PixelFormat vformat; |
Uint32 video_flags; |
/* Toggle the event thread flags, based on OS requirements */ |
#if defined(MUST_THREAD_EVENTS) |
flags |= SDL_INIT_EVENTTHREAD; |
#elif defined(CANT_THREAD_EVENTS) |
if ( (flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD ) { |
SDL_SetError("OS doesn't support threaded events"); |
return(-1); |
} |
#endif |
/* Check to make sure we don't overwrite 'current_video' */ |
if ( current_video != NULL ) { |
SDL_VideoQuit(); |
} |
/* Select the proper video driver */ |
index = 0; |
video = NULL; |
if ( driver_name != NULL ) { |
for ( i=0; bootstrap[i]; ++i ) { |
if ( strncmp(bootstrap[i]->name, driver_name, |
strlen(bootstrap[i]->name)) == 0 ) { |
if ( bootstrap[i]->available() ) { |
video = bootstrap[i]->create(index); |
break; |
} |
} |
} |
} else { |
for ( i=0; bootstrap[i]; ++i ) { |
if ( bootstrap[i]->available() ) { |
video = bootstrap[i]->create(index); |
if ( video != NULL ) { |
break; |
} |
} |
} |
} |
if ( video == NULL ) { |
SDL_SetError("No available video device"); |
return(-1); |
} |
current_video = video; |
current_video->name = bootstrap[i]->name; |
/* Do some basic variable initialization */ |
video->screen = NULL; |
video->shadow = NULL; |
video->visible = NULL; |
video->physpal = NULL; |
video->gammacols = NULL; |
video->gamma = NULL; |
video->wm_title = NULL; |
video->wm_icon = NULL; |
video->offset_x = 0; |
video->offset_y = 0; |
memset(&video->info, 0, (sizeof video->info)); |
/* Set some very sane GL defaults */ |
video->gl_config.driver_loaded = 0; |
video->gl_config.dll_handle = NULL; |
video->gl_config.red_size = 5; |
#if 1 /* This seems to work on more video cards, as a default */ |
video->gl_config.green_size = 5; |
#else |
video->gl_config.green_size = 6; |
#endif |
video->gl_config.blue_size = 5; |
video->gl_config.alpha_size = 0; |
video->gl_config.buffer_size = 0; |
video->gl_config.depth_size = 16; |
video->gl_config.stencil_size = 0; |
video->gl_config.double_buffer = 1; |
video->gl_config.accum_red_size = 0; |
video->gl_config.accum_green_size = 0; |
video->gl_config.accum_blue_size = 0; |
video->gl_config.accum_alpha_size = 0; |
/* Initialize the video subsystem */ |
memset(&vformat, 0, sizeof(vformat)); |
if ( video->VideoInit(video, &vformat) < 0 ) { |
SDL_VideoQuit(); |
return(-1); |
} |
/* Create a zero sized video surface of the appropriate format */ |
video_flags = SDL_SWSURFACE; |
SDL_VideoSurface = SDL_CreateRGBSurface(video_flags, 0, 0, |
vformat.BitsPerPixel, |
vformat.Rmask, vformat.Gmask, vformat.Bmask, 0); |
if ( SDL_VideoSurface == NULL ) { |
SDL_VideoQuit(); |
return(-1); |
} |
SDL_PublicSurface = NULL; /* Until SDL_SetVideoMode() */ |
#if 0 /* Don't change the current palette - may be used by other programs. |
* The application can't do anything with the display surface until |
* a video mode has been set anyway. :) |
*/ |
/* If we have a palettized surface, create a default palette */ |
if ( SDL_VideoSurface->format->palette ) { |
SDL_PixelFormat *vf = SDL_VideoSurface->format; |
SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel); |
video->SetColors(video, |
0, vf->palette->ncolors, vf->palette->colors); |
} |
#endif |
video->info.vfmt = SDL_VideoSurface->format; |
/* Start the event loop */ |
if ( SDL_StartEventLoop(flags) < 0 ) { |
SDL_VideoQuit(); |
return(-1); |
} |
SDL_CursorInit(flags & SDL_INIT_EVENTTHREAD); |
/* We're ready to go! */ |
return(0); |
} |
char *SDL_VideoDriverName(char *namebuf, int maxlen) |
{ |
if ( current_video != NULL ) { |
strncpy(namebuf, current_video->name, maxlen-1); |
namebuf[maxlen-1] = '\0'; |
return(namebuf); |
} |
return(NULL); |
} |
/* |
* Get the current display surface |
*/ |
SDL_Surface *SDL_GetVideoSurface(void) |
{ |
SDL_Surface *visible; |
visible = NULL; |
if ( current_video ) { |
visible = current_video->visible; |
} |
return(visible); |
} |
/* |
* Get the current information about the video hardware |
*/ |
const SDL_VideoInfo *SDL_GetVideoInfo(void) |
{ |
const SDL_VideoInfo *info; |
info = NULL; |
if ( current_video ) { |
info = ¤t_video->info; |
} |
return(info); |
} |
/* |
* Return a pointer to an array of available screen dimensions for the |
* given format, sorted largest to smallest. Returns NULL if there are |
* no dimensions available for a particular format, or (SDL_Rect **)-1 |
* if any dimension is okay for the given format. If 'format' is NULL, |
* the mode list will be for the format given by SDL_GetVideoInfo()->vfmt |
*/ |
SDL_Rect ** SDL_ListModes (SDL_PixelFormat *format, Uint32 flags) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
SDL_Rect **modes; |
modes = NULL; |
if ( SDL_VideoSurface ) { |
if ( format == NULL ) { |
format = SDL_VideoSurface->format; |
} |
modes = video->ListModes(this, format, flags); |
} |
return(modes); |
} |
/* |
* Check to see if a particular video mode is supported. |
* It returns 0 if the requested mode is not supported under any bit depth, |
* or returns the bits-per-pixel of the closest available mode with the |
* given width and height. If this bits-per-pixel is different from the |
* one used when setting the video mode, SDL_SetVideoMode() will succeed, |
* but will emulate the requested bits-per-pixel with a shadow surface. |
*/ |
static Uint8 SDL_closest_depths[4][8] = { |
/* 8 bit closest depth ordering */ |
{ 0, 8, 16, 15, 32, 24, 0, 0 }, |
/* 15,16 bit closest depth ordering */ |
{ 0, 16, 15, 32, 24, 8, 0, 0 }, |
/* 24 bit closest depth ordering */ |
{ 0, 24, 32, 16, 15, 8, 0, 0 }, |
/* 32 bit closest depth ordering */ |
{ 0, 32, 16, 15, 24, 8, 0, 0 } |
}; |
int SDL_VideoModeOK (int width, int height, int bpp, Uint32 flags) |
{ |
int table, b, i; |
int supported; |
SDL_PixelFormat format; |
SDL_Rect **sizes; |
/* Currently 1 and 4 bpp are not supported */ |
if ( bpp < 8 || bpp > 32 ) { |
return(0); |
} |
if ( (width == 0) || (height == 0) ) { |
return(0); |
} |
/* Search through the list valid of modes */ |
memset(&format, 0, sizeof(format)); |
supported = 0; |
table = ((bpp+7)/8)-1; |
SDL_closest_depths[table][0] = bpp; |
SDL_closest_depths[table][7] = 0; |
for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) { |
format.BitsPerPixel = SDL_closest_depths[table][b]; |
sizes = SDL_ListModes(&format, flags); |
if ( sizes == (SDL_Rect **)0 ) { |
/* No sizes supported at this bit-depth */ |
continue; |
} else |
#ifdef macintosh /* MPW optimization bug? */ |
if ( (sizes == (SDL_Rect **)0xFFFFFFFF) || |
#else |
if ( (sizes == (SDL_Rect **)-1) || |
#endif |
current_video->handles_any_size ) { |
/* Any size supported at this bit-depth */ |
supported = 1; |
continue; |
} else |
for ( i=0; sizes[i]; ++i ) { |
if ((sizes[i]->w == width) && (sizes[i]->h == height)) { |
supported = 1; |
break; |
} |
} |
} |
if ( supported ) { |
--b; |
return(SDL_closest_depths[table][b]); |
} else { |
return(0); |
} |
} |
/* |
* Get the closest non-emulated video mode to the one requested |
*/ |
static int SDL_GetVideoMode (int *w, int *h, int *BitsPerPixel, Uint32 flags) |
{ |
int table, b, i; |
int supported; |
int native_bpp; |
SDL_PixelFormat format; |
SDL_Rect **sizes; |
/* Try the original video mode, get the closest depth */ |
native_bpp = SDL_VideoModeOK(*w, *h, *BitsPerPixel, flags); |
if ( native_bpp == *BitsPerPixel ) { |
return(1); |
} |
if ( native_bpp > 0 ) { |
*BitsPerPixel = native_bpp; |
return(1); |
} |
/* No exact size match at any depth, look for closest match */ |
memset(&format, 0, sizeof(format)); |
supported = 0; |
table = ((*BitsPerPixel+7)/8)-1; |
SDL_closest_depths[table][0] = *BitsPerPixel; |
SDL_closest_depths[table][7] = SDL_VideoSurface->format->BitsPerPixel; |
for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) { |
format.BitsPerPixel = SDL_closest_depths[table][b]; |
sizes = SDL_ListModes(&format, flags); |
if ( sizes == (SDL_Rect **)0 ) { |
/* No sizes supported at this bit-depth */ |
continue; |
} |
for ( i=0; sizes[i]; ++i ) { |
if ((sizes[i]->w < *w) || (sizes[i]->h < *h)) { |
if ( i > 0 ) { |
--i; |
*w = sizes[i]->w; |
*h = sizes[i]->h; |
*BitsPerPixel = SDL_closest_depths[table][b]; |
supported = 1; |
} else { |
/* Largest mode too small... */; |
} |
break; |
} |
} |
if ( (i > 0) && ! sizes[i] ) { |
/* The smallest mode was larger than requested, OK */ |
--i; |
*w = sizes[i]->w; |
*h = sizes[i]->h; |
*BitsPerPixel = SDL_closest_depths[table][b]; |
supported = 1; |
} |
} |
if ( ! supported ) { |
SDL_SetError("No video mode large enough for %dx%d", *w, *h); |
} |
return(supported); |
} |
/* This should probably go somewhere else -- like SDL_surface.c */ |
static void SDL_ClearSurface(SDL_Surface *surface) |
{ |
Uint32 black; |
black = SDL_MapRGB(surface->format, 0, 0, 0); |
SDL_FillRect(surface, NULL, black); |
if ((surface->flags&SDL_HWSURFACE) && (surface->flags&SDL_DOUBLEBUF)) { |
SDL_Flip(surface); |
SDL_FillRect(surface, NULL, black); |
} |
SDL_Flip(surface); |
} |
/* |
* Create a shadow surface suitable for fooling the app. :-) |
*/ |
static void SDL_CreateShadowSurface(int depth) |
{ |
Uint32 Rmask, Gmask, Bmask; |
/* Allocate the shadow surface */ |
if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) { |
Rmask = (SDL_VideoSurface->format)->Rmask; |
Gmask = (SDL_VideoSurface->format)->Gmask; |
Bmask = (SDL_VideoSurface->format)->Bmask; |
} else { |
Rmask = Gmask = Bmask = 0; |
} |
SDL_ShadowSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, |
SDL_VideoSurface->w, SDL_VideoSurface->h, |
depth, Rmask, Gmask, Bmask, 0); |
if ( SDL_ShadowSurface == NULL ) { |
return; |
} |
/* 8-bit shadow surfaces report that they have exclusive palette */ |
if ( SDL_ShadowSurface->format->palette ) { |
SDL_ShadowSurface->flags |= SDL_HWPALETTE; |
if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) { |
memcpy(SDL_ShadowSurface->format->palette->colors, |
SDL_VideoSurface->format->palette->colors, |
SDL_VideoSurface->format->palette->ncolors* |
sizeof(SDL_Color)); |
} else { |
SDL_DitherColors( |
SDL_ShadowSurface->format->palette->colors, depth); |
} |
} |
/* If the video surface is resizable, the shadow should say so */ |
if ( (SDL_VideoSurface->flags & SDL_RESIZABLE) == SDL_RESIZABLE ) { |
SDL_ShadowSurface->flags |= SDL_RESIZABLE; |
} |
/* If the video surface has no frame, the shadow should say so */ |
if ( (SDL_VideoSurface->flags & SDL_NOFRAME) == SDL_NOFRAME ) { |
SDL_ShadowSurface->flags |= SDL_NOFRAME; |
} |
/* If the video surface is fullscreen, the shadow should say so */ |
if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { |
SDL_ShadowSurface->flags |= SDL_FULLSCREEN; |
} |
/* If the video surface is flippable, the shadow should say so */ |
if ( (SDL_VideoSurface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { |
SDL_ShadowSurface->flags |= SDL_DOUBLEBUF; |
} |
return; |
} |
/* |
* Set the requested video mode, allocating a shadow buffer if necessary. |
*/ |
SDL_Surface * SDL_SetVideoMode (int width, int height, int bpp, Uint32 flags) |
{ |
SDL_VideoDevice *video, *this; |
SDL_Surface *prev_mode, *mode; |
int video_w; |
int video_h; |
int video_bpp; |
int is_opengl; |
SDL_GrabMode saved_grab; |
/* Start up the video driver, if necessary.. |
WARNING: This is the only function protected this way! |
*/ |
if ( ! current_video ) { |
if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0 ) { |
return(NULL); |
} |
} |
this = video = current_video; |
/* Default to the current video bpp */ |
if ( bpp == 0 ) { |
flags |= SDL_ANYFORMAT; |
bpp = SDL_VideoSurface->format->BitsPerPixel; |
} |
/* Get a good video mode, the closest one possible */ |
video_w = width; |
video_h = height; |
video_bpp = bpp; |
if ( ! SDL_GetVideoMode(&video_w, &video_h, &video_bpp, flags) ) { |
return(NULL); |
} |
/* Check the requested flags */ |
/* There's no palette in > 8 bits-per-pixel mode */ |
if ( video_bpp > 8 ) { |
flags &= ~SDL_HWPALETTE; |
} |
#if 0 |
if ( (flags&SDL_FULLSCREEN) != SDL_FULLSCREEN ) { |
/* There's no windowed double-buffering */ |
flags &= ~SDL_DOUBLEBUF; |
} |
#endif |
if ( (flags&SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { |
/* Use hardware surfaces when double-buffering */ |
flags |= SDL_HWSURFACE; |
} |
is_opengl = ( ( flags & SDL_OPENGL ) == SDL_OPENGL ); |
if ( is_opengl ) { |
/* These flags are for 2D video modes only */ |
flags &= ~(SDL_HWSURFACE|SDL_DOUBLEBUF); |
} |
/* Reset the keyboard here so event callbacks can run */ |
SDL_ResetKeyboard(); |
/* Clean up any previous video mode */ |
if ( SDL_PublicSurface != NULL ) { |
SDL_PublicSurface = NULL; |
} |
if ( SDL_ShadowSurface != NULL ) { |
SDL_Surface *ready_to_go; |
ready_to_go = SDL_ShadowSurface; |
SDL_ShadowSurface = NULL; |
SDL_FreeSurface(ready_to_go); |
} |
if ( video->physpal ) { |
free(video->physpal->colors); |
free(video->physpal); |
video->physpal = NULL; |
} |
if( video->gammacols) { |
free(video->gammacols); |
video->gammacols = NULL; |
} |
/* Save the previous grab state and turn off grab for mode switch */ |
saved_grab = SDL_WM_GrabInputOff(); |
/* Try to set the video mode, along with offset and clipping */ |
prev_mode = SDL_VideoSurface; |
SDL_LockCursor(); |
SDL_VideoSurface = NULL; /* In case it's freed by driver */ |
mode = video->SetVideoMode(this, prev_mode,video_w,video_h,video_bpp,flags); |
if ( mode ) { /* Prevent resize events from mode change */ |
SDL_PrivateResize(mode->w, mode->h); |
} |
/* |
* rcg11292000 |
* If you try to set an SDL_OPENGL surface, and fail to find a |
* matching visual, then the next call to SDL_SetVideoMode() |
* will segfault, since we no longer point to a dummy surface, |
* but rather NULL. |
* Sam 11/29/00 |
* WARNING, we need to make sure that the previous mode hasn't |
* already been freed by the video driver. What do we do in |
* that case? Should we call SDL_VideoInit() again? |
*/ |
SDL_VideoSurface = (mode != NULL) ? mode : prev_mode; |
if ( (mode != NULL) && (!is_opengl) ) { |
/* Sanity check */ |
if ( (mode->w < width) || (mode->h < height) ) { |
SDL_SetError("Video mode smaller than requested"); |
return(NULL); |
} |
/* If we have a palettized surface, create a default palette */ |
if ( mode->format->palette ) { |
SDL_PixelFormat *vf = mode->format; |
SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel); |
video->SetColors(this, 0, vf->palette->ncolors, |
vf->palette->colors); |
} |
/* Clear the surface to black */ |
video->offset_x = 0; |
video->offset_y = 0; |
mode->offset = 0; |
SDL_SetClipRect(mode, NULL); |
SDL_ClearSurface(mode); |
/* Now adjust the offsets to match the desired mode */ |
video->offset_x = (mode->w-width)/2; |
video->offset_y = (mode->h-height)/2; |
mode->offset = video->offset_y*mode->pitch + |
video->offset_x*mode->format->BytesPerPixel; |
#ifdef DEBUG_VIDEO |
SDL_printf("Requested mode: %dx%dx%d, obtained mode %dx%dx%d (offset %d)\n", |
width, height, bpp, |
mode->w, mode->h, mode->format->BitsPerPixel, mode->offset); |
#endif |
mode->w = width; |
mode->h = height; |
SDL_SetClipRect(mode, NULL); |
} |
SDL_ResetCursor(); |
SDL_UnlockCursor(); |
/* If we failed setting a video mode, return NULL... (Uh Oh!) */ |
if ( mode == NULL ) { |
return(NULL); |
} |
/* If there is no window manager, set the SDL_NOFRAME flag */ |
if ( ! video->info.wm_available ) { |
mode->flags |= SDL_NOFRAME; |
} |
/* Reset the mouse cursor and grab for new video mode */ |
SDL_SetCursor(NULL); |
if ( video->UpdateMouse ) { |
video->UpdateMouse(this); |
} |
SDL_WM_GrabInput(saved_grab); |
SDL_GetRelativeMouseState(NULL, NULL); /* Clear first large delta */ |
/* If we're running OpenGL, make the context current */ |
if ( (video->screen->flags & SDL_OPENGL) && |
video->GL_MakeCurrent ) { |
if ( video->GL_MakeCurrent(this) < 0 ) { |
return(NULL); |
} |
} |
/* Set up a fake SDL surface for OpenGL "blitting" */ |
if ( (flags & SDL_OPENGLBLIT) == SDL_OPENGLBLIT ) { |
/* Load GL functions for performing the texture updates */ |
#ifdef HAVE_OPENGL |
#define SDL_PROC(ret,func,params) \ |
do { \ |
video->func = SDL_GL_GetProcAddress(#func); \ |
if ( ! video->func ) { \ |
SDL_SetError("Couldn't load GL function: %s\n", #func); \ |
return(NULL); \ |
} \ |
} while ( 0 ); |
#include "SDL_glfuncs.h" |
#undef SDL_PROC |
/* Create a software surface for blitting */ |
#ifdef GL_VERSION_1_2 |
/* If the implementation either supports the packed pixels |
extension, or implements the core OpenGL 1.2 API, it will |
support the GL_UNSIGNED_SHORT_5_6_5 texture format. |
*/ |
if ( (bpp == 16) && |
(strstr((const char *)video->glGetString(GL_EXTENSIONS), |
"GL_EXT_packed_pixels") || |
(strncmp((const char *)video->glGetString(GL_VERSION), |
"1.2", 3) == 0)) ) |
{ |
video->is_32bit = 0; |
SDL_VideoSurface = SDL_CreateRGBSurface( |
flags, |
width, |
height, |
16, |
31 << 11, |
63 << 5, |
31, |
0 |
); |
} |
else |
#endif /* OpenGL 1.2 */ |
{ |
video->is_32bit = 1; |
SDL_VideoSurface = SDL_CreateRGBSurface( |
flags, |
width, |
height, |
32, |
#if SDL_BYTEORDER == SDL_LIL_ENDIAN |
0x000000FF, |
0x0000FF00, |
0x00FF0000, |
0xFF000000 |
#else |
0xFF000000, |
0x00FF0000, |
0x0000FF00, |
0x000000FF |
#endif |
); |
} |
if ( ! SDL_VideoSurface ) { |
return(NULL); |
} |
SDL_VideoSurface->flags = mode->flags | SDL_OPENGLBLIT; |
/* Free the original video mode surface (is this safe?) */ |
SDL_FreeSurface(mode); |
/* Set the surface completely opaque & white by default */ |
memset( SDL_VideoSurface->pixels, 255, SDL_VideoSurface->h * SDL_VideoSurface->pitch ); |
video->glGenTextures( 1, &video->texture ); |
video->glBindTexture( GL_TEXTURE_2D, video->texture ); |
video->glTexImage2D( |
GL_TEXTURE_2D, |
0, |
video->is_32bit ? GL_RGBA : GL_RGB, |
256, |
256, |
0, |
video->is_32bit ? GL_RGBA : GL_RGB, |
#ifdef GL_VERSION_1_2 |
video->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5, |
#else |
GL_UNSIGNED_BYTE, |
#endif |
NULL); |
video->UpdateRects = SDL_GL_UpdateRectsLock; |
#else |
SDL_SetError("Somebody forgot to #define HAVE_OPENGL"); |
return(NULL); |
#endif |
} |
/* Create a shadow surface if necessary */ |
/* There are three conditions under which we create a shadow surface: |
1. We need a particular bits-per-pixel that we didn't get. |
2. We need a hardware palette and didn't get one. |
3. We need a software surface and got a hardware surface. |
*/ |
if ( !(SDL_VideoSurface->flags & SDL_OPENGL) && |
( |
( !(flags&SDL_ANYFORMAT) && |
(SDL_VideoSurface->format->BitsPerPixel != bpp)) || |
( (flags&SDL_HWPALETTE) && |
!(SDL_VideoSurface->flags&SDL_HWPALETTE)) || |
/* If the surface is in hardware, video writes are visible |
as soon as they are performed, so we need to buffer them |
*/ |
( ((flags&SDL_HWSURFACE) == SDL_SWSURFACE) && |
(SDL_VideoSurface->flags&SDL_HWSURFACE)) |
) ) { |
SDL_CreateShadowSurface(bpp); |
if ( SDL_ShadowSurface == NULL ) { |
SDL_SetError("Couldn't create shadow surface"); |
return(NULL); |
} |
SDL_PublicSurface = SDL_ShadowSurface; |
} else { |
SDL_PublicSurface = SDL_VideoSurface; |
} |
video->info.vfmt = SDL_VideoSurface->format; |
/* We're done! */ |
return(SDL_PublicSurface); |
} |
/* |
* Convert a surface into the video pixel format. |
*/ |
SDL_Surface * SDL_DisplayFormat (SDL_Surface *surface) |
{ |
Uint32 flags; |
if ( ! SDL_PublicSurface ) { |
SDL_SetError("No video mode has been set"); |
return(NULL); |
} |
/* Set the flags appropriate for copying to display surface */ |
flags = (SDL_PublicSurface->flags&SDL_HWSURFACE); |
#ifdef AUTORLE_DISPLAYFORMAT |
flags |= (surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA)); |
flags |= SDL_RLEACCELOK; |
#else |
flags |= surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA|SDL_RLEACCELOK); |
#endif |
return(SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags)); |
} |
/* |
* Convert a surface into a format that's suitable for blitting to |
* the screen, but including an alpha channel. |
*/ |
SDL_Surface *SDL_DisplayFormatAlpha(SDL_Surface *surface) |
{ |
SDL_PixelFormat *vf; |
SDL_PixelFormat *format; |
SDL_Surface *converted; |
Uint32 flags; |
/* default to ARGB8888 */ |
Uint32 amask = 0xff000000; |
Uint32 rmask = 0x00ff0000; |
Uint32 gmask = 0x0000ff00; |
Uint32 bmask = 0x000000ff; |
if ( ! SDL_PublicSurface ) { |
SDL_SetError("No video mode has been set"); |
return(NULL); |
} |
vf = SDL_PublicSurface->format; |
switch(vf->BytesPerPixel) { |
case 2: |
/* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}. |
For anything else (like ARGB4444) it doesn't matter |
since we have no special code for it anyway */ |
if ( (vf->Rmask == 0x1f) && |
(vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) { |
rmask = 0xff; |
bmask = 0xff0000; |
} |
break; |
case 3: |
case 4: |
/* Keep the video format, as long as the high 8 bits are |
unused or alpha */ |
if ( (vf->Rmask == 0xff) && (vf->Bmask == 0xff0000) ) { |
rmask = 0xff; |
bmask = 0xff0000; |
} |
break; |
default: |
/* We have no other optimised formats right now. When/if a new |
optimised alpha format is written, add the converter here */ |
break; |
} |
format = SDL_AllocFormat(32, rmask, gmask, bmask, amask); |
flags = SDL_PublicSurface->flags & SDL_HWSURFACE; |
flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK); |
converted = SDL_ConvertSurface(surface, format, flags); |
SDL_FreeFormat(format); |
return(converted); |
} |
/* |
* Update a specific portion of the physical screen |
*/ |
void SDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h) |
{ |
if ( screen ) { |
SDL_Rect rect; |
/* Perform some checking */ |
if ( w == 0 ) |
w = screen->w; |
if ( h == 0 ) |
h = screen->h; |
if ( (int)(x+w) > screen->w ) |
return; |
if ( (int)(y+h) > screen->h ) |
return; |
/* Fill the rectangle */ |
rect.x = x; |
rect.y = y; |
rect.w = w; |
rect.h = h; |
SDL_UpdateRects(screen, 1, &rect); |
} |
} |
void SDL_UpdateRects (SDL_Surface *screen, int numrects, SDL_Rect *rects) |
{ |
int i; |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
if ( screen == SDL_ShadowSurface ) { |
/* Blit the shadow surface using saved mapping */ |
SDL_Palette *pal = screen->format->palette; |
SDL_Color *saved_colors = NULL; |
if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) { |
/* simulated 8bpp, use correct physical palette */ |
saved_colors = pal->colors; |
if ( video->gammacols ) { |
/* gamma-corrected palette */ |
pal->colors = video->gammacols; |
} else if ( video->physpal ) { |
/* physical palette different from logical */ |
pal->colors = video->physpal->colors; |
} |
} |
if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { |
SDL_LockCursor(); |
SDL_DrawCursor(SDL_ShadowSurface); |
for ( i=0; i<numrects; ++i ) { |
SDL_LowerBlit(SDL_ShadowSurface, &rects[i], |
SDL_VideoSurface, &rects[i]); |
} |
SDL_EraseCursor(SDL_ShadowSurface); |
SDL_UnlockCursor(); |
} else { |
for ( i=0; i<numrects; ++i ) { |
SDL_LowerBlit(SDL_ShadowSurface, &rects[i], |
SDL_VideoSurface, &rects[i]); |
} |
} |
if ( saved_colors ) |
pal->colors = saved_colors; |
/* Fall through to video surface update */ |
screen = SDL_VideoSurface; |
} |
if ( screen == SDL_VideoSurface ) { |
/* Update the video surface */ |
if ( screen->offset ) { |
for ( i=0; i<numrects; ++i ) { |
rects[i].x += video->offset_x; |
rects[i].y += video->offset_y; |
} |
video->UpdateRects(this, numrects, rects); |
for ( i=0; i<numrects; ++i ) { |
rects[i].x -= video->offset_x; |
rects[i].y -= video->offset_y; |
} |
} else { |
video->UpdateRects(this, numrects, rects); |
} |
} |
} |
/* |
* Performs hardware double buffering, if possible, or a full update if not. |
*/ |
int SDL_Flip(SDL_Surface *screen) |
{ |
SDL_VideoDevice *video = current_video; |
/* Copy the shadow surface to the video surface */ |
if ( screen == SDL_ShadowSurface ) { |
SDL_Rect rect; |
SDL_Palette *pal = screen->format->palette; |
SDL_Color *saved_colors = NULL; |
if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) { |
/* simulated 8bpp, use correct physical palette */ |
saved_colors = pal->colors; |
if ( video->gammacols ) { |
/* gamma-corrected palette */ |
pal->colors = video->gammacols; |
} else if ( video->physpal ) { |
/* physical palette different from logical */ |
pal->colors = video->physpal->colors; |
} |
} |
rect.x = 0; |
rect.y = 0; |
rect.w = screen->w; |
rect.h = screen->h; |
SDL_LowerBlit(SDL_ShadowSurface,&rect, SDL_VideoSurface,&rect); |
if ( saved_colors ) |
pal->colors = saved_colors; |
screen = SDL_VideoSurface; |
} |
if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { |
SDL_VideoDevice *this = current_video; |
return(video->FlipHWSurface(this, SDL_VideoSurface)); |
} else { |
SDL_UpdateRect(screen, 0, 0, 0, 0); |
} |
return(0); |
} |
static void SetPalette_logical(SDL_Surface *screen, SDL_Color *colors, |
int firstcolor, int ncolors) |
{ |
SDL_Palette *pal = screen->format->palette; |
SDL_Palette *vidpal; |
if ( colors != (pal->colors + firstcolor) ) { |
memcpy(pal->colors + firstcolor, colors, |
ncolors * sizeof(*colors)); |
} |
vidpal = SDL_VideoSurface->format->palette; |
if ( (screen == SDL_ShadowSurface) && vidpal ) { |
/* |
* This is a shadow surface, and the physical |
* framebuffer is also indexed. Propagate the |
* changes to its logical palette so that |
* updates are always identity blits |
*/ |
memcpy(vidpal->colors + firstcolor, colors, |
ncolors * sizeof(*colors)); |
} |
SDL_FormatChanged(screen); |
} |
static int SetPalette_physical(SDL_Surface *screen, |
SDL_Color *colors, int firstcolor, int ncolors) |
{ |
SDL_VideoDevice *video = current_video; |
int gotall = 1; |
if ( video->physpal ) { |
/* We need to copy the new colors, since we haven't |
* already done the copy in the logical set above. |
*/ |
memcpy(video->physpal->colors + firstcolor, |
colors, ncolors * sizeof(*colors)); |
} |
if ( screen == SDL_ShadowSurface ) { |
if ( SDL_VideoSurface->flags & SDL_HWPALETTE ) { |
/* |
* The real screen is also indexed - set its physical |
* palette. The physical palette does not include the |
* gamma modification, we apply it directly instead, |
* but this only happens if we have hardware palette. |
*/ |
screen = SDL_VideoSurface; |
} else { |
/* |
* The video surface is not indexed - invalidate any |
* active shadow-to-video blit mappings. |
*/ |
if ( screen->map->dst == SDL_VideoSurface ) { |
SDL_InvalidateMap(screen->map); |
} |
if ( video->gamma ) { |
if( ! video->gammacols ) { |
SDL_Palette *pp = video->physpal; |
if(!pp) |
pp = screen->format->palette; |
video->gammacols = malloc(pp->ncolors |
* sizeof(SDL_Color)); |
SDL_ApplyGamma(video->gamma, |
pp->colors, |
video->gammacols, |
pp->ncolors); |
} else { |
SDL_ApplyGamma(video->gamma, colors, |
video->gammacols |
+ firstcolor, |
ncolors); |
} |
} |
SDL_UpdateRect(screen, 0, 0, 0, 0); |
} |
} |
if ( screen == SDL_VideoSurface ) { |
SDL_Color gcolors[256]; |
if ( video->gamma ) { |
SDL_ApplyGamma(video->gamma, colors, gcolors, ncolors); |
colors = gcolors; |
} |
gotall = video->SetColors(video, firstcolor, ncolors, colors); |
if ( ! gotall ) { |
/* The video flags shouldn't have SDL_HWPALETTE, and |
the video driver is responsible for copying back the |
correct colors into the video surface palette. |
*/ |
; |
} |
SDL_CursorPaletteChanged(); |
} |
return gotall; |
} |
/* |
* Set the physical and/or logical colormap of a surface: |
* Only the screen has a physical colormap. It determines what is actually |
* sent to the display. |
* The logical colormap is used to map blits to/from the surface. |
* 'which' is one or both of SDL_LOGPAL, SDL_PHYSPAL |
* |
* Return nonzero if all colours were set as requested, or 0 otherwise. |
*/ |
int SDL_SetPalette(SDL_Surface *screen, int which, |
SDL_Color *colors, int firstcolor, int ncolors) |
{ |
SDL_Palette *pal; |
int gotall; |
int palsize; |
if ( ! current_video ) { |
return 0; |
} |
if ( screen != SDL_PublicSurface ) { |
/* only screens have physical palettes */ |
which &= ~SDL_PHYSPAL; |
} else if( (screen->flags & SDL_HWPALETTE) != SDL_HWPALETTE ) { |
/* hardware palettes required for split colormaps */ |
which |= SDL_PHYSPAL | SDL_LOGPAL; |
} |
/* Verify the parameters */ |
pal = screen->format->palette; |
if( !pal ) { |
return 0; /* not a palettized surface */ |
} |
gotall = 1; |
palsize = 1 << screen->format->BitsPerPixel; |
if ( ncolors > (palsize - firstcolor) ) { |
ncolors = (palsize - firstcolor); |
gotall = 0; |
} |
if ( which & SDL_LOGPAL ) { |
/* |
* Logical palette change: The actual screen isn't affected, |
* but the internal colormap is altered so that the |
* interpretation of the pixel values (for blits etc) is |
* changed. |
*/ |
SetPalette_logical(screen, colors, firstcolor, ncolors); |
} |
if ( which & SDL_PHYSPAL ) { |
SDL_VideoDevice *video = current_video; |
/* |
* Physical palette change: This doesn't affect the |
* program's idea of what the screen looks like, but changes |
* its actual appearance. |
*/ |
if(!video) |
return gotall; /* video not yet initialized */ |
if(!video->physpal && !(which & SDL_LOGPAL) ) { |
/* Lazy physical palette allocation */ |
int size; |
SDL_Palette *pp = malloc(sizeof(*pp)); |
current_video->physpal = pp; |
pp->ncolors = pal->ncolors; |
size = pp->ncolors * sizeof(SDL_Color); |
pp->colors = malloc(size); |
memcpy(pp->colors, pal->colors, size); |
} |
if ( ! SetPalette_physical(screen, |
colors, firstcolor, ncolors) ) { |
gotall = 0; |
} |
} |
return gotall; |
} |
int SDL_SetColors(SDL_Surface *screen, SDL_Color *colors, int firstcolor, |
int ncolors) |
{ |
return SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL, |
colors, firstcolor, ncolors); |
} |
/* |
* Clean up the video subsystem |
*/ |
void SDL_VideoQuit (void) |
{ |
SDL_Surface *ready_to_go; |
if ( current_video ) { |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
/* Halt event processing before doing anything else */ |
SDL_StopEventLoop(); |
/* Clean up allocated window manager items */ |
if ( SDL_PublicSurface ) { |
SDL_PublicSurface = NULL; |
} |
SDL_CursorQuit(); |
/* Just in case... */ |
SDL_WM_GrabInputOff(); |
/* Clean up the system video */ |
video->VideoQuit(this); |
/* Free any lingering surfaces */ |
ready_to_go = SDL_ShadowSurface; |
SDL_ShadowSurface = NULL; |
SDL_FreeSurface(ready_to_go); |
if ( SDL_VideoSurface != NULL ) { |
ready_to_go = SDL_VideoSurface; |
SDL_VideoSurface = NULL; |
SDL_FreeSurface(ready_to_go); |
} |
SDL_PublicSurface = NULL; |
/* Clean up miscellaneous memory */ |
if ( video->physpal ) { |
free(video->physpal->colors); |
free(video->physpal); |
video->physpal = NULL; |
} |
if ( video->gammacols ) { |
free(video->gammacols); |
video->gammacols = NULL; |
} |
if ( video->gamma ) { |
free(video->gamma); |
video->gamma = NULL; |
} |
if ( video->wm_title != NULL ) { |
free(video->wm_title); |
video->wm_title = NULL; |
} |
if ( video->wm_icon != NULL ) { |
free(video->wm_icon); |
video->wm_icon = NULL; |
} |
/* Finish cleaning up video subsystem */ |
video->free(this); |
current_video = NULL; |
} |
return; |
} |
/* Load the GL driver library */ |
int SDL_GL_LoadLibrary(const char *path) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
int retval; |
retval = -1; |
if ( video && video->GL_LoadLibrary ) { |
retval = video->GL_LoadLibrary(this, path); |
} else { |
SDL_SetError("No dynamic GL support in video driver"); |
} |
return(retval); |
} |
void *SDL_GL_GetProcAddress(const char* proc) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
void *func; |
func = NULL; |
if ( video->GL_GetProcAddress ) { |
if ( video->gl_config.driver_loaded ) { |
func = video->GL_GetProcAddress(this, proc); |
} else { |
SDL_SetError("No GL driver has been loaded"); |
} |
} else { |
SDL_SetError("No dynamic GL support in video driver"); |
} |
return func; |
} |
/* Set the specified GL attribute for setting up a GL video mode */ |
int SDL_GL_SetAttribute( SDL_GLattr attr, int value ) |
{ |
int retval; |
SDL_VideoDevice *video = current_video; |
retval = 0; |
switch (attr) { |
case SDL_GL_RED_SIZE: |
video->gl_config.red_size = value; |
break; |
case SDL_GL_GREEN_SIZE: |
video->gl_config.green_size = value; |
break; |
case SDL_GL_BLUE_SIZE: |
video->gl_config.blue_size = value; |
break; |
case SDL_GL_ALPHA_SIZE: |
video->gl_config.alpha_size = value; |
break; |
case SDL_GL_DOUBLEBUFFER: |
video->gl_config.double_buffer = value; |
break; |
case SDL_GL_BUFFER_SIZE: |
video->gl_config.buffer_size = value; |
break; |
case SDL_GL_DEPTH_SIZE: |
video->gl_config.depth_size = value; |
break; |
case SDL_GL_STENCIL_SIZE: |
video->gl_config.stencil_size = value; |
break; |
case SDL_GL_ACCUM_RED_SIZE: |
video->gl_config.accum_red_size = value; |
break; |
case SDL_GL_ACCUM_GREEN_SIZE: |
video->gl_config.accum_green_size = value; |
break; |
case SDL_GL_ACCUM_BLUE_SIZE: |
video->gl_config.accum_blue_size = value; |
break; |
case SDL_GL_ACCUM_ALPHA_SIZE: |
video->gl_config.accum_alpha_size = value; |
break; |
default: |
SDL_SetError("Unknown OpenGL attribute"); |
retval = -1; |
break; |
} |
return(retval); |
} |
/* Retrieve an attribute value from the windowing system. */ |
int SDL_GL_GetAttribute(SDL_GLattr attr, int* value) |
{ |
int retval = -1; |
SDL_VideoDevice* video = current_video; |
SDL_VideoDevice* this = current_video; |
if ( video->GL_GetAttribute ) { |
retval = this->GL_GetAttribute(this, attr, value); |
} else { |
*value = 0; |
SDL_SetError("GL_GetAttribute not supported"); |
} |
return retval; |
} |
/* Perform a GL buffer swap on the current GL context */ |
void SDL_GL_SwapBuffers(void) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
if ( video->screen->flags & SDL_OPENGL ) { |
video->GL_SwapBuffers( this ); |
} |
} |
/* Update rects with locking */ |
void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect *rects) |
{ |
SDL_GL_Lock(); |
SDL_GL_UpdateRects(numrects, rects); |
SDL_GL_Unlock(); |
} |
/* Update rects without state setting and changing (the caller is responsible for it) */ |
void SDL_GL_UpdateRects(int numrects, SDL_Rect *rects) |
{ |
#ifdef HAVE_OPENGL |
SDL_VideoDevice *this = current_video; |
SDL_Rect update, tmp; |
int x, y, i; |
for ( i = 0; i < numrects; i++ ) |
{ |
tmp.y = rects[i].y; |
tmp.h = rects[i].h; |
for ( y = 0; y <= rects[i].h / 256; y++ ) |
{ |
tmp.x = rects[i].x; |
tmp.w = rects[i].w; |
for ( x = 0; x <= rects[i].w / 256; x++ ) |
{ |
update.x = tmp.x; |
update.y = tmp.y; |
update.w = tmp.w; |
update.h = tmp.h; |
if ( update.w > 256 ) |
update.w = 256; |
if ( update.h > 256 ) |
update.h = 256; |
this->glFlush(); |
this->glTexSubImage2D( |
GL_TEXTURE_2D, |
0, |
0, |
0, |
update.w, |
update.h, |
this->is_32bit? GL_RGBA : GL_RGB, |
#ifdef GL_VERSION_1_2 |
this->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5, |
#else |
GL_UNSIGNED_BYTE, |
#endif |
(Uint8 *)this->screen->pixels + |
this->screen->format->BytesPerPixel * update.x + |
update.y * this->screen->pitch ); |
this->glFlush(); |
/* |
* Note the parens around the function name: |
* This is because some OpenGL implementations define glTexCoord etc |
* as macros, and we don't want them expanded here. |
*/ |
this->glBegin(GL_TRIANGLE_STRIP); |
(this->glTexCoord2f)( 0.0, 0.0 ); |
(this->glVertex2i)( update.x, update.y ); |
(this->glTexCoord2f)( (float)(update.w / 256.0), 0.0 ); |
(this->glVertex2i)( update.x + update.w, update.y ); |
(this->glTexCoord2f)( 0.0, (float)(update.h / 256.0) ); |
(this->glVertex2i)( update.x, update.y + update.h ); |
(this->glTexCoord2f)( (float)(update.w / 256.0), (float)(update.h / 256.0) ); |
(this->glVertex2i)( update.x + update.w , update.y + update.h ); |
this->glEnd(); |
tmp.x += 256; |
tmp.w -= 256; |
} |
tmp.y += 256; |
tmp.h -= 256; |
} |
} |
#endif |
} |
/* Lock == save current state */ |
void SDL_GL_Lock() |
{ |
#ifdef HAVE_OPENGL |
lock_count--; |
if (lock_count==-1) |
{ |
SDL_VideoDevice *this = current_video; |
this->glPushAttrib( GL_ALL_ATTRIB_BITS ); /* TODO: narrow range of what is saved */ |
this->glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT ); |
this->glEnable(GL_TEXTURE_2D); |
this->glEnable(GL_BLEND); |
this->glDisable(GL_FOG); |
this->glDisable(GL_ALPHA_TEST); |
this->glDisable(GL_DEPTH_TEST); |
this->glDisable(GL_SCISSOR_TEST); |
this->glDisable(GL_STENCIL_TEST); |
this->glDisable(GL_CULL_FACE); |
this->glBindTexture( GL_TEXTURE_2D, this->texture ); |
this->glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); |
this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); |
this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); |
this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); |
this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); |
this->glPixelStorei( GL_UNPACK_ROW_LENGTH, this->screen->pitch / this->screen->format->BytesPerPixel ); |
this->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
(this->glColor4f)(1.0, 1.0, 1.0, 1.0); /* Solaris workaround */ |
this->glViewport(0, 0, this->screen->w, this->screen->h); |
this->glMatrixMode(GL_PROJECTION); |
this->glPushMatrix(); |
this->glLoadIdentity(); |
this->glOrtho(0.0, (GLdouble) this->screen->w, (GLdouble) this->screen->h, 0.0, 0.0, 1.0); |
this->glMatrixMode(GL_MODELVIEW); |
this->glPushMatrix(); |
this->glLoadIdentity(); |
} |
#endif |
} |
/* Unlock == restore saved state */ |
void SDL_GL_Unlock() |
{ |
#ifdef HAVE_OPENGL |
lock_count++; |
if (lock_count==0) |
{ |
SDL_VideoDevice *this = current_video; |
this->glPopMatrix(); |
this->glMatrixMode(GL_PROJECTION); |
this->glPopMatrix(); |
this->glPopClientAttrib(); |
this->glPopAttrib(); |
} |
#endif |
} |
/* |
* Sets/Gets the title and icon text of the display window, if any. |
*/ |
void SDL_WM_SetCaption (const char *title, const char *icon) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
if ( video ) { |
if ( title ) { |
if ( video->wm_title ) { |
free(video->wm_title); |
} |
video->wm_title = (char *)malloc(strlen(title)+1); |
if ( video->wm_title != NULL ) { |
strcpy(video->wm_title, title); |
} |
} |
if ( icon ) { |
if ( video->wm_icon ) { |
free(video->wm_icon); |
} |
video->wm_icon = (char *)malloc(strlen(icon)+1); |
if ( video->wm_icon != NULL ) { |
strcpy(video->wm_icon, icon); |
} |
} |
if ( (title || icon) && (video->SetCaption != NULL) ) { |
video->SetCaption(this, video->wm_title,video->wm_icon); |
} |
} |
} |
void SDL_WM_GetCaption (char **title, char **icon) |
{ |
SDL_VideoDevice *video = current_video; |
if ( video ) { |
if ( title ) { |
*title = video->wm_title; |
} |
if ( icon ) { |
*icon = video->wm_icon; |
} |
} |
} |
/* Utility function used by SDL_WM_SetIcon() */ |
static void CreateMaskFromColorKey(SDL_Surface *icon, Uint8 *mask) |
{ |
int x, y; |
Uint32 colorkey; |
#define SET_MASKBIT(icon, x, y, mask) \ |
mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8))) |
colorkey = icon->format->colorkey; |
switch (icon->format->BytesPerPixel) { |
case 1: { Uint8 *pixels; |
for ( y=0; y<icon->h; ++y ) { |
pixels = (Uint8 *)icon->pixels + y*icon->pitch; |
for ( x=0; x<icon->w; ++x ) { |
if ( *pixels++ == colorkey ) { |
SET_MASKBIT(icon, x, y, mask); |
} |
} |
} |
} |
break; |
case 2: { Uint16 *pixels; |
for ( y=0; y<icon->h; ++y ) { |
pixels = (Uint16 *)icon->pixels + |
y*icon->pitch/2; |
for ( x=0; x<icon->w; ++x ) { |
if ( *pixels++ == colorkey ) { |
SET_MASKBIT(icon, x, y, mask); |
} |
} |
} |
} |
break; |
case 4: { Uint32 *pixels; |
for ( y=0; y<icon->h; ++y ) { |
pixels = (Uint32 *)icon->pixels + |
y*icon->pitch/4; |
for ( x=0; x<icon->w; ++x ) { |
if ( *pixels++ == colorkey ) { |
SET_MASKBIT(icon, x, y, mask); |
} |
} |
} |
} |
break; |
} |
} |
/* |
* Sets the window manager icon for the display window. |
*/ |
void SDL_WM_SetIcon (SDL_Surface *icon, Uint8 *mask) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
if ( icon && video->SetIcon ) { |
/* Generate a mask if necessary, and create the icon! */ |
if ( mask == NULL ) { |
int mask_len = icon->h*(icon->w+7)/8; |
mask = (Uint8 *)malloc(mask_len); |
if ( mask == NULL ) { |
return; |
} |
memset(mask, ~0, mask_len); |
if ( icon->flags & SDL_SRCCOLORKEY ) { |
CreateMaskFromColorKey(icon, mask); |
} |
video->SetIcon(video, icon, mask); |
free(mask); |
} else { |
video->SetIcon(this, icon, mask); |
} |
} |
} |
/* |
* Grab or ungrab the keyboard and mouse input. |
* This function returns the final grab mode after calling the |
* driver dependent function. |
*/ |
static SDL_GrabMode SDL_WM_GrabInputRaw(SDL_GrabMode mode) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
/* Only do something if we have support for grabs */ |
/*if ( video->GrabInput == NULL ) { |
return(video->input_grab); |
}*/ |
/* If the final grab mode if off, only then do we actually grab */ |
#ifdef DEBUG_GRAB |
SDL_printf("SDL_WM_GrabInputRaw(%d) ... ", mode); |
#endif |
/*if ( mode == SDL_GRAB_OFF ) { |
if ( video->input_grab != SDL_GRAB_OFF ) { |
mode = video->GrabInput(this, mode); |
} |
} else { |
if ( video->input_grab == SDL_GRAB_OFF ) { |
mode = video->GrabInput(this, mode); |
} |
}*/ |
if ( mode != video->input_grab ) { |
video->input_grab = mode; |
if ( video->CheckMouseMode ) { |
video->CheckMouseMode(this); |
} |
} |
#ifdef DEBUG_GRAB |
SDL_printf("Final mode %d\n", video->input_grab); |
#endif |
/* Return the final grab state */ |
if ( mode >= SDL_GRAB_FULLSCREEN ) { |
mode -= SDL_GRAB_FULLSCREEN; |
} |
return(mode); |
} |
SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode) |
{ |
SDL_VideoDevice *video = current_video; |
/* If the video isn't initialized yet, we can't do anything */ |
if ( ! video ) { |
return SDL_GRAB_OFF; |
} |
/* Return the current mode on query */ |
if ( mode == SDL_GRAB_QUERY ) { |
mode = video->input_grab; |
if ( mode >= SDL_GRAB_FULLSCREEN ) { |
mode -= SDL_GRAB_FULLSCREEN; |
} |
return(mode); |
} |
#ifdef DEBUG_GRAB |
SDL_printf("SDL_WM_GrabInput(%d) ... ", mode); |
#endif |
/* If the video surface is fullscreen, we always grab */ |
if ( mode >= SDL_GRAB_FULLSCREEN ) { |
mode -= SDL_GRAB_FULLSCREEN; |
} |
if ( SDL_VideoSurface && (SDL_VideoSurface->flags & SDL_FULLSCREEN) ) { |
mode += SDL_GRAB_FULLSCREEN; |
} |
return(SDL_WM_GrabInputRaw(mode)); |
} |
static SDL_GrabMode SDL_WM_GrabInputOff(void) |
{ |
SDL_GrabMode mode; |
/* First query the current grab state */ |
mode = SDL_WM_GrabInput(SDL_GRAB_QUERY); |
/* Now explicitly turn off input grab */ |
SDL_WM_GrabInputRaw(SDL_GRAB_OFF); |
/* Return the old state */ |
return(mode); |
} |
/* |
* Iconify the window in window managed environments. |
* A successful iconification will result in an SDL_APPACTIVE loss event. |
*/ |
int SDL_WM_IconifyWindow(void) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
int retval; |
retval = 0; |
if ( video->IconifyWindow ) { |
retval = video->IconifyWindow(this); |
} |
return(retval); |
} |
/* |
* Toggle fullscreen mode |
*/ |
int SDL_WM_ToggleFullScreen(SDL_Surface *surface) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
int toggled; |
toggled = 0; |
if ( SDL_PublicSurface && (surface == SDL_PublicSurface) && |
video->ToggleFullScreen ) { |
if ( surface->flags & SDL_FULLSCREEN ) { |
toggled = video->ToggleFullScreen(this, 0); |
if ( toggled ) { |
SDL_VideoSurface->flags &= ~SDL_FULLSCREEN; |
SDL_PublicSurface->flags &= ~SDL_FULLSCREEN; |
} |
} else { |
toggled = video->ToggleFullScreen(this, 1); |
if ( toggled ) { |
SDL_VideoSurface->flags |= SDL_FULLSCREEN; |
SDL_PublicSurface->flags |= SDL_FULLSCREEN; |
} |
} |
/* Double-check the grab state inside SDL_WM_GrabInput() */ |
if ( toggled ) { |
SDL_WM_GrabInput(video->input_grab); |
} |
} |
return(toggled); |
} |
/* |
* Get some platform dependent window manager information |
*/ |
int SDL_GetWMInfo (SDL_SysWMinfo *info) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
if ( video && video->GetWMInfo ) { |
return(video->GetWMInfo(this, info)); |
} else { |
return(0); |
} |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_yuv.c |
---|
0,0 → 1,89 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
/* This is the implementation of the YUV video surface support */ |
#include <stdlib.h> |
#include <string.h> |
#include "SDL_getenv.h" |
#include "SDL_video.h" |
#include "SDL_sysvideo.h" |
#include "SDL_yuvfuncs.h" |
#include "SDL_yuv_sw_c.h" |
SDL_Overlay *SDL_CreateYUVOverlay(int w, int h, Uint32 format, |
SDL_Surface *display) |
{ |
SDL_VideoDevice *video = current_video; |
SDL_VideoDevice *this = current_video; |
const char *yuv_hwaccel; |
SDL_Overlay *overlay; |
overlay = NULL; |
/* Display directly on video surface, if possible */ |
if ( getenv("SDL_VIDEO_YUV_DIRECT") ) { |
if ( (display == SDL_PublicSurface) && |
((SDL_VideoSurface->format->BytesPerPixel == 2) || |
(SDL_VideoSurface->format->BytesPerPixel == 4)) ) { |
display = SDL_VideoSurface; |
} |
} |
yuv_hwaccel = getenv("SDL_VIDEO_YUV_HWACCEL"); |
if ( ((display == SDL_VideoSurface) && video->CreateYUVOverlay) && |
(!yuv_hwaccel || (atoi(yuv_hwaccel) > 0)) ) { |
overlay = video->CreateYUVOverlay(this, w, h, format, display); |
} |
/* If hardware YUV overlay failed ... */ |
if ( overlay == NULL ) { |
overlay = SDL_CreateYUV_SW(this, w, h, format, display); |
} |
return overlay; |
} |
int SDL_LockYUVOverlay(SDL_Overlay *overlay) |
{ |
return overlay->hwfuncs->Lock(current_video, overlay); |
} |
void SDL_UnlockYUVOverlay(SDL_Overlay *overlay) |
{ |
overlay->hwfuncs->Unlock(current_video, overlay); |
} |
int SDL_DisplayYUVOverlay(SDL_Overlay *overlay, SDL_Rect *dstrect) |
{ |
return overlay->hwfuncs->Display(current_video, overlay, dstrect); |
} |
void SDL_FreeYUVOverlay(SDL_Overlay *overlay) |
{ |
if ( overlay ) { |
if ( overlay->hwfuncs ) { |
overlay->hwfuncs->FreeHW(current_video, overlay); |
} |
free(overlay); |
} |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_yuv_mmx.c |
---|
0,0 → 1,418 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) |
#include "SDL_types.h" |
#ifdef __ELF__ |
#define ASM_VAR(X) _##X |
#else |
#define ASM_VAR(X) X |
#endif |
#define static |
static unsigned int ASM_VAR(MMX_0080w)[] = {0x00800080, 0x00800080}; |
static unsigned int ASM_VAR(MMX_00FFw)[] = {0x00ff00ff, 0x00ff00ff}; |
static unsigned int ASM_VAR(MMX_FF00w)[] = {0xff00ff00, 0xff00ff00}; |
static unsigned short ASM_VAR(MMX_Ycoeff)[] = {0x004a, 0x004a, 0x004a, 0x004a}; |
static unsigned short ASM_VAR(MMX_UbluRGB)[] = {0x0072, 0x0072, 0x0072, 0x0072}; |
static unsigned short ASM_VAR(MMX_VredRGB)[] = {0x0059, 0x0059, 0x0059, 0x0059}; |
static unsigned short ASM_VAR(MMX_UgrnRGB)[] = {0xffea, 0xffea, 0xffea, 0xffea}; |
static unsigned short ASM_VAR(MMX_VgrnRGB)[] = {0xffd2, 0xffd2, 0xffd2, 0xffd2}; |
static unsigned short ASM_VAR(MMX_Ublu5x5)[] = {0x0081, 0x0081, 0x0081, 0x0081}; |
static unsigned short ASM_VAR(MMX_Vred5x5)[] = {0x0066, 0x0066, 0x0066, 0x0066}; |
static unsigned short ASM_VAR(MMX_Ugrn555)[] = {0xffe7, 0xffe7, 0xffe7, 0xffe7}; |
static unsigned short ASM_VAR(MMX_Vgrn555)[] = {0xffcc, 0xffcc, 0xffcc, 0xffcc}; |
static unsigned short ASM_VAR(MMX_Ugrn565)[] = {0xffe8, 0xffe8, 0xffe8, 0xffe8}; |
static unsigned short ASM_VAR(MMX_Vgrn565)[] = {0xffcd, 0xffcd, 0xffcd, 0xffcd}; |
static unsigned short ASM_VAR(MMX_red555)[] = {0x7c00, 0x7c00, 0x7c00, 0x7c00}; |
static unsigned short ASM_VAR(MMX_red565)[] = {0xf800, 0xf800, 0xf800, 0xf800}; |
static unsigned short ASM_VAR(MMX_grn555)[] = {0x03e0, 0x03e0, 0x03e0, 0x03e0}; |
static unsigned short ASM_VAR(MMX_grn565)[] = {0x07e0, 0x07e0, 0x07e0, 0x07e0}; |
static unsigned short ASM_VAR(MMX_blu5x5)[] = {0x001f, 0x001f, 0x001f, 0x001f}; |
/** |
This MMX assembler is my first assembler/MMX program ever. |
Thus it maybe buggy. |
Send patches to: |
mvogt@rhrk.uni-kl.de |
After it worked fine I have "obfuscated" the code a bit to have |
more parallism in the MMX units. This means I moved |
initilisation around and delayed other instruction. |
Performance measurement did not show that this brought any advantage |
but in theory it _should_ be faster this way. |
The overall performanve gain to the C based dither was 30%-40%. |
The MMX routine calculates 256bit=8RGB values in each cycle |
(4 for row1 & 4 for row2) |
The red/green/blue.. coefficents are taken from the mpeg_play |
player. They look nice, but I dont know if you can have |
better values, to avoid integer rounding errors. |
IMPORTANT: |
========== |
It is a requirement that the cr/cb/lum are 8 byte aligned and |
the out are 16byte aligned or you will/may get segfaults |
*/ |
void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ) |
{ |
Uint32 *row1; |
Uint32 *row2; |
unsigned char* y = lum +cols*rows; // Pointer to the end |
int x=0; |
row1 = (Uint32 *)out; // 32 bit target |
row2 = (Uint32 *)out+cols+mod; // start of second row |
mod = (mod+cols+mod)*4; // increment for row1 in byte |
__asm__ __volatile__ ( |
/* We don't really care about PIC - the code should be rewritten to use |
relative addressing for the static tables, so right now we take the |
COW hit on the pages this code resides. Big deal. |
This spill is just to reduce register pressure in the PIC case. */ |
"pushl %%ebx\n" |
"movl %0, %%ebx\n" |
".align 8\n" |
"1:\n" |
// create Cr (result in mm1) |
"movd (%%ebx), %%mm1\n" // 0 0 0 0 v3 v2 v1 v0 |
"pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00 |
"movd (%2), %%mm2\n" // 0 0 0 0 l3 l2 l1 l0 |
"punpcklbw %%mm7,%%mm1\n" // 0 v3 0 v2 00 v1 00 v0 |
"punpckldq %%mm1,%%mm1\n" // 00 v1 00 v0 00 v1 00 v0 |
"psubw _MMX_0080w,%%mm1\n" // mm1-128:r1 r1 r0 r0 r1 r1 r0 r0 |
// create Cr_g (result in mm0) |
"movq %%mm1,%%mm0\n" // r1 r1 r0 r0 r1 r1 r0 r0 |
"pmullw _MMX_VgrnRGB,%%mm0\n"// red*-46dec=0.7136*64 |
"pmullw _MMX_VredRGB,%%mm1\n"// red*89dec=1.4013*64 |
"psraw $6, %%mm0\n" // red=red/64 |
"psraw $6, %%mm1\n" // red=red/64 |
// create L1 L2 (result in mm2,mm4) |
// L2=lum+cols |
"movq (%2,%4),%%mm3\n" // 0 0 0 0 L3 L2 L1 L0 |
"punpckldq %%mm3,%%mm2\n" // L3 L2 L1 L0 l3 l2 l1 l0 |
"movq %%mm2,%%mm4\n" // L3 L2 L1 L0 l3 l2 l1 l0 |
"pand _MMX_FF00w,%%mm2\n" // L3 0 L1 0 l3 0 l1 0 |
"pand _MMX_00FFw,%%mm4\n" // 0 L2 0 L0 0 l2 0 l0 |
"psrlw $8,%%mm2\n" // 0 L3 0 L1 0 l3 0 l1 |
// create R (result in mm6) |
"movq %%mm2,%%mm5\n" // 0 L3 0 L1 0 l3 0 l1 |
"movq %%mm4,%%mm6\n" // 0 L2 0 L0 0 l2 0 l0 |
"paddsw %%mm1, %%mm5\n" // lum1+red:x R3 x R1 x r3 x r1 |
"paddsw %%mm1, %%mm6\n" // lum1+red:x R2 x R0 x r2 x r0 |
"packuswb %%mm5,%%mm5\n" // R3 R1 r3 r1 R3 R1 r3 r1 |
"packuswb %%mm6,%%mm6\n" // R2 R0 r2 r0 R2 R0 r2 r0 |
"pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00 |
"punpcklbw %%mm5,%%mm6\n" // R3 R2 R1 R0 r3 r2 r1 r0 |
// create Cb (result in mm1) |
"movd (%1), %%mm1\n" // 0 0 0 0 u3 u2 u1 u0 |
"punpcklbw %%mm7,%%mm1\n" // 0 u3 0 u2 00 u1 00 u0 |
"punpckldq %%mm1,%%mm1\n" // 00 u1 00 u0 00 u1 00 u0 |
"psubw _MMX_0080w,%%mm1\n" // mm1-128:u1 u1 u0 u0 u1 u1 u0 u0 |
// create Cb_g (result in mm5) |
"movq %%mm1,%%mm5\n" // u1 u1 u0 u0 u1 u1 u0 u0 |
"pmullw _MMX_UgrnRGB,%%mm5\n" // blue*-109dec=1.7129*64 |
"pmullw _MMX_UbluRGB,%%mm1\n" // blue*114dec=1.78125*64 |
"psraw $6, %%mm5\n" // blue=red/64 |
"psraw $6, %%mm1\n" // blue=blue/64 |
// create G (result in mm7) |
"movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1 |
"movq %%mm4,%%mm7\n" // 0 L2 0 L0 0 l2 0 l1 |
"paddsw %%mm5, %%mm3\n" // lum1+Cb_g:x G3t x G1t x g3t x g1t |
"paddsw %%mm5, %%mm7\n" // lum1+Cb_g:x G2t x G0t x g2t x g0t |
"paddsw %%mm0, %%mm3\n" // lum1+Cr_g:x G3 x G1 x g3 x g1 |
"paddsw %%mm0, %%mm7\n" // lum1+blue:x G2 x G0 x g2 x g0 |
"packuswb %%mm3,%%mm3\n" // G3 G1 g3 g1 G3 G1 g3 g1 |
"packuswb %%mm7,%%mm7\n" // G2 G0 g2 g0 G2 G0 g2 g0 |
"punpcklbw %%mm3,%%mm7\n" // G3 G2 G1 G0 g3 g2 g1 g0 |
// create B (result in mm5) |
"movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1 |
"movq %%mm4,%%mm5\n" // 0 L2 0 L0 0 l2 0 l1 |
"paddsw %%mm1, %%mm3\n" // lum1+blue:x B3 x B1 x b3 x b1 |
"paddsw %%mm1, %%mm5\n" // lum1+blue:x B2 x B0 x b2 x b0 |
"packuswb %%mm3,%%mm3\n" // B3 B1 b3 b1 B3 B1 b3 b1 |
"packuswb %%mm5,%%mm5\n" // B2 B0 b2 b0 B2 B0 b2 b0 |
"punpcklbw %%mm3,%%mm5\n" // B3 B2 B1 B0 b3 b2 b1 b0 |
// fill destination row1 (needed are mm6=Rr,mm7=Gg,mm5=Bb) |
"pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 |
"pxor %%mm4,%%mm4\n" // 0 0 0 0 0 0 0 0 |
"movq %%mm6,%%mm1\n" // R3 R2 R1 R0 r3 r2 r1 r0 |
"movq %%mm5,%%mm3\n" // B3 B2 B1 B0 b3 b2 b1 b0 |
// process lower lum |
"punpcklbw %%mm4,%%mm1\n" // 0 r3 0 r2 0 r1 0 r0 |
"punpcklbw %%mm4,%%mm3\n" // 0 b3 0 b2 0 b1 0 b0 |
"movq %%mm1,%%mm2\n" // 0 r3 0 r2 0 r1 0 r0 |
"movq %%mm3,%%mm0\n" // 0 b3 0 b2 0 b1 0 b0 |
"punpcklwd %%mm1,%%mm3\n" // 0 r1 0 b1 0 r0 0 b0 |
"punpckhwd %%mm2,%%mm0\n" // 0 r3 0 b3 0 r2 0 b2 |
"pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 |
"movq %%mm7,%%mm1\n" // G3 G2 G1 G0 g3 g2 g1 g0 |
"punpcklbw %%mm1,%%mm2\n" // g3 0 g2 0 g1 0 g0 0 |
"punpcklwd %%mm4,%%mm2\n" // 0 0 g1 0 0 0 g0 0 |
"por %%mm3, %%mm2\n" // 0 r1 g1 b1 0 r0 g0 b0 |
"movq %%mm2,(%3)\n" // wrote out ! row1 |
"pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 |
"punpcklbw %%mm1,%%mm4\n" // g3 0 g2 0 g1 0 g0 0 |
"punpckhwd %%mm2,%%mm4\n" // 0 0 g3 0 0 0 g2 0 |
"por %%mm0, %%mm4\n" // 0 r3 g3 b3 0 r2 g2 b2 |
"movq %%mm4,8(%3)\n" // wrote out ! row1 |
// fill destination row2 (needed are mm6=Rr,mm7=Gg,mm5=Bb) |
// this can be done "destructive" |
"pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 |
"punpckhbw %%mm2,%%mm6\n" // 0 R3 0 R2 0 R1 0 R0 |
"punpckhbw %%mm1,%%mm5\n" // G3 B3 G2 B2 G1 B1 G0 B0 |
"movq %%mm5,%%mm1\n" // G3 B3 G2 B2 G1 B1 G0 B0 |
"punpcklwd %%mm6,%%mm1\n" // 0 R1 G1 B1 0 R0 G0 B0 |
"movq %%mm1,(%5)\n" // wrote out ! row2 |
"punpckhwd %%mm6,%%mm5\n" // 0 R3 G3 B3 0 R2 G2 B2 |
"movq %%mm5,8(%5)\n" // wrote out ! row2 |
"addl $4,%2\n" // lum+4 |
"leal 16(%3),%3\n" // row1+16 |
"leal 16(%5),%5\n" // row2+16 |
"addl $2, %%ebx\n" // cr+2 |
"addl $2, %1\n" // cb+2 |
"addl $4,%6\n" // x+4 |
"cmpl %4,%6\n" |
"jl 1b\n" |
"addl %4, %2\n" // lum += cols |
"addl %8, %3\n" // row1+= mod |
"addl %8, %5\n" // row2+= mod |
"movl $0, %6\n" // x=0 |
"cmpl %7, %2\n" |
"jl 1b\n" |
"emms\n" |
"popl %%ebx\n" |
: |
: "m" (cr), "r"(cb),"r"(lum), |
"r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod) |
: "%ebx" |
); |
} |
void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ) |
{ |
Uint16 *row1; |
Uint16 *row2; |
unsigned char* y = lum +cols*rows; /* Pointer to the end */ |
int x=0; |
row1 = (Uint16 *)out; /* 16 bit target */ |
row2 = (Uint16 *)out+cols+mod; /* start of second row */ |
mod = (mod+cols+mod)*2; /* increment for row1 in byte */ |
__asm__ __volatile__( |
"pushl %%ebx\n" |
"movl %0, %%ebx\n" |
".align 8\n" |
"1:\n" |
"movd (%1), %%mm0\n" // 4 Cb 0 0 0 0 u3 u2 u1 u0 |
"pxor %%mm7, %%mm7\n" |
"movd (%%ebx), %%mm1\n" // 4 Cr 0 0 0 0 v3 v2 v1 v0 |
"punpcklbw %%mm7, %%mm0\n" // 4 W cb 0 u3 0 u2 0 u1 0 u0 |
"punpcklbw %%mm7, %%mm1\n" // 4 W cr 0 v3 0 v2 0 v1 0 v0 |
"psubw _MMX_0080w, %%mm0\n" |
"psubw _MMX_0080w, %%mm1\n" |
"movq %%mm0, %%mm2\n" // Cb 0 u3 0 u2 0 u1 0 u0 |
"movq %%mm1, %%mm3\n" // Cr |
"pmullw _MMX_Ugrn565, %%mm2\n" // Cb2green 0 R3 0 R2 0 R1 0 R0 |
"movq (%2), %%mm6\n" // L1 l7 L6 L5 L4 L3 L2 L1 L0 |
"pmullw _MMX_Ublu5x5, %%mm0\n" // Cb2blue |
"pand _MMX_00FFw, %%mm6\n" // L1 00 L6 00 L4 00 L2 00 L0 |
"pmullw _MMX_Vgrn565, %%mm3\n" // Cr2green |
"movq (%2), %%mm7\n" // L2 |
"pmullw _MMX_Vred5x5, %%mm1\n" // Cr2red |
"psrlw $8, %%mm7\n" // L2 00 L7 00 L5 00 L3 00 L1 |
"pmullw _MMX_Ycoeff, %%mm6\n" // lum1 |
"paddw %%mm3, %%mm2\n" // Cb2green + Cr2green == green |
"pmullw _MMX_Ycoeff, %%mm7\n" // lum2 |
"movq %%mm6, %%mm4\n" // lum1 |
"paddw %%mm0, %%mm6\n" // lum1 +blue 00 B6 00 B4 00 B2 00 B0 |
"movq %%mm4, %%mm5\n" // lum1 |
"paddw %%mm1, %%mm4\n" // lum1 +red 00 R6 00 R4 00 R2 00 R0 |
"paddw %%mm2, %%mm5\n" // lum1 +green 00 G6 00 G4 00 G2 00 G0 |
"psraw $6, %%mm4\n" // R1 0 .. 64 |
"movq %%mm7, %%mm3\n" // lum2 00 L7 00 L5 00 L3 00 L1 |
"psraw $6, %%mm5\n" // G1 - .. + |
"paddw %%mm0, %%mm7\n" // Lum2 +blue 00 B7 00 B5 00 B3 00 B1 |
"psraw $6, %%mm6\n" // B1 0 .. 64 |
"packuswb %%mm4, %%mm4\n" // R1 R1 |
"packuswb %%mm5, %%mm5\n" // G1 G1 |
"packuswb %%mm6, %%mm6\n" // B1 B1 |
"punpcklbw %%mm4, %%mm4\n" |
"punpcklbw %%mm5, %%mm5\n" |
"pand _MMX_red565, %%mm4\n" |
"psllw $3, %%mm5\n" // GREEN 1 |
"punpcklbw %%mm6, %%mm6\n" |
"pand _MMX_grn565, %%mm5\n" |
"pand _MMX_red565, %%mm6\n" |
"por %%mm5, %%mm4\n" // |
"psrlw $11, %%mm6\n" // BLUE 1 |
"movq %%mm3, %%mm5\n" // lum2 |
"paddw %%mm1, %%mm3\n" // lum2 +red 00 R7 00 R5 00 R3 00 R1 |
"paddw %%mm2, %%mm5\n" // lum2 +green 00 G7 00 G5 00 G3 00 G1 |
"psraw $6, %%mm3\n" // R2 |
"por %%mm6, %%mm4\n" // MM4 |
"psraw $6, %%mm5\n" // G2 |
"movq (%2, %4), %%mm6\n" // L3 load lum2 |
"psraw $6, %%mm7\n" |
"packuswb %%mm3, %%mm3\n" |
"packuswb %%mm5, %%mm5\n" |
"packuswb %%mm7, %%mm7\n" |
"pand _MMX_00FFw, %%mm6\n" // L3 |
"punpcklbw %%mm3, %%mm3\n" |
"punpcklbw %%mm5, %%mm5\n" |
"pmullw _MMX_Ycoeff, %%mm6\n" // lum3 |
"punpcklbw %%mm7, %%mm7\n" |
"psllw $3, %%mm5\n" // GREEN 2 |
"pand _MMX_red565, %%mm7\n" |
"pand _MMX_red565, %%mm3\n" |
"psrlw $11, %%mm7\n" // BLUE 2 |
"pand _MMX_grn565, %%mm5\n" |
"por %%mm7, %%mm3\n" |
"movq (%2,%4), %%mm7\n" // L4 load lum2 |
"por %%mm5, %%mm3\n" // |
"psrlw $8, %%mm7\n" // L4 |
"movq %%mm4, %%mm5\n" |
"punpcklwd %%mm3, %%mm4\n" |
"pmullw _MMX_Ycoeff, %%mm7\n" // lum4 |
"punpckhwd %%mm3, %%mm5\n" |
"movq %%mm4, (%3)\n" // write row1 |
"movq %%mm5, 8(%3)\n" // write row1 |
"movq %%mm6, %%mm4\n" // Lum3 |
"paddw %%mm0, %%mm6\n" // Lum3 +blue |
"movq %%mm4, %%mm5\n" // Lum3 |
"paddw %%mm1, %%mm4\n" // Lum3 +red |
"paddw %%mm2, %%mm5\n" // Lum3 +green |
"psraw $6, %%mm4\n" |
"movq %%mm7, %%mm3\n" // Lum4 |
"psraw $6, %%mm5\n" |
"paddw %%mm0, %%mm7\n" // Lum4 +blue |
"psraw $6, %%mm6\n" // Lum3 +blue |
"movq %%mm3, %%mm0\n" // Lum4 |
"packuswb %%mm4, %%mm4\n" |
"paddw %%mm1, %%mm3\n" // Lum4 +red |
"packuswb %%mm5, %%mm5\n" |
"paddw %%mm2, %%mm0\n" // Lum4 +green |
"packuswb %%mm6, %%mm6\n" |
"punpcklbw %%mm4, %%mm4\n" |
"punpcklbw %%mm5, %%mm5\n" |
"punpcklbw %%mm6, %%mm6\n" |
"psllw $3, %%mm5\n" // GREEN 3 |
"pand _MMX_red565, %%mm4\n" |
"psraw $6, %%mm3\n" // psr 6 |
"psraw $6, %%mm0\n" |
"pand _MMX_red565, %%mm6\n" // BLUE |
"pand _MMX_grn565, %%mm5\n" |
"psrlw $11, %%mm6\n" // BLUE 3 |
"por %%mm5, %%mm4\n" |
"psraw $6, %%mm7\n" |
"por %%mm6, %%mm4\n" |
"packuswb %%mm3, %%mm3\n" |
"packuswb %%mm0, %%mm0\n" |
"packuswb %%mm7, %%mm7\n" |
"punpcklbw %%mm3, %%mm3\n" |
"punpcklbw %%mm0, %%mm0\n" |
"punpcklbw %%mm7, %%mm7\n" |
"pand _MMX_red565, %%mm3\n" |
"pand _MMX_red565, %%mm7\n" // BLUE |
"psllw $3, %%mm0\n" // GREEN 4 |
"psrlw $11, %%mm7\n" |
"pand _MMX_grn565, %%mm0\n" |
"por %%mm7, %%mm3\n" |
"por %%mm0, %%mm3\n" |
"movq %%mm4, %%mm5\n" |
"punpcklwd %%mm3, %%mm4\n" |
"punpckhwd %%mm3, %%mm5\n" |
"movq %%mm4, (%5)\n" |
"movq %%mm5, 8(%5)\n" |
"addl $8, %6\n" |
"addl $8, %2\n" |
"addl $4, %%ebx\n" |
"addl $4, %1\n" |
"cmpl %4, %6\n" |
"leal 16(%3), %3\n" |
"leal 16(%5),%5\n" // row2+16 |
"jl 1b\n" |
"addl %4, %2\n" // lum += cols |
"addl %8, %3\n" // row1+= mod |
"addl %8, %5\n" // row2+= mod |
"movl $0, %6\n" // x=0 |
"cmpl %7, %2\n" |
"jl 1b\n" |
"emms\n" |
"popl %%ebx\n" |
: |
:"m" (cr), "r"(cb),"r"(lum), |
"r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod) |
: "%ebx" |
); |
} |
#endif /* GCC i386 inline assembly */ |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_yuv_sw.c |
---|
0,0 → 1,1316 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_yuv_sw.c,v 1.3 2001/04/27 20:25:25 hercules Exp $"; |
#endif |
/* This is the software implementation of the YUV video overlay support */ |
/* This code was derived from code carrying the following copyright notices: |
* Copyright (c) 1995 The Regents of the University of California. |
* All rights reserved. |
* |
* Permission to use, copy, modify, and distribute this software and its |
* documentation for any purpose, without fee, and without written agreement is |
* hereby granted, provided that the above copyright notice and the following |
* two paragraphs appear in all copies of this software. |
* |
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR |
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT |
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF |
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, |
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY |
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO |
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
* Copyright (c) 1995 Erik Corry |
* All rights reserved. |
* |
* Permission to use, copy, modify, and distribute this software and its |
* documentation for any purpose, without fee, and without written agreement is |
* hereby granted, provided that the above copyright notice and the following |
* two paragraphs appear in all copies of this software. |
* |
* IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, |
* SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF |
* THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED |
* OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
* ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" |
* BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, |
* UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
* Portions of this software Copyright (c) 1995 Brown University. |
* All rights reserved. |
* |
* Permission to use, copy, modify, and distribute this software and its |
* documentation for any purpose, without fee, and without written agreement |
* is hereby granted, provided that the above copyright notice and the |
* following two paragraphs appear in all copies of this software. |
* |
* IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR |
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT |
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN |
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
* BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" |
* BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, |
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
*/ |
#include <stdlib.h> |
#include <string.h> |
#include "SDL_error.h" |
#include "SDL_video.h" |
#include "SDL_stretch_c.h" |
#include "SDL_yuvfuncs.h" |
#include "SDL_yuv_sw_c.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 |
#ifdef USE_ASMBLIT |
#define X86_ASSEMBLER |
#define HermesConverterInterface void |
#define HermesClearInterface void |
#define STACKCALL |
typedef Uint32 int32; |
#include "HeadX86.h" |
#endif |
/* The functions used to manipulate software video overlays */ |
static struct private_yuvhwfuncs sw_yuvfuncs = { |
SDL_LockYUV_SW, |
SDL_UnlockYUV_SW, |
SDL_DisplayYUV_SW, |
SDL_FreeYUV_SW |
}; |
/* RGB conversion lookup tables */ |
struct private_yuvhwdata { |
SDL_Surface *stretch; |
SDL_Surface *display; |
Uint8 *pixels; |
int *colortab; |
Uint32 *rgb_2_pix; |
void (*Display1X)(int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ); |
void (*Display2X)(int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ); |
/* These are just so we don't have to allocate them separately */ |
Uint16 pitches[3]; |
Uint8 *planes[3]; |
}; |
/* The colorspace conversion functions */ |
extern void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ); |
extern void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ); |
static void Color16DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ) |
{ |
unsigned short* row1; |
unsigned short* row2; |
unsigned char* lum2; |
int x, y; |
int cr_r; |
int crb_g; |
int cb_b; |
int cols_2 = cols / 2; |
row1 = (unsigned short*) out; |
row2 = row1 + cols + mod; |
lum2 = lum + cols; |
mod += cols + mod; |
y = rows / 2; |
while( y-- ) |
{ |
x = cols_2; |
while( x-- ) |
{ |
register int L; |
cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; |
crb_g = 1*768+256 + colortab[ *cr + 1*256 ] |
+ colortab[ *cb + 2*256 ]; |
cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; |
++cr; ++cb; |
L = *lum++; |
*row1++ = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
L = *lum++; |
*row1++ = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
/* Now, do second row. */ |
L = *lum2++; |
*row2++ = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
L = *lum2++; |
*row2++ = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
} |
/* |
* These values are at the start of the next line, (due |
* to the ++'s above),but they need to be at the start |
* of the line after that. |
*/ |
lum += cols; |
lum2 += cols; |
row1 += mod; |
row2 += mod; |
} |
} |
static void Color24DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ) |
{ |
unsigned int value; |
unsigned char* row1; |
unsigned char* row2; |
unsigned char* lum2; |
int x, y; |
int cr_r; |
int crb_g; |
int cb_b; |
int cols_2 = cols / 2; |
row1 = out; |
row2 = row1 + cols*3 + mod*3; |
lum2 = lum + cols; |
mod += cols + mod; |
mod *= 3; |
y = rows / 2; |
while( y-- ) |
{ |
x = cols_2; |
while( x-- ) |
{ |
register int L; |
cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; |
crb_g = 1*768+256 + colortab[ *cr + 1*256 ] |
+ colortab[ *cb + 2*256 ]; |
cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; |
++cr; ++cb; |
L = *lum++; |
value = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
*row1++ = (value ) & 0xFF; |
*row1++ = (value >> 8) & 0xFF; |
*row1++ = (value >> 16) & 0xFF; |
L = *lum++; |
value = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
*row1++ = (value ) & 0xFF; |
*row1++ = (value >> 8) & 0xFF; |
*row1++ = (value >> 16) & 0xFF; |
/* Now, do second row. */ |
L = *lum2++; |
value = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
*row2++ = (value ) & 0xFF; |
*row2++ = (value >> 8) & 0xFF; |
*row2++ = (value >> 16) & 0xFF; |
L = *lum2++; |
value = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
*row2++ = (value ) & 0xFF; |
*row2++ = (value >> 8) & 0xFF; |
*row2++ = (value >> 16) & 0xFF; |
} |
/* |
* These values are at the start of the next line, (due |
* to the ++'s above),but they need to be at the start |
* of the line after that. |
*/ |
lum += cols; |
lum2 += cols; |
row1 += mod; |
row2 += mod; |
} |
} |
static void Color32DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ) |
{ |
unsigned int* row1; |
unsigned int* row2; |
unsigned char* lum2; |
int x, y; |
int cr_r; |
int crb_g; |
int cb_b; |
int cols_2 = cols / 2; |
row1 = (unsigned int*) out; |
row2 = row1 + cols + mod; |
lum2 = lum + cols; |
mod += cols + mod; |
y = rows / 2; |
while( y-- ) |
{ |
x = cols_2; |
while( x-- ) |
{ |
register int L; |
cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; |
crb_g = 1*768+256 + colortab[ *cr + 1*256 ] |
+ colortab[ *cb + 2*256 ]; |
cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; |
++cr; ++cb; |
L = *lum++; |
*row1++ = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
L = *lum++; |
*row1++ = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
/* Now, do second row. */ |
L = *lum2++; |
*row2++ = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
L = *lum2++; |
*row2++ = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
} |
/* |
* These values are at the start of the next line, (due |
* to the ++'s above),but they need to be at the start |
* of the line after that. |
*/ |
lum += cols; |
lum2 += cols; |
row1 += mod; |
row2 += mod; |
} |
} |
/* |
* In this function I make use of a nasty trick. The tables have the lower |
* 16 bits replicated in the upper 16. This means I can write ints and get |
* the horisontal doubling for free (almost). |
*/ |
static void Color16DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ) |
{ |
unsigned int* row1 = (unsigned int*) out; |
const int next_row = cols+(mod/2); |
unsigned int* row2 = row1 + 2*next_row; |
unsigned char* lum2; |
int x, y; |
int cr_r; |
int crb_g; |
int cb_b; |
int cols_2 = cols / 2; |
lum2 = lum + cols; |
mod = (next_row * 3) + (mod/2); |
y = rows / 2; |
while( y-- ) |
{ |
x = cols_2; |
while( x-- ) |
{ |
register int L; |
cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; |
crb_g = 1*768+256 + colortab[ *cr + 1*256 ] |
+ colortab[ *cb + 2*256 ]; |
cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; |
++cr; ++cb; |
L = *lum++; |
row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row1++; |
L = *lum++; |
row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row1++; |
/* Now, do second row. */ |
L = *lum2++; |
row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row2++; |
L = *lum2++; |
row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row2++; |
} |
/* |
* These values are at the start of the next line, (due |
* to the ++'s above),but they need to be at the start |
* of the line after that. |
*/ |
lum += cols; |
lum2 += cols; |
row1 += mod; |
row2 += mod; |
} |
} |
static void Color24DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ) |
{ |
unsigned int value; |
unsigned char* row1 = out; |
const int next_row = (cols*2 + mod) * 3; |
unsigned char* row2 = row1 + 2*next_row; |
unsigned char* lum2; |
int x, y; |
int cr_r; |
int crb_g; |
int cb_b; |
int cols_2 = cols / 2; |
lum2 = lum + cols; |
mod = next_row*3 + mod*3; |
y = rows / 2; |
while( y-- ) |
{ |
x = cols_2; |
while( x-- ) |
{ |
register int L; |
cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; |
crb_g = 1*768+256 + colortab[ *cr + 1*256 ] |
+ colortab[ *cb + 2*256 ]; |
cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; |
++cr; ++cb; |
L = *lum++; |
value = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] = |
(value ) & 0xFF; |
row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] = |
(value >> 8) & 0xFF; |
row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] = |
(value >> 16) & 0xFF; |
row1 += 2*3; |
L = *lum++; |
value = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] = |
(value ) & 0xFF; |
row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] = |
(value >> 8) & 0xFF; |
row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] = |
(value >> 16) & 0xFF; |
row1 += 2*3; |
/* Now, do second row. */ |
L = *lum2++; |
value = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] = |
(value ) & 0xFF; |
row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] = |
(value >> 8) & 0xFF; |
row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] = |
(value >> 16) & 0xFF; |
row2 += 2*3; |
L = *lum2++; |
value = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] = |
(value ) & 0xFF; |
row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] = |
(value >> 8) & 0xFF; |
row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] = |
(value >> 16) & 0xFF; |
row2 += 2*3; |
} |
/* |
* These values are at the start of the next line, (due |
* to the ++'s above),but they need to be at the start |
* of the line after that. |
*/ |
lum += cols; |
lum2 += cols; |
row1 += mod; |
row2 += mod; |
} |
} |
static void Color32DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ) |
{ |
unsigned int* row1 = (unsigned int*) out; |
const int next_row = cols*2+mod; |
unsigned int* row2 = row1 + 2*next_row; |
unsigned char* lum2; |
int x, y; |
int cr_r; |
int crb_g; |
int cb_b; |
int cols_2 = cols / 2; |
lum2 = lum + cols; |
mod = (next_row * 3) + mod; |
y = rows / 2; |
while( y-- ) |
{ |
x = cols_2; |
while( x-- ) |
{ |
register int L; |
cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; |
crb_g = 1*768+256 + colortab[ *cr + 1*256 ] |
+ colortab[ *cb + 2*256 ]; |
cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; |
++cr; ++cb; |
L = *lum++; |
row1[0] = row1[1] = row1[next_row] = row1[next_row+1] = |
(rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row1 += 2; |
L = *lum++; |
row1[0] = row1[1] = row1[next_row] = row1[next_row+1] = |
(rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row1 += 2; |
/* Now, do second row. */ |
L = *lum2++; |
row2[0] = row2[1] = row2[next_row] = row2[next_row+1] = |
(rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row2 += 2; |
L = *lum2++; |
row2[0] = row2[1] = row2[next_row] = row2[next_row+1] = |
(rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row2 += 2; |
} |
/* |
* These values are at the start of the next line, (due |
* to the ++'s above),but they need to be at the start |
* of the line after that. |
*/ |
lum += cols; |
lum2 += cols; |
row1 += mod; |
row2 += mod; |
} |
} |
static void Color16DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ) |
{ |
unsigned short* row; |
int x, y; |
int cr_r; |
int crb_g; |
int cb_b; |
int cols_2 = cols / 2; |
row = (unsigned short*) out; |
y = rows; |
while( y-- ) |
{ |
x = cols_2; |
while( x-- ) |
{ |
register int L; |
cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; |
crb_g = 1*768+256 + colortab[ *cr + 1*256 ] |
+ colortab[ *cb + 2*256 ]; |
cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; |
cr += 4; cb += 4; |
L = *lum; lum += 2; |
*row++ = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
L = *lum; lum += 2; |
*row++ = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
} |
row += mod; |
} |
} |
static void Color24DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ) |
{ |
unsigned int value; |
unsigned char* row; |
int x, y; |
int cr_r; |
int crb_g; |
int cb_b; |
int cols_2 = cols / 2; |
row = (unsigned char*) out; |
mod *= 3; |
y = rows; |
while( y-- ) |
{ |
x = cols_2; |
while( x-- ) |
{ |
register int L; |
cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; |
crb_g = 1*768+256 + colortab[ *cr + 1*256 ] |
+ colortab[ *cb + 2*256 ]; |
cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; |
cr += 4; cb += 4; |
L = *lum; lum += 2; |
value = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
*row++ = (value ) & 0xFF; |
*row++ = (value >> 8) & 0xFF; |
*row++ = (value >> 16) & 0xFF; |
L = *lum; lum += 2; |
value = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
*row++ = (value ) & 0xFF; |
*row++ = (value >> 8) & 0xFF; |
*row++ = (value >> 16) & 0xFF; |
} |
row += mod; |
} |
} |
static void Color32DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ) |
{ |
unsigned int* row; |
int x, y; |
int cr_r; |
int crb_g; |
int cb_b; |
int cols_2 = cols / 2; |
row = (unsigned int*) out; |
y = rows; |
while( y-- ) |
{ |
x = cols_2; |
while( x-- ) |
{ |
register int L; |
cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; |
crb_g = 1*768+256 + colortab[ *cr + 1*256 ] |
+ colortab[ *cb + 2*256 ]; |
cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; |
cr += 4; cb += 4; |
L = *lum; lum += 2; |
*row++ = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
L = *lum; lum += 2; |
*row++ = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
} |
row += mod; |
} |
} |
/* |
* In this function I make use of a nasty trick. The tables have the lower |
* 16 bits replicated in the upper 16. This means I can write ints and get |
* the horisontal doubling for free (almost). |
*/ |
static void Color16DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ) |
{ |
unsigned int* row = (unsigned int*) out; |
const int next_row = cols+(mod/2); |
int x, y; |
int cr_r; |
int crb_g; |
int cb_b; |
int cols_2 = cols / 2; |
y = rows; |
while( y-- ) |
{ |
x = cols_2; |
while( x-- ) |
{ |
register int L; |
cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; |
crb_g = 1*768+256 + colortab[ *cr + 1*256 ] |
+ colortab[ *cb + 2*256 ]; |
cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; |
cr += 4; cb += 4; |
L = *lum; lum += 2; |
row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row++; |
L = *lum; lum += 2; |
row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row++; |
} |
row += next_row; |
} |
} |
static void Color24DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ) |
{ |
unsigned int value; |
unsigned char* row = out; |
const int next_row = (cols*2 + mod) * 3; |
int x, y; |
int cr_r; |
int crb_g; |
int cb_b; |
int cols_2 = cols / 2; |
y = rows; |
while( y-- ) |
{ |
x = cols_2; |
while( x-- ) |
{ |
register int L; |
cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; |
crb_g = 1*768+256 + colortab[ *cr + 1*256 ] |
+ colortab[ *cb + 2*256 ]; |
cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; |
cr += 4; cb += 4; |
L = *lum; lum += 2; |
value = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] = |
(value ) & 0xFF; |
row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] = |
(value >> 8) & 0xFF; |
row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] = |
(value >> 16) & 0xFF; |
row += 2*3; |
L = *lum; lum += 2; |
value = (rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] = |
(value ) & 0xFF; |
row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] = |
(value >> 8) & 0xFF; |
row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] = |
(value >> 16) & 0xFF; |
row += 2*3; |
} |
row += next_row; |
} |
} |
static void Color32DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, |
unsigned char *lum, unsigned char *cr, |
unsigned char *cb, unsigned char *out, |
int rows, int cols, int mod ) |
{ |
unsigned int* row = (unsigned int*) out; |
const int next_row = cols*2+mod; |
int x, y; |
int cr_r; |
int crb_g; |
int cb_b; |
int cols_2 = cols / 2; |
mod+=mod; |
y = rows; |
while( y-- ) |
{ |
x = cols_2; |
while( x-- ) |
{ |
register int L; |
cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; |
crb_g = 1*768+256 + colortab[ *cr + 1*256 ] |
+ colortab[ *cb + 2*256 ]; |
cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; |
cr += 4; cb += 4; |
L = *lum; lum += 2; |
row[0] = row[1] = row[next_row] = row[next_row+1] = |
(rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row += 2; |
L = *lum; lum += 2; |
row[0] = row[1] = row[next_row] = row[next_row+1] = |
(rgb_2_pix[ L + cr_r ] | |
rgb_2_pix[ L + crb_g ] | |
rgb_2_pix[ L + cb_b ]); |
row += 2; |
} |
row += next_row; |
} |
} |
/* |
* How many 1 bits are there in the Uint32. |
* Low performance, do not call often. |
*/ |
static int number_of_bits_set( Uint32 a ) |
{ |
if(!a) return 0; |
if(a & 1) return 1 + number_of_bits_set(a >> 1); |
return(number_of_bits_set(a >> 1)); |
} |
/* |
* How many 0 bits are there at least significant end of Uint32. |
* Low performance, do not call often. |
*/ |
static int free_bits_at_bottom( Uint32 a ) |
{ |
/* assume char is 8 bits */ |
if(!a) return sizeof(Uint32) * 8; |
if(((Sint32)a) & 1l) return 0; |
return 1 + free_bits_at_bottom ( a >> 1); |
} |
SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_Surface *display) |
{ |
SDL_Overlay *overlay; |
struct private_yuvhwdata *swdata; |
int *Cr_r_tab; |
int *Cr_g_tab; |
int *Cb_g_tab; |
int *Cb_b_tab; |
Uint32 *r_2_pix_alloc; |
Uint32 *g_2_pix_alloc; |
Uint32 *b_2_pix_alloc; |
int i, cpu_mmx; |
int CR, CB; |
Uint32 Rmask, Gmask, Bmask; |
/* Only RGB packed pixel conversion supported */ |
if ( (display->format->BytesPerPixel != 2) && |
(display->format->BytesPerPixel != 3) && |
(display->format->BytesPerPixel != 4) ) { |
SDL_SetError("Can't use YUV data on non 16/24/32 bit surfaces"); |
return(NULL); |
} |
/* Verify that we support the format */ |
switch (format) { |
case SDL_YV12_OVERLAY: |
case SDL_IYUV_OVERLAY: |
case SDL_YUY2_OVERLAY: |
case SDL_UYVY_OVERLAY: |
case SDL_YVYU_OVERLAY: |
break; |
default: |
SDL_SetError("Unsupported YUV format"); |
return(NULL); |
} |
/* Create the overlay structure */ |
overlay = (SDL_Overlay *)malloc(sizeof *overlay); |
if ( overlay == NULL ) { |
SDL_OutOfMemory(); |
return(NULL); |
} |
memset(overlay, 0, (sizeof *overlay)); |
/* Fill in the basic members */ |
overlay->format = format; |
overlay->w = width; |
overlay->h = height; |
/* Set up the YUV surface function structure */ |
overlay->hwfuncs = &sw_yuvfuncs; |
/* Create the pixel data and lookup tables */ |
swdata = (struct private_yuvhwdata *)malloc(sizeof *swdata); |
overlay->hwdata = swdata; |
if ( swdata == NULL ) { |
SDL_OutOfMemory(); |
SDL_FreeYUVOverlay(overlay); |
return(NULL); |
} |
swdata->stretch = NULL; |
swdata->display = display; |
swdata->pixels = (Uint8 *) malloc(width*height*2); |
swdata->colortab = (int *)malloc(4*256*sizeof(int)); |
Cr_r_tab = &swdata->colortab[0*256]; |
Cr_g_tab = &swdata->colortab[1*256]; |
Cb_g_tab = &swdata->colortab[2*256]; |
Cb_b_tab = &swdata->colortab[3*256]; |
swdata->rgb_2_pix = (Uint32 *)malloc(3*768*sizeof(Uint32)); |
r_2_pix_alloc = &swdata->rgb_2_pix[0*768]; |
g_2_pix_alloc = &swdata->rgb_2_pix[1*768]; |
b_2_pix_alloc = &swdata->rgb_2_pix[2*768]; |
if ( ! swdata->pixels || ! swdata->colortab || ! swdata->rgb_2_pix ) { |
SDL_OutOfMemory(); |
SDL_FreeYUVOverlay(overlay); |
return(NULL); |
} |
/* Generate the tables for the display surface */ |
for (i=0; i<256; i++) { |
/* Gamma correction (luminescence table) and chroma correction |
would be done here. See the Berkeley mpeg_play sources. |
*/ |
CB = CR = (i-128); |
Cr_r_tab[i] = (int) ( (0.419/0.299) * CR); |
Cr_g_tab[i] = (int) (-(0.299/0.419) * CR); |
Cb_g_tab[i] = (int) (-(0.114/0.331) * CB); |
Cb_b_tab[i] = (int) ( (0.587/0.331) * CB); |
} |
/* |
* Set up entries 0-255 in rgb-to-pixel value tables. |
*/ |
Rmask = display->format->Rmask; |
Gmask = display->format->Gmask; |
Bmask = display->format->Bmask; |
for ( i=0; i<256; ++i ) { |
r_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Rmask)); |
r_2_pix_alloc[i+256] <<= free_bits_at_bottom(Rmask); |
g_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Gmask)); |
g_2_pix_alloc[i+256] <<= free_bits_at_bottom(Gmask); |
b_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Bmask)); |
b_2_pix_alloc[i+256] <<= free_bits_at_bottom(Bmask); |
} |
/* |
* If we have 16-bit output depth, then we double the value |
* in the top word. This means that we can write out both |
* pixels in the pixel doubling mode with one op. It is |
* harmless in the normal case as storing a 32-bit value |
* through a short pointer will lose the top bits anyway. |
*/ |
if( display->format->BytesPerPixel == 2 ) { |
for ( i=0; i<256; ++i ) { |
r_2_pix_alloc[i+256] |= (r_2_pix_alloc[i+256]) << 16; |
g_2_pix_alloc[i+256] |= (g_2_pix_alloc[i+256]) << 16; |
b_2_pix_alloc[i+256] |= (b_2_pix_alloc[i+256]) << 16; |
} |
} |
/* |
* Spread out the values we have to the rest of the array so that |
* we do not need to check for overflow. |
*/ |
for ( i=0; i<256; ++i ) { |
r_2_pix_alloc[i] = r_2_pix_alloc[256]; |
r_2_pix_alloc[i+512] = r_2_pix_alloc[511]; |
g_2_pix_alloc[i] = g_2_pix_alloc[256]; |
g_2_pix_alloc[i+512] = g_2_pix_alloc[511]; |
b_2_pix_alloc[i] = b_2_pix_alloc[256]; |
b_2_pix_alloc[i+512] = b_2_pix_alloc[511]; |
} |
/* You have chosen wisely... */ |
switch (format) { |
case SDL_YV12_OVERLAY: |
case SDL_IYUV_OVERLAY: |
cpu_mmx = CPU_Flags() & MMX_CPU; |
if ( display->format->BytesPerPixel == 2 ) { |
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) |
/* inline assembly functions */ |
if ( cpu_mmx && (Rmask == 0xF800) && |
(Gmask == 0x07E0) && |
(Bmask == 0x001F) && |
(width & 15) == 0) { |
/*printf("Using MMX 16-bit 565 dither\n");*/ |
swdata->Display1X = Color565DitherYV12MMX1X; |
} else { |
/*printf("Using C 16-bit dither\n");*/ |
swdata->Display1X = Color16DitherYV12Mod1X; |
} |
#else |
swdata->Display1X = Color16DitherYV12Mod1X; |
#endif |
swdata->Display2X = Color16DitherYV12Mod2X; |
} |
if ( display->format->BytesPerPixel == 3 ) { |
swdata->Display1X = Color24DitherYV12Mod1X; |
swdata->Display2X = Color24DitherYV12Mod2X; |
} |
if ( display->format->BytesPerPixel == 4 ) { |
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) |
/* inline assembly functions */ |
if ( cpu_mmx && (Rmask == 0x00FF0000) && |
(Gmask == 0x0000FF00) && |
(Bmask == 0x000000FF) && |
(width & 15) == 0) { |
/*printf("Using MMX 32-bit dither\n");*/ |
swdata->Display1X = ColorRGBDitherYV12MMX1X; |
} else { |
/*printf("Using C 32-bit dither\n");*/ |
swdata->Display1X = Color32DitherYV12Mod1X; |
} |
#else |
swdata->Display1X = Color32DitherYV12Mod1X; |
#endif |
swdata->Display2X = Color32DitherYV12Mod2X; |
} |
break; |
case SDL_YUY2_OVERLAY: |
case SDL_UYVY_OVERLAY: |
case SDL_YVYU_OVERLAY: |
if ( display->format->BytesPerPixel == 2 ) { |
swdata->Display1X = Color16DitherYUY2Mod1X; |
swdata->Display2X = Color16DitherYUY2Mod2X; |
} |
if ( display->format->BytesPerPixel == 3 ) { |
swdata->Display1X = Color24DitherYUY2Mod1X; |
swdata->Display2X = Color24DitherYUY2Mod2X; |
} |
if ( display->format->BytesPerPixel == 4 ) { |
swdata->Display1X = Color32DitherYUY2Mod1X; |
swdata->Display2X = Color32DitherYUY2Mod2X; |
} |
break; |
default: |
/* We should never get here (caught above) */ |
break; |
} |
/* Find the pitch and offset values for the overlay */ |
overlay->pitches = swdata->pitches; |
overlay->pixels = swdata->planes; |
switch (format) { |
case SDL_YV12_OVERLAY: |
case SDL_IYUV_OVERLAY: |
overlay->pitches[0] = overlay->w; |
overlay->pitches[1] = overlay->pitches[0] / 2; |
overlay->pitches[2] = overlay->pitches[0] / 2; |
overlay->pixels[0] = swdata->pixels; |
overlay->pixels[1] = overlay->pixels[0] + |
overlay->pitches[0] * overlay->h; |
overlay->pixels[2] = overlay->pixels[1] + |
overlay->pitches[1] * overlay->h / 2; |
overlay->planes = 3; |
break; |
case SDL_YUY2_OVERLAY: |
case SDL_UYVY_OVERLAY: |
case SDL_YVYU_OVERLAY: |
overlay->pitches[0] = overlay->w*2; |
overlay->pixels[0] = swdata->pixels; |
overlay->planes = 1; |
break; |
default: |
/* We should never get here (caught above) */ |
break; |
} |
/* We're all done.. */ |
return(overlay); |
} |
int SDL_LockYUV_SW(_THIS, SDL_Overlay *overlay) |
{ |
return(0); |
} |
void SDL_UnlockYUV_SW(_THIS, SDL_Overlay *overlay) |
{ |
return; |
} |
int SDL_DisplayYUV_SW(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) |
{ |
struct private_yuvhwdata *swdata; |
SDL_Surface *stretch; |
SDL_Surface *display; |
int scale_2x; |
Uint8 *lum, *Cr, *Cb; |
Uint8 *dst; |
int mod; |
swdata = overlay->hwdata; |
scale_2x = 0; |
stretch = 0; |
if ( (overlay->w != dstrect->w) || (overlay->h != dstrect->h) ) { |
if ( (dstrect->w == 2*overlay->w) && |
(dstrect->h == 2*overlay->h) ) { |
scale_2x = 1; |
} else { |
if ( ! swdata->stretch ) { |
display = swdata->display; |
swdata->stretch = SDL_CreateRGBSurface( |
SDL_SWSURFACE, |
overlay->w, overlay->h, |
display->format->BitsPerPixel, |
display->format->Rmask, |
display->format->Gmask, |
display->format->Bmask, 0); |
if ( ! swdata->stretch ) { |
return(-1); |
} |
} |
stretch = swdata->stretch; |
} |
} |
if ( stretch ) { |
display = stretch; |
} else { |
display = swdata->display; |
} |
switch (overlay->format) { |
case SDL_YV12_OVERLAY: |
lum = overlay->pixels[0]; |
Cr = overlay->pixels[1]; |
Cb = overlay->pixels[2]; |
break; |
case SDL_IYUV_OVERLAY: |
lum = overlay->pixels[0]; |
Cr = overlay->pixels[2]; |
Cb = overlay->pixels[1]; |
break; |
case SDL_YUY2_OVERLAY: |
lum = overlay->pixels[0]; |
Cr = lum + 3; |
Cb = lum + 1; |
break; |
case SDL_UYVY_OVERLAY: |
lum = overlay->pixels[0]+1; |
Cr = lum + 1; |
Cb = lum - 1; |
break; |
case SDL_YVYU_OVERLAY: |
lum = overlay->pixels[0]; |
Cr = lum + 1; |
Cb = lum + 3; |
break; |
default: |
SDL_SetError("Unsupported YUV format in blit (??)"); |
return(-1); |
} |
if ( SDL_MUSTLOCK(display) ) { |
if ( SDL_LockSurface(display) < 0 ) { |
return(-1); |
} |
} |
if ( stretch ) { |
dst = (Uint8 *)stretch->pixels; |
} else { |
dst = (Uint8 *)display->pixels |
+ dstrect->x * display->format->BytesPerPixel |
+ dstrect->y * display->pitch; |
} |
mod = (display->pitch / display->format->BytesPerPixel); |
if ( scale_2x ) { |
mod -= (overlay->w * 2); |
swdata->Display2X(swdata->colortab, swdata->rgb_2_pix, |
lum, Cr, Cb, dst, overlay->h, overlay->w,mod); |
} else { |
mod -= overlay->w; |
swdata->Display1X(swdata->colortab, swdata->rgb_2_pix, |
lum, Cr, Cb, dst, overlay->h, overlay->w,mod); |
} |
if ( SDL_MUSTLOCK(display) ) { |
SDL_UnlockSurface(display); |
} |
if ( stretch ) { |
display = swdata->display; |
SDL_SoftStretch(stretch, NULL, display, dstrect); |
} |
SDL_UpdateRects(display, 1, dstrect); |
return(0); |
} |
void SDL_FreeYUV_SW(_THIS, SDL_Overlay *overlay) |
{ |
struct private_yuvhwdata *swdata; |
swdata = overlay->hwdata; |
if ( swdata ) { |
if ( swdata->stretch ) { |
SDL_FreeSurface(swdata->stretch); |
} |
if ( swdata->pixels ) { |
free(swdata->pixels); |
} |
if ( swdata->colortab ) { |
free(swdata->colortab); |
} |
if ( swdata->rgb_2_pix ) { |
free(swdata->rgb_2_pix); |
} |
free(swdata); |
} |
} |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_yuv_sw_c.h |
---|
0,0 → 1,41 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_yuv_sw_c.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; |
#endif |
#include "SDL_video.h" |
#include "SDL_sysvideo.h" |
/* This is the software implementation of the YUV video overlay support */ |
extern SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_Surface *display); |
extern int SDL_LockYUV_SW(_THIS, SDL_Overlay *overlay); |
extern void SDL_UnlockYUV_SW(_THIS, SDL_Overlay *overlay); |
extern int SDL_DisplayYUV_SW(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect); |
extern void SDL_FreeYUV_SW(_THIS, SDL_Overlay *overlay); |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/SDL_yuvfuncs.h |
---|
0,0 → 1,41 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_yuvfuncs.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; |
#endif |
/* This is the definition of the YUV video surface function structure */ |
#include "SDL_video.h" |
#include "SDL_sysvideo.h" |
#ifndef _THIS |
#define _THIS SDL_VideoDevice *_this |
#endif |
struct private_yuvhwfuncs { |
int (*Lock)(_THIS, SDL_Overlay *overlay); |
void (*Unlock)(_THIS, SDL_Overlay *overlay); |
int (*Display)(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect); |
void (*FreeHW)(_THIS, SDL_Overlay *overlay); |
}; |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/blank_cursor.h |
---|
0,0 → 1,38 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: blank_cursor.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; |
#endif |
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
* A default blank 8x8 cursor */ |
#define BLANK_CWIDTH 8 |
#define BLANK_CHEIGHT 8 |
#define BLANK_CHOTX 0 |
#define BLANK_CHOTY 0 |
static unsigned char blank_cdata[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
static unsigned char blank_cmask[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/sdk/sources/SDL-1.2.2_newlib/src/video/default_cursor.h |
---|
0,0 → 1,121 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: default_cursor.h,v 1.3 2001/05/10 20:13:28 hercules Exp $"; |
#endif |
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
* Default cursor - it happens to be the Mac cursor, but could be anything */ |
#define DEFAULT_CWIDTH 16 |
#define DEFAULT_CHEIGHT 16 |
#define DEFAULT_CHOTX 0 |
#define DEFAULT_CHOTY 0 |
/* Added a real MacOS cursor, at the request of Luc-Olivier de Charrière */ |
#define USE_MACOS_CURSOR |
#ifdef USE_MACOS_CURSOR |
static unsigned char default_cdata[] = |
{ |
0x00,0x00, |
0x40,0x00, |
0x60,0x00, |
0x70,0x00, |
0x78,0x00, |
0x7C,0x00, |
0x7E,0x00, |
0x7F,0x00, |
0x7F,0x80, |
0x7C,0x00, |
0x6C,0x00, |
0x46,0x00, |
0x06,0x00, |
0x03,0x00, |
0x03,0x00, |
0x00,0x00 |
}; |
static unsigned char default_cmask[] = |
{ |
0xC0,0x00, |
0xE0,0x00, |
0xF0,0x00, |
0xF8,0x00, |
0xFC,0x00, |
0xFE,0x00, |
0xFF,0x00, |
0xFF,0x80, |
0xFF,0xC0, |
0xFF,0xE0, |
0xFE,0x00, |
0xEF,0x00, |
0xCF,0x00, |
0x87,0x80, |
0x07,0x80, |
0x03,0x00 |
}; |
#else |
static unsigned char default_cdata[] = |
{ |
0x00,0x00, |
0x40,0x00, |
0x60,0x00, |
0x70,0x00, |
0x78,0x00, |
0x7C,0x00, |
0x7E,0x00, |
0x7F,0x00, |
0x7F,0x80, |
0x7C,0x00, |
0x6C,0x00, |
0x46,0x00, |
0x06,0x00, |
0x03,0x00, |
0x03,0x00, |
0x00,0x00 |
}; |
static unsigned char default_cmask[] = |
{ |
0x40,0x00, |
0xE0,0x00, |
0xF0,0x00, |
0xF8,0x00, |
0xFC,0x00, |
0xFE,0x00, |
0xFF,0x00, |
0xFF,0x80, |
0xFF,0xC0, |
0xFF,0x80, |
0xFE,0x00, |
0xEF,0x00, |
0x4F,0x00, |
0x07,0x80, |
0x07,0x80, |
0x03,0x00 |
}; |
#endif /* TRUE_MACINTOSH_CURSOR */ |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |