src/platform/example/client-server/client.c (view raw)
1/* Copyright (c) 2013-2016 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include <mgba/core/core.h>
7#include <mgba/core/version.h>
8#include <mgba-util/socket.h>
9
10#include <SDL.h>
11
12#define DEFAULT_PORT 13721
13
14int main() {
15 SocketSubsystemInit();
16 struct Address serverIP = {
17 .version = IPV4,
18 .ipv4 = 0x7F000001
19 };
20 Socket server = SocketConnectTCP(DEFAULT_PORT, &serverIP);
21 if (SOCKET_FAILED(server)) {
22 SocketSubsystemDeinit();
23 return 1;
24 }
25
26 unsigned width, height, bpp;
27 SocketRecv(server, &width, sizeof(width));
28 SocketRecv(server, &height, sizeof(height));
29 SocketRecv(server, &bpp, sizeof(bpp));
30 width = ntohl(width);
31 height = ntohl(height);
32 if (ntohl(bpp) != BYTES_PER_PIXEL) {
33 SocketClose(server);
34 SocketSubsystemDeinit();
35 return 1;
36 }
37 ssize_t bufferSize = width * height * BYTES_PER_PIXEL;
38
39#if !SDL_VERSION_ATLEAST(2, 0, 0)
40#ifdef COLOR_16_BIT
41 SDL_SetVideoMode(width, height, 16, SDL_DOUBLEBUF | SDL_HWSURFACE);
42#else
43 SDL_SetVideoMode(width, height, 32, SDL_DOUBLEBUF | SDL_HWSURFACE);
44#endif
45#endif
46
47#if SDL_VERSION_ATLEAST(2, 0, 0)
48 SDL_Window* window = SDL_CreateWindow(projectName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL);
49 SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
50
51 Uint32 pixfmt;
52#ifdef COLOR_16_BIT
53#ifdef COLOR_5_6_5
54 pixfmt = SDL_PIXELFORMAT_RGB565;
55#else
56 pixfmt = SDL_PIXELFORMAT_ABGR1555;
57#endif
58#else
59 pixfmt = SDL_PIXELFORMAT_ABGR8888;
60#endif
61 SDL_Texture* sdlTex = SDL_CreateTexture(renderer, pixfmt, SDL_TEXTUREACCESS_STREAMING, width, height);
62#endif
63
64
65 SDL_Event event;
66#if !SDL_VERSION_ATLEAST(2, 0, 0)
67 SDL_Surface* surface = SDL_GetVideoSurface();
68#endif
69
70 int keys = 0;
71 while (true) {
72 while (SDL_PollEvent(&event)) {
73 if (event.type == SDL_QUIT) {
74 SocketClose(server);
75 break;
76 }
77 if (event.type != SDL_KEYDOWN && event.type != SDL_KEYUP) {
78 continue;
79 }
80 int key = 0;
81 switch (event.key.keysym.sym) {
82 case SDLK_x:
83 key = 1;
84 break;
85 case SDLK_z:
86 key = 2;
87 break;
88 case SDLK_BACKSPACE:
89 key = 4;
90 break;
91 case SDLK_RETURN:
92 key = 8;
93 break;
94 case SDLK_RIGHT:
95 key = 16;
96 break;
97 case SDLK_LEFT:
98 key = 32;
99 break;
100 case SDLK_UP:
101 key = 64;
102 break;
103 case SDLK_DOWN:
104 key = 128;
105 break;
106 case SDLK_s:
107 key = 256;
108 break;
109 case SDLK_a:
110 key = 512;
111 break;
112 default:
113 break;
114 }
115 if (event.type == SDL_KEYDOWN) {
116 keys |= key;
117 } else {
118 keys &= ~key;
119 }
120 }
121 uint16_t keysNO = htons(keys);
122 if (SocketSend(server, &keysNO, sizeof(keysNO)) != sizeof(keysNO)) {
123 break;
124 }
125 void* pixels;
126#if SDL_VERSION_ATLEAST(2, 0, 0)
127 int pitch;
128 SDL_LockTexture(sdlTex, NULL, &pixels, &pitch);
129#else
130 SDL_LockSurface(surface);
131 pixels = surface->pixels;
132#endif
133
134 ssize_t expected = bufferSize;
135 ssize_t gotten;
136 while ((gotten = SocketRecv(server, pixels, expected)) != expected) {
137 if (gotten < 0) {
138 break;
139 }
140 pixels = (void*) ((uintptr_t) pixels + gotten);
141 expected -= gotten;
142 }
143 if (gotten < 0) {
144 break;
145 }
146
147#if SDL_VERSION_ATLEAST(2, 0, 0)
148 SDL_UnlockTexture(sdlTex);
149 SDL_RenderCopy(renderer, sdlTex, NULL, NULL);
150 SDL_RenderPresent(renderer);
151#else
152 SDL_UnlockSurface(surface);
153 SDL_Flip(surface);
154#endif
155 }
156 SocketSubsystemDeinit();
157
158 return 0;
159}