Merge branch '12.0-development' into metal

This commit is contained in:
Alex Szpakowski
2020-12-22 22:37:17 -04:00
288 changed files with 15292 additions and 12550 deletions
+83
View File
@@ -0,0 +1,83 @@
/**
* Copyright (c) 2006-2020 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#pragma once
#include <stddef.h>
#include <algorithm>
#include <limits>
namespace love
{
struct Range
{
size_t first;
size_t last;
Range()
: first(std::numeric_limits<size_t>::max())
, last(0)
{}
Range(size_t offset, size_t size)
: first(offset)
, last(offset + size - 1)
{}
bool isValid() const { return first <= last; }
void invalidate()
{
first = std::numeric_limits<size_t>::max();
last = 0;
}
size_t getMin() const { return first; }
size_t getMax() const { return last; }
size_t getOffset() const { return first; }
size_t getSize() const { return (last - first) + 1; }
bool contains(const Range &other) const
{
return first <= other.first && last >= other.last;
}
void encapsulate(size_t index)
{
first = std::min(first, index);
last = std::max(last, index);
}
void encapsulate(size_t offset, size_t size)
{
first = std::min(first, offset);
last = std::max(last, offset + size - 1);
}
void encapsulate(const Range &other)
{
first = std::min(first, other.first);
last = std::max(last, other.last);
}
};
} // love
+1 -1
View File
@@ -71,7 +71,7 @@
#endif
// NEON instructions.
#if defined(__ARM_NEON)
#if defined(__ARM_NEON) || defined(_M_ARM64)
# define LOVE_SIMD_NEON
#endif
+6
View File
@@ -78,6 +78,12 @@ bool setAudioMixWithOthers(bool mixEnabled);
**/
bool hasBackgroundMusic();
/**
* Registers notifications to handle and restore audio interruptions
**/
void initAudioSessionInterruptionHandler();
void destroyAudioSessionInterruptionHandler();
/**
* Gets the area in the window that is safe for UI to render to (not covered by
* the status bar, notch, etc.)
+84
View File
@@ -28,6 +28,8 @@
#import <AudioToolbox/AudioServices.h>
#import <AVFoundation/AVFoundation.h>
#include "modules/audio/Audio.h"
#include <vector>
#include <SDL_events.h>
@@ -200,6 +202,56 @@ static int dropFileEventFilter(void *userdata, SDL_Event *event)
}
}
@interface LoveAudioInterruptionListener : NSObject
@end
@implementation LoveAudioInterruptionListener
+ (id) shared
{
// thread-safe singleton
static dispatch_once_t pred = 0;
__strong static id _shared = nil;
dispatch_once(&pred, ^{
_shared = [[self alloc] init];
});
return _shared;
}
- (void)audioSessionInterruption:(NSNotification *)note
{
@synchronized (self)
{
auto audio = love::Module::getInstance<love::audio::Audio>(love::Module::M_AUDIO);
if (!audio)
{
NSLog(@"LoveAudioInterruptionListener could not get love audio module");
return;
}
NSNumber *type = note.userInfo[AVAudioSessionInterruptionTypeKey];
if (type.unsignedIntegerValue == AVAudioSessionInterruptionTypeBegan)
audio->pauseContext();
else
audio->resumeContext();
}
}
- (void)applicationBecameActive:(NSNotification *)note
{
@synchronized (self)
{
auto audio = love::Module::getInstance<love::audio::Audio>(love::Module::M_AUDIO);
if (!audio)
{
NSLog(@"ERROR:could not get love audio module");
return;
}
audio->resumeContext();
}
}
@end // LoveAudioInterruptionListener
namespace love
{
namespace ios
@@ -380,6 +432,38 @@ bool hasBackgroundMusic()
}
}
void initAudioSessionInterruptionHandler()
{
@autoreleasepool
{
AVAudioSession *session = [AVAudioSession sharedInstance];
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:[LoveAudioInterruptionListener shared]
selector:@selector(audioSessionInterruption:)
name:AVAudioSessionInterruptionNotification
object:session];
// An interruption end notification is not guaranteed to be sent if
// we were previously interrupted... resuming if needed when the app
// becomes active seems to be the way to go.
[center addObserver:[LoveAudioInterruptionListener shared]
selector:@selector(applicationBecameActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
[center addObserver:[LoveAudioInterruptionListener shared]
selector:@selector(applicationBecameActive:)
name:UIApplicationWillEnterForegroundNotification
object:nil];
}
}
void destroyAudioSessionInterruptionHandler()
{
[[NSNotificationCenter defaultCenter] removeObserver:[LoveAudioInterruptionListener shared]];
}
Rect getSafeArea(SDL_Window *window)
{
@autoreleasepool