all repos — mgba @ af96ee70879f65255c11e1cc28a88f2afd23894c

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