Commit 9f24e9f6 authored by Eli Gottlieb's avatar Eli Gottlieb

Updated test code, updated win32 code a bit (still not complete, but hopefully...

Updated test code, updated win32 code a bit (still not complete, but hopefully tonight), and removed the last vestiges of ellipse and polygon drawing support.
parent a50bf48e
/*
SDL - Simple DirectMedia Layer
Copyright (C) 2010 Eli Gottlieb
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Eli Gottlieb
eligottlieb@gmail.com
*/
/**
* \file SDL_ellipse.h
*
* Header file for SDL_ellipse definition and management functions.
*/
#ifndef _SDL_ellipse_h
#define _SDL_ellipse_h
#include "SDL_stdinc.h"
#include "SDL_error.h"
#include "SDL_pixels.h"
#include "SDL_rwops.h"
#include "begin_code.h"
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
/**
* \brief The structure that defines an ellipse.
*
* \sa SDL_EllipseEmpty
* \sa SDL_EllipseEquals
* \sa SDL_EllipsesIntersect
* \sa SDL_IntersectEllipseAndLine
*/
typedef struct SDL_Ellipse {
int x,y;
int a,b;
int r;
} SDL_Ellipse;
/**
* \brief Returns true if the ellipse has no area.
*/
#define SDL_EllipseEmpty(X) ((X)->r <= 0)
/**
* \brief Returns true if the two ellipses are equal.
*/
#define SDL_EllipseEquals(A, B) (((A)->x == (B)->x) && ((A)->y == (B)->y) && \
((A)->a == (B)->a) && ((A)->b == (B)->b) && ((A)->r == (B)->r))
/**
* \brief Determine whether two ellipses intersect.
*
* \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
*/
extern DECLSPEC SDL_bool SDLCALL SDL_EllipsesIntersect(const SDL_Ellipse * A,const SDL_Ellipse * B);
/**
* \brief Calculate the intersection of an ellipse and line segment.
*
* \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
*/
extern DECLSPEC SDL_bool SDLCALL SDL_IntersectEllipseAndLine(const SDL_Ellipse *ellipse,int *X1,int *Y1,int *X2,int *Y2);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif
#include "close_code.h"
#endif /* _SDL_ellipse_h */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 2010 Eli Gottlieb
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Eli Gottlieb
eligottlieb@gmail.com
*/
/**
* \file SDL_poly.h
*
* Header file for SDL_poly definition and management functions.
*/
#ifndef _SDL_poly_h
#define _SDL_poly_h
#include "SDL_stdinc.h"
#include "SDL_error.h"
#include "SDL_pixels.h"
#include "SDL_rwops.h"
#include "SDL_rect.h"
#include "begin_code.h"
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
/**
* \brief The structure that defines an polygon.
*
* \sa SDL_PolyEmpty
* \sa SDL_PolyEquals
* \sa SDL_PolysIntersect
* \sa SDL_IntersectPoly
* \sa SDL_WrapPoints
* \sa SDL_IntersectPolyAndLine
*/
typedef struct SDL_Poly {
SDL_Point *vertices;
int count;
} SDL_Poly;
/**
* \brief Returns true if the polygon has no area.
*/
#define SDL_PolyEmpty(X) (((X)->vertices == NULL) || ((X)->count <= 2))
/**
* \brief Determine whether two polygons are equal.
*
* \return SDL_TRUE if the polygons are equal, SDL_FALSE otherwise.
*/
extern DECLSPEC SDL_bool SDLCALL SDL_PolyEquals(const SDL_Poly *A,const SDL_Poly *B);
/**
* \brief Determine whether two rectangles intersect.
*
* \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
*/
extern DECLSPEC SDL_bool SDLCALL SDL_PolysIntersect(const SDL_Poly * A,const SDL_Poly * B);
/**
* \brief Calculate the intersection of two rectangles.
*
* \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
*/
extern DECLSPEC SDL_bool SDLCALL SDL_IntersectPoly(const SDL_Poly * A,const SDL_Poly * B,SDL_Poly * result);
/**
* \brief Calculate a minimal polygon wrapping a set of points
*
* \return 0 on success, -1 if the parameters were invalid, and -2 if an insufficient number of points were supplied
* in the output polygon.
*/
extern DECLSPEC int SDLCALL SDL_WrapPoints(const SDL_Point * points,int count,SDL_Poly *result);
/**
* \brief Calculate the intersection of a polygon and line segment.
*
* \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
*/
extern DECLSPEC SDL_bool SDLCALL SDL_IntersectPolyAndLine(const SDL_Poly *poly,int *X1,int *Y1,int *X2,int *Y2);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif
#include "close_code.h"
#endif /* _SDL_poly_h */
...@@ -32,8 +32,6 @@ ...@@ -32,8 +32,6 @@
#include "SDL_stdinc.h" #include "SDL_stdinc.h"
#include "SDL_pixels.h" #include "SDL_pixels.h"
#include "SDL_rect.h" #include "SDL_rect.h"
#include "SDL_ellipse.h"
#include "SDL_poly.h"
#include "SDL_surface.h" #include "SDL_surface.h"
#include "begin_code.h" #include "begin_code.h"
......
...@@ -45,7 +45,7 @@ SDL_bool SDL_IsShapedWindow(const SDL_Window *window) { ...@@ -45,7 +45,7 @@ SDL_bool SDL_IsShapedWindow(const SDL_Window *window) {
} }
/* REQUIRES that bitmap point to a w-by-h bitmap with 1bpp. */ /* REQUIRES that bitmap point to a w-by-h bitmap with 1bpp. */
void SDL_CalculateShapeBitmap(Uint8 alphacutoff,SDL_Surface *shape,Uint8* bitmap) { void SDL_CalculateShapeBitmap(Uint8 alphacutoff,SDL_Surface *shape,Uint8* bitmap,Uint8 ppb,Uint8 value) {
if(SDL_MUSTLOCK(shape)) if(SDL_MUSTLOCK(shape))
SDL_LockSurface(shape); SDL_LockSurface(shape);
int x = 0,y = 0; int x = 0,y = 0;
...@@ -55,7 +55,7 @@ void SDL_CalculateShapeBitmap(Uint8 alphacutoff,SDL_Surface *shape,Uint8* bitmap ...@@ -55,7 +55,7 @@ void SDL_CalculateShapeBitmap(Uint8 alphacutoff,SDL_Surface *shape,Uint8* bitmap
Uint8 alpha = 0; Uint8 alpha = 0;
SDL_GetRGBA(*(Uint32*)pixel,shape->format,NULL,NULL,NULL,&alpha); SDL_GetRGBA(*(Uint32*)pixel,shape->format,NULL,NULL,NULL,&alpha);
Uint32 bitmap_pixel = y*shape->w + x; Uint32 bitmap_pixel = y*shape->w + x;
bitmap[bitmap_pixel / 8] |= (alpha >= alphacutoff ? 1 : 0) << (8 - (bitmap_pixel % 8)); bitmap[bitmap_pixel / ppb] |= (alpha >= alphacutoff ? value : 0) << ((ppb - 1) - (bitmap_pixel % ppb));
} }
if(SDL_MUSTLOCK(shape)) if(SDL_MUSTLOCK(shape))
SDL_UnlockSurface(shape); SDL_UnlockSurface(shape);
...@@ -81,7 +81,7 @@ int SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode ...@@ -81,7 +81,7 @@ int SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode
} }
} }
} }
//TODO: Platform-specific implementations of SetWindowShape. X11 is in-progress. //TODO: Platform-specific implementations of SetWindowShape. X11 is finished. Win32 is in progress.
int result = window->display->device->shape_driver.SetWindowShape(window->shaper,shape,shapeMode); int result = window->display->device->shape_driver.SetWindowShape(window->shaper,shape,shapeMode);
window->shaper->hasshape = SDL_TRUE; window->shaper->hasshape = SDL_TRUE;
if(window->shaper->usershownflag & SDL_WINDOW_SHOWN == SDL_WINDOW_SHOWN) { if(window->shaper->usershownflag & SDL_WINDOW_SHOWN == SDL_WINDOW_SHOWN) {
......
...@@ -20,6 +20,65 @@ ...@@ -20,6 +20,65 @@
eligottlieb@gmail.com eligottlieb@gmail.com
*/ */
#include "SDL_shape.h" #include <windows.h>
#include "SDL_win32shape.h"
/* Functions implementing shaped windows for Win32 will be implemented when the API is set. */ SDL_WindowShaper* Win32_CreateShaper(SDL_Window * window) {
SDL_WindowShaper* result = malloc(sizeof(SDL_WindowShaper));
result->window = window;
result->alphacutoff = 0;
result->usershownflag = 0;
//Put some driver-data here.
window->shaper = result;
int resized_properly = X11ResizeWindowShape(window);
assert(resized_properly == 0);
return result;
}
int Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) {
assert(shaper != NULL && shape != NULL);
if(!SDL_ISPIXELFORMAT_ALPHA(SDL_MasksToPixelFormatEnum(shape->format->BitsPerPixel,shape->format->Rmask,shape->format->Gmask,shape->format->Bmask,shape->format->Amask)))
return -2;
if(shape->w != shaper->window->w || shape->h != shaper->window->h)
return -3;
/* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */
/*
* Start with empty region
*/
HRGN MaskRegion = CreateRectRgn(0, 0, 0, 0);
unsigned int pitch = shape->pitch;
unsigned int width = shape->width;
unsigned int height = shape->height;
unsigned int dy = pitch - width;
SDL_ShapeData *data = (SDL_ShapeData*)shaper->driverdata;
/*
* Transfer binarized mask image into workbuffer
*/
SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->shapebuffer,1,0xff);
//Move code over to here from AW_windowShape.c
}
int Win32_ResizeWindowShape(SDL_Window *window) {
SDL_ShapeData* data = window->shaper->driverdata;
assert(data != NULL);
unsigned int buffersize = window->w * window->h;
if(data->buffersize != buffersize || data->shapebuffer == NULL) {
data->buffersize = buffersize;
if(data->shapebuffer != NULL)
free(data->shapebuffer);
data->shapebuffer = malloc(data->buffersize);
if(data->shapebuffer == NULL) {
SDL_SetError("Could not allocate memory for shaped-window bitmap.");
return -1;
}
}
window->shaper->usershownflag = window->flags & SDL_WINDOW_SHOWN;
return 0;
}
...@@ -62,6 +62,7 @@ int X11_ResizeWindowShape(SDL_Window* window) { ...@@ -62,6 +62,7 @@ int X11_ResizeWindowShape(SDL_Window* window) {
} }
int X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) { int X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) {
assert(shaper != NULL && shape != NULL);
if(!SDL_ISPIXELFORMAT_ALPHA(SDL_MasksToPixelFormatEnum(shape->format->BitsPerPixel,shape->format->Rmask,shape->format->Gmask,shape->format->Bmask,shape->format->Amask))) if(!SDL_ISPIXELFORMAT_ALPHA(SDL_MasksToPixelFormatEnum(shape->format->BitsPerPixel,shape->format->Rmask,shape->format->Gmask,shape->format->Bmask,shape->format->Amask)))
return -2; return -2;
if(shape->w != shaper->window->w || shape->h != shaper->window->h) if(shape->w != shaper->window->w || shape->h != shaper->window->h)
...@@ -69,8 +70,8 @@ int X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowSha ...@@ -69,8 +70,8 @@ int X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowSha
SDL_ShapeData *data = shaper->driverdata; SDL_ShapeData *data = shaper->driverdata;
assert(data != NULL); assert(data != NULL);
/* Assume that shaper->alphacutoff already has a value. */ /* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */
SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->bitmap); SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->bitmap,8,1);
SDL_WindowData *windowdata = (SDL_WindowData*)(shaper->window->driverdata); SDL_WindowData *windowdata = (SDL_WindowData*)(shaper->window->driverdata);
Pixmap shapemask = XCreateBitmapFromData(windowdata->videodata->display,windowdata->xwindow,data->bitmap,shaper->window->w,shaper->window->h); Pixmap shapemask = XCreateBitmapFromData(windowdata->videodata->display,windowdata->xwindow,data->bitmap,shaper->window->w,shaper->window->h);
......
...@@ -143,7 +143,7 @@ int main(int argc,char** argv) { ...@@ -143,7 +143,7 @@ int main(int argc,char** argv) {
exit(-3); exit(-3);
} }
SDL_Color bnw_palette[2] = {{0,0,0,0},{255,255,255,255}}; SDL_Color bnw_palette[2] = {{0,0,0,255},{255,255,255,255}};
SDL_Texture *eyes_texture = SDL_CreateTexture(SDL_PIXELFORMAT_INDEX1LSB,SDL_TEXTUREACCESS_STREAMING,eyes_width,eyes_height); SDL_Texture *eyes_texture = SDL_CreateTexture(SDL_PIXELFORMAT_INDEX1LSB,SDL_TEXTUREACCESS_STREAMING,eyes_width,eyes_height);
if(eyes_texture == NULL) { if(eyes_texture == NULL) {
SDL_DestroyRenderer(window); SDL_DestroyRenderer(window);
...@@ -162,8 +162,11 @@ int main(int argc,char** argv) { ...@@ -162,8 +162,11 @@ int main(int argc,char** argv) {
memcpy(pixels+pitch*row,eyes_bits+(eyes_width/8)*row,eyes_width/8); memcpy(pixels+pitch*row,eyes_bits+(eyes_width/8)*row,eyes_width/8);
SDL_UnlockTexture(eyes_texture); SDL_UnlockTexture(eyes_texture);
SDL_Texture *mask_texture = SDL_CreateTexture(SDL_PIXELFORMAT_INDEX1LSB,SDL_TEXTUREACCESS_STREAMING,eyesmask_width,eyesmask_height); int bpp = 0;
if(mask_texture == NULL) { Uint32 r = 0,g = 0,b = 0,a = 0;
SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ARGB4444,&bpp,&r,&g,&b,&a);
SDL_Surface *mask = SDL_CreateRGBSurface(0,eyesmask_width,eyesmask_height,bpp,r,g,b,a);
if(mask == NULL) {
SDL_DestroyTexture(eyes_texture); SDL_DestroyTexture(eyes_texture);
SDL_DestroyRenderer(window); SDL_DestroyRenderer(window);
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
...@@ -171,19 +174,20 @@ int main(int argc,char** argv) { ...@@ -171,19 +174,20 @@ int main(int argc,char** argv) {
printf("Could not create shape mask texture.\n"); printf("Could not create shape mask texture.\n");
exit(-5); exit(-5);
} }
SDL_SetTexturePalette(mask_texture,bnw_palette,0,2);
rect.x = rect.y = 0; if(SDL_MUSTLOCK(mask))
rect.w = eyesmask_width; SDL_LockSurface(mask);
rect.h = eyesmask_height; pixels = mask->pixels;
SDL_LockTexture(mask_texture,&rect,1,&pixels,&pitch); for(int y=0;y<eyesmask_height;y++)
for(int row = 0;row<eyesmask_height;row++) for(int x=0;x<eyesmask_width;x++) {
memcpy(pixels+pitch*row,eyesmask_bits+(eyesmask_width/8)*row,eyesmask_width/8); Uint8 alpha = *(Uint8*)(eyesmask_bits+(eyesmask_width/8)*y+(x/8)) & (1 << (7 - x % 8)) ? 1 : 0;
SDL_UnlockTexture(mask_texture); *(Uint16*)(pixels+pitch*y+x*bpp/8) = SDL_MapRGBA(mask->format,0,0,0,alpha);
}
if(SDL_MUSTLOCK(mask))
SDL_UnlockSurface(mask);
SDL_SelectShapeRenderer(window); SDL_WindowShapeMode mode = {ShapeModeDefault,1};
SDL_RenderCopy(mask_texture,&rect,&rect); SDL_SetWindowShape(window,mask,&mode);
SDL_RenderPresent();
SDL_Event event; SDL_Event event;
int event_pending = 0; int event_pending = 0;
...@@ -203,6 +207,9 @@ int main(int argc,char** argv) { ...@@ -203,6 +207,9 @@ int main(int argc,char** argv) {
event_pending = SDL_PollEvent(&event); event_pending = SDL_PollEvent(&event);
} }
SDL_FreeSurface(mask);
SDL_DestroyTexture(eyes_texture);
SDL_DestroyWindow(window);
//Call SDL_VideoQuit() before quitting. //Call SDL_VideoQuit() before quitting.
SDL_VideoQuit(); SDL_VideoQuit();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment