}
}
]
- },
- {
- "Name" : "Emscripten",
- "Options" : {
- "ExcludeFromBuild" : true
- }
}
]
},
}
]
},
- {
- "FileName" : "PNGFormat.ec",
- "Configurations" : [
- {
- "Name" : "Emscripten",
- "Options" : {
- "ExcludeFromBuild" : true
- }
- }
- ]
- },
+ "PNGFormat.ec",
{
"FileName" : "RGBFormat.ec",
"Configurations" : [
"Options" : {
"ExcludeFromBuild" : false
}
+ },
+ {
+ "Name" : "Static",
+ "Options" : {
+ "ExcludeFromBuild" : false
+ }
+ },
+ {
+ "Name" : "Emscripten",
+ "Options" : {
+ "ExcludeFromBuild" : false
+ }
}
]
},
"Options" : {
"ExcludeFromBuild" : false
}
+ },
+ {
+ "Name" : "Static",
+ "Options" : {
+ "ExcludeFromBuild" : false
+ }
+ },
+ {
+ "Name" : "Emscripten",
+ "Options" : {
+ "ExcludeFromBuild" : false
+ }
}
]
},
"Options" : {
"ExcludeFromBuild" : false
}
+ },
+ {
+ "Name" : "Static",
+ "Options" : {
+ "ExcludeFromBuild" : false
+ }
+ },
+ {
+ "Name" : "Emscripten",
+ "Options" : {
+ "ExcludeFromBuild" : false
+ }
}
]
},
"Options" : {
"ExcludeFromBuild" : false
}
+ },
+ {
+ "Name" : "Static",
+ "Options" : {
+ "ExcludeFromBuild" : false
+ }
}
]
},
}
}
]
+ },
+ {
+ "Name" : "Emscripten",
+ "Platforms" : [
+ {
+ "Name" : "linux",
+ "Options" : {
+ "ExcludeFromBuild" : true
+ }
+ }
+ ]
}
]
}
}
}
]
+ },
+ {
+ "Name" : "Emscripten",
+ "Platforms" : [
+ {
+ "Name" : "linux",
+ "Options" : {
+ "ExcludeFromBuild" : true
+ }
+ }
+ ]
}
]
},
}
}
]
+ },
+ {
+ "Name" : "Emscripten",
+ "Platforms" : [
+ {
+ "Name" : "linux",
+ "Options" : {
+ "ExcludeFromBuild" : true
+ }
+ }
+ ]
}
]
},
}
}
]
- }
+ },
+ "test_html5.c"
],
"Options" : {
"ExcludeFromBuild" : true
+#define _Noreturn
+
namespace sys;
#define set _set
#include <stdlib.h>
#include <stdarg.h>
#if !defined(ECERE_BOOTSTRAP) // quick fix for now
-#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
+#if defined(__WIN32__)
#define WIN32_LEAN_AND_MEAN
#define String _String
#include <windows.h>
+#define _Noreturn
+
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#undef bool
#endif
-#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
+#if defined(__WIN32__)
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#include <windows.h>
__declspec(dllexport) int isblank(int c) { return c == '\t' || c == ' '; }
#endif
-#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
+#if defined(__WIN32__)
intptr_t stdinHandle, stdoutHandle;
int osfStdin, osfStdout;
FILE * fStdIn, * fStdOut;
#endif
FILE *eC_stdin(void) {
-#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
+#if defined(__WIN32__)
if(!fStdIn)
{
stdinHandle = (intptr_t)GetStdHandle(STD_INPUT_HANDLE);
typedef enum { unknown, win32, tux, apple } Platform;
-#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
+#if defined(__WIN32__)
Platform runtimePlatform = win32;
#elif defined(__APPLE__)
Platform runtimePlatform = apple;
bool Instance_LocateModule(const char * name, char * fileName)
{
-#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
+#if defined(__WIN32__)
HMODULE hModule = null;
if(name && name[0])
{
void Instance_COM_Initialize(int argc, char ** argv, char ** parsedCommand, int * argcPtr, const char *** argvPtr)
{
-#if !defined(__WIN32__) && !defined(__EMSCRIPTEN__) && !defined(ECERE_BOOTSTRAP)
+#if !defined(__WIN32__) && !defined(ECERE_BOOTSTRAP)
// Disable stdout buffering on Unix
setvbuf(stdout, null, _IONBF, 0);
#endif
-#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
+#if defined(__WIN32__)
*parsedCommand = UTF16toUTF8(GetCommandLineW());
*argvPtr = eSystem_New0(sizeof(char *) * 512);
*argcPtr = Tokenize(*parsedCommand, 512,(void*)(char **)(*argvPtr), forArgsPassing);
*Load = null;
*Unload = null;
-#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
+#if defined(__WIN32__)
strcpy(fileName, name);
GetExtension(fileName, extension);
if(!extension[0])
void Instance_Module_Free(void * library)
{
-#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
+#if defined(__WIN32__)
if(library)
FreeLibrary(library);
#elif (defined(__unix__) || defined(__APPLE__)) && !defined(__EMSCRIPTEN__)
+#define _Noreturn
+
namespace com;
// #define DISABLE_MEMMGR
#endif
#endif
+#if defined(__EMSCRIPTEN__)
+#define GetCurrentThreadID() 0
+#endif
+
// #define MEMINFO
/*
#ifdef MEMINFO
void * pointer;
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Wait();
#endif
printf(" %s\n", stack.frames[c]);
memoryErrorsCount++;
+#if !defined(__EMSCRIPTEN__)
memMutex.Release();
+#endif
return null;
}
}
#endif
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Release();
#endif
#else
void * pointer;
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Wait();
#endif
if(stack.frames[c])
printf(" %s\n", stack.frames[c]);
memoryErrorsCount++;
+#if !defined(__EMSCRIPTEN__)
memMutex.Release();
+#endif
return null;
}
}
#endif
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Release();
#endif
#else
if(!size) { _free(pointer); return null; }
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Wait();
#endif
if(stack.frames[c])
printf(" %s\n", stack.frames[c]);
memoryErrorsCount++;
+#if !defined(__EMSCRIPTEN__)
memMutex.Release();
+#endif
return null;
}
memset(pointer, 0xAB, REDZONE);
pointer = realloc(pointer, size);
#endif
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Release();
#endif
return pointer ? ((byte *)pointer + REDZONE) : null;
#else
if(!size) { _free(pointer); return null; }
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Wait();
#endif
if(stack.frames[c])
printf(" %s\n", stack.frames[c]);
memoryErrorsCount++;
+#if !defined(__EMSCRIPTEN__)
memMutex.Release();
+#endif
return null;
}
memset(pointer, 0xAB, REDZONE);
pointer = crealloc(pointer, size);
#endif
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
memMutex.Release();
#endif
return pointer ? ((byte *)pointer + REDZONE) : null;
#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
free(pointer);
#else
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
if(memMutex != pointer) memMutex.Wait();
#endif
free(pointer);
#endif
-#if !defined(ECERE_BOOTSTRAP)
+#if !defined(ECERE_BOOTSTRAP) && !defined(__EMSCRIPTEN__)
if(memMutex != pointer) memMutex.Release();
#endif
switch(param.type)
{
case type:
- arg.dataTypeString = CopyString(arg.dataTypeString);
+ arg.dataTypeString = CopyString(arg.dataTypeString);
break;
case expression:
#ifdef MEMINFO
#undef malloc
+#if !defined(__EMSCRIPTEN__)
memMutex.Wait();
+#endif
//allocateClass = _class;
allocateClass = malloc(strlen(_class.name)+1);
allocateInternal = _class.module == __thisModule;
}
#ifdef MEMINFO
allocateClass = null;
+#if !defined(__EMSCRIPTEN__)
memMutex.Release();
#endif
+#endif
#if !defined(MEMINFO) && defined(MEMTRACKING)
{
blocksByClass.Free();
sizeByClass.Free();
+#if !defined(__EMSCRIPTEN__)
memMutex.Wait();
+#endif
for(p = 0; pools && p < NUM_POOLS; p++)
{
BlockPool * pool = &pools[p];
sizeByClass[c] += block.size;
}
}
+#if !defined(__EMSCRIPTEN__)
memMutex.Release();
+#endif
//for(c : blocksByClass)
{
namespace gfx::bitmaps;
+#define _Noreturn
import "Display"
#include <setjmp.h>
namespace gfx::bitmaps;
-import "Display"
+#define _Noreturn
-#if !defined(__EMSCRIPTEN__)
+import "Display"
#define uint _uint
#include "png.h"
return result;
}
}
-
-#endif // !defined(__EMSCRIPTEN__)
+#define _Noreturn
+
namespace gfx::drivers;
#ifdef __MSC__
import "instance"
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(ECERE_MINIGLX) && !defined(__EMSCRIPTEN__)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(ECERE_MINIGLX)
default:
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#if !defined(__EMSCRIPTEN__)
#include <X11/extensions/shape.h>
#include <X11/extensions/Xrender.h>
-#endif
#include <X11/extensions/XShm.h>
#include <sys/ipc.h>
#include <sys/shm.h>
+#define _Noreturn
+
namespace gui;
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
+#include <html5.h>
#endif
#ifdef __EMSCRIPTEN__
desktop.Update(null);
}
// When does the desktop have a display in not fullscreen mode?
+#if defined(__EMSCRIPTEN__)
+ if(true)
+#else
if(!fullScreenMode && !modeSwitching)
+#endif
desktop.UpdateDisplay();
desktop.display.Unlock();
}
{
Window window;
+#ifdef __EMSCRIPTEN__
+ {
+ int w = 0, h = 0;
+ double dw = 0, dh = 0;
+
+ emscripten_get_element_css_size(0, &dw, &dh);
+ w = (int)dw, h = (int)dh;
+ if(w && h)
+ {
+ emscripten_set_canvas_size(w, h);
+ guiApp.desktop.ExternalPosition(0,0, w, h);
+ if(guiApp.desktop.display && guiApp.desktop.display.displaySystem)
+ guiApp.desktop.display.Resize(w, h);
+ }
+ }
+#endif
+
if(Init())
{
if(desktop)
}
#ifdef __EMSCRIPTEN__
- emscripten_set_main_loop(emscripten_main_loop_callback, 1/*60*/, 1);
+ emscripten_set_main_loop(emscripten_main_loop_callback, 0 /*60*/, 1);
#endif
if(desktop)
{
int terminated = 0;
incref desktop;
+
ProcessInput(true);
while(desktop && interfaceDriver)
{
if(interfaceDriver)
{
+#if defined(__EMSCRIPTEN__)
+ if(true)
+#else
if(fullScreenMode && desktop.display)
+#endif
{
#if !defined(__EMSCRIPTEN__)
desktop.mutex.Wait();
(!refreshRate || refreshRate == fbRefreshRate) &&
(currentSkin && (!skinName || !strcmp(currentSkin.name, skinName))))
result = true;
+#if defined(__EMSCRIPTEN__)
+ else if(interfaceDriver && (!driverName || (fbDriver && !strcmp(fbDriver, driverName))) &&
+ fullScreen != fbFullScreen &&
+ (!resolution || resolution == fbResolution) &&
+ (!colorDepth || colorDepth == fbColorDepth) &&
+ (!refreshRate || refreshRate == fbRefreshRate) &&
+ (currentSkin && (!skinName || !strcmp(currentSkin.name, skinName))))
+ {
+ if(inter.ScreenMode(fullScreen, resolution, colorDepth, refreshRate, &textMode))
+ this.fullScreen = fullScreen;
+ result = true;
+ }
+#endif
else if(inter)
{
bool wasFullScreen = fullScreenMode;
{
set { timerResolution = value; if(interfaceDriver) interfaceDriver.SetTimerResolution(value); }
};
+ property Window acquiredWindow { get { return acquiredWindow; } };
};
#ifdef __EMSCRIPTEN__
x -= rootWindow.clientStart.x;
y -= rootWindow.clientStart.y - (rootWindow.hasMenuBar ? skinMenuHeight : 0);
}
+#if !defined(__EMSCRIPTEN__)
if(!guiApp.fullScreenMode || is3D)
+#endif
{
x -= rootWindow.absPosition.x;
y -= rootWindow.absPosition.y;
if(display && !display.flags.memBackBuffer && changeRootWindow)
guiApp.interfaceDriver.PositionRootWindow(this, x, y, w, h, windowMoved, windowResized); //realResized);
- if(!guiApp.fullScreenMode && this != guiApp.desktop && (windowResized || windowMoved))
+ if(
+#if !defined(__EMSCRIPTEN__)
+ !guiApp.fullScreenMode &&
+#endif
+ this != guiApp.desktop && (windowResized || windowMoved))
for(child = parent.children.first; child && child != this; child = child.next)
if(child.rootWindow)
guiApp.interfaceDriver.UpdateRootWindow(child.rootWindow);
if(activateParent && parent && !parent.active /*parent != parent.parent.activeChild*/)
parent.ActivateEx(true, true, moveInactive, activateRoot, external, externalSwap);
}
- else if(!guiApp.fullScreenMode)
+ else
+#if !defined(__EMSCRIPTEN__)
+ if(!guiApp.fullScreenMode)
+#endif
{
Window modalRoot = FindModal();
if(!modalRoot) modalRoot = this;
Window child;
// Setup relationship with outside world (bb root || !bb)
+#if defined(__EMSCRIPTEN__)
+ if(this == guiApp.desktop)
+#else
if((!guiApp.fullScreenMode && parent == guiApp.desktop) || this == guiApp.desktop ||
(_displayDriver && parent.dispDriver && dispDriver != parent.dispDriver))
+#endif
{
rootWindow = this;
if(!tempExtents)
bool result = false;
Window child;
+#if defined(__EMSCRIPTEN__)
+ if(this == guiApp.desktop)
+#else
if((!guiApp.fullScreenMode && parent == guiApp.desktop) || (guiApp.fullScreenMode && (this == guiApp.desktop || (_displayDriver && parent.dispDriver && dispDriver != parent.dispDriver))))
+#endif
{
subclass(DisplayDriver) dDriver = (dispDriver && !formDesigner) ? dispDriver : GetDisplayDriver(guiApp.defaultDisplayDriver);
DisplaySystem displaySystem = dDriver ? dDriver.displaySystem : null;
}
}
- if(guiApp.fullScreenMode || this != guiApp.desktop)
+ if(
+#if !defined(__EMSCRIPTEN__)
+ guiApp.fullScreenMode ||
+#endif
+ this != guiApp.desktop)
{
SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
if(display)
public bool AcquireInput(bool acquired)
{
bool result = true;
- if(acquiredInput != acquired)
+ if((guiApp.acquiredWindow && acquiredInput) != acquired)
{
if(active || (!visible && creationActivation == activate))
result = AcquireInputEx(acquired);
{
if(guiApp.driver != null)
{
+#if !defined(__EMSCRIPTEN__)
if(guiApp.fullScreenMode && guiApp.desktop.display)
+#else
+ if(true)
+#endif
{
#if !defined(__EMSCRIPTEN__)
guiApp.desktop.mutex.Wait();
bool MenuWindowWindows(MenuItem selection, Modifiers mods)
{
- WindowList dialog { master = this };
- Window document = (Window)(intptr)dialog.Modal();
- if(document)
+ WindowList
{
- if(activeChild.state == maximized)
- document.SetState(maximized, false, mods);
- else if(document.state == minimized)
- document.SetState(normal, false, mods);
- document.Activate();
- }
+ master = this; isModal = true;
+
+ void NotifyDestroyed(Window window, DialogResult result)
+ {
+ Window document = (Window)(intptr)result;
+ if(document)
+ {
+ if(activeChild.state == maximized)
+ document.SetState(maximized, false, 0);
+ else if(document.state == minimized)
+ document.SetState(normal, false, 0);
+ document.Activate();
+ }
+ }
+ }.Create();
return true;
}
+#define _Noreturn
+
namespace gui::drivers;
import "Window"
#define property _property
#define uint _uint
-//#include <GLES2/gl2.h>
-#include <GL/glfw.h>
-#include <emscripten/emscripten.h>
+#include <emscripten.h>
+#include <html5.h>
#undef property
#undef uint
+default:
+extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit;
+extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp;
+extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown;
+extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit;
+extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove;
+extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick;
+extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown;
+extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp;
+extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleDoubleClick;
+extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown;
+extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonUp;
+extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightDoubleClick;
+extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown;
+extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonUp;
+
+private:
+
+static Point lastMouse;
+
+static inline const char *emscripten_event_type_to_string(int eventType) {
+ const char *events[] = { "(invalid)", "(none)", "keypress", "keydown", "keyup", "click", "mousedown", "mouseup", "dblclick", "mousemove", "wheel", "resize",
+ "scroll", "blur", "focus", "focusin", "focusout", "deviceorientation", "devicemotion", "orientationchange", "fullscreenchange", "pointerlockchange",
+ "visibilitychange", "touchstart", "touchend", "touchmove", "touchcancel", "gamepadconnected", "gamepaddisconnected", "beforeunload",
+ "batterychargingchange", "batterylevelchange", "webglcontextlost", "webglcontextrestored", "mouseenter", "mouseleave", "mouseover", "mouseout", "(invalid)" };
+ ++eventType;
+ if (eventType < 0) eventType = 0;
+ if (eventType >= sizeof(events)/sizeof(events[0])) eventType = sizeof(events)/sizeof(events[0])-1;
+ return events[eventType];
+}
+
+static int mouseButtons;
+static int movementX, movementY;
+
+static bool isFullScreen;
+
+static EM_BOOL mouse_callback(int eventType, const EmscriptenMouseEvent *e, void *userData)
+{
+ Window window = guiApp.desktop;
+ Modifiers mods { };
+ int methodID;
+
+ switch(eventType)
+ {
+ case EMSCRIPTEN_EVENT_MOUSEMOVE:
+ lastMouse = { e->canvasX, e->canvasY };
+ window.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove,
+ e->canvasX, e->canvasY, &mods, false, true);
+ movementX += e->movementX;
+ movementY += e->movementY;
+ break;
+ case EMSCRIPTEN_EVENT_MOUSEDOWN:
+ // PrintLn("EMSCRIPTEN_EVENT_MOUSEDOWN!");
+ methodID =
+ e->button == 0 ? __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown :
+ e->button == 2 ? __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown :
+ __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown;
+ window.MouseMessage(methodID, e->canvasX, e->canvasY, &mods, false, true);
+ if(e->button == 0)
+ mouseButtons |= 1;
+ else if(e->button == 2)
+ mouseButtons |= 2;
+ else
+ mouseButtons |= 4;
+ break;
+ case EMSCRIPTEN_EVENT_MOUSEUP:
+ methodID =
+ e->button == 0 ? __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp :
+ e->button == 2 ? __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonUp :
+ __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonUp;
+ window.MouseMessage(methodID, e->canvasX, e->canvasY, &mods, false, true);
+ if(e->button == 0)
+ mouseButtons &= ~1;
+ else if(e->button == 2)
+ mouseButtons &= ~2;
+ else
+ mouseButtons &= ~4;
+ break;
+ case EMSCRIPTEN_EVENT_DBLCLICK:
+ methodID =
+ e->button == 0 ? __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick :
+ e->button == 2 ? __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightDoubleClick :
+ __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleDoubleClick;
+ window.MouseMessage(methodID, e->canvasX, e->canvasY, &mods, false, true);
+ break;
+ }
+
+/*
+ printf("%s, screen: (%ld,%ld), client: (%ld,%ld),%s%s%s%s button: %hu, buttons: %hu, movement: (%ld,%ld), canvas: (%ld,%ld)\n",
+ emscripten_event_type_to_string(eventType), e->screenX, e->screenY, e->clientX, e->clientY,
+ e->ctrlKey ? " CTRL" : "", e->shiftKey ? " SHIFT" : "", e->altKey ? " ALT" : "", e->metaKey ? " META" : "",
+ e->button, e->buttons, e->movementX, e->movementY, e->canvasX, e->canvasY);
+*/
+ return 0;
+}
+
+static EM_BOOL wheel_callback(int eventType, const EmscriptenWheelEvent *e, void *userData)
+{
+ Window window = guiApp.desktop;
+ window.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit,
+ e->deltaY < 0 ? wheelUp : wheelDown, 0);
+ /*
+ printf("%s, screen: (%ld,%ld), client: (%ld,%ld),%s%s%s%s button: %hu, buttons: %hu, canvas: (%ld,%ld), delta:(%g,%g,%g), deltaMode:%lu\n",
+ emscripten_event_type_to_string(eventType), e->mouse.screenX, e->mouse.screenY, e->mouse.clientX, e->mouse.clientY,
+ e->mouse.ctrlKey ? " CTRL" : "", e->mouse.shiftKey ? " SHIFT" : "", e->mouse.altKey ? " ALT" : "", e->mouse.metaKey ? " META" : "",
+ e->mouse.button, e->mouse.buttons, e->mouse.canvasX, e->mouse.canvasY,
+ (float)e->deltaX, (float)e->deltaY, (float)e->deltaZ, e->deltaMode);
+ */
+ return 0;
+}
+static bool keyStatus[KeyCode];
+
+EM_BOOL pointerlockchange_callback(int eventType, const EmscriptenPointerlockChangeEvent *e, void *userData)
+{
+ if(!e->isActive)
+ {
+ if(guiApp.acquiredWindow)
+ {
+ guiApp.acquiredWindow.acquiredInput = false;
+ guiApp.acquiredWindow = null;
+ }
+ }
+ else
+ {
+ Window w = guiApp.desktop;
+ if(w && w.children.first) w = w.children.first;
+ guiApp.acquiredWindow = w;
+ guiApp.acquiredWindow.acquiredInput = true;
+ }
+/*
+ printf("%s, isActive: %d, pointerlock element nodeName: \"%s\", id: \"%s\"\n",
+ emscripten_event_type_to_string(eventType), e->isActive, e->nodeName, e->id);
+*/
+ movementX = 0;
+ movementY = 0;
+ return 0;
+}
+
+EM_BOOL fullscreenchange_callback(int eventType, const EmscriptenFullscreenChangeEvent *e, void *userData)
+{
+ int w = 0, h = 0;
+ double dw = 0, dh = 0;
+ isFullScreen = (bool)e->isFullscreen;
+ *&guiApp.fullScreen = isFullScreen;
+
+ emscripten_get_element_css_size(0, &dw, &dh);
+ w = (int)dw, h = (int)dh;
+ if(w && h)
+ {
+ emscripten_set_canvas_size(w, h);
+ guiApp.desktop.ExternalPosition(0,0, w, h);
+ if(guiApp.desktop.display && guiApp.desktop.display.displaySystem)
+ guiApp.desktop.display.Resize(w, h);
+ }
+ movementX = 0;
+ movementY = 0;
+ return 0;
+}
+
+// The event handler functions can return 1 to suppress the event and disable the default action. That calls event.preventDefault();
+// Returning 0 signals that the event was not consumed by the code, and will allow the event to pass on and bubble up normally.
+EM_BOOL key_callback(int eventType, const EmscriptenKeyboardEvent *e, void *userData)
+{
+ Window window = guiApp.desktop;
+ Key key = 0;
+ switch(e->keyCode)
+ {
+ case 8: key = backSpace; break;
+ case 9: key = tab; break;
+ case 13: key = enter; break;
+ case 16: key = shift; break;
+ case 17: key = control; break;
+ case 18: key = alt; break;
+ case 19: key = pause; break;
+ case 20: key = capsLock; break;
+ case 27: key = escape; break;
+ case 32: key = space; break;
+ case 33: key = pageUp; break;
+ case 34: key = pageDown; break;
+ case 35: key = end; break;
+ case 36: key = home; break;
+ case 37: key = left; break;
+ case 38: key = up; break;
+ case 39: key = right; break;
+ case 40: key = down; break;
+ case 44: key = printScreen; break;
+ case 45: key = insert; break;
+ case 46: key = del; break;
+ case 48: key = k0; break;
+ case 49: key = k1; break;
+ case 50: key = k2; break;
+ case 51: key = k3; break;
+ case 52: key = k4; break;
+ case 53: key = k5; break;
+ case 54: key = k6; break;
+ case 55: key = k7; break;
+ case 56: key = k8; break;
+ case 57: key = k9; break;
+ case 65: key = a; break;
+ case 66: key = b; break;
+ case 67: key = c; break;
+ case 68: key = d; break;
+ case 69: key = KeyCode::e; break;
+ case 70: key = f; break;
+ case 71: key = g; break;
+ case 72: key = h; break;
+ case 73: key = i; break;
+ case 74: key = j; break;
+ case 75: key = k; break;
+ case 76: key = l; break;
+ case 77: key = m; break;
+ case 78: key = n; break;
+ case 79: key = o; break;
+ case 80: key = p; break;
+ case 81: key = q; break;
+ case 82: key = r; break;
+ case 83: key = s; break;
+ case 84: key = t; break;
+ case 85: key = u; break;
+ case 86: key = v; break;
+ case 87: key = w; break;
+ case 88: key = x; break;
+ case 89: key = y; break;
+ case 90: key = z; break;
+ // case 91: key = start; break;
+ // case 93: key = context; break;
+ case 112: key = f1; break;
+ case 113: key = f2; break;
+ case 114: key = f3; break;
+ case 115: key = f4; break;
+ case 116: key = f5; break;
+ case 117: key = f6; break;
+ case 118: key = f7; break;
+ case 119: key = f8; break;
+ case 120: key = f9; break;
+ case 121: key = f10; break;
+ case 122: key = f11; break;
+ case 123: key = f12; break;
+ case 144: key = numLock; break;
+ case 125: key = scrollLock; break;
+ case 188: key = comma; break;
+ case 190: key = period; break;
+ case 191: key = slash; break;
+ case 192: key = tilde; break;
+ case 219: key = leftBracket; break; // also corresponds to the Win Key (Start) in older versions of Opera.
+ case 220: key = backSlash; break;
+ case 221: key = rightBracket; break;
+ case 222: key = quote; break;
+
+ /*case 173: */case 181: key = mute; break; // FF: 181
+ case 174: case 182: key = volumeDown; break; // FF: 182
+ case 175: case 183: key = volumeDown; break; // FF: 183
+ case 186: case 59: key = semicolon; break; // FF: 59
+ case 187: case 61: key = equal; break; // FF: 61
+ case 189: case 173: key = minus; break; // FF: 61
+
+ case 96: key = keyPad0; break;
+ //case 45: key = keyPadInsert; break;
+
+ case 97: key = keyPad1; break;
+ //case 35: key = keyPadEnd; break;
+
+ case 98: key = keyPad2; break;
+ //case 40: key = keyPadDown; break;
+
+ case 99: key = keyPad3; break;
+ //case 34: key = keyPadPageDown; break;
+
+ case 100: key = keyPad4; break;
+ //case 37: key = keyPadLeft; break;
+
+ case 101: key = keyPad5; break;
+ case 12: key = keyPad5; break;
+
+ case 102: key = keyPad6; break;
+ //case 39: key = keyPadRight; break;
+
+ case 103: key = keyPad7; break;
+ //case 36: key = keyPadHome; break;
+
+ case 104: key = keyPad8; break;
+ //case 38: key = keyPadUp; break;
+
+ case 105: key = keyPad9; break;
+ //case 33: key = keyPadPageUp; break;
+
+ case 106: key = keyPadStar; break;
+ case 107: key = keyPadPlus; break;
+ case 109: key = keyPadMinus; break;
+
+ case 110: key = keyPadDelete; break;
+ //case 46: key = keyPadDelete; break;
+
+ case 11: key = keyPadSlash; break;
+ }
+
+ key.alt = (bool)e->altKey;
+ key.shift = (bool)e->shiftKey;
+ key.ctrl = (bool)e->ctrlKey;
+/*
+ printf("%s, key: \"%s\", code: \"%s\", location: %lu,%s%s%s%s repeat: %d, locale: \"%s\", char: \"%s\", charCode: %lu, keyCode: %lu, which: %lu\n",
+ emscripten_event_type_to_string(eventType), e->key, e->code, e->location,
+ e->ctrlKey ? " CTRL" : "", e->shiftKey ? " SHIFT" : "", e->altKey ? " ALT" : "", e->metaKey ? " META" : "",
+ e->repeat, e->locale, e->charValue, e->charCode, e->keyCode, e->which);
+*/
+ if(key)
+ {
+ switch(eventType)
+ {
+ case EMSCRIPTEN_EVENT_KEYDOWN:
+ //PrintLn("Setting ", key, " to down");
+ keyStatus[key] = true;
+ window.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown, key, (unichar)e->charCode);
+ break;
+ case EMSCRIPTEN_EVENT_KEYUP:
+ //PrintLn("Setting ", key, " to false");
+ keyStatus[key] = false;
+ window.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp, key, (unichar)e->charCode);
+ break;
+ }
+ }
+
+ /*
+ if (eventType == EMSCRIPTEN_EVENT_KEYPRESS && (!strcmp(e->key, "f") || e->which == 102)) {
+ EmscriptenFullscreenChangeEvent fsce;
+ EMSCRIPTEN_RESULT ret = emscripten_get_fullscreen_status(&fsce);
+ TEST_RESULT(emscripten_get_fullscreen_status);
+ if (!fsce.isFullscreen) {
+ printf("Requesting fullscreen..\n");
+ ret = emscripten_request_fullscreen(0, 1);
+ TEST_RESULT(emscripten_request_fullscreen);
+ } else {
+ printf("Exiting fullscreen..\n");
+ ret = emscripten_exit_fullscreen();
+ TEST_RESULT(emscripten_exit_fullscreen);
+ ret = emscripten_get_fullscreen_status(&fsce);
+ TEST_RESULT(emscripten_get_fullscreen_status);
+ if (fsce.isFullscreen) {
+ fprintf(stderr, "Fullscreen exit did not work!\n");
+ }
+ }
+ }
+
+ if (eventType == EMSCRIPTEN_EVENT_KEYPRESS && (!strcmp(e->key, "p") || e->which == 112)) {
+ EmscriptenPointerlockChangeEvent plce;
+ EMSCRIPTEN_RESULT ret = emscripten_get_pointerlock_status(&plce);
+ TEST_RESULT(emscripten_get_pointerlock_status);
+ if (!plce.isActive) {
+ printf("Requesting pointer lock..\n");
+ ret = emscripten_request_pointerlock(0, 1);
+ TEST_RESULT(emscripten_request_pointerlock);
+ } else {
+ printf("Exiting pointer lock..\n");
+ ret = emscripten_exit_pointerlock();
+ TEST_RESULT(emscripten_exit_pointerlock);
+ ret = emscripten_get_pointerlock_status(&plce);
+ TEST_RESULT(emscripten_get_pointerlock_status);
+ if (plce.isActive) {
+ fprintf(stderr, "Pointer lock exit did not work!\n");
+ }
+ }
+ }
+ */
+
+ return 0;
+}
+
+static EM_BOOL uievent_callback(int eventType, const EmscriptenUiEvent *e, void *userData)
+{
+ switch(eventType)
+ {
+ case EMSCRIPTEN_EVENT_RESIZE:
+ //case EMSCRIPTEN_EVENT_SCROLL:
+ {
+ int w = 0, h = 0;
+ double dw = 0, dh = 0;
+ emscripten_get_element_css_size(0, &dw, &dh);
+ w = (int)dw, h = (int)dh;
+ if(w && h)
+ {
+ emscripten_set_canvas_size(w, h);
+ guiApp.desktop.ExternalPosition(0,0, w, h);
+ if(guiApp.desktop.display && guiApp.desktop.display.displaySystem)
+ guiApp.desktop.display.Resize(w, h);
+ }
+ //PrintLn("EMSCRIPTEN_EVENT_RESIZE: ", w, " x ", h);
+ break;
+ }
+ }
+ /*
+ printf("%s, detail: %ld, document.body.client size: (%d,%d), window.inner size: (%d,%d), scrollPos: (%d, %d)\n",
+ emscripten_event_type_to_string(eventType), e->detail, e->documentBodyClientWidth, e->documentBodyClientHeight,
+ e->windowInnerWidth, e->windowInnerHeight, e->scrollTop, e->scrollLeft);
+ */
+ return 0;
+}
class EmscriptenInterface : Interface
{
class_property(name) = "Emscripten";
-
// --- User Interface System ---
bool ::Initialize()
{
- sflnprintf("class(EmscriptenInterface) ::Initialize [STUB!]\n");
- guiApp.desktop.ExternalPosition(0,0, 640, 480);
+ emscripten_set_resize_callback(0, 0, 1, uievent_callback);
+ //emscripten_set_scroll_callback(0, 0, 1, uievent_callback);
+ emscripten_set_click_callback(0, 0, 1, mouse_callback);
+ emscripten_set_mousedown_callback(0, 0, 1, mouse_callback);
+ emscripten_set_mouseup_callback(0, 0, 1, mouse_callback);
+ emscripten_set_dblclick_callback(0, 0, 1, mouse_callback);
+ emscripten_set_mousemove_callback(0, 0, 1, mouse_callback);
+ emscripten_set_wheel_callback(0, 0, 1, wheel_callback);
+ emscripten_set_keypress_callback(0, 0, 1, key_callback);
+ emscripten_set_keydown_callback(0, 0, 1, key_callback);
+ emscripten_set_keyup_callback(0, 0, 1, key_callback);
+ emscripten_set_pointerlockchange_callback(0, 0, 1, pointerlockchange_callback);
+ emscripten_set_fullscreenchange_callback(0, 0, 1, fullscreenchange_callback);
+ /*emscripten_set_mouseenter_callback(0, 0, 1, mouse_callback);
+ emscripten_set_mouseleave_callback(0, 0, 1, mouse_callback);*/
return true;
}
void ::Terminate()
{
- sflnprintf("class(EmscriptenInterface) ::Terminate [STUB!]\n");
+
}
bool ::ProcessInput(bool processAll)
{
- sflnprintf("class(EmscriptenInterface) ::ProcessInput [STUB!]\n");
+
return false;
}
void ::Wait()
{
- sflnprintf("class(EmscriptenInterface) ::Wait [STUB!]\n");
+
}
void ::Lock(Window window)
{
- sflnprintf("class(EmscriptenInterface) ::Lock [STUB!]\n");
+
}
void ::Unlock(Window window)
{
- sflnprintf("class(EmscriptenInterface) ::Unlock [STUB!]\n");
+
}
void ::SetTimerResolution(uint hertz)
{
- sflnprintf("class(EmscriptenInterface) ::SetTimerResolution [STUB!] Implement high resolution timer here\n");
+
}
const char ** ::GraphicsDrivers(int * numDrivers)
{
- //sflnprintf("class(EmscriptenInterface) ::GraphicsDrivers [STUB!]\n");
static const char *graphicsDrivers[] = { "OpenGL" };
*numDrivers = sizeof(graphicsDrivers) / sizeof(char *);
return (const char **)graphicsDrivers;
void ::EnsureFullScreen(bool * fullScreen)
{
- sflnprintf("class(EmscriptenInterface) ::EnsureFullScreen [STUB!]\n");
- *fullScreen = true;
+
}
void ::GetCurrentMode(bool * fullScreen, Resolution * resolution, PixelFormat * colorDepth, int * refreshRate)
{
- sflnprintf("class(EmscriptenInterface) ::GetCurrentMode [STUB!]\n");
+ *fullScreen = isFullScreen;
}
bool ::ScreenMode(bool fullScreen, Resolution resolution, PixelFormat colorDepth, int refreshRate, bool * textMode)
{
- sflnprintf("class(EmscriptenInterface) ::ScreenMode [STUB!]\n");
+ if(fullScreen)
+ emscripten_request_fullscreen(0, 1);
+ else
+ emscripten_exit_fullscreen();
return true;
}
void * ::CreateRootWindow(Window window)
{
- sflnprintf("class(EmscriptenInterface) ::CreateRootWindow [STUB!]\n");
+
return null;
}
void ::DestroyRootWindow(Window window)
{
- sflnprintf("class(EmscriptenInterface) ::DestroyRootWindow [STUB!]\n");
+
}
void ::SetRootWindowCaption(Window window, const char * name)
{
- sflnprintf("class(EmscriptenInterface) ::SetRootWindowCaption [STUB!]\n");
+
}
void ::PositionRootWindow(Window window, int x, int y, int w, int h, bool move, bool resize)
{
- sflnprintf("class(EmscriptenInterface) ::Stub [STUB!]\n");
+
}
void ::OffsetWindow(Window window, int * x, int * y)
{
- sflnprintf("class(EmscriptenInterface) ::OffsetWindow [STUB!]\n");
+
}
void ::UpdateRootWindow(Window window)
{
- sflnprintf("class(EmscriptenInterface) ::UpdateRootWindow [STUB!]\n");
+
}
void ::SetRootWindowState(Window window, WindowState state, bool visible)
{
- sflnprintf("class(EmscriptenInterface) ::SetRootWindowState [STUB!]\n");
+
}
void ::ActivateRootWindow(Window window)
{
- sflnprintf("class(EmscriptenInterface) ::ActivateRootWindow [STUB!]\n");
+
}
void ::OrderRootWindow(Window window, bool topMost)
{
- sflnprintf("class(EmscriptenInterface) ::OrderRootWindow [STUB!]\n");
+
}
void ::SetRootWindowColor(Window window)
{
- sflnprintf("class(EmscriptenInterface) ::SetRootWindowColor [STUB!]\n");
+
}
void ::FlashRootWindow(Window window)
{
- sflnprintf("class(EmscriptenInterface) ::FlashRootWindow [STUB!]\n");
+
}
void ::StartMoving(Window window, int x, int y, bool fromKeyBoard)
{
- sflnprintf("class(EmscriptenInterface) ::StartMoving [STUB!]\n");
+
}
void ::StopMoving(Window window)
{
- sflnprintf("class(EmscriptenInterface) ::StopMoving [STUB!]\n");
+
}
void ::GetMousePosition(int *x, int *y)
{
- sflnprintf("class(EmscriptenInterface) ::GetMousePosition [STUB!]\n");
+ *x = lastMouse.x;
+ *y = lastMouse.y;
}
void ::SetMousePosition(int x, int y)
{
- sflnprintf("class(EmscriptenInterface) ::SetMousePosition [STUB!]\n");
+
}
void ::SetMouseRange(Window window, Box box)
{
- sflnprintf("class(EmscriptenInterface) ::SetMouseRange [STUB!]\n");
+
}
void ::SetMouseCapture(Window window)
{
- sflnprintf("class(EmscriptenInterface) ::SetMouseCapture [STUB!]\n");
+
}
void ::SetMouseCursor(Window window, SystemCursor cursor)
{
- sflnprintf("class(EmscriptenInterface) ::SetMouseCursor [STUB!]\n");
+
}
void ::SetCaret(int caretX, int caretY, int size)
{
- sflnprintf("class(EmscriptenInterface) ::SetCaret [STUB!]\n");
+
}
void ::ClearClipboard()
{
- sflnprintf("class(EmscriptenInterface) ::ClearClipboard [STUB!]\n");
+
}
bool ::AllocateClipboard(ClipBoard clipBoard, uint size)
{
- sflnprintf("class(EmscriptenInterface) ::AllocateClipboard [STUB!]\n");
+
return false;
}
bool ::SaveClipboard(ClipBoard clipBoard)
{
- sflnprintf("class(EmscriptenInterface) ::SaveClipboard [STUB!]\n");
+
return false;
}
bool ::LoadClipboard(ClipBoard clipBoard)
{
- sflnprintf("class(EmscriptenInterface) ::LoadClipboard [STUB!]\n");
+
return false;
}
void ::UnloadClipboard(ClipBoard clipBoard)
{
- sflnprintf("class(EmscriptenInterface) ::UnloadClipboard [STUB!]\n");
+
}
bool ::AcquireInput(Window window, bool state)
{
- sflnprintf("class(EmscriptenInterface) ::AcquireInput [STUB!]\n");
- return false;
+ if(state)
+ emscripten_request_pointerlock(0, 1);
+ else
+ emscripten_exit_pointerlock();
+
+ movementX = 0;
+ movementY = 0;
+ return true;
}
bool ::GetMouseState(MouseButtons * buttons, int * x, int * y)
{
- sflnprintf("class(EmscriptenInterface) ::GetMouseState [STUB!]\n");
- return false;
+ if(buttons) *buttons = { left = mouseButtons & 1, right = (mouseButtons & 2) ? true : false, middle = (mouseButtons & 4) ? true : false };
+ if(x) { *x = movementX; movementX = 0; }
+ if(y) { *y = movementY; movementY = 0; }
+
+ return true;
}
bool ::GetJoystickState(int device, Joystick joystick)
{
- sflnprintf("class(EmscriptenInterface) ::GetJoystickState [STUB!]\n");
+
return false;
}
bool ::GetKeyState(Key key)
{
- sflnprintf("class(EmscriptenInterface) ::GetKeyState [STUB!]\n");
- return false;
+ return keyStatus[key];
}
bool ::SetIcon(Window window, BitmapResource icon)
{
- sflnprintf("class(EmscriptenInterface) ::SetIcon [STUB!]\n");
+
return false;
}
void ::GetScreenArea(Window window, Box box)
{
- sflnprintf("class(EmscriptenInterface) ::GetScreenArea [STUB!]\n");
}
}
+#define _Noreturn
+
namespace gui::drivers;
import "instance"
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(__DOS__) && !defined(__EMSCRIPTEN__)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(__DOS__)
#undef __BLOCKS__
#define DBLCLICK_DELAY 0.3 // seconds
+#define _Noreturn
namespace gui::drivers;
import "instance"
import "OpenGLDisplayDriver"
#endif
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(ECERE_MINIGLX) && !defined(__EMSCRIPTEN__)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(ECERE_MINIGLX)
#undef __BLOCKS__
default:
+#define _Noreturn
+
#ifdef __statement
#undef __statement
#endif
+#define _Noreturn
+
namespace net;
#include <stdarg.h>
+#define _Noreturn
+
namespace net;
#if defined(__WIN32__)
+#define _Noreturn
+
namespace net;
#ifndef ECERE_NONET
+#define _Noreturn
+
#if defined(__WIN32__)
#define WIN32_LEAN_AND_MEAN
#define UNICODE
name = ((SubModule)__thisModule.application.modules.first).next.module.name;
#endif
- if(LocateModule(name, moduleName))
+#if defined(__EMSCRIPTEN__)
+ if(!name[0])
+ f = FileOpen("resources.ear", read);
+#endif
+
+ if(!f && LocateModule(name, moduleName))
f = FileOpen(moduleName, read);
}
else
result = EARGetEntry(f, entry, fileName, null);
delete f;
}
+ #ifdef ECERE_STATIC
+ if(!f && archive[0] == ':')
+ {
+ f = EAROpenArchive(":", &header);
+ if(f)
+ {
+ EAREntry entry { };
+ char fn[MAX_LOCATION];
+ strcpy(fn, archive + 1);
+ PathCat(fn, fileName);
+ result = EARGetEntry(f, entry, fn, null);
+ }
+ delete f;
+ }
+ #endif
return result;
}
+#define _Noreturn
+
#undef __BLOCKS__
+
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
namespace sys;
+#define _Noreturn
+
default:
#define set _set
#define uint _uint
+#define _Noreturn
+
#if defined(__ANDROID__)
#include <android/log.h>
#define uint _uint
#define set _set
#define String _String
-#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
+#if defined(__WIN32__)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
+#define _Noreturn
+
default:
#include <errno.h>
private:
+#define _Noreturn
+
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
namespace sys;
+#define _Noreturn
+
#if defined(ECERE_BOOTSTRAP)
#undef __WIN32__
#undef __unix__
+#define _Noreturn
+
namespace sys;
#define set _set
#undef Thread
#else
#include <pthread.h>
-#ifndef __ANDROID__
+#if !defined(__ANDROID__)
#include <signal.h>
#endif
#endif
namespace sys;
+#define _Noreturn
+
#define set _set
#define Date _Date
#define uint _uint
"adb shell am start -a android.intent.action.MAIN -n com.ecere.$(MODULE)/android.app.NativeActivity"
]
}
+ },
+ {
+ "Name" : "Emscripten",
+ "Options" : {
+ "Optimization" : "Speed",
+ "PreprocessorDefinitions" : [
+ "ECERE_STATIC",
+ "CHESS_NONET"
+ ],
+ "TargetFileName" : "chess.html",
+ "Libraries" : [
+ "ecereStatic",
+ "z",
+ "freetype",
+ "jpeg",
+ "png"
+ ],
+ "LibraryDirs" : [
+ "../../../ecere/obj/emscripten.linux.emscripten"
+ ],
+ "FastMath" : true
+ }
}
],
"Files" : [
],
"ResourcesPath" : "res",
"Resources" : [
+ {
+ "Folder" : "ecere",
+ "Files" : [
+ {
+ "Folder" : "actions",
+ "Files" : [
+ "../../../ecere/res/actions/clean.png",
+ "../../../ecere/res/actions/docNew.png",
+ "../../../ecere/res/actions/docSave.png",
+ "../../../ecere/res/actions/editFind.png",
+ "../../../ecere/res/actions/folderNew.png",
+ "../../../ecere/res/actions/goDown.png",
+ "../../../ecere/res/actions/goHome.png",
+ "../../../ecere/res/actions/goNext.png",
+ "../../../ecere/res/actions/goPrevious.png",
+ "../../../ecere/res/actions/goUp.png",
+ "../../../ecere/res/actions/listAdd.png",
+ "../../../ecere/res/actions/listRemove.png",
+ "../../../ecere/res/actions/viewRefresh.png",
+ "../../../ecere/res/actions/windowNew.png"
+ ]
+ },
+ {
+ "Folder" : "aqua",
+ "Files" : [
+ "../../../ecere/res/aqua/back.png",
+ "../../../ecere/res/aqua/down.png",
+ "../../../ecere/res/aqua/downLeft.png",
+ "../../../ecere/res/aqua/downMiddle.png",
+ "../../../ecere/res/aqua/downRight.png",
+ "../../../ecere/res/aqua/sDown.png",
+ "../../../ecere/res/aqua/sUp.png",
+ "../../../ecere/res/aqua/up.png",
+ "../../../ecere/res/aqua/upLeft.png",
+ "../../../ecere/res/aqua/upMiddle.png",
+ "../../../ecere/res/aqua/upRight.png"
+ ]
+ },
+ {
+ "Folder" : "constructs",
+ "Files" : [
+ "../../../ecere/res/constructs/class.png",
+ "../../../ecere/res/constructs/data.png",
+ "../../../ecere/res/constructs/dataPrivate.png",
+ "../../../ecere/res/constructs/dataType.png",
+ "../../../ecere/res/constructs/enum.png",
+ "../../../ecere/res/constructs/enumValue.png",
+ "../../../ecere/res/constructs/event.png",
+ "../../../ecere/res/constructs/library.png",
+ "../../../ecere/res/constructs/method.png",
+ "../../../ecere/res/constructs/methodPrivate.png",
+ "../../../ecere/res/constructs/namespace.png",
+ "../../../ecere/res/constructs/property.png",
+ "../../../ecere/res/constructs/propertyPrivate.png"
+ ]
+ },
+ {
+ "Folder" : "controls",
+ "Files" : [
+ "../../../ecere/res/controls/button.png",
+ "../../../ecere/res/controls/calendar.png",
+ "../../../ecere/res/controls/checkBox.png",
+ "../../../ecere/res/controls/dataBox.png",
+ "../../../ecere/res/controls/dropBox.png",
+ "../../../ecere/res/controls/editBox.png",
+ "../../../ecere/res/controls/groupBox.png",
+ "../../../ecere/res/controls/label.png",
+ "../../../ecere/res/controls/listBox.png",
+ "../../../ecere/res/controls/menu.png",
+ "../../../ecere/res/controls/optionBox.png",
+ "../../../ecere/res/controls/progressBar.png",
+ "../../../ecere/res/controls/scrollBarHorizontal.png",
+ "../../../ecere/res/controls/scrollBarVertical.png",
+ "../../../ecere/res/controls/statusBar.png"
+ ]
+ },
+ {
+ "Folder" : "cursors",
+ "Files" : [
+ "../../../ecere/res/cursors/arrow.png",
+ "../../../ecere/res/cursors/cross.png",
+ "../../../ecere/res/cursors/iBeam.png",
+ "../../../ecere/res/cursors/move.png",
+ "../../../ecere/res/cursors/sizeEastWest.png",
+ "../../../ecere/res/cursors/sizeNortEastSouthWest.png",
+ "../../../ecere/res/cursors/sizeNorthSouth.png",
+ "../../../ecere/res/cursors/sizeNortWestSouthEast.png"
+ ]
+ },
+ {
+ "Folder" : "devices",
+ "Files" : [
+ "../../../ecere/res/devices/computer.png",
+ "../../../ecere/res/devices/driveHardDisk.png",
+ "../../../ecere/res/devices/driveRemovableMedia.png",
+ "../../../ecere/res/devices/mediaFloppy.png",
+ "../../../ecere/res/devices/mediaOptical.png"
+ ]
+ },
+ {
+ "Folder" : "elements",
+ "Files" : [
+ "../../../ecere/res/elements/areaClose.png",
+ "../../../ecere/res/elements/areaMaximize.png",
+ "../../../ecere/res/elements/areaMinimize.png",
+ "../../../ecere/res/elements/areaRestore.png",
+ "../../../ecere/res/elements/arrowDown.png",
+ "../../../ecere/res/elements/arrowLeft.png",
+ "../../../ecere/res/elements/arrowRight.png",
+ "../../../ecere/res/elements/arrowUp.png",
+ "../../../ecere/res/elements/checkBox.png",
+ "../../../ecere/res/elements/checkBoxChecked.png",
+ "../../../ecere/res/elements/checkBoxDisabled.png",
+ "../../../ecere/res/elements/checkBoxDisabledChecked.png",
+ "../../../ecere/res/elements/optionBoxDisabled.png",
+ "../../../ecere/res/elements/optionBoxDisabledSelected.png",
+ "../../../ecere/res/elements/optionBoxDown.png",
+ "../../../ecere/res/elements/optionBoxSelectedDown.png",
+ "../../../ecere/res/elements/optionBoxSelectedUp.png",
+ "../../../ecere/res/elements/optionBoxUp.png",
+ "../../../ecere/res/elements/orderAscending.png",
+ "../../../ecere/res/elements/orderCategorized.png",
+ "../../../ecere/res/elements/orderDescending.png"
+ ]
+ },
+ {
+ "Folder" : "emblems",
+ "Files" : [
+ "../../../ecere/res/emblems/unreadable.png"
+ ]
+ },
+ {
+ "Folder" : "mimeTypes",
+ "Files" : [
+ "../../../ecere/res/mimeTypes/brokenFile.png",
+ "../../../ecere/res/mimeTypes/file.png",
+ "../../../ecere/res/mimeTypes/image.png",
+ "../../../ecere/res/mimeTypes/package.png",
+ "../../../ecere/res/mimeTypes/packageOpticalDisc.png",
+ "../../../ecere/res/mimeTypes/packageSoftware.png",
+ "../../../ecere/res/mimeTypes/text.png",
+ "../../../ecere/res/mimeTypes/textC++Header.png",
+ "../../../ecere/res/mimeTypes/textC++Source.png",
+ "../../../ecere/res/mimeTypes/textCHeader.png",
+ "../../../ecere/res/mimeTypes/textCSource.png",
+ "../../../ecere/res/mimeTypes/textEcereHeader.png",
+ "../../../ecere/res/mimeTypes/textEcereProject.png",
+ "../../../ecere/res/mimeTypes/textEcereSource.png",
+ "../../../ecere/res/mimeTypes/textEcereWorkspace.png",
+ "../../../ecere/res/mimeTypes/textHyperTextMarkup.png"
+ ]
+ },
+ {
+ "Folder" : "places",
+ "Files" : [
+ "../../../ecere/res/places/brokenFolder.png",
+ "../../../ecere/res/places/driveRemote.png",
+ "../../../ecere/res/places/folder.png",
+ "../../../ecere/res/places/folderRemote.png",
+ "../../../ecere/res/places/networkServer.png",
+ "../../../ecere/res/places/networkWorkgroup.png"
+ ]
+ },
+ {
+ "Folder" : "status",
+ "Files" : [
+ "../../../ecere/res/status/audioVolumeHigh.png",
+ "../../../ecere/res/status/folderOpen.png"
+ ]
+ },
+ {
+ "Folder" : "unicode",
+ "Files" : [
+ "../../../ecere/res/unicode/derivedGeneralCategoryStripped.txt"
+ ]
+ },
+ {
+ "Folder" : "shaders",
+ "Files" : [
+ "../../../ecere/src/gfx/drivers/gl3/fixed.frag",
+ "../../../ecere/src/gfx/drivers/gl3/fixed.vertex"
+ ]
+ },
+ "C:/Windows/Fonts/tahoma.ttf",
+ "C:/Windows/Fonts/tahomabd.ttf"
+ ],
+ "Options" : {
+ "ExcludeFromBuild" : true
+ },
+ "Configurations" : [
+ {
+ "Name" : "Emscripten",
+ "Options" : {
+ "ExcludeFromBuild" : false
+ }
+ }
+ ]
+ },
"aboutPic.jpg",
"blackBishop.png",
"blackKing.png",
void OnRedraw(Surface surface)
{
- surface.WriteTextf(200, 30, "Copyright (c) 1996-2005");
- surface.WriteTextf(200, 50, " Jerome Jacovella-St-Louis");
+ surface.WriteTextf(200, 30, "Copyright (c) 1996-2015");
+ surface.WriteTextf(200, 50, " Jérôme Jacovella-St-Louis");
surface.WriteTextf(200, 70, "Models Copyright (c) 2004");
- surface.WriteTextf(200, 90, " Gaetan Loyer");
+ surface.WriteTextf(200, 90, " Gaétan Loyer");
}
}
void Play()
{
abortAI = false;
+#if defined(__EMSCRIPTEN__)
+ Main();
+ chess.MakeMove(aiMove.x1, aiMove.y1, aiMove.x2, aiMove.y2, aiMove.promotion);
+ aiMoveResult = false;
+#else
app.UpdateDisplay();
Create();
aiTimer.Start();
+#endif
}
void Abort()
}
}
+enum GameAction { newAIGame, newLocalGame, endGame, close, connect, host, stop };
+
+
#ifdef HIGH_DPI
define stateWidth = 300;
define turnWidth = 150;
class Chess : Window
{
background = gray, hasMenuBar = true, hasStatusBar = true,
+ fullRender = true;
text = APPNAME,
-#ifndef __ANDROID__
+#if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
hasClose = true, hasMaximize = true, hasMinimize = true,
borderStyle = sizable,
#endif
anchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
bool hosting, local, ai;
+#ifndef CHESS_NONET
Socket sockets[Player];
ChessService service { port = CHESS_PORT, chess = this };
+#endif
MenuItem * driverItems;
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- if(EndGame())
+ if(EndGame(newAIGame))
{
ai = true;
chessState.gameRunning = true;
gameMenu, "New Local Game\tCtrl+L", l, ctrlL;
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- if(EndGame())
+ if(EndGame(newLocalGame))
{
local = true;
chessState.gameRunning = true;
gameMenu, "End Game", e;
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- EndGame();
+ EndGame(endGame);
return true;
}
};
MenuItem { gameMenu, "Exit\tAlt+F4", x, NotifySelect = MenuFileExit };
+#ifndef CHESS_NONET
// Network Menu
MenuItem connectItem
{
networkMenu, "Connect...", c;
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- if(EndGame())
+ if(EndGame(connect))
{
hosting = false;
service.Stop();
- ConnectDialog { master = this }.Modal();
+ ConnectDialog { master = this, isModal = true }.Create();
}
return true;
}
networkMenu, "Host", h;
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- if(EndGame())
+ if(EndGame(host))
{
if(service.Start())
{
networkMenu, "Stop Hosting", s;
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- if(EndGame())
+ if(EndGame(stop))
{
hosting = false;
service.Stop();
return true;
}
};
+#endif
// View Menu
MenuItem fullScreenItem
helpMenu, "About...\tF1", a, f1;
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- AboutChess { master = this }.Modal();
+ AboutChess { master = this, isModal = true }.Create();
return true;
}
};
- // --- Chess Utilities ---
- bool MakeMove(int x1, int y1, int x2, int y2, PieceType promotion)
+ int cx1, cy1, cx2, cy2;
+
+ bool DoMove(int x1, int y1, int x2, int y2, PieceType promotion)
{
bool valid = false;
-
PieceType type = chessState.board[y1][x1].type;
Player player = chessState.board[y1][x1].player;
- // Pawn Promotion
- if(type == Pawn && y2 == ((player == White) ? 7 : 0))
- {
- if(chessState.isLocalPlayer[chessState.turn] &&
- IsMoveValid(x1,y1,x2,y2, chessState, null, true))
- {
- chess2D.Update(null);
- chess3D.Update(null);
- promotion = (PieceType)Promotion { master = this }.Modal();
- }
- }
-
if(StateMakeMove(chessState, x1,y1,x2,y2, promotion, true, null))
{
valid = true;
y2 = (byte)y2,
promotion = promotion
};
+#ifndef CHESS_NONET
sockets[player^(Player)1].Send((byte *)&packet, sizeof(ChessPacket));
+#endif
}
if(player == Black)
return valid;
}
+ // --- Chess Utilities ---
+ bool MakeMove(int x1, int y1, int x2, int y2, PieceType promotion)
+ {
+ bool valid = false;
+
+ PieceType type = chessState.board[y1][x1].type;
+ Player player = chessState.board[y1][x1].player;
+
+ // Pawn Promotion
+ if(type == Pawn && y2 == ((player == White) ? 7 : 0))
+ {
+ valid = true;
+ if(chessState.isLocalPlayer[chessState.turn] &&
+ (valid = IsMoveValid(x1,y1,x2,y2, chessState, null, true)))
+ {
+ valid = false;
+ cx1 = x1, cy1 = y1, cx2 = x2, cy2 = y2;
+ chess2D.Update(null);
+ chess3D.Update(null);
+ promotion = (PieceType)Promotion
+ {
+ master = this;
+ isModal = true;
+
+ void Chess::NotifyDestroyed(Window promotionDlg, DialogResult r)
+ {
+ DoMove(cx1, cy1, cx2, cy2, (PieceType)r);
+ if(ai)
+ aiThread.Play();
+ }
+ }.Create();
+ }
+ }
+ else
+ valid = DoMove(x1, y1, x2, y2, promotion);
+ return valid;
+ }
+
void ProcessUserMove(int x1, int y1, int x2, int y2)
{
if(MakeMove(x1, y1, x2, y2, 0))
void EnableMenus()
{
+#ifndef CHESS_NONET
stopItem.disabled = !hosting;
disconnectItem.disabled = !sockets[SERVER_COLOR] && !sockets[CLIENT_COLOR];
- endGameItem.disabled = !chessState.gameRunning;
hostItem.disabled = hosting;
+#endif
+ endGameItem.disabled = !chessState.gameRunning;
}
void SetDriver()
return true;
}
- bool EndGame()
+ void DoEndGame(GameAction action)
{
- if(chessState.gameRunning &&
- (chessState.state == Normal || chessState.state == Check))
- {
- if(MessageBox { type = okCancel, contents = "Quit current game?",
- master = this, text = "ECERE Chess" }.Modal() == cancel)
- return false;
- }
+#ifndef CHESS_NONET
if(sockets[SERVER_COLOR])
sockets[SERVER_COLOR].Disconnect(0);
else if(sockets[CLIENT_COLOR])
sockets[CLIENT_COLOR].Disconnect(0);
- else if(local || ai)
+ else
+#endif
+ if(local || ai)
{
if(ai) aiThread.Abort();
local = ai = false;
turnField.text = "";
stateField.text = "";
+ switch(action)
+ {
+ case newAIGame: aiItem.NotifySelect(this, aiItem, 0); break;
+ case newLocalGame: localItem.NotifySelect(this, localItem, 0); break;
+ }
+ }
+
+ GameAction nextAction;
+
+ bool EndGame(GameAction action)
+ {
+ if(chessState.gameRunning &&
+ (chessState.state == Normal || chessState.state == Check))
+ {
+ nextAction = action;
+ MessageBox
+ {
+ type = okCancel, contents = "Quit current game?",
+ master = this, text = "ECERE Chess";
+ isModal = true;
+
+ void Chess::NotifyDestroyed(Window msgBox, DialogResult result)
+ {
+ if(result != cancel)
+ DoEndGame(nextAction);
+ }
+ }.Create();
+ return false;
+ }
return true;
}
bool OnClose(bool parentClosing)
{
- return EndGame();
+ return EndGame(close);
}
void OnDestroy()
{
+#ifndef CHESS_NONET
delete sockets[Black];
delete sockets[White];
+#endif
delete driverItems;
}
+#ifndef CHESS_NONET
void Connect(const char * address)
{
ChessSocket socket { chess = this };
chessState.isLocalPlayer[SERVER_COLOR] = false;
}
}
+#endif
}
// --- Chess Communications ---
+#ifndef CHESS_NONET
class ChessSocket : Socket
{
Chess chess;
}
}
}
+#endif
void OnRedraw(Surface surface)
{
- //surface.SetBackground(white);
- surface.Clear(colorAndDepth);
+ surface.Clear(depthBuffer);
camera.Update();
display.antiAlias = antiAlias;
import "chess.ec"
+#ifndef CHESS_NONET
class ConnectDialog : Window
{
minClientSize = Size { 300, 100 };
line.text = "localhost"
};
}
+#endif
}
}
]
+ },
+ {
+ "Name" : "Emscripten",
+ "Options" : {
+ "Optimization" : "Speed",
+ "PreprocessorDefinitions" : [
+ "IMPORT_STATIC=static"
+ ],
+ "TargetFileName" : "mekano.html",
+ "Libraries" : [
+ "ecereStatic",
+ "z",
+ "freetype",
+ "png",
+ "jpeg"
+ ],
+ "LibraryDirs" : [
+ "../../../ecere/obj/emscripten.linux.emscripten"
+ ],
+ "FastMath" : true
+ }
}
],
"Files" : [
import "mekanodisplay"
-class MekanoSimulation
+class MekanoSimulation : struct
{
private:
List<MekanoObject> m_Objects { };
public:
caption = "Mekano";
+#if defined(__EMSCRIPTEN__) || defined(__ANDROID__)
+ anchor = { 0, 0, 0, 0 };
+#else
+ clientSize = { 640, 480 };
hasMaximize = true, hasMinimize = true, hasClose = true;
borderStyle = sizable;
- clientSize = { 640, 480 };
+#endif
background = slateGray;
BitmapResource bg { ":ecere.bmp", window = this };