all repos — mgba @ 3a9d77d9e0fe59d488a538474381a564b1c061d3

mGBA Game Boy Advance Emulator

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}