Bladeren bron

Merge pull request #693 from sanghakchun/goodbye_cmake

Emscripten improvements
Ivan Safrin 9 jaren geleden
bovenliggende
commit
252c839803

File diff suppressed because it is too large
+ 0 - 0
build/emscripten/Makefile


+ 12 - 2
include/polycode/core/PolyEmscriptenCore.h

@@ -27,10 +27,12 @@
 #include <vector>
 #include <pthread.h>
 #include <time.h>
-// #include <SDL2/SDL.h>
+#include <SDL2/SDL.h>
 
 #ifndef NO_PAUDIO
 	#include "polycode/core/PolyPAAudioInterface.h"
+#else
+	#include "polycode/core/PolySDLAudioInterface.h"
 #endif
 
 #define POLYCODE_CORE EmscriptenCore
@@ -89,9 +91,14 @@ namespace Polycode {
 		String executeExternalCommand(String command, String args, String inDirectory="");
 		void openURL(String url);
 
+		Number getBackingXRes();
+		Number getBackingYRes();
 	private:
 		bool checkSpecialKeyEvents(PolyKEY key);
-		
+
+		int backingX;
+		int backingY;
+
 		uint32_t flags;
 		bool resizableWindow;
 		
@@ -100,5 +107,8 @@ namespace Polycode {
 
 		int lastMouseX;
 		int lastMouseY;
+
+		SDL_GLContext sdlContext;
+		SDL_Window* sdlWindow;
 	};
 }

+ 48 - 0
include/polycode/core/PolySDLAudioInterface.h

@@ -0,0 +1,48 @@
+/*
+	Copyright (C) 2016 by Sang Hak Chun
+
+	Permission is hereby granted, free of charge, to any person obtaining a copy
+	of this software and associated documentation files (the "Software"), to deal
+	in the Software without restriction, including without limitation the rights
+	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+	copies of the Software, and to permit persons to whom the Software is
+	furnished to do so, subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be included in
+	all copies or substantial portions of the Software.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+	THE SOFTWARE.
+*/
+
+#pragma once
+
+#include "polycode/core/PolyGlobals.h"
+#include "polycode/core/PolySoundManager.h"
+
+#include <SDL/SDL_audio.h>
+#include <stdlib.h>
+
+#define SDL_AUDIO_NUM_OF_SAMPLES 8192
+
+namespace Polycode {
+
+	class SDLAudioInterface : public Polycode::AudioInterface {
+		public:
+			SDLAudioInterface();
+			~SDLAudioInterface();
+
+			static void sdlCallback(void* userData, Uint8* _stream, int _length);
+		private:
+			SDL_AudioSpec *desired;
+			SDL_AudioSpec *obtained;
+
+			int16_t* buffer;
+	};
+
+}

+ 126 - 83
src/core/PolyEmscriptenCore.cpp

@@ -33,8 +33,7 @@
 	#include "polycode/core/PolyPhysFSFileProvider.h"
 #endif
 
-#include <SDL/SDL.h>
-#include <SDL/SDL_syswm.h>
+#include <SDL2/SDL.h>
 #include <stdio.h>
 #include <limits.h>
 #include <dirent.h>
@@ -65,11 +64,13 @@ long getThreadID() {
 }
 
 void Core::getScreenInfo(int *width, int *height, int *hz) {
-	SDL_Init(SDL_INIT_VIDEO); // Or GetVideoInfo will not work
-	const SDL_VideoInfo *video = SDL_GetVideoInfo();
-	if (width) *width = video->current_w;
-	if (height) *height = video->current_h;
-	if (hz) *hz = 0;
+	SDL_DisplayMode current;
+
+	SDL_GetCurrentDisplayMode(0, &current);
+
+	if (width) *width = current.w;
+	if (height) *height = current.h;
+	if (hz) *hz = current.refresh_rate;
 }
 
 EmscriptenCore::EmscriptenCore(PolycodeView *view, int _xRes, int _yRes, bool fullScreen, bool vSync, int aaLevel, int anisotropyLevel, int frameRate, int monitorIndex, bool retinaSupport) : Core(_xRes, _yRes, fullScreen, vSync, aaLevel, anisotropyLevel, frameRate, monitorIndex) {
@@ -95,17 +96,15 @@ EmscriptenCore::EmscriptenCore(PolycodeView *view, int _xRes, int _yRes, bool fu
 	} else {
 		setenv("SDL_VIDEO_CENTERED", "1", 1);
 	}
+
+	sdlContext = nullptr;
+	sdlWindow = nullptr;
 	
 	int sdlerror = SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
 	if(sdlerror < 0) {
 	  Logger::log("SDL_Init failed! Code: %d, %s\n", sdlerror, SDL_GetError());
 	}
 	
-	SDL_Surface* icon = SDL_LoadBMP("icon.bmp");
-	if(icon){
-		SDL_WM_SetIcon(icon, NULL);
-	}
-	
 	eventMutex = createMutex();
 	
 	renderThread = new RenderThread();
@@ -117,12 +116,7 @@ EmscriptenCore::EmscriptenCore(PolycodeView *view, int _xRes, int _yRes, bool fu
 	renderer->setGraphicsInterface(this, renderInterface);
 	services->setRenderer(renderer);
 	setVideoMode(xRes, yRes, fullScreen, vSync, aaLevel, anisotropyLevel, retinaSupport);
-	
-	SDL_WM_SetCaption(windowTitle->c_str(), windowTitle->c_str());
-	
-	SDL_EnableUNICODE(1);
-	SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
-	
+
 	SDL_JoystickEventState(SDL_ENABLE);
 	
 	int numJoysticks = SDL_NumJoysticks();
@@ -134,17 +128,12 @@ EmscriptenCore::EmscriptenCore(PolycodeView *view, int _xRes, int _yRes, bool fu
 
 #ifndef NO_PAUDIO
 	services->getSoundManager()->setAudioInterface(new PAAudioInterface());
-#endif 
+#else
+	services->getSoundManager()->setAudioInterface(new SDLAudioInterface());
+#endif
 
 	lastMouseX = 0;
 	lastMouseY = 0;
-
-#ifdef USE_X11
-	// Start listening to clipboard events.
-	// (Yes on X11 you need to actively listen to
-	//	clipboard events and respond to them)
-	init_scrap();
-#endif // USE_X11
 }
 
 void EmscriptenCore::setVideoMode(int xRes, int yRes, bool fullScreen, bool vSync, int aaLevel, int anisotropyLevel, bool retinaSupport) {
@@ -176,31 +165,53 @@ void EmscriptenCore::handleVideoModeChange(VideoModeChangeInfo* modeInfo){
 		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
 	}
 	
-	flags = SDL_OPENGL;
+	flags = SDL_WINDOW_OPENGL;
 
 	if(fullScreen) {
-		flags |= SDL_FULLSCREEN;
+		flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
 	}
 
 	if(resizableWindow) {
-		flags |= SDL_RESIZABLE;
+		flags |= SDL_WINDOW_RESIZABLE;
 	}
 	
-//	if(modeInfo->retinaSupport) {
-//		flags |= SDL_WINDOW_ALLOW_HIGHDPI;
-//	}
-/*
+	if(modeInfo->retinaSupport) {
+		flags |= SDL_WINDOW_ALLOW_HIGHDPI;
+	}
+
 	if(vSync) {
-		flags |= SDL_DOUBLEBUF;
-		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-		SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
+		if(SDL_GL_SetSwapInterval(-1) == -1) {
+			SDL_GL_SetSwapInterval(1);
+		}
 	} else {
-		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
- -		SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0);
+		SDL_GL_SetSwapInterval(0);
 	}
-*/
 
-	SDL_SetVideoMode(xRes, yRes, 0, flags);
+	if(!sdlWindow) {
+		sdlWindow = SDL_CreateWindow(windowTitle->c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, xRes, yRes, flags);
+		sdlContext = SDL_GL_CreateContext(sdlWindow);
+		SDL_Surface* icon = SDL_LoadBMP("icon.bmp");
+		if(icon){
+			SDL_SetWindowIcon(sdlWindow, icon);
+		} else {
+			Logger::log("icon error: %s\n",SDL_GetError());
+		}
+	} else {
+		SDL_SetWindowSize(sdlWindow, xRes, yRes);
+	}
+
+	int x, y;
+	SDL_GL_GetDrawableSize(sdlWindow, &x, &y);
+	if(x >= xRes){
+		backingX = x;
+	} else {
+		backingX = xRes;
+	}
+	if(y >= yRes) {
+		backingY = y;
+	} else {
+		backingY = yRes;
+	}
 
 	/*
 	int glewcode = glewInit();
@@ -216,13 +227,13 @@ void EmscriptenCore::handleVideoModeChange(VideoModeChangeInfo* modeInfo){
 
 vector<Polycode::Rectangle> EmscriptenCore::getVideoModes() {
 	vector<Polycode::Rectangle> retVector;
-	
-	SDL_Rect **modes;
-	modes=SDL_ListModes(NULL, SDL_FULLSCREEN);
-	for(int i=0;modes[i];++i) {
+
+	SDL_DisplayMode modes;
+	for(int i=0;i<SDL_GetNumDisplayModes(0);++i) {
+		SDL_GetDisplayMode(0, i, &modes);
 		Rectangle res;
-		res.w = modes[i]->w;
-		res.h = modes[i]->h;
+		res.w = modes.w;
+		res.h = modes.h;
 		retVector.push_back(res);
 	}	
 	
@@ -230,10 +241,12 @@ vector<Polycode::Rectangle> EmscriptenCore::getVideoModes() {
 }
 
 EmscriptenCore::~EmscriptenCore() {
+	SDL_GL_DeleteContext(sdlContext);
+	SDL_DestroyWindow(sdlWindow);
 	SDL_Quit();
 }
 
-void EmscriptenCore::openURL(String url) {
+void EmscriptenCore::openURL(String url) { // TODO
 	int childExitStatus;
 	pid_t pid = fork();
 	if (pid == 0) {
@@ -298,9 +311,9 @@ void EmscriptenCore::enableMouse(bool newval) {
 
 void EmscriptenCore::captureMouse(bool newval) {
 	if(newval) {
-		SDL_WM_GrabInput(SDL_GRAB_ON);
+		SDL_SetWindowGrab(sdlWindow, SDL_TRUE);
 	} else {
-		SDL_WM_GrabInput(SDL_GRAB_OFF);
+		SDL_SetWindowGrab(sdlWindow, SDL_FALSE);
 	}
 	Core::captureMouse(newval);
 }
@@ -348,7 +361,7 @@ void EmscriptenCore::Render() {
 }
 
 void EmscriptenCore::flushRenderContext(){
-	SDL_GL_SwapBuffers();
+	SDL_GL_SwapWindow(sdlWindow);
 }
 
 bool EmscriptenCore::systemUpdate() {
@@ -364,24 +377,38 @@ bool EmscriptenCore::systemUpdate() {
 				case SDL_QUIT:
 					running = false;
 				break;
-				case SDL_VIDEORESIZE:
-					if(resizableWindow) {
-						unsetenv("SDL_VIDEO_CENTERED");
-					} else {
-						setenv("SDL_VIDEO_CENTERED", "1", 1);
-					}
-					this->xRes = event.resize.w;
-					this->yRes = event.resize.h;
-					SDL_SetVideoMode(xRes, yRes, 0, flags);
-					dispatchEvent(new Event(), EVENT_CORE_RESIZE);	
-				break;
-				case SDL_ACTIVEEVENT:
-					if(event.active.state == SDL_APPINPUTFOCUS){
-						if(event.active.gain == 1){
+				case SDL_WINDOWEVENT:
+					switch (event.window.event) {
+						case SDL_WINDOWEVENT_RESIZED:
+							if (resizableWindow) {
+								unsetenv("SDL_VIDEO_CENTERED");
+							} else {
+								setenv("SDL_VIDEO_CENTERED", "1", 1);
+							}
+							this->xRes = event.window.data1;
+							this->yRes = event.window.data2;
+
+							SDL_SetWindowSize(sdlWindow, xRes, yRes);
+							int x, y;
+							SDL_GL_GetDrawableSize(sdlWindow, &x, &y);
+							if (x >= xRes) {
+								backingX = x;
+							} else {
+								backingX = xRes;
+							}
+							if (y >= yRes) {
+								backingY = y;
+							} else {
+								backingY = yRes;
+							}
+							dispatchEvent(new Event(), EVENT_CORE_RESIZE);
+							break;
+						case SDL_WINDOWEVENT_FOCUS_GAINED:
 							gainFocus();
-						} else {
+							break;
+						case SDL_WINDOWEVENT_FOCUS_LOST:
 							loseFocus();
-						}
+							break;
 					}
 				break;
 				case SDL_JOYAXISMOTION:
@@ -395,29 +422,29 @@ bool EmscriptenCore::systemUpdate() {
 				break;
 				case SDL_KEYDOWN:
 					if(!checkSpecialKeyEvents((PolyKEY)(event.key.keysym.sym))) {
-						input->setKeyState((PolyKEY)(event.key.keysym.sym), event.key.keysym.unicode, true, getTicks());
-					}
+						input->setKeyState((PolyKEY)(event.key.keysym.sym), event.key.keysym.sym, true, getTicks()); 					}
 				break;
 				case SDL_KEYUP:
-					input->setKeyState((PolyKEY)(event.key.keysym.sym), event.key.keysym.unicode, false, getTicks());
+					input->setKeyState((PolyKEY)(event.key.keysym.sym), event.key.keysym.sym, false, getTicks());
 				break;
-				case SDL_MOUSEBUTTONDOWN:
-					if(event.button.button == SDL_BUTTON_WHEELUP){
+				case SDL_MOUSEWHEEL:
+					if(event.wheel.y > 0) {
 						input->mouseWheelUp(getTicks());
-					} else if (event.button.button == SDL_BUTTON_WHEELDOWN){
+					} else if(event.wheel.y < 0) {
 						input->mouseWheelDown(getTicks());
-					} else {
-						switch(event.button.button) {
-							case SDL_BUTTON_LEFT:
-								input->setMouseButtonState(CoreInput::MOUSE_BUTTON1, true, getTicks());
+					}
+				break;
+				case SDL_MOUSEBUTTONDOWN:
+					switch (event.button.button) {
+						case SDL_BUTTON_LEFT:
+							input->setMouseButtonState(CoreInput::MOUSE_BUTTON1, true, getTicks());
 							break;
-							case SDL_BUTTON_RIGHT:
-								input->setMouseButtonState(CoreInput::MOUSE_BUTTON2, true, getTicks());
+						case SDL_BUTTON_RIGHT:
+							input->setMouseButtonState(CoreInput::MOUSE_BUTTON2, true, getTicks());
 							break;
-							case SDL_BUTTON_MIDDLE:
-								input->setMouseButtonState(CoreInput::MOUSE_BUTTON3, true, getTicks());
+						case SDL_BUTTON_MIDDLE:
+							input->setMouseButtonState(CoreInput::MOUSE_BUTTON3, true, getTicks());
 							break;
-						}
 					}
 				break;
 				case SDL_MOUSEBUTTONUP:
@@ -450,7 +477,7 @@ void EmscriptenCore::setCursor(int cursorType) {
 }
 
 void EmscriptenCore::warpCursor(int x, int y) {
-	SDL_WarpMouse(x, y);
+	SDL_WarpMouseInWindow(sdlWindow, x, y);
 	lastMouseX = x;
 	lastMouseY = y;
 }
@@ -473,10 +500,18 @@ CoreMutex *EmscriptenCore::createMutex() {
 }
 
 void EmscriptenCore::copyStringToClipboard(const String& str) {
-//	SDL_SetClipboardText(str.c_str());
+	SDL_SetClipboardText(str.c_str());
 }
 
 String EmscriptenCore::getClipboardString() {
+	String rval;
+	if(SDL_HasClipboardText() ==SDL_TRUE){
+		rval=SDL_GetClipboardText();
+	} else {
+		rval="";
+	}
+
+	return rval;
 }
 
 void EmscriptenCore::createFolder(const String& folderPath) {
@@ -553,3 +588,11 @@ bool EmscriptenCore::systemParseFolder(const String& pathString, bool showHidden
 	}
 	return true;
 }
+
+Number EmscriptenCore::getBackingXRes() {
+	return backingX;
+}
+
+Number EmscriptenCore::getBackingYRes() {
+	return backingY;
+}

+ 66 - 0
src/core/PolySDLAudioInterface.cpp

@@ -0,0 +1,66 @@
+/*
+	Copyright (C) 2016 by Sang Hak Chun
+
+	Permission is hereby granted, free of charge, to any person obtaining a copy
+	of this software and associated documentation files (the "Software"), to deal
+	in the Software without restriction, including without limitation the rights
+	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+	copies of the Software, and to permit persons to whom the Software is
+	furnished to do so, subject to the following conditions:
+
+	The above copyright notice and this permission notice shall be included in
+	all copies or substantial portions of the Software.
+
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+	THE SOFTWARE.
+*/
+
+#include "polycode/core/PolySDLAudioInterface.h"
+#include "polycode/core/PolyLogger.h"
+
+using namespace Polycode;
+
+SDLAudioInterface::SDLAudioInterface() {
+	desired = (SDL_AudioSpec*) malloc(sizeof(SDL_AudioSpec));
+	obtained = (SDL_AudioSpec*) malloc(sizeof(SDL_AudioSpec));
+
+	desired->freq = POLY_AUDIO_FREQ;
+	desired->format = AUDIO_S16SYS;
+	desired->channels = POLY_NUM_CHANNELS;
+	desired->samples = SDL_AUDIO_NUM_OF_SAMPLES;
+	desired->callback = SDLAudioInterface::sdlCallback;
+	desired->userdata = this;
+
+	int error = SDL_OpenAudio(desired, obtained);
+
+	if (error < 0) {
+		Logger::log("Error opening SDL_audio stream\n");
+	}
+
+	free(desired);
+
+	buffer = (int16_t*) malloc(sizeof(int16_t) * POLY_FRAMES_PER_BUFFER * POLY_NUM_CHANNELS);
+
+	SDL_PauseAudio(0); // start playing
+}
+
+SDLAudioInterface::~SDLAudioInterface() {
+	SDL_CloseAudio();
+	free(buffer);
+}
+
+void SDLAudioInterface::sdlCallback(void *userData, Uint8 *_stream, int _length) {
+	if ( _length == 0 )
+		return;
+
+	memset(_stream, 0, _length);
+	SDLAudioInterface *audioInterface = (SDLAudioInterface*) userData;
+	if(_stream && audioInterface->getMixer()) {
+		audioInterface->getMixer()->mixIntoBuffer((int16_t*)_stream, (_length / (sizeof(int16_t) * POLY_NUM_CHANNELS)));
+	}
+};

Some files were not shown because too many files changed in this diff