File: pmask.h

package info (click to toggle)
open-invaders 0.3-4.1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 6,404 kB
  • ctags: 394
  • sloc: sh: 9,043; cpp: 4,439; ansic: 884; makefile: 129
file content (162 lines) | stat: -rw-r--r-- 6,970 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#ifndef pmask_H
#define pmask_H

/*
This is the Pixel MASK library, which does pixel-perfect collisions using
bit masks.

There are several configuration options here, hope they aren't too
confusing.
*/

#define PMASK_VERSION          5

#define USE_ALLEGRO
//#define USE_SDL

#ifdef USE_ALLEGRO
	struct BITMAP;
#endif
#ifdef USE_SDL
	struct SDL_Surface;
#endif

#ifdef __cplusplus
#	define pmask_USE_INLINE
	extern "C" {
#endif

//MASK_WORD_TYPE and MASK_WORD_BITBITS can be changed for your platform

//MASK_WORD_TYPE should be the largest fast integer type available
#define MASK_WORD_TYPE unsigned long int

//MASK_WORD_BITBITS should be the log base 2
//of the number of bits in MASK_WORD_TYPE
//e.g. 4 for 16-bit ints, 5 for 32-bit ints, 6 for 64-bit ints
//don't worry about setting it incorrectly
//you'll get a compile error if you do, not a run-time error
#if defined(__alpha__) || defined(__ia64__) || (defined(__x86_64__) && defined(__LP64__)) || defined(__s390x__) || (defined(__sparc__) && defined(__arch64__)) \
      || defined(__powerpc64__) || defined(__aarch64__) || (defined(__mips64) && defined(__LP64__))
	#define MASK_WORD_BITBITS 6
#else
	#define MASK_WORD_BITBITS 5
#endif


//if SINGLE_MEMORY_BLOCK is defined
//then each mask will be allocated as
//only a single memory block.  
//this means that masks will (in theory) 
//be ever-so-slightly faster and more memory efficient
//however, if in single memory block mode
//then the masks are variable-sized
//so you can not use an array of them
//#define MASK_SINGLE_MEMORY_BLOCK

//trying to make portable const-ness easier:
#ifndef CONST
#	define CONST const
#endif

//This is the bounding box collision detection macro.
//It is a general purpose macro. Pass it the coordinates of one rectangle and the width and
//height of it, then pass the coordinates of a second rectangle and the width and height of
//it. It will return 0 if theres not collision or 1 if there is a collision between the
//rectangles (the ectangles overlap).
//This macro works looking for out of range values, if some value is out of
//range it returns 0, if all the values are in range it returns true.
#define check_bb_collision_general(x1,y1,w1,h1,x2,y2,w2,h2) (!( ((x1)>=(x2)+(w2)) || ((x2)>=(x1)+(w1)) || ((y1)>=(y2)+(h2)) || ((y2)>=(y1)+(h1)) ))
#define check_bb_collision(mask1,mask2,x1,y1,x2,y2) check_bb_collision_general(x1,y1,mask1->w,mask1->h,x2,y2,mask2->w,mask2->h)


typedef struct PMASK //8 bytes in a 32-bit environment
{
	short int w;//width
	short int h;//height
#	ifdef MASK_SINGLE_MEMORY_BLOCK
		MASK_WORD_TYPE mask[1];//mask data (single memory block)
#	else
		MASK_WORD_TYPE *mask;//mask data (pointer at second memory block)
#	endif
} PMASK;

void install_pmask(); //sets up library

int _check_pmask_collision(CONST struct PMASK *mask1, CONST struct PMASK *mask2, int dx, int dy); //checks for collision (0 = no collision, 1 = collision)
int check_pmask_collision(CONST struct PMASK *mask1, CONST struct PMASK *mask2, int x1, int y1, int x2, int y2); //checks for collision (0 = no collision, 1 = collision)

//note: result[0] is set to the X coordinate of the collision, result[1] to the Y coordinate
int _check_pmask_collision_position(CONST struct PMASK *mask1, CONST struct PMASK *mask2, int dx, int dy, int *result);
int check_pmask_collision_position(CONST struct PMASK *mask1, CONST struct PMASK *mask2, int x1, int y1, int x2, int y2, int *result);

int get_pmask_pixel(CONST struct PMASK *mask, int x, int y) ; //returns 0 if mask is clear at those coordinates, 1 if not clear
void set_pmask_pixel(struct PMASK *mask, int x, int y, int value) ;//makes mask clear at those coordinates if value is zero, others makes mask not-clear at those coordinates

void init_pmask        (struct PMASK *mask, int w, int h); //initializes a PMASK
void pmask_load_pixels (struct PMASK *mask, void *pixels, int pitch, int bytes_per_pixel, int trans_color);//loads a pmask with pixel data from memory
void pmask_load_func   (struct PMASK *mask, int x, int y, void *surface, int trans_color, int (*func)(void*,int,int));//loads a pmask with pixel data from a function
void deinit_pmask(PMASK *mask);//de-initializes a pmask

PMASK *create_pmask  (int w, int h);//creates a new pmask and initializes it
void destroy_pmask(struct PMASK *mask);//destroys a pmask created by create_pmask

#if defined USE_ALLEGRO
	void init_allegro_pmask(struct PMASK *mask, struct BITMAP *sprite);
	PMASK *create_allegro_pmask(struct BITMAP *sprite);
	void draw_allegro_pmask(CONST struct PMASK *mask, struct BITMAP *destination, int x, int y, int color) ;
	void draw_allegro_pmask_stretch(CONST struct PMASK *mask, struct BITMAP *destination, int x, int y, int w, int h, int color) ;
#endif

#if defined USE_SDL
	void init_sdl_pmask(struct PMASK *mask, struct SDL_Surface *sprite, int trans_color);
	PMASK *create_sdl_pmask(struct SDL_Surface *sprite, int trans_color);
#endif


int serialize_pmask(void *destination, int maxsize, CONST PMASK *source);
//serialize_pmask is a helper for sending a PMASK to a file or over a network
//it accepts a buffer to write to, and a maxime number of bytes to write
//it returns the number of bytes written, or -1 if an error occured
int init_deserialize_pmask(void *source, int maxsize, PMASK *destination);
//init_deserialize_pmask is a helper for reading a PMASK from a file or over a network
//it accepts a buffer to read from, and a maximum number of bytes to read
//it also accepts a pointer at the PMASK to initialize
//it returns the number of bytes read
PMASK *create_deserialize_pmask(void *source, int maxsize, int *size);
//create_deserialize_pmask is a helper for reading a PMASK from a file or over a network
//it accepts a buffer to read from, and a maximum number of bytes to read
//it accepts a pointer at an integer to put the # of bytes read 
//it returns a newly allocated PMASK structure, or NULL if an error occured
int get_serialized_pmask_size ( int w, int h );
//simple helper to determine the serialized size of a PMASK


#ifdef __cplusplus
}
#endif

#define MASK_WORD_SIZE sizeof(MASK_WORD_TYPE)
#define MASK_WORD_BITS (MASK_WORD_SIZE*8)

#if defined pmask_USE_INLINED
inline int _get_pmask_pixel(struct PMASK *mask, int x, int y) {
	//no bounds checking
	return 1 & (mask->mask[(mask->h * (x >> MASK_WORD_BITBITS)) + y] >> (x & (MASK_WORD_BITS-1)));
}
inline void _set_pmask_pixel(struct PMASK *mask, int x, int y, int value) {
	//no bounds checking
	if (value) {
		mask->mask[(mask->h * (x >> MASK_WORD_BITBITS)) + y] |= 1 << (x & (MASK_WORD_BITS-1));
	} else {
		mask->mask[(mask->h * (x >> MASK_WORD_BITBITS)) + y] &=~(1 << (x & (MASK_WORD_BITS-1)));
	}
}
#else
#	define _get_pmask_pixel get_pmask_pixel
#	define _set_pmask_pixel set_pmask_pixel
#endif


#endif          /* ifndef pmask_H */