Mercurial > sdl-ios-xcode
comparison test/testeyes.c @ 4770:cf7976fd3258
Moved the SDL_Eyes test program for shaped windows into the Hg repository and got it building and linking as a test.
author | Eli Gottlieb <eligottlieb@gmail.com> |
---|---|
date | Mon, 31 May 2010 21:23:06 -0400 |
parents | |
children | ef8b32ef9793 |
comparison
equal
deleted
inserted
replaced
4769:83f9b95da263 | 4770:cf7976fd3258 |
---|---|
1 #include <stdlib.h> | |
2 #include <math.h> | |
3 #include <SDL_events.h> | |
4 #include <SDL_rect.h> | |
5 #include <SDL_pixels.h> | |
6 #include <SDL_video.h> | |
7 #include <SDL_shape.h> | |
8 #include "testeyes_bitmap.h" | |
9 #include "testeyes_mask_bitmap.h" | |
10 | |
11 /* The following code for the calculation of pupil positions has been taken and rewritten from the original xeyes. The | |
12 copyright notice is included as follows, and the code is now under the same license as the rest of this file. */ | |
13 /* | |
14 | |
15 Copyright (c) 1991 X Consortium | |
16 | |
17 Permission is hereby granted, free of charge, to any person obtaining | |
18 a copy of this software and associated documentation files (the | |
19 "Software"), to deal in the Software without restriction, including | |
20 without limitation the rights to use, copy, modify, merge, publish, | |
21 distribute, sublicense, and/or sell copies of the Software, and to | |
22 permit persons to whom the Software is furnished to do so, subject to | |
23 the following conditions: | |
24 | |
25 The above copyright notice and this permission notice shall be included | |
26 in all copies or substantial portions of the Software. | |
27 | |
28 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
29 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
30 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
31 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
32 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
33 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
34 OTHER DEALINGS IN THE SOFTWARE. | |
35 | |
36 Except as contained in this notice, the name of the X Consortium shall | |
37 not be used in advertising or otherwise to promote the sale, use or | |
38 other dealings in this Software without prior written authorization | |
39 from the X Consortium. | |
40 | |
41 */ | |
42 # define NUM_EYES 2 | |
43 # define EYE_X(n) ((n) * 2.0) | |
44 # define EYE_Y(n) (0.0) | |
45 # define EYE_THICK (0.175) /* thickness of eye rim */ | |
46 # define EYE_OFFSET (0.1) /* padding between eyes */ | |
47 # define EYE_WIDTH (2.0 - (EYE_THICK + EYE_OFFSET) * 2) | |
48 # define EYE_HEIGHT EYE_WIDTH | |
49 # define EYE_HWIDTH (EYE_WIDTH / 2.0) | |
50 # define EYE_HHEIGHT (EYE_HEIGHT / 2.0) | |
51 # define BALL_WIDTH (0.3) | |
52 # define BALL_HEIGHT BALL_WIDTH | |
53 # define BALL_PAD (0.05) | |
54 # define BALL_DIST ((EYE_WIDTH - BALL_WIDTH) / 2.0 - BALL_PAD) | |
55 | |
56 SDL_Point computePupil (int num,SDL_Point mouse) { | |
57 double dx = mouse.x - EYE_X(num); | |
58 double dy = mouse.y - EYE_Y(num); | |
59 double cx = 0.0,cy = 0.0; | |
60 if(dx == 0 && dy == 0) { | |
61 cx = EYE_X(num); | |
62 cy = EYE_Y(num); | |
63 } | |
64 else { | |
65 double angle = atan2((double)dy,(double)dx); | |
66 double cosa = cos(angle); | |
67 double sina = sin(angle); | |
68 double hypotenuse = hypot(EYE_HHEIGHT * cosa, EYE_HWIDTH * sina); | |
69 double dist = BALL_DIST * hypot((EYE_HWIDTH * EYE_HHEIGHT) * cosa / hypotenuse, | |
70 (EYE_HWIDTH * EYE_HHEIGHT) * sina / hypotenuse); | |
71 if(dist > hypot((double)dx,(double)dy)) { | |
72 cx = dx + EYE_X(num); | |
73 cy = dy + EYE_Y(num); | |
74 } | |
75 else { | |
76 cx = dist * cosa + EYE_X(num); | |
77 cy = dist * sina + EYE_Y(num); | |
78 } | |
79 } | |
80 SDL_Point ret = {cx,cy}; | |
81 return ret; | |
82 } | |
83 | |
84 /* Here begins the code exclusively and entirely written by Eli Gottlieb in May 2010. */ | |
85 typedef struct { | |
86 SDL_Rect left; | |
87 SDL_Rect right; | |
88 } Pupil_Pair; | |
89 typedef struct { | |
90 SDL_Point left; | |
91 SDL_Point right; | |
92 } Pupil_Points; | |
93 | |
94 Pupil_Pair compute_pupil_positions(SDL_Point target) { | |
95 Pupil_Pair result; | |
96 Pupil_Points points; | |
97 points.left = computePupil(0,target); | |
98 points.right = computePupil(1,target); | |
99 result.left.x = points.left.x - BALL_WIDTH / 2.0; | |
100 result.left.y = points.left.y - BALL_HEIGHT / 2.0; | |
101 result.right.x = points.right.x - BALL_WIDTH / 2.0; | |
102 result.right.y = points.right.y - BALL_HEIGHT / 2.0; | |
103 result.left.w = result.right.w = BALL_WIDTH; | |
104 result.left.h = result.left.w = BALL_HEIGHT; | |
105 return result; | |
106 } | |
107 | |
108 void render_eyes(SDL_Window *window,SDL_Texture *eyes_texture,Pupil_Pair pupils) { | |
109 SDL_SelectRenderer(window); | |
110 | |
111 //Clear render-target to blue. | |
112 SDL_SetRenderDrawColor(0x00,0x00,0xff,0xff); | |
113 SDL_RenderClear(); | |
114 | |
115 //Render the whites of the eyes. | |
116 SDL_Rect srcdestrect = {0,0,eyes_width,eyes_height}; | |
117 SDL_RenderCopy(eyes_texture,&srcdestrect,&srcdestrect); | |
118 | |
119 //Render the pupils. | |
120 SDL_SetRenderDrawColor(0x00,0x00,0x00,0xff); | |
121 const SDL_Rect eyes[2] = {pupils.left,pupils.right}; | |
122 SDL_RenderFillRects((const SDL_Rect**)&eyes,2); | |
123 | |
124 SDL_RenderPresent(); | |
125 } | |
126 | |
127 int main(int argc,char** argv) { | |
128 if(SDL_VideoInit(NULL,0) == -1) { | |
129 printf("Could not initialize SDL video.\n"); | |
130 exit(-1); | |
131 } | |
132 | |
133 SDL_Window *window = SDL_CreateShapedWindow("Big Brother is watching you.",eyes_x_hot,eyes_y_hot,eyes_width,eyes_height,SDL_WINDOW_RESIZABLE); | |
134 if(window == NULL) { | |
135 SDL_VideoQuit(); | |
136 printf("Could not create shaped window for eyes.\n"); | |
137 exit(-2); | |
138 } | |
139 if(SDL_CreateRenderer(window,-1,SDL_RENDERER_PRESENTFLIP2) == -1) { | |
140 SDL_DestroyWindow(window); | |
141 SDL_VideoQuit(); | |
142 printf("Could not create rendering context for SDL_Eyes window.\n"); | |
143 exit(-3); | |
144 } | |
145 | |
146 SDL_Color bnw_palette[2] = {{0,0,0,0},{255,255,255,255}}; | |
147 SDL_Texture *eyes_texture = SDL_CreateTexture(SDL_PIXELFORMAT_INDEX1LSB,SDL_TEXTUREACCESS_STREAMING,eyes_width,eyes_height); | |
148 if(eyes_texture == NULL) { | |
149 SDL_DestroyRenderer(window); | |
150 SDL_DestroyWindow(window); | |
151 SDL_VideoQuit(); | |
152 printf("Could not create eyes texture.\n"); | |
153 exit(-4); | |
154 } | |
155 SDL_SetTexturePalette(eyes_texture,bnw_palette,0,2); | |
156 | |
157 void *pixels = NULL; | |
158 int pitch = 0; | |
159 SDL_Rect rect = {0,0,eyes_width,eyes_height}; | |
160 SDL_LockTexture(eyes_texture,&rect,1,&pixels,&pitch); | |
161 for(int row = 0;row<eyes_height;row++) | |
162 memcpy(pixels+pitch*row,eyes_bits+(eyes_width/8)*row,eyes_width/8); | |
163 SDL_UnlockTexture(eyes_texture); | |
164 | |
165 SDL_Texture *mask_texture = SDL_CreateTexture(SDL_PIXELFORMAT_INDEX1LSB,SDL_TEXTUREACCESS_STREAMING,eyesmask_width,eyesmask_height); | |
166 if(mask_texture == NULL) { | |
167 SDL_DestroyTexture(eyes_texture); | |
168 SDL_DestroyRenderer(window); | |
169 SDL_DestroyWindow(window); | |
170 SDL_VideoQuit(); | |
171 printf("Could not create shape mask texture.\n"); | |
172 exit(-5); | |
173 } | |
174 SDL_SetTexturePalette(mask_texture,bnw_palette,0,2); | |
175 | |
176 rect.x = rect.y = 0; | |
177 rect.w = eyesmask_width; | |
178 rect.h = eyesmask_height; | |
179 SDL_LockTexture(mask_texture,&rect,1,&pixels,&pitch); | |
180 for(int row = 0;row<eyesmask_height;row++) | |
181 memcpy(pixels+pitch*row,eyesmask_bits+(eyesmask_width/8)*row,eyesmask_width/8); | |
182 SDL_UnlockTexture(mask_texture); | |
183 | |
184 SDL_SelectShapeRenderer(window); | |
185 SDL_RenderCopy(mask_texture,&rect,&rect); | |
186 SDL_RenderPresent(); | |
187 | |
188 SDL_Event event; | |
189 int event_pending = 0; | |
190 event_pending = SDL_PollEvent(&event); | |
191 SDL_Point mouse_position; | |
192 Pupil_Pair pupil_positions; | |
193 SDL_SelectMouse(0); | |
194 SDL_GetMouseState(&mouse_position.x,&mouse_position.y); | |
195 pupil_positions = compute_pupil_positions(mouse_position); | |
196 while(event.type != SDL_QUIT) { | |
197 if(event.type == SDL_MOUSEMOTION) { | |
198 mouse_position.x = event.motion.x; | |
199 mouse_position.y = event.motion.y; | |
200 pupil_positions = compute_pupil_positions(mouse_position); | |
201 } | |
202 render_eyes(window,eyes_texture,pupil_positions); | |
203 event_pending = SDL_PollEvent(&event); | |
204 } | |
205 | |
206 //Call SDL_VideoQuit() before quitting. | |
207 SDL_VideoQuit(); | |
208 } |