diff --git a/CHANGELOG.md b/CHANGELOG.md index dfe39f482..308bab168 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +2.3.3 (04/21/2015) +------------------ + +* Added audioSource.loops, audioSource.offset, audioSource.length +* Renamed audioSource.timeOffset to audioSource.currentTime +* Fixed onComplete for AudioSource instances +* Fixed support for embedded bytes on HTML5 +* Fixed support for hardware anti-aliasing on SDL2 targets +* Fixed some loose file handles in the format decoders +* Fixed a possible crash in copyPixels +* Improved accuracy of URLLoader progress + + 2.3.2 (04/15/2015) ------------------ diff --git a/haxelib.json b/haxelib.json index cb15392f7..dd81bb5d8 100644 --- a/haxelib.json +++ b/haxelib.json @@ -4,7 +4,7 @@ "license": "MIT", "tags": [], "description": "A flexible lightweight layer for Haxe cross-platform developers", - "version": "2.3.2", - "releasenote": "Improved Image performance, improved Windows 10 support, fixes", + "version": "2.3.3", + "releasenote": "AudioSource improvements, other fixes", "contributors": [ "singmajesty" ] } diff --git a/lime/Assets.hx b/lime/Assets.hx index 58ec5a076..0182aa001 100644 --- a/lime/Assets.hx +++ b/lime/Assets.hx @@ -1286,7 +1286,10 @@ class Assets { case EConst(CString(filePath)): - var path = Context.resolvePath (filePath); + var path = filePath; + if (!sys.FileSystem.exists(filePath)) { + path = Context.resolvePath (filePath); + } var bytes = File.getBytes (path); var resourceName = "__ASSET__" + metaName + "_" + (classType.pack.length > 0 ? classType.pack.join ("_") + "_" : "") + classType.name; @@ -1382,7 +1385,10 @@ class Assets { case EConst(CString(filePath)): - path = Context.resolvePath (filePath); + path = filePath; + if (!sys.FileSystem.exists(filePath)) { + path = Context.resolvePath (filePath); + } default: diff --git a/lime/_backend/flash/FlashApplication.hx b/lime/_backend/flash/FlashApplication.hx index c407442e6..7488b6795 100644 --- a/lime/_backend/flash/FlashApplication.hx +++ b/lime/_backend/flash/FlashApplication.hx @@ -25,6 +25,7 @@ class FlashApplication { private var cacheTime:Int; + private var mouseLeft:Bool; private var parent:Application; @@ -138,6 +139,7 @@ class FlashApplication { Lib.current.stage.addEventListener (Event.DEACTIVATE, handleWindowEvent); Lib.current.stage.addEventListener (FocusEvent.FOCUS_IN, handleWindowEvent); Lib.current.stage.addEventListener (FocusEvent.FOCUS_OUT, handleWindowEvent); + Lib.current.stage.addEventListener (Event.MOUSE_LEAVE, handleWindowEvent); Lib.current.stage.addEventListener (Event.RESIZE, handleWindowEvent); cacheTime = Lib.getTimer (); @@ -192,6 +194,13 @@ class FlashApplication { case "mouseMove": + if (mouseLeft) { + + mouseLeft = false; + parent.window.onWindowEnter.dispatch (); + + } + parent.window.onMouseMove.dispatch (event.stageX, event.stageY); case "mouseUp", "middleMouseUp", "rightMouseUp": @@ -280,6 +289,11 @@ class FlashApplication { parent.window.onWindowFocusOut.dispatch (); + case Event.MOUSE_LEAVE: + + mouseLeft = true; + parent.window.onWindowLeave.dispatch (); + default: parent.window.width = Lib.current.stage.stageWidth; diff --git a/lime/_backend/html5/HTML5Application.hx b/lime/_backend/html5/HTML5Application.hx index 20acf56fc..0af060c6e 100644 --- a/lime/_backend/html5/HTML5Application.hx +++ b/lime/_backend/html5/HTML5Application.hx @@ -156,11 +156,11 @@ class HTML5Application { // space and arrow keys - switch (event.keyCode) { - - case 32, 37, 38, 39, 40: event.preventDefault (); - - } + //switch (event.keyCode) { + // + //case 32, 37, 38, 39, 40: event.preventDefault (); + // + //} var keyCode = cast convertKeyCode (event.keyCode != null ? event.keyCode : event.which); var modifier = (event.shiftKey ? (KeyModifier.SHIFT) : 0) | (event.ctrlKey ? (KeyModifier.CTRL) : 0) | (event.altKey ? (KeyModifier.ALT) : 0) | (event.metaKey ? (KeyModifier.META) : 0); diff --git a/lime/_backend/html5/HTML5Window.hx b/lime/_backend/html5/HTML5Window.hx index 101bea46f..6cae8c737 100644 --- a/lime/_backend/html5/HTML5Window.hx +++ b/lime/_backend/html5/HTML5Window.hx @@ -140,7 +140,7 @@ class HTML5Window { } - var events = [ "mousedown", "mousemove", "mouseup", "wheel" ]; + var events = [ "mousedown", "mouseenter", "mouseleave", "mousemove", "mouseup", "wheel" ]; for (event in events) { @@ -210,6 +210,14 @@ class HTML5Window { parent.onMouseDown.dispatch (x, y, event.button); + case "mouseenter": + + parent.onWindowEnter.dispatch (); + + case "mouseleave": + + parent.onWindowLeave.dispatch (); + case "mouseup": parent.onMouseUp.dispatch (x, y, event.button); diff --git a/lime/_backend/native/NativeApplication.hx b/lime/_backend/native/NativeApplication.hx index 4ab68db87..1b86c4f1e 100644 --- a/lime/_backend/native/NativeApplication.hx +++ b/lime/_backend/native/NativeApplication.hx @@ -287,6 +287,10 @@ class NativeApplication { parent.window.onWindowDeactivate.dispatch (); + case WINDOW_ENTER: + + parent.window.onWindowEnter.dispatch (); + case WINDOW_FOCUS_IN: parent.window.onWindowFocusIn.dispatch (); @@ -295,6 +299,10 @@ class NativeApplication { parent.window.onWindowFocusOut.dispatch (); + case WINDOW_LEAVE: + + parent.window.onWindowLeave.dispatch (); + case WINDOW_MINIMIZE: parent.window.__minimized = true; @@ -650,11 +658,13 @@ private class WindowEventInfo { var WINDOW_ACTIVATE = 0; var WINDOW_CLOSE = 1; var WINDOW_DEACTIVATE = 2; - var WINDOW_FOCUS_IN = 3; - var WINDOW_FOCUS_OUT = 4; - var WINDOW_MINIMIZE = 5; - var WINDOW_MOVE = 6; - var WINDOW_RESIZE = 7; - var WINDOW_RESTORE = 8; + var WINDOW_ENTER = 3; + var WINDOW_FOCUS_IN = 4; + var WINDOW_FOCUS_OUT = 5; + var WINDOW_LEAVE = 6; + var WINDOW_MINIMIZE = 7; + var WINDOW_MOVE = 8; + var WINDOW_RESIZE = 9; + var WINDOW_RESTORE = 10; } \ No newline at end of file diff --git a/lime/app/Application.hx b/lime/app/Application.hx index 90d455be0..9fa4dad85 100644 --- a/lime/app/Application.hx +++ b/lime/app/Application.hx @@ -119,9 +119,11 @@ class Application extends Module { window.onWindowActivate.add (onWindowActivate); window.onWindowClose.add (onWindowClose); window.onWindowDeactivate.add (onWindowDeactivate); + window.onWindowEnter.add (onWindowEnter); window.onWindowFocusIn.add (onWindowFocusIn); window.onWindowFocusOut.add (onWindowFocusOut); window.onWindowFullscreen.add (onWindowFullscreen); + window.onWindowLeave.add (onWindowLeave); window.onWindowMinimize.add (onWindowMinimize); window.onWindowMove.add (onWindowMove); window.onWindowResize.add (onWindowResize); @@ -393,6 +395,17 @@ class Application extends Module { } + public override function onWindowEnter ():Void { + + for (module in modules) { + + module.onWindowEnter (); + + } + + } + + public override function onWindowFocusIn ():Void { for (module in modules) { @@ -426,6 +439,17 @@ class Application extends Module { } + public override function onWindowLeave ():Void { + + for (module in modules) { + + module.onWindowLeave (); + + } + + } + + public override function onWindowMinimize ():Void { for (module in modules) { diff --git a/lime/app/IModule.hx b/lime/app/IModule.hx index 5b26d41f2..4627999ae 100644 --- a/lime/app/IModule.hx +++ b/lime/app/IModule.hx @@ -178,6 +178,12 @@ interface IModule { public function onWindowDeactivate ():Void; + /** + * Called when a window enter event is fired + */ + public function onWindowEnter ():Void; + + /** * Called when a window focus in event is fired */ @@ -196,6 +202,12 @@ interface IModule { public function onWindowFullscreen ():Void; + /** + * Called when a window leave event is fired + */ + public function onWindowLeave ():Void; + + /** * Called when a window move event is fired * @param x The x position of the window diff --git a/lime/app/Module.hx b/lime/app/Module.hx index 05573667c..88b469fad 100644 --- a/lime/app/Module.hx +++ b/lime/app/Module.hx @@ -153,6 +153,12 @@ class Module implements IModule { public function onWindowDeactivate ():Void { } + /** + * Called when a window enter event is fired + */ + public function onWindowEnter ():Void { } + + /** * Called when a window focus in event is fired */ @@ -165,7 +171,21 @@ class Module implements IModule { public function onWindowFocusOut ():Void { } + /** + * Called when a window fullscreen event is fired + */ public function onWindowFullscreen ():Void { } + + + /** + * Called when a mouse leave event is fired + */ + public function onWindowLeave ():Void { } + + + /** + * Called when a window minimize event is fired + */ public function onWindowMinimize ():Void { } diff --git a/lime/audio/AudioSource.hx b/lime/audio/AudioSource.hx index 5e6626c67..4101b7858 100644 --- a/lime/audio/AudioSource.hx +++ b/lime/audio/AudioSource.hx @@ -35,7 +35,7 @@ class AudioSource { private var channel:Channel; #end - #if (cpp || neko) + #if (cpp || neko || nodejs) private var timer:Timer; #end diff --git a/lime/graphics/Image.hx b/lime/graphics/Image.hx index 5e90d5fb4..a2db73263 100644 --- a/lime/graphics/Image.hx +++ b/lime/graphics/Image.hx @@ -249,15 +249,41 @@ class Image { public function copyPixels (sourceImage:Image, sourceRect:Rectangle, destPoint:Vector2, alphaImage:Image = null, alphaPoint:Vector2 = null, mergeAlpha:Bool = false):Void { + //fast fails -- if source or destination is null or of 0 dimensions, do nothing if (buffer == null || sourceImage == null) return; + if (sourceRect.width <= 0 || sourceRect.height <= 0) return; + if (width <= 0 || height <= 0) return; + //source rect expands too far right or too far below source image boundaries if (sourceRect.x + sourceRect.width > sourceImage.width) sourceRect.width = sourceImage.width - sourceRect.x; if (sourceRect.y + sourceRect.height > sourceImage.height) sourceRect.height = sourceImage.height - sourceRect.y; - if (sourceRect.width <= 0 || sourceRect.height <= 0) return; + //source rect starts too far left or too far above source image boundaries + if (sourceRect.x < 0) { + sourceRect.width += sourceRect.x; //shrink width by amount off canvas + sourceRect.x = 0; //clamp rect to 0 + } + if (sourceRect.y < 0) { + sourceRect.height += sourceRect.y; //shrink height by amount off canvas + sourceRect.y = 0; //clamp rect to 0 + } + + //draw area expands too far right or too far below destination image boundaries if (destPoint.x + sourceRect.width > width) sourceRect.width = width - destPoint.x; if (destPoint.y + sourceRect.height > height) sourceRect.height = height - destPoint.y; + //draw area starts too far left or too far above destination image boundaries + if (destPoint.x < 0) { + sourceRect.width += destPoint.x; //shrink width by amount off canvas + sourceRect.x = -destPoint.x; //adjust source rect to effective starting point + destPoint.x = 0; //clamp destination point to 0 + } + if (destPoint.y < 0) { + sourceRect.height += destPoint.y; //shrink height by amount off canvas + sourceRect.y = -destPoint.y; //adjust source rect to effective starting point + destPoint.y = 0; //clamp destination point to 0 + } + switch (type) { case CANVAS: @@ -387,6 +413,7 @@ class Image { public static function fromBase64 (base64:String, type:String, onload:Image -> Void):Image { + if (base64 == null) return null; var image = new Image (); image.__fromBase64 (base64, type, onload); return image; @@ -396,6 +423,7 @@ class Image { public static function fromBitmapData (bitmapData:#if flash BitmapData #else Dynamic #end):Image { + if (bitmapData == null) return null; var buffer = new ImageBuffer (null, bitmapData.width, bitmapData.height); buffer.__srcBitmapData = bitmapData; return new Image (buffer); @@ -405,6 +433,7 @@ class Image { public static function fromBytes (bytes:ByteArray, onload:Image -> Void = null):Image { + if (bytes == null) return null; var image = new Image (); image.__fromBytes (bytes, onload); return image; @@ -414,6 +443,7 @@ class Image { public static function fromCanvas (canvas:#if (js && html5) CanvasElement #else Dynamic #end):Image { + if (canvas == null) return null; var buffer = new ImageBuffer (null, canvas.width, canvas.height); buffer.src = canvas; return new Image (buffer); @@ -432,12 +462,42 @@ class Image { public static function fromImageElement (image:#if (js && html5) ImageElement #else Dynamic #end):Image { + if (image == null) return null; var buffer = new ImageBuffer (null, image.width, image.height); buffer.src = image; return new Image (buffer); } + public function getColorBoundsRect (mask:Int, color:Int, findColor:Bool = true, format:PixelFormat = null):Rectangle { + + if (buffer == null) return null; + + switch (type) { + + case CANVAS: + + #if (js && html5) + ImageCanvasUtil.convertToData (this); + #end + + return ImageDataUtil.getColorBoundsRect (this, mask, color, findColor, format); + + case DATA: + + return ImageDataUtil.getColorBoundsRect (this, mask, color, findColor, format); + + case FLASH: + + var rect = buffer.__srcBitmapData.getColorBoundsRect (mask, color, findColor); + return new Rectangle (rect.x, rect.y, rect.width, rect.height); + + default: + + return null; + } + + } public function getPixel (x:Int, y:Int, format:PixelFormat = null):Int { @@ -1270,6 +1330,7 @@ class Image { private function get_transparent ():Bool { + if (buffer == null) return false; return buffer.transparent; } @@ -1278,7 +1339,7 @@ class Image { private function set_transparent (value:Bool):Bool { // TODO, modify data to set transparency - + if (buffer == null) return false; return buffer.transparent = value; } diff --git a/lime/graphics/utils/ImageDataUtil.hx b/lime/graphics/utils/ImageDataUtil.hx index 71cb6e777..94fffae68 100644 --- a/lime/graphics/utils/ImageDataUtil.hx +++ b/lime/graphics/utils/ImageDataUtil.hx @@ -228,6 +228,8 @@ class ImageDataUtil { } else { var sourceAlpha:Float; + var destAlpha:Float; + var outA:Float; var oneMinusSourceAlpha:Float; for (row in Std.int (sourceRect.top + sourceImage.offsetY)...Std.int (sourceRect.bottom + sourceImage.offsetY)) { @@ -237,13 +239,16 @@ class ImageDataUtil { sourceOffset = (row * sourceStride) + (column * 4); offset = ((row + rowOffset) * stride) + ((column + columnOffset) * 4); - sourceAlpha = sourceData[sourceOffset + 3] / 255; + sourceAlpha = sourceData[sourceOffset + 3] / 255.0; + destAlpha = data[offset + 3] / 255.0; oneMinusSourceAlpha = (1 - sourceAlpha); - data[offset] = __clamp[Std.int (sourceData[sourceOffset] + (data[offset] * oneMinusSourceAlpha))]; - data[offset + 1] = __clamp[Std.int (sourceData[sourceOffset + 1] + (data[offset + 1] * oneMinusSourceAlpha))]; - data[offset + 2] = __clamp[Std.int (sourceData[sourceOffset + 2] + (data[offset + 2] * oneMinusSourceAlpha))]; - data[offset + 3] = __clamp[Std.int (sourceData[sourceOffset + 3] + (data[offset + 3] * oneMinusSourceAlpha))]; + outA = sourceAlpha + destAlpha * oneMinusSourceAlpha; + data[offset + 0] = __clamp[Math.round ((sourceData[sourceOffset + 0] * sourceAlpha + data[offset + 0] * destAlpha * oneMinusSourceAlpha) / outA)]; + data[offset + 1] = __clamp[Math.round ((sourceData[sourceOffset + 1] * sourceAlpha + data[offset + 1] * destAlpha * oneMinusSourceAlpha) / outA)]; + data[offset + 2] = __clamp[Math.round ((sourceData[sourceOffset + 2] * sourceAlpha + data[offset + 2] * destAlpha * oneMinusSourceAlpha) / outA)]; + data[offset + 3] = __clamp[Math.round (outA * 255.0)]; + } @@ -424,6 +429,173 @@ class ImageDataUtil { } + public static function getColorBoundsRect (image:Image, mask:Int, color:Int, findColor:Bool = true, format:PixelFormat):Rectangle { + + var left:Int = image.width + 1; + var right:Int = 0; + var top:Int = image.height + 1; + var bottom:Int = 0; + + var r, g, b, a; + var mr, mg, mb, ma; + + if (format == ARGB) { + + a = (image.transparent) ? (color >> 24) & 0xFF : 0xFF; + r = (color >> 16) & 0xFF; + g = (color >> 8) & 0xFF; + b = color & 0xFF; + + ma = (image.transparent) ? (mask >> 24) & 0xFF : 0xFF; + mr = (mask >> 16) & 0xFF; + mg = (mask >> 8) & 0xFF; + mb = mask & 0xFF; + + } else { + + r = (color >> 24) & 0xFF; + g = (color >> 16) & 0xFF; + b = (color >> 8) & 0xFF; + a = (image.transparent) ? color & 0xFF : 0xFF; + + mr = (mask >> 24) & 0xFF; + mg = (mask >> 16) & 0xFF; + mb = (mask >> 8) & 0xFF; + ma = (image.transparent) ? mask & 0xFF : 0xFF; + + } + + color = (r | (g << 8) | (b << 16) | (a << 24)); + mask = (mr | (mg << 8) | (mb << 16) | (mask << 24)); + + var pix:Int; + + for (ix in 0...image.width) { + + var hit = false; + + for (iy in 0...image.height) { + + pix = image.getPixel32 (ix, iy); + hit = findColor ? (pix & mask) == color : (pix & mask) != color; + + if (hit) { + + if (ix < left) left = ix; + break; + + } + + } + + if (hit) { + + break; + + } + + } + + for (_ix in 0...image.width) { + + var ix = (image.width - 1) - _ix; + var hit = false; + + for (iy in 0...image.height) { + + pix = image.getPixel32 (ix, iy); + hit = findColor ? (pix & mask) == color : (pix & mask) != color; + + if (hit) { + + if (ix > right) right = ix; + break; + + } + + } + + if (hit) { + + break; + + } + + } + + for (iy in 0...image.height) { + + var hit = false; + + for (ix in 0...image.width) { + + pix = image.getPixel32 (ix, iy); + hit = findColor ? (pix & mask) == color : (pix & mask) != color; + + if (hit) { + + if (iy < top) top = iy; + break; + + } + + } + + if (hit) { + + break; + + } + + } + + for (_iy in 0...image.height) { + + var iy = (image.height - 1) - _iy; + var hit = false; + + for (ix in 0...image.width) { + + pix = image.getPixel32 (ix, iy); + hit = findColor ? (pix & mask) == color : (pix & mask) != color; + + if (hit) { + + if (iy > bottom) bottom = iy; + break; + + } + + } + + if (hit) { + + break; + + } + + } + + var w = right - left; + var h = bottom - top; + + if (w > 0) w++; + if (h > 0) h++; + + if (w < 0) w = 0; + if (h < 0) h = 0; + + if (left == right) w = 1; + if (top == bottom) h = 1; + + if (left > image.width) left = 0; + if (top > image.height) top = 0; + + return new Rectangle (left, top, w, h); + + } + + public static function getPixel (image:Image, x:Int, y:Int, format:PixelFormat):Int { var data = image.buffer.data; diff --git a/lime/ui/Window.hx b/lime/ui/Window.hx index efb4b3dd0..637d01871 100644 --- a/lime/ui/Window.hx +++ b/lime/ui/Window.hx @@ -34,9 +34,11 @@ class Window { public var onWindowActivate = new EventVoid> (); public var onWindowClose = new EventVoid> (); public var onWindowDeactivate = new EventVoid> (); + public var onWindowEnter = new EventVoid> (); public var onWindowFocusIn = new EventVoid> (); public var onWindowFocusOut = new EventVoid> (); public var onWindowFullscreen = new EventVoid> (); + public var onWindowLeave = new EventVoid> (); public var onWindowMinimize = new EventVoid> (); public var onWindowMove = new EventFloat->Void> (); public var onWindowResize = new EventInt->Void> (); diff --git a/project/Build.xml b/project/Build.xml index 01a5864c5..34d3135a5 100644 --- a/project/Build.xml +++ b/project/Build.xml @@ -28,9 +28,11 @@ + + + - @@ -141,6 +143,7 @@ + diff --git a/project/include/graphics/ImageBuffer.h b/project/include/graphics/ImageBuffer.h index d6ddf291f..6e6e0ecfd 100644 --- a/project/include/graphics/ImageBuffer.h +++ b/project/include/graphics/ImageBuffer.h @@ -26,6 +26,7 @@ namespace lime { ByteArray *data; int height; int width; + bool transparent; private: diff --git a/project/include/ui/WindowEvent.h b/project/include/ui/WindowEvent.h index 34ee8db1d..a96b33fcc 100644 --- a/project/include/ui/WindowEvent.h +++ b/project/include/ui/WindowEvent.h @@ -13,12 +13,14 @@ namespace lime { WINDOW_ACTIVATE, WINDOW_CLOSE, WINDOW_DEACTIVATE, + WINDOW_ENTER, WINDOW_FOCUS_IN, WINDOW_FOCUS_OUT, + WINDOW_LEAVE, WINDOW_MINIMIZE, WINDOW_MOVE, WINDOW_RESIZE, - WINDOW_RESTORE + WINDOW_RESTORE, }; diff --git a/project/lib/sdl b/project/lib/sdl index 47e23f265..c40b7c2e0 160000 --- a/project/lib/sdl +++ b/project/lib/sdl @@ -1 +1 @@ -Subproject commit 47e23f2659d729c16af96b91f6fe733e6f917ca0 +Subproject commit c40b7c2e076a2e74e0c3c3d754ac4b9343988b98 diff --git a/project/src/audio/format/OGG.cpp b/project/src/audio/format/OGG.cpp index ecedc639a..756e7c2af 100644 --- a/project/src/audio/format/OGG.cpp +++ b/project/src/audio/format/OGG.cpp @@ -120,10 +120,16 @@ namespace lime { if (file->isFile ()) { - ov_open (file->getFile (), &oggFile, NULL, file->getLength ()); + if (ov_open (file->getFile (), &oggFile, NULL, file->getLength ()) != 0) { + + lime::fclose (file); + return false; + + } } else { + lime::fclose (file); ByteArray data = ByteArray (resource->path); OAL_OggMemoryFile fakeFile = { data.Bytes (), data.Size (), 0 }; @@ -166,6 +172,7 @@ namespace lime { if (pInfo == NULL) { //LOG_SOUND("FAILED TO READ OGG SOUND INFO, IS THIS EVEN AN OGG FILE?\n"); + ov_clear (&oggFile); return false; } diff --git a/project/src/audio/format/WAV.cpp b/project/src/audio/format/WAV.cpp index 71c3c068b..2afe61877 100644 --- a/project/src/audio/format/WAV.cpp +++ b/project/src/audio/format/WAV.cpp @@ -73,6 +73,7 @@ namespace lime { if ((riff_header.chunkID[0] != 'R' || riff_header.chunkID[1] != 'I' || riff_header.chunkID[2] != 'F' || riff_header.chunkID[3] != 'F') || (riff_header.format[0] != 'W' || riff_header.format[1] != 'A' || riff_header.format[2] != 'V' || riff_header.format[3] != 'E')) { //LOG_SOUND ("Invalid RIFF or WAVE Header!\n"); + lime::fclose (file); return false; } @@ -88,13 +89,14 @@ namespace lime { if (result != 1) { LOG_SOUND ("Invalid Wave Format!\n"); + lime::fclose (file); return false; } if (wave_format.subChunkID[0] != 'f' || wave_format.subChunkID[1] != 'm' || wave_format.subChunkID[2] != 't' || wave_format.subChunkID[3] != ' ') { - lime::fseek (file, wave_data.subChunkSize, SEEK_CUR); + lime::fseek (file, wave_format.subChunkSize, SEEK_CUR); } else { @@ -104,11 +106,11 @@ namespace lime { } - if (wave_format.subChunkSize > 16) { - - lime::fseek (file, sizeof (short), SEEK_CUR); - - } + //if (wave_format.subChunkSize > 16) { + // + //lime::fseek (file, sizeof (short), SEEK_CUR); + // + //} bool foundData = false; @@ -120,6 +122,7 @@ namespace lime { if (result != 1) { LOG_SOUND ("Invalid Wav Data Header!\n"); + lime::fclose (file); return false; } @@ -141,6 +144,7 @@ namespace lime { if (!lime::fread (audioBuffer->data->Bytes (), wave_data.subChunkSize, 1, file)) { LOG_SOUND ("error loading WAVE data into struct!\n"); + lime::fclose (file); return false; } diff --git a/project/src/backend/sdl/SDLApplication.cpp b/project/src/backend/sdl/SDLApplication.cpp index 3f55c091a..25a153bb7 100644 --- a/project/src/backend/sdl/SDLApplication.cpp +++ b/project/src/backend/sdl/SDLApplication.cpp @@ -149,6 +149,8 @@ namespace lime { switch (event->window.event) { + case SDL_WINDOWEVENT_ENTER: + case SDL_WINDOWEVENT_LEAVE: case SDL_WINDOWEVENT_SHOWN: case SDL_WINDOWEVENT_HIDDEN: case SDL_WINDOWEVENT_FOCUS_GAINED: @@ -351,8 +353,10 @@ namespace lime { case SDL_WINDOWEVENT_SHOWN: windowEvent.type = WINDOW_ACTIVATE; break; case SDL_WINDOWEVENT_CLOSE: windowEvent.type = WINDOW_CLOSE; break; case SDL_WINDOWEVENT_HIDDEN: windowEvent.type = WINDOW_DEACTIVATE; break; + case SDL_WINDOWEVENT_ENTER: windowEvent.type = WINDOW_ENTER; break; case SDL_WINDOWEVENT_FOCUS_GAINED: windowEvent.type = WINDOW_FOCUS_IN; break; case SDL_WINDOWEVENT_FOCUS_LOST: windowEvent.type = WINDOW_FOCUS_OUT; break; + case SDL_WINDOWEVENT_LEAVE: windowEvent.type = WINDOW_LEAVE; break; case SDL_WINDOWEVENT_MINIMIZED: windowEvent.type = WINDOW_MINIMIZE; break; case SDL_WINDOWEVENT_MOVED: diff --git a/project/src/backend/sdl/SDLWindow.cpp b/project/src/backend/sdl/SDLWindow.cpp index 81baefb13..068d6d47c 100644 --- a/project/src/backend/sdl/SDLWindow.cpp +++ b/project/src/backend/sdl/SDLWindow.cpp @@ -22,6 +22,15 @@ namespace lime { if (flags & WINDOW_FLAG_RESIZABLE) sdlFlags |= SDL_WINDOW_RESIZABLE; if (flags & WINDOW_FLAG_BORDERLESS) sdlFlags |= SDL_WINDOW_BORDERLESS; + #if defined (HX_WINDOWS) && defined (NATIVE_TOOLKIT_SDL_ANGLE) + + SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_SetHint (SDL_HINT_VIDEO_WIN_D3DCOMPILER, "d3dcompiler_47.dll"); + + #endif + if (flags & WINDOW_FLAG_DEPTH_BUFFER) { SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 32 - (flags & WINDOW_FLAG_STENCIL_BUFFER) ? 8 : 0); diff --git a/project/src/graphics/Image.cpp b/project/src/graphics/Image.cpp index 4a84bffb4..3ad8692db 100644 --- a/project/src/graphics/Image.cpp +++ b/project/src/graphics/Image.cpp @@ -44,7 +44,7 @@ namespace lime { buffer = new ImageBuffer (val_field (image, id_buffer)); offsetX = val_int (val_field (image, id_offsetX)); offsetY = val_int (val_field (image, id_offsetY)); - transparent = val_int (val_field (image, id_transparent)); + transparent = val_bool (val_field (image, id_transparent)); } diff --git a/project/src/graphics/ImageBuffer.cpp b/project/src/graphics/ImageBuffer.cpp index 2f95b52b2..4f6c179ce 100644 --- a/project/src/graphics/ImageBuffer.cpp +++ b/project/src/graphics/ImageBuffer.cpp @@ -10,6 +10,7 @@ namespace lime { static int id_data; static int id_height; static int id_width; + static int id_transparent; static bool init = false; @@ -19,6 +20,7 @@ namespace lime { height = 0; bpp = 4; data = 0; + transparent = false; } @@ -29,6 +31,7 @@ namespace lime { id_bpp = val_id ("bpp"); id_bitsPerPixel = val_id ("bitsPerPixel"); + id_transparent = val_id ("transparent"); id_buffer = val_id ("buffer"); id_width = val_id ("width"); id_height = val_id ("height"); @@ -40,6 +43,7 @@ namespace lime { width = val_int (val_field (imageBuffer, id_width)); height = val_int (val_field (imageBuffer, id_height)); bpp = val_int (val_field (imageBuffer, id_bitsPerPixel)); + transparent = val_bool (val_field (imageBuffer, id_transparent)); value data_value = val_field (imageBuffer, id_data); value buffer_value = val_field (data_value, id_buffer); @@ -94,6 +98,7 @@ namespace lime { id_bpp = val_id ("bpp"); id_bitsPerPixel = val_id ("bitsPerPixel"); + id_transparent = val_id ("transparent"); id_buffer = val_id ("buffer"); id_width = val_id ("width"); id_height = val_id ("height"); @@ -106,6 +111,7 @@ namespace lime { alloc_field (mValue, id_width, alloc_int (width)); alloc_field (mValue, id_height, alloc_int (height)); alloc_field (mValue, id_bpp, alloc_int (bpp)); + alloc_field (mValue, id_transparent, alloc_bool (transparent)); alloc_field (mValue, id_data, data->mValue); return mValue; diff --git a/project/src/graphics/format/PNG.cpp b/project/src/graphics/format/PNG.cpp index 1dd707f38..503f5e2a8 100644 --- a/project/src/graphics/format/PNG.cpp +++ b/project/src/graphics/format/PNG.cpp @@ -201,6 +201,8 @@ namespace lime { png_read_end (png_ptr, NULL); png_destroy_read_struct (&png_ptr, &info_ptr, (png_infopp)NULL); + if (file) lime::fclose (file); + return true; } diff --git a/project/src/graphics/opengl/OpenGL.h b/project/src/graphics/opengl/OpenGL.h index 95a830f95..cbc5c1395 100644 --- a/project/src/graphics/opengl/OpenGL.h +++ b/project/src/graphics/opengl/OpenGL.h @@ -60,6 +60,7 @@ #include typedef ptrdiff_t GLsizeiptrARB; #define NEED_EXTENSIONS +#define DYNAMIC_OGL #include #include diff --git a/project/src/graphics/opengl/OpenGLExtensions.h b/project/src/graphics/opengl/OpenGLExtensions.h index 7f78a5d24..3dbb07a75 100644 --- a/project/src/graphics/opengl/OpenGLExtensions.h +++ b/project/src/graphics/opengl/OpenGLExtensions.h @@ -12,6 +12,10 @@ #include "OpenGLBindings.h" +#ifdef LIME_SDL +#include +#endif + #ifdef DECLARE_EXTENSION @@ -27,7 +31,14 @@ #elif defined(GET_EXTENSION) -#ifdef HX_WINDOWS +#ifdef LIME_SDL + #define OGL_EXT(func,ret,args) \ + {\ + *(void **)&lime::func = (void *)SDL_GL_GetProcAddress(#func);\ + if (!func) \ + *(void **)&lime::func = (void *)SDL_GL_GetProcAddress(#func "ARB");\ + } +#elif HX_WINDOWS #define OGL_EXT(func,ret,args) \ {\ *(void **)&lime::func = (void *)wglGetProcAddress(#func);\ diff --git a/project/src/graphics/utils/ImageDataUtil.cpp b/project/src/graphics/utils/ImageDataUtil.cpp index 3a663ea82..70863675a 100644 --- a/project/src/graphics/utils/ImageDataUtil.cpp +++ b/project/src/graphics/utils/ImageDataUtil.cpp @@ -141,7 +141,7 @@ namespace lime { int rows = sourceRect->y + sourceRect->height + sourceImage->offsetY; int columns = sourceRect->x + sourceRect->width + sourceImage->offsetX; - if (!mergeAlpha || !sourceImage->transparent) { + if (!mergeAlpha || !sourceImage->buffer->transparent) { for (int row = sourceRect->y + sourceImage->offsetY; row < rows; row++) { @@ -162,6 +162,8 @@ namespace lime { } else { float sourceAlpha; + float destAlpha; + float outA; float oneMinusSourceAlpha; for (int row = sourceRect->y + sourceImage->offsetY; row < rows; row++) { @@ -171,13 +173,15 @@ namespace lime { sourceOffset = (row * sourceStride) + (column * 4); offset = ((row + rowOffset) * stride) + ((column + columnOffset) * 4); - sourceAlpha = sourceData[sourceOffset + 3] / 255; + sourceAlpha = sourceData[sourceOffset + 3] / 255.0; + destAlpha = data[offset + 3] / 255.0; oneMinusSourceAlpha = (1 - sourceAlpha); - data[offset] = __clamp[int (sourceData[sourceOffset] + (data[offset] * oneMinusSourceAlpha))]; - data[offset + 1] = __clamp[int (sourceData[sourceOffset + 1] + (data[offset + 1] * oneMinusSourceAlpha))]; - data[offset + 2] = __clamp[int (sourceData[sourceOffset + 2] + (data[offset + 2] * oneMinusSourceAlpha))]; - data[offset + 3] = __clamp[int (sourceData[sourceOffset + 3] + (data[offset + 3] * oneMinusSourceAlpha))]; + outA = sourceAlpha + destAlpha * oneMinusSourceAlpha; + data[offset + 0] = __clamp[int (0.5 + ((sourceData[sourceOffset + 0] * sourceAlpha + data[offset + 0] * destAlpha * oneMinusSourceAlpha) / outA))]; + data[offset + 1] = __clamp[int (0.5 + ((sourceData[sourceOffset + 1] * sourceAlpha + data[offset + 1] * destAlpha * oneMinusSourceAlpha) / outA))]; + data[offset + 2] = __clamp[int (0.5 + ((sourceData[sourceOffset + 2] * sourceAlpha + data[offset + 2] * destAlpha * oneMinusSourceAlpha) / outA))]; + data[offset + 3] = __clamp[int (0.5 + (outA * 255.0))]; } diff --git a/project/src/ui/WindowEvent.cpp b/project/src/ui/WindowEvent.cpp index fae1090b6..e67960ca9 100644 --- a/project/src/ui/WindowEvent.cpp +++ b/project/src/ui/WindowEvent.cpp @@ -19,6 +19,7 @@ namespace lime { WindowEvent::WindowEvent () { type = WINDOW_ACTIVATE; + width = 0; height = 0; x = 0; diff --git a/tools/utils/PlatformSetup.hx b/tools/utils/PlatformSetup.hx index eb7b9d675..e58fca915 100644 --- a/tools/utils/PlatformSetup.hx +++ b/tools/utils/PlatformSetup.hx @@ -153,8 +153,8 @@ class PlatformSetup { if (extension != "zip") { - var arguments = "xvzf"; - + var arguments = "xvzf"; + if (extension == "bz2" || extension == "tbz2") { arguments = "xvjf"; @@ -178,7 +178,7 @@ class PlatformSetup { } ProcessHelper.runCommand ("", "tar", [ arguments, sourceZIP ], false); - ProcessHelper.runCommand ("", "cp", [ "-R", ignoreRootFolder + "/*", targetPath ], false); + ProcessHelper.runCommand ("", "cp", [ "-R", ignoreRootFolder + "/.", targetPath ], false); Sys.command ("rm", [ "-r", ignoreRootFolder ]); } else { @@ -668,7 +668,7 @@ class PlatformSetup { defaultInstallPath = "/opt/air-sdk"; } - + downloadFile (downloadPath); var path = unescapePath (CLIHelper.param ("Output directory [" + defaultInstallPath + "]"));