Rev 419 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
419 | lvd | 1 | #include <stdlib.h> |
2 | #include <stdio.h> |
||
3 | #include <errno.h> |
||
4 | |||
5 | #include <sys/types.h> |
||
6 | #include <sys/socket.h> |
||
7 | #include <arpa/inet.h> |
||
8 | |||
9 | #if defined(_MSC_VER) |
||
10 | #include "SDL.h" |
||
11 | #else |
||
12 | #include "SDL/SDL.h" |
||
13 | #endif |
||
14 | |||
15 | SDL_Surface *plane; |
||
16 | |||
17 | |||
18 | void net_init(void); |
||
19 | void net_recv(void); |
||
20 | void parse_recv_data(char * buf,int bytes_read); |
||
21 | void bufrender(void); |
||
22 | |||
23 | void render(void); |
||
24 | |||
25 | void exitt(int); |
||
26 | |||
27 | #define SIZEX 896 |
||
28 | #define SIZEY 640 |
||
29 | #define BITSIZE 32 |
||
30 | |||
31 | #define ZXSIZEX 1792 |
||
32 | #define ZXSIZEY 320 |
||
33 | |||
34 | char zxbuf[ZXSIZEX*ZXSIZEY*4]; |
||
35 | |||
36 | |||
37 | // Entry point |
||
38 | int main(int argc, char *argv[]) |
||
39 | { |
||
40 | // Initialize SDL's subsystems - in this case, only video. |
||
41 | if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) |
||
42 | { |
||
43 | fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); |
||
44 | exit(1); |
||
45 | } |
||
46 | |||
47 | // Register SDL_Quit to be called at exit; makes sure things are |
||
48 | // cleaned up when we quit. |
||
49 | atexit(SDL_Quit); |
||
50 | |||
51 | // Attempt to create a window with 32bit pixels. |
||
52 | plane = SDL_SetVideoMode(SIZEX, SIZEY, BITSIZE, SDL_SWSURFACE); |
||
53 | |||
54 | // If we fail, return error. |
||
55 | if ( plane == NULL ) |
||
56 | { |
||
57 | fprintf(stderr, "Unable to set 896x640 video: %s\n", SDL_GetError()); |
||
58 | exit(1); |
||
59 | } |
||
60 | |||
61 | |||
62 | net_init(); |
||
63 | |||
64 | |||
65 | // Main loop: loop forever. |
||
66 | while (1) |
||
67 | { |
||
68 | net_recv(); |
||
69 | |||
70 | render(); |
||
71 | |||
72 | // Poll for events, and handle the ones we care about. |
||
73 | SDL_Event event; |
||
74 | while (SDL_PollEvent(&event)) |
||
75 | { |
||
76 | switch (event.type) |
||
77 | { |
||
78 | case SDL_KEYDOWN: |
||
79 | break; |
||
80 | case SDL_KEYUP: |
||
81 | // If escape is pressed, return (and thus, quit) |
||
82 | if (event.key.keysym.sym == SDLK_ESCAPE) |
||
83 | return 0; |
||
84 | break; |
||
85 | case SDL_QUIT: |
||
86 | return(0); |
||
87 | } |
||
88 | } |
||
89 | } |
||
90 | return 0; |
||
91 | } |
||
92 | |||
93 | |||
94 | |||
95 | |||
96 | |||
97 | |||
98 | int sock=(-1), listener=(-1); |
||
99 | struct sockaddr_in addr; |
||
100 | |||
101 | |||
102 | |||
103 | |||
104 | void net_init(void) |
||
105 | { |
||
106 | listener = socket(AF_INET, SOCK_STREAM, 0); |
||
107 | if(listener < 0) |
||
108 | { |
||
109 | perror("socket init error"); |
||
110 | exit(1); |
||
111 | } |
||
112 | |||
113 | int tr=1; |
||
114 | |||
115 | setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&tr,sizeof(int)); |
||
116 | |||
117 | addr.sin_family = AF_INET; |
||
118 | addr.sin_port = htons(12345); |
||
119 | addr.sin_addr.s_addr = htonl(INADDR_ANY); |
||
120 | if(bind(listener, (struct sockaddr *)&addr, sizeof(addr)) < 0) |
||
121 | { |
||
122 | perror("bind error"); |
||
123 | exit(2); |
||
124 | } |
||
125 | |||
126 | listen(listener, 1); |
||
127 | |||
128 | sock = accept(listener, NULL, NULL); |
||
129 | if(sock < 0) |
||
130 | { |
||
131 | perror("accept error"); |
||
132 | exitt(3); |
||
133 | } |
||
134 | } |
||
135 | |||
136 | |||
137 | |||
138 | |||
139 | |||
140 | void net_recv(void) |
||
141 | { |
||
142 | #define BUFSIZE 10240 |
||
143 | char buf[BUFSIZE]; |
||
144 | |||
145 | |||
146 | int bytes_read; |
||
147 | |||
148 | |||
149 | |||
150 | bytes_read = recv(sock,buf,BUFSIZE, MSG_DONTWAIT); |
||
151 | // bytes_read = recv(sock,buf,BUFSIZE, 0); |
||
152 | |||
153 | if( bytes_read<0 ) |
||
154 | { |
||
155 | if( ! ((errno==EAGAIN) || (errno==EWOULDBLOCK)) ) |
||
156 | { |
||
157 | printf("recv failed - error %d!\n",errno); |
||
158 | exitt(1); |
||
159 | } |
||
160 | } |
||
161 | else if( bytes_read==0 ) |
||
162 | { |
||
163 | printf("recv failed - closed! errno=%d\n",errno); |
||
164 | exitt(1); |
||
165 | } |
||
166 | else // >0 |
||
167 | { |
||
168 | parse_recv_data(buf,bytes_read); |
||
169 | } |
||
170 | |||
171 | // if( 4!=sscanf(buf,"%X<=%X:%X with %X",&addr,&dat_hi,&dat_lo,&sel) ) |
||
172 | } |
||
173 | |||
174 | |||
175 | |||
176 | |||
177 | |||
178 | void parse_recv_data(char * buf,int bytes_read) |
||
179 | { |
||
180 | #define PBUF_SIZE 63 |
||
181 | char pbuf[PBUF_SIZE+1]; |
||
182 | |||
183 | static int parsed = 0; |
||
184 | |||
185 | |||
186 | int i; |
||
187 | char c; |
||
188 | char r,g,b; |
||
189 | char * pix; |
||
190 | |||
191 | int xcoord,ycoord,color; |
||
192 | |||
193 | |||
194 | i=0; |
||
195 | |||
196 | while( bytes_read>0 ) |
||
197 | { |
||
198 | c = *(buf++); |
||
199 | |||
200 | if(c=='\n') |
||
201 | { |
||
202 | pbuf[parsed]=0; |
||
203 | parsed=0; |
||
204 | |||
205 | if( (*pbuf)=='p' ) |
||
206 | { |
||
207 | //printf("%s\n",pbuf+1); |
||
208 | |||
209 | if( 3==sscanf(pbuf+1,"%X,%X,%X",&xcoord,&ycoord,&color) ) |
||
210 | { |
||
211 | if( (0<=xcoord)&&(xcoord<ZXSIZEX)&& |
||
212 | (0<=ycoord)&&(ycoord<ZXSIZEY) ) |
||
213 | { |
||
214 | pix = zxbuf + ( xcoord*4 + (ycoord*ZXSIZEX*4) ); |
||
215 | |||
216 | r = (color<<2); |
||
217 | g = (color<<4); |
||
218 | b = (color<<6); |
||
219 | |||
220 | r &= 0xC0; |
||
221 | g &= 0xC0; |
||
222 | b &= 0xC0; |
||
223 | |||
224 | r |= r>>2; |
||
225 | g |= g>>2; |
||
226 | b |= b>>2; |
||
227 | |||
228 | r |= r>>4; |
||
229 | g |= g>>4; |
||
230 | b |= b>>4; |
||
231 | |||
232 | *(pix+0) = b; |
||
233 | *(pix+1) = g; |
||
234 | *(pix+2) = r; |
||
235 | } |
||
236 | } |
||
237 | } |
||
238 | } |
||
239 | else |
||
240 | { |
||
241 | if(parsed>=PBUF_SIZE) |
||
242 | { |
||
243 | printf("too long string in network data!\n"); |
||
244 | exitt(1); |
||
245 | } |
||
246 | pbuf[parsed++]=c; |
||
247 | } |
||
248 | |||
249 | bytes_read--; |
||
250 | } |
||
251 | } |
||
252 | |||
253 | |||
254 | |||
255 | |||
256 | |||
257 | void bufrender(void) |
||
258 | { |
||
259 | |||
260 | int bx,by; |
||
261 | |||
262 | int * la1, * la2; |
||
263 | |||
264 | unsigned char * za; |
||
265 | |||
266 | int r,g,b; |
||
267 | int value; |
||
268 | |||
269 | |||
270 | for(by=0;by<ZXSIZEY;by++) |
||
271 | { |
||
272 | la1 = ((int *)plane->pixels) + by*((plane->pitch)>>2)*2; |
||
273 | la2 = la1 + ((plane->pitch)>>2); |
||
274 | |||
275 | za = (unsigned char *)zxbuf + (by*ZXSIZEX*4); |
||
276 | |||
277 | for(bx=0;bx<(ZXSIZEX/2);bx++) |
||
278 | { |
||
279 | r = *(za+2); |
||
280 | g = *(za+1); |
||
281 | b = *(za+0); |
||
282 | |||
283 | r += *(za+6); |
||
284 | g += *(za+5); |
||
285 | b += *(za+4); |
||
286 | |||
287 | r <<= 15; |
||
288 | g <<= 7; |
||
289 | b >>= 1; |
||
290 | |||
291 | r &= 0x00FF0000; |
||
292 | g &= 0x0000FF00; |
||
293 | b &= 0x000000FF; |
||
294 | |||
295 | za += 8; |
||
296 | |||
297 | value = r|g|b; |
||
298 | |||
299 | *(la1++) = value; |
||
300 | *(la2++) = value; |
||
301 | } |
||
302 | } |
||
303 | } |
||
304 | |||
305 | |||
306 | |||
307 | |||
308 | |||
309 | |||
310 | |||
311 | |||
312 | |||
313 | |||
314 | void render() |
||
315 | { |
||
316 | // Lock surface if needed |
||
317 | if( SDL_MUSTLOCK(plane) ) |
||
318 | if (SDL_LockSurface(plane) < 0) |
||
319 | return; |
||
320 | |||
321 | // Ask SDL for the time in milliseconds |
||
322 | int tick = SDL_GetTicks(); |
||
323 | |||
324 | // Unlock if needed |
||
325 | if( SDL_MUSTLOCK(plane) ) |
||
326 | SDL_UnlockSurface(plane); |
||
327 | |||
328 | //render picture |
||
329 | bufrender(); |
||
330 | |||
331 | // Tell SDL to update the whole plane |
||
332 | SDL_UpdateRect(plane, 0, 0, SIZEX, SIZEY); |
||
333 | } |
||
334 | |||
335 | |||
336 | |||
337 | |||
338 | |||
339 | |||
340 | |||
341 | |||
342 | void exitt(int a) |
||
343 | { |
||
344 | |||
345 | if( sock>=0 ) close(sock); |
||
346 | |||
347 | if( listener>=0 ) close(listener); |
||
348 | |||
349 | exit(a); |
||
350 | |||
351 | |||
352 | |||
353 | |||
354 | |||
355 | } |
||
356 |