File:
[RetroPC.NET] /
np2 /
sdl /
win32s /
SDLvideo.c
Revision
1.1:
download - view:
text,
annotated -
select for diffs
Fri Nov 21 15:51:13 2003 JST (21 years, 11 months ago) by
yui
Branches:
MAIN
CVS tags:
VER_0_82_x64,
VER_0_82,
VER_0_81A,
VER_0_81,
VER_0_80,
VER_0_79,
VER_0_78,
VER_0_77,
VER_0_76,
VER_0_75,
VER_0_74,
VER_0_73,
VER_0_72,
HEAD
debuneko- (T.Yui)
#include "compiler.h"
static SDL_VideoInfo vinfo;
static SDL_PixelFormat vinfofmt;
static const char vinfostr[] = "SDL simulate";
extern SDL_Surface *__sdl_vsurf;
extern HWND __sdl_hWnd;
// ---- surface
enum {
SURFTYPE_MEMORY = 0,
SURFTYPE_BITMAP = 1
};
typedef struct {
UINT type;
HBITMAP hbmp;
} _SURFINF, *SURFINF;
#pragma pack(push, 1)
typedef struct {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[256];
} BMPINFO;
#pragma pack(pop)
static BYTE mask2sft(DWORD mask) {
BYTE ret;
ret = 0;
if (mask) {
while(!(mask & (1 << ret))) {
ret++;
}
}
return(ret);
}
static SDL_Surface *cresurf_sw(DWORD flags, int width, int height,
int depth, DWORD Rmask, DWORD Gmask, DWORD Bmask, DWORD Amask) {
int size;
int xalign;
SDL_Surface *ret;
SURFINF inf;
SDL_PixelFormat *fmt;
SDL_Palette *pal;
SDL_Color *col;
if ((depth != 8) && (depth != 16) && (depth != 24) && (depth != 32)) {
return(NULL);
}
xalign = depth / 8;
size = width * height * xalign;
size += sizeof(SDL_Surface) + sizeof(_SURFINF) + sizeof(SDL_PixelFormat);
if (depth == 8) {
size += sizeof(SDL_Palette) + (sizeof(SDL_Color) << depth);
}
ret = (SDL_Surface *)_MALLOC(size, "SDL_Surface");
if (ret != NULL) {
ZeroMemory(ret, size);
inf = (SURFINF)(ret + 1);
fmt = (SDL_PixelFormat *)(inf + 1);
ret->format = fmt;
ret->w = width;
ret->h = height;
ret->pitch = (WORD)(width * xalign);
if (depth == 8) {
pal = (SDL_Palette *)(fmt + 1);
col = (SDL_Color *)(pal + 1);
fmt->palette = pal;
pal->ncolors = 1 << depth;
pal->colors = col;
ret->pixels = (void *)(col + (1 << depth));
}
else {
ret->pixels = (void *)(fmt + 1);
fmt->Rmask = Rmask;
fmt->Gmask = Gmask;
fmt->Bmask = Bmask;
fmt->Amask = Amask;
fmt->Rshift = mask2sft(Rmask);
fmt->Gshift = mask2sft(Gmask);
fmt->Bshift = mask2sft(Bmask);
fmt->Ashift = mask2sft(Amask);
}
inf->type = SURFTYPE_MEMORY;
fmt->BitsPerPixel = depth;
fmt->BytesPerPixel = xalign;
}
return(ret);
}
static SDL_Surface *cresurf_hw(DWORD flags, int width, int height,
int depth, DWORD Rmask, DWORD Gmask, DWORD Bmask, DWORD Amask) {
BMPINFO bi;
HDC hdc;
HBITMAP hbmp;
void *image;
SDL_Surface *ret;
int size;
SURFINF inf;
SDL_PixelFormat *fmt;
ZeroMemory(&bi, sizeof(bi));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = width;
bi.bmiHeader.biHeight = 0 - height;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = depth;
if (depth == 16) {
bi.bmiHeader.biCompression = BI_BITFIELDS;
*(DWORD *)(bi.bmiColors + 0) = 0xf800;
*(DWORD *)(bi.bmiColors + 1) = 0x07e0;
*(DWORD *)(bi.bmiColors + 2) = 0x001f;
}
else if (depth == 24) {
bi.bmiHeader.biCompression = BI_RGB;
}
else {
goto ssc_err1;
}
hdc = GetDC(NULL);
hbmp = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS,
&image, NULL, 0);
ReleaseDC(NULL, hdc);
if (hbmp == NULL) {
goto ssc_err1;
}
size = sizeof(SDL_Surface) + sizeof(_SURFINF) + sizeof(SDL_PixelFormat);
ret = (SDL_Surface *)_MALLOC(size, "SDL_Surface");
if (ret == NULL) {
goto ssc_err2;
}
ZeroMemory(ret, size);
inf = (SURFINF)(ret + 1);
fmt = (SDL_PixelFormat *)(inf + 1);
ret->format = fmt;
ret->w = width;
ret->h = height;
ret->pitch = (WORD)(((width * depth / 8) + 3) & (~3));
ret->pixels = image;
inf->type = SURFTYPE_BITMAP;
inf->hbmp = hbmp;
fmt->BitsPerPixel = depth;
fmt->BytesPerPixel = depth / 8;
if (depth == 16) {
fmt->Rshift = 11;
fmt->Gshift = 5;
fmt->Bshift = 0;
fmt->Rmask = 0xf800;
fmt->Gmask = 0x07e0;
fmt->Bmask = 0x001f;
}
else if (depth == 24) {
fmt->Rshift = 16;
fmt->Gshift = 8;
fmt->Bshift = 0;
fmt->Rmask = 0xff0000;
fmt->Gmask = 0x00ff00;
fmt->Bmask = 0x0000ff;
}
return(ret);
ssc_err2:
DeleteObject(hbmp);
ssc_err1:
return(NULL);
}
SDL_Surface *SDL_CreateRGBSurface(DWORD flags, int width, int height,
int depth, DWORD Rmask, DWORD Gmask, DWORD Bmask, DWORD Amask) {
if ((width <= 0) || (height <= 0)) {
return(NULL);
}
if (flags & SDL_HWSURFACE) {
return(cresurf_hw(flags, width, height, depth,
Rmask, Gmask, Bmask, Amask));
}
else {
return(cresurf_sw(flags, width, height, depth,
Rmask, Gmask, Bmask, Amask));
}
}
void SDL_FreeSurface(SDL_Surface *surface) {
SURFINF inf;
if (surface) {
inf = (SURFINF)(surface + 1);
if (inf->type == SURFTYPE_BITMAP) {
DeleteObject(inf->hbmp);
}
_MFREE(surface);
}
}
// ---- video
void __sdl_videoinit(void) {
ZeroMemory(&vinfofmt, sizeof(vinfofmt));
vinfofmt.BitsPerPixel = 16;
vinfofmt.BytesPerPixel = 2;
vinfofmt.Rshift = 11;
vinfofmt.Gshift = 5;
vinfofmt.Bshift = 0;
vinfofmt.Rmask = 0xf800;
vinfofmt.Gmask = 0x07e0;
vinfofmt.Bmask = 0x001f;
ZeroMemory(&vinfo, sizeof(vinfo));
vinfo.vfmt = &vinfofmt;
}
void __sdl_videopaint(HWND hWnd, SDL_Surface *screen) {
SURFINF inf;
HDC hdc;
HDC hmemdc;
HBITMAP hbitmap;
if (screen) {
inf = (SURFINF)(screen + 1);
if (inf->type == SURFTYPE_BITMAP) {
hdc = GetDC(hWnd);
hmemdc = CreateCompatibleDC(hdc);
hbitmap = (HBITMAP)SelectObject(hmemdc, inf->hbmp);
BitBlt(hdc, 0, 0, screen->w, screen->h, hmemdc, 0, 0, SRCCOPY);
SelectObject(hmemdc, hbitmap);
DeleteDC(hmemdc);
ReleaseDC(hWnd, hdc);
}
}
}
static void setclientsize(HWND hwnd, LONG width, LONG height) {
int scx, scy;
int x, y, w, h;
RECT rectWindow, rectClient, rectDisktop;
GetWindowRect(hwnd, &rectWindow);
GetClientRect(hwnd, &rectClient);
w = width + (rectWindow.right - rectWindow.left)
- (rectClient.right - rectClient.left);
h = height + (rectWindow.bottom - rectWindow.top)
- (rectClient.bottom - rectClient.top);
scx = GetSystemMetrics(SM_CXSCREEN);
scy = GetSystemMetrics(SM_CYSCREEN);
SystemParametersInfo(SPI_GETWORKAREA, 0, &rectDisktop, 0);
x = rectWindow.left;
y = rectWindow.top;
if (scx < w) {
x = (scx - w) / 2;
}
else {
if ((x + w) > rectDisktop.right) {
x = rectDisktop.right - w;
}
if (x < rectDisktop.left) {
x = rectDisktop.left;
}
}
if (scy < h) {
y = (scy - h) / 2;
}
else {
if ((y + h) > rectDisktop.bottom) {
y = rectDisktop.bottom - h;
}
if (y < rectDisktop.top) {
y = rectDisktop.top;
}
}
MoveWindow(hwnd, x, y, w, h, TRUE);
}
// ----
void SDL_WM_SetCaption(const char *title, const char *icon) {
char caption[256];
milstr_ncpy(caption, "SDL", sizeof(caption));
if (title) {
milstr_ncat(caption, " - ", sizeof(caption));
milstr_ncat(caption, title, sizeof(caption));
}
SetWindowText(__sdl_hWnd, caption);
}
const SDL_VideoInfo *SDL_GetVideoInfo(void) {
return(&vinfo);
}
char *SDL_VideoDriverName(char *namebuf, int maxlen) {
if ((namebuf) && (maxlen)) {
milstr_ncpy(namebuf, vinfostr, maxlen);
}
return((char *)vinfostr);
}
SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, DWORD flags) {
SDL_FreeSurface(__sdl_vsurf);
__sdl_vsurf = SDL_CreateRGBSurface(SDL_HWSURFACE, width, height, bpp,
0, 0, 0, 0);
setclientsize(__sdl_hWnd, width, height);
return(__sdl_vsurf);
}
SDL_Surface *SDL_GetVideoSurface(void) {
return(__sdl_vsurf);
}
int SDL_LockSurface(SDL_Surface *surface) {
return(0);
}
void SDL_UnlockSurface(SDL_Surface *surface) {
}
int SDL_Flip(SDL_Surface *screen) {
__sdl_videopaint(__sdl_hWnd, screen);
return(0);
}
RetroPC.NET-CVS <cvs@retropc.net>