Merge tracking branch of Big Sur update #58

Merged
kode54 merged 26 commits from ohsir into master 2020-11-26 23:28:49 -03:00
1267 changed files with 116967 additions and 31751 deletions

4
.gitmodules vendored
View file

@ -1,6 +1,6 @@
[submodule "Frameworks/mGBA/mGBA/mgba"]
path = Frameworks/mGBA/mGBA/mgba
url = https://g.losno.co/chris/mgba.git
url = https://git.lopez-snowhill.net/chris/mgba.git
[submodule "Frameworks/AdPlug/AdPlug/adplug"]
path = Frameworks/AdPlug/AdPlug/adplug
url = https://github.com/adplug/adplug.git
@ -12,7 +12,7 @@
url = https://github.com/adplug/database.git
[submodule "Frameworks/libsidplay/sidplay-residfp-code"]
path = Frameworks/libsidplay/sidplay-residfp-code
url = https://g.losno.co/chris/sidplay-residfp.git
url = https://git.lopez-snowhill.net/chris/sidplay-residfp.git
[submodule "Frameworks/libatrac9/libatrac9"]
path = Frameworks/libatrac9/libatrac9
url = https://github.com/Thealexbarney/LibAtrac9.git

View file

@ -74,8 +74,12 @@
- (IBAction)delEntries:(id)sender;
- (IBAction)savePlaylist:(id)sender;
- (IBAction)donate:(id)sender;
- (IBAction)patreon:(id)sender;
- (IBAction)openLiberapayPage:(id)sender;
- (IBAction)openPaypalPage:(id)sender;
- (IBAction)openBitcoinPage:(id)sender;
- (IBAction)openPatreonPage:(id)sender;
- (IBAction)openKofiPage:(id)sender;
- (IBAction)feedback:(id)sender;
- (IBAction)toggleInfoDrawer:(id)sender;

View file

@ -12,6 +12,7 @@
#import "SpotlightWindowController.h"
#import "StringToURLTransformer.h"
#import "FontSizetoLineHeightTransformer.h"
#import "Cog-Swift.h"
#import "PathNode.h"
#import <CogAudio/Status.h>
@ -36,6 +37,9 @@
NSValueTransformer *miniModeMenuTitleTransformer = [[MiniModeMenuTitleTransformer alloc] init];
[NSValueTransformer setValueTransformer:miniModeMenuTitleTransformer
forName:@"MiniModeMenuTitleTransformer"];
NSValueTransformer *playbackStatusToHiddenTransformer = [[PlaybackStatusToHiddenTransformer alloc] init];
[NSValueTransformer setValueTransformer:playbackStatusToHiddenTransformer forName:@"PlaybackStatusToHiddenTransformer"];
}
@ -330,16 +334,32 @@
}
}
- (IBAction)donate:(id)sender
- (IBAction)openLiberapayPage:(id)sender
{
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.paypal.me/kode54"]];
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://liberapay.com/kode54"]];
}
- (IBAction)patreon:(id)sender
- (IBAction)openPaypalPage:(id)sender
{
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.patreon.com/kode54"]];
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.paypal.com/paypalme/kode54"]];
}
- (IBAction)openBitcoinPage:(id)sender
{
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://kode54.net/donateBitcoin"]];
}
- (IBAction)openPatreonPage:(id)sender
{
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://patreon.com/kode54"]];
}
- (IBAction)openKofiPage:(id)sender
{
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://ko-fi.com/kode54"]];
}
- (IBAction)feedback:(id)sender
{
NSString *version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];

View file

@ -365,8 +365,8 @@
LastUpgradeCheck = 1020;
TargetAttributes = {
8DC2EF4F0486A6940098B216 = {
DevelopmentTeam = N6E749HJ2X;
ProvisioningStyle = Manual;
DevelopmentTeam = 4S876G9VCD;
ProvisioningStyle = Automatic;
};
};
};
@ -431,8 +431,11 @@
1DEB91AE08733DA50010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_SEARCH_PATHS = "";
@ -448,6 +451,7 @@
OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
PRODUCT_NAME = CogAudio;
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SKIP_INSTALL = YES;
WARNING_LDFLAGS = "";
@ -459,7 +463,10 @@
1DEB91AF08733DA50010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_SEARCH_PATHS = "";
@ -473,6 +480,7 @@
OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
PRODUCT_NAME = CogAudio;
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SKIP_INSTALL = YES;
WARNING_LDFLAGS = "";
@ -514,7 +522,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SYMROOT = ../build;
@ -553,7 +561,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
SDKROOT = macosx;
SYMROOT = ../build;
};

View file

@ -78,7 +78,10 @@ NSArray * sortClassesByPriority(NSArray * theClasses)
Class decoder = NSClassFromString(classString);
theDecoder = [[decoder alloc] init];
for (NSDictionary *obsItem in cachedObservers) {
[theDecoder addObserver:[obsItem objectForKey:@"observer"] forKeyPath:[obsItem objectForKey:@"keyPath"] options:[obsItem objectForKey:@"options"] context:(__bridge void *)([obsItem objectForKey:@"context"])];
[theDecoder addObserver:[obsItem objectForKey:@"observer"]
forKeyPath:[obsItem objectForKey:@"keyPath"]
options:[[obsItem objectForKey:@"options"] unsignedIntegerValue]
context:(__bridge void *)([obsItem objectForKey:@"context"])];
}
if ([theDecoder open:source])
return YES;
@ -118,7 +121,11 @@ NSArray * sortClassesByPriority(NSArray * theClasses)
/* By the current design, the core adds its observers to decoders before they are opened */
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
{
[cachedObservers addObject:[NSDictionary dictionaryWithObjectsAndKeys:observer, @"observer", keyPath, @"keyPath", options, @"options", context, @"context", nil]];
if(context != nil) {
[cachedObservers addObject:[NSDictionary dictionaryWithObjectsAndKeys:observer, @"observer", keyPath, @"keyPath", @(options), @"options", context, @"context", nil]];
} else {
[cachedObservers addObject:[NSDictionary dictionaryWithObjectsAndKeys:observer, @"observer", keyPath, @"keyPath", @(options), @"options", nil]];
}
}
/* And this is currently called after the decoder is closed */

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="16096" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16096"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -14,52 +14,51 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Cog" allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="Cog" animationBehavior="default" id="21" userLabel="Window" customClass="MainWindow">
<window title="Cog" separatorStyle="none" allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="Cog" animationBehavior="default" toolbarStyle="compact" titleVisibility="hidden" id="21" userLabel="Window" customClass="MainWindow">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
<windowPositionMask key="initialPositionMask" topStrut="YES"/>
<rect key="contentRect" x="331" y="367" width="800" height="400"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1057"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="875"/>
<value key="minSize" type="size" width="400" height="200"/>
<view key="contentView" id="2">
<stackView key="contentView" orientation="vertical" alignment="centerX" hasEqualSpacing="YES" detachesHiddenViews="YES" id="2">
<rect key="frame" x="0.0" y="0.0" width="800" height="400"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="778">
<rect key="frame" x="17" y="4" width="758" height="15"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" alignment="center" title="Total Duration: 00 hours 00 minutes 00 seconds" bezelStyle="round" id="1473">
<font key="font" metaFont="message" size="11"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<middleViews>
<button toolTip="Click to select currently playing track" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gev-jg-41I">
<rect key="frame" x="314" y="384" width="173" height="16"/>
<buttonCell key="cell" type="bevel" title="Now Playing Track title here" bezelStyle="rounded" alignment="center" lineBreakMode="truncatingTail" imageScaling="proportionallyDown" inset="2" id="oXd-7z-UQS">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="218" name="displayPatternValue1" keyPath="totalTime" id="1891">
<action selector="scrollToCurrentEntry:" target="207" id="e2T-5R-8Eo"/>
<binding destination="1897" name="title" keyPath="content.display" id="fno-Aq-DvV"/>
<binding destination="705" name="hidden" keyPath="playbackStatus" id="Kl1-lE-Z5C">
<dictionary key="options">
<string key="NSDisplayPattern">Total Duration: %{value1}@</string>
<string key="NSValueTransformerName">PlaybackStatusToHiddenTransformer</string>
</dictionary>
</binding>
</connections>
</textField>
</button>
<splitView fixedFrame="YES" dividerStyle="thin" vertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2123">
<rect key="frame" x="0.0" y="24" width="800" height="377"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<rect key="frame" x="0.0" y="22" width="800" height="354"/>
<subviews>
<scrollView fixedFrame="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="24" horizontalPageScroll="0.0" verticalLineScroll="24" verticalPageScroll="0.0" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="206" userLabel="Scroll View - Playlist View">
<rect key="frame" x="0.0" y="0.0" width="800" height="377"/>
<rect key="frame" x="0.0" y="0.0" width="800" height="354"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="KWC-Ti-8KY">
<rect key="frame" x="0.0" y="0.0" width="800" height="377"/>
<rect key="frame" x="0.0" y="0.0" width="800" height="354"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" alternatingRowBackgroundColors="YES" autosaveName="Playlist" rowHeight="18" headerView="1517" id="207" customClass="PlaylistView">
<rect key="frame" x="0.0" y="0.0" width="800" height="360"/>
<rect key="frame" x="0.0" y="0.0" width="800" height="337"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="6"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn identifier="index" editable="NO" width="41" minWidth="28" maxWidth="64" id="209">
<tableColumn identifier="index" editable="NO" width="36" minWidth="28" maxWidth="64" id="209">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="#">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.33333299" alpha="1" colorSpace="calibratedWhite"/>
@ -97,7 +96,7 @@
</binding>
</connections>
</tableColumn>
<tableColumn identifier="title" editable="NO" width="126" minWidth="96" maxWidth="1024" id="208">
<tableColumn identifier="title" editable="NO" width="121" minWidth="96" maxWidth="1024" id="208">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Title">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.33333299" alpha="1" colorSpace="calibratedWhite"/>
@ -118,7 +117,7 @@
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="1914"/>
</connections>
</tableColumn>
<tableColumn identifier="artist" editable="NO" width="125" minWidth="96" maxWidth="1024" id="391">
<tableColumn identifier="artist" editable="NO" width="120.5" minWidth="96" maxWidth="1024" id="391">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Artist">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
@ -139,7 +138,7 @@
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="1916"/>
</connections>
</tableColumn>
<tableColumn identifier="album" editable="NO" width="125" minWidth="96" maxWidth="1024" id="806">
<tableColumn identifier="album" editable="NO" width="121.5" minWidth="96" maxWidth="1024" id="806">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Album">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
@ -160,7 +159,7 @@
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="1917"/>
</connections>
</tableColumn>
<tableColumn identifier="length" editable="NO" width="71" minWidth="43.62012" maxWidth="96" id="807">
<tableColumn identifier="length" editable="NO" width="67.5" minWidth="43.62012" maxWidth="96" id="807">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="Length">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
@ -180,7 +179,7 @@
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="1919"/>
</connections>
</tableColumn>
<tableColumn identifier="year" editable="NO" width="71" minWidth="42" maxWidth="96" id="848">
<tableColumn identifier="year" editable="NO" width="67.5" minWidth="42" maxWidth="96" id="848">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="Year">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
@ -196,7 +195,7 @@
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="1921"/>
</connections>
</tableColumn>
<tableColumn identifier="genre" editable="NO" width="123" minWidth="96" maxWidth="512" id="849">
<tableColumn identifier="genre" editable="NO" width="119.5" minWidth="96" maxWidth="512" id="849">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Genre">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
@ -213,7 +212,7 @@
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="1922"/>
</connections>
</tableColumn>
<tableColumn identifier="track" editable="NO" width="71" minWidth="24" maxWidth="72" id="850">
<tableColumn identifier="track" editable="NO" width="67.5" minWidth="24" maxWidth="72" id="850">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="№">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
@ -295,7 +294,7 @@
<rect key="frame" x="85" y="17" width="15" height="68"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<tableHeaderView key="headerView" id="1517" customClass="PlaylistHeaderView">
<tableHeaderView key="headerView" wantsLayer="YES" id="1517" customClass="PlaylistHeaderView">
<rect key="frame" x="0.0" y="0.0" width="800" height="17"/>
<autoresizingMask key="autoresizingMask"/>
</tableHeaderView>
@ -308,26 +307,51 @@
<outlet property="delegate" destination="2172" id="2182"/>
</connections>
</splitView>
</subviews>
</view>
</middleViews>
<endViews>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="778">
<rect key="frame" x="270" y="0.0" width="261" height="14"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" alignment="center" title="Total Duration: 00 hours 00 minutes 00 seconds" bezelStyle="round" id="1473">
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="218" name="displayPatternValue1" keyPath="totalTime" id="1891">
<dictionary key="options">
<string key="NSDisplayPattern">Total Duration: %{value1}@</string>
</dictionary>
</binding>
</connections>
</textField>
</endViews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<toolbar key="toolbar" implicitIdentifier="B4998081-90DD-45DD-8243-0F7039C7DEA2" displayMode="iconOnly" sizeMode="regular" id="1523">
<allowedToolbarItems>
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="1552"/>
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="1529"/>
<toolbarItem implicitItemIdentifier="NSToolbarSeparatorItem" id="1673"/>
<toolbarItem implicitItemIdentifier="NSToolbarCustomizeToolbarItem" id="1645"/>
<toolbarItem implicitItemIdentifier="A06F7688-72A2-4AAD-B9E1-C66720B2B0D3" label="Playback Control" paletteLabel="Playback Control" id="1539">
<toolbarItem implicitItemIdentifier="A06F7688-72A2-4AAD-B9E1-C66720B2B0D3" label="Playback Control" paletteLabel="Playback Control" sizingBehavior="auto" id="1539">
<nil key="toolTip"/>
<size key="minSize" width="120" height="25"/>
<size key="maxSize" width="130" height="25"/>
<segmentedControl key="view" verticalHuggingPriority="750" id="1537" customClass="PlaybackButtons">
<rect key="frame" x="0.0" y="14" width="121" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<segmentedCell key="cell" state="on" borderStyle="border" alignment="left" style="rounded" trackingMode="momentary" id="1538">
<rect key="frame" x="0.0" y="14" width="133" height="23"/>
<autoresizingMask key="autoresizingMask"/>
<segmentedCell key="cell" state="on" borderStyle="border" alignment="left" style="texturedRounded" trackingMode="momentary" id="1538">
<font key="font" metaFont="system"/>
<segments>
<segment toolTip="Previous" image="previousTemplate" imageScaling="none" width="28"/>
<segment toolTip="Play" image="playTemplate" imageScaling="none" width="28" tag="1"/>
<segment toolTip="Play" image="playTemplate" width="28" tag="1"/>
<segment toolTip="Next" image="stopTemplate" imageScaling="none" width="28"/>
<segment image="nextTemplate" imageScaling="none" width="28">
<nil key="label"/>
@ -339,13 +363,11 @@
</connections>
</segmentedControl>
</toolbarItem>
<toolbarItem implicitItemIdentifier="0D05748D-3258-44F5-9D1C-CBF211C15E2D" label="Search" paletteLabel="Search" id="1533">
<toolbarItem implicitItemIdentifier="0D05748D-3258-44F5-9D1C-CBF211C15E2D" label="Search" paletteLabel="Search" sizingBehavior="auto" id="1533">
<nil key="toolTip"/>
<size key="minSize" width="64" height="22"/>
<size key="maxSize" width="96" height="22"/>
<searchField key="view" wantsLayer="YES" verticalHuggingPriority="750" id="1531">
<rect key="frame" x="0.0" y="14" width="96" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<autoresizingMask key="autoresizingMask"/>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" placeholderString="All" bezelStyle="round" recentsAutosaveName="CogFilter" id="1532">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -391,13 +413,11 @@
</searchFieldCell>
</searchField>
</toolbarItem>
<toolbarItem implicitItemIdentifier="2CDD90B4-2355-4E8A-AE42-A6C872DF700A" label="Position" paletteLabel="Position" id="1551">
<toolbarItem implicitItemIdentifier="2CDD90B4-2355-4E8A-AE42-A6C872DF700A" label="Position" paletteLabel="Position" sizingBehavior="auto" id="1551">
<nil key="toolTip"/>
<size key="minSize" width="96" height="21"/>
<size key="maxSize" width="1024" height="21"/>
<slider key="view" verticalHuggingPriority="750" id="1549" customClass="PositionSlider">
<rect key="frame" x="0.0" y="14" width="96" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="0.0" y="14" width="96" height="28"/>
<autoresizingMask key="autoresizingMask"/>
<sliderCell key="cell" enabled="NO" alignment="left" maxValue="10000" tickMarkPosition="above" sliderType="linear" id="1550" customClass="TrackingCell"/>
<connections>
<action selector="seek:" target="705" id="1597"/>
@ -408,13 +428,11 @@
</connections>
</slider>
</toolbarItem>
<toolbarItem implicitItemIdentifier="B042D8A5-AFF4-43B2-9DFB-E87A09B7F861" label="Current Time" paletteLabel="Current Time" id="1568">
<toolbarItem implicitItemIdentifier="B042D8A5-AFF4-43B2-9DFB-E87A09B7F861" label="Current Time" paletteLabel="Current Time" sizingBehavior="auto" id="1568">
<nil key="toolTip"/>
<size key="minSize" width="46" height="15"/>
<size key="maxSize" width="58" height="15"/>
<textField key="view" verticalHuggingPriority="750" id="1566" customClass="TimeField">
<rect key="frame" x="15" y="14" width="46" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="14" y="14" width="49" height="19"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" borderStyle="bezel" alignment="center" title="0:00" usesSingleLineMode="YES" bezelStyle="round" id="1567">
<font key="font" metaFont="message" size="11"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -422,13 +440,11 @@
</textFieldCell>
</textField>
</toolbarItem>
<toolbarItem implicitItemIdentifier="3B680DEB-106E-4549-A478-FFB8A6738053" label="Volume" paletteLabel="Volume" image="volume3Template" id="1610">
<toolbarItem implicitItemIdentifier="3B680DEB-106E-4549-A478-FFB8A6738053" label="Volume" paletteLabel="Volume" image="volume3Template" sizingBehavior="auto" id="1610">
<nil key="toolTip"/>
<size key="minSize" width="28" height="25"/>
<size key="maxSize" width="28" height="25"/>
<button key="view" verticalHuggingPriority="750" id="1608" customClass="VolumeButton">
<rect key="frame" x="9" y="14" width="28" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="9" y="14" width="29" height="23"/>
<autoresizingMask key="autoresizingMask"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="volume3Template" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="1609">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -438,13 +454,11 @@
</connections>
</button>
</toolbarItem>
<toolbarItem implicitItemIdentifier="2F487D99-16E9-4BF8-9A98-637FABEB2716" label="Info Inspector" paletteLabel="Info Inspector" image="infoTemplate" id="1629">
<toolbarItem implicitItemIdentifier="2F487D99-16E9-4BF8-9A98-637FABEB2716" label="Info Inspector" paletteLabel="Info Inspector" image="infoTemplate" sizingBehavior="auto" id="1629">
<nil key="toolTip"/>
<size key="minSize" width="28" height="25"/>
<size key="maxSize" width="28" height="25"/>
<button key="view" verticalHuggingPriority="750" id="1627">
<rect key="frame" x="26" y="14" width="28" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="26" y="14" width="28" height="23"/>
<autoresizingMask key="autoresizingMask"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="infoTemplate" imagePosition="only" alignment="center" borderStyle="border" id="1628">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -454,13 +468,11 @@
</connections>
</button>
</toolbarItem>
<toolbarItem implicitItemIdentifier="6EE50288-54ED-448F-BB25-347479AE119F" label="File Tree" paletteLabel="File Tree" image="navigatorTemplate" id="1630">
<toolbarItem implicitItemIdentifier="6EE50288-54ED-448F-BB25-347479AE119F" label="File Tree" paletteLabel="File Tree" image="navigatorTemplate" sizingBehavior="auto" id="1630">
<nil key="toolTip"/>
<size key="minSize" width="28" height="25"/>
<size key="maxSize" width="28" height="25"/>
<button key="view" verticalHuggingPriority="750" id="1631">
<rect key="frame" x="12" y="14" width="28" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="12" y="14" width="28" height="23"/>
<autoresizingMask key="autoresizingMask"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="navigatorTemplate" imagePosition="only" alignment="center" borderStyle="border" id="1632">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -470,13 +482,11 @@
</connections>
</button>
</toolbarItem>
<toolbarItem implicitItemIdentifier="972E4070-D310-48FE-BA9B-C06B248FF020" label="Randomize" paletteLabel="Randomize" image="randomizeTemplate" id="2466">
<toolbarItem implicitItemIdentifier="972E4070-D310-48FE-BA9B-C06B248FF020" label="Randomize" paletteLabel="Randomize" image="randomizeTemplate" sizingBehavior="auto" id="2466">
<nil key="toolTip"/>
<size key="minSize" width="28" height="25"/>
<size key="maxSize" width="28" height="25"/>
<button key="view" verticalHuggingPriority="750" id="2467">
<rect key="frame" x="19" y="14" width="28" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="18" y="14" width="29" height="23"/>
<autoresizingMask key="autoresizingMask"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="randomizeTemplate" imagePosition="only" alignment="center" borderStyle="border" id="2468">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -486,13 +496,11 @@
</connections>
</button>
</toolbarItem>
<toolbarItem implicitItemIdentifier="384C0EB5-D1D6-4D39-8113-03FB4958D7ED" label="Shuffle" paletteLabel="Shuffle" image="shuffleOffTemplate" id="1636">
<toolbarItem implicitItemIdentifier="384C0EB5-D1D6-4D39-8113-03FB4958D7ED" label="Shuffle" paletteLabel="Shuffle" image="shuffleOffTemplate" sizingBehavior="auto" id="1636">
<nil key="toolTip"/>
<size key="minSize" width="28" height="25"/>
<size key="maxSize" width="28" height="25"/>
<button key="view" verticalHuggingPriority="750" id="1637">
<rect key="frame" x="9" y="14" width="28" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="7" y="14" width="32" height="23"/>
<autoresizingMask key="autoresizingMask"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="shuffleOffTemplate" imagePosition="only" alignment="center" borderStyle="border" id="1638">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -507,13 +515,11 @@
</connections>
</button>
</toolbarItem>
<toolbarItem implicitItemIdentifier="F3591DBA-E0EC-4564-896A-C6EFFABC7873" label="Repeat" paletteLabel="Repeat" image="repeatModeOffTemplate" id="1639">
<toolbarItem implicitItemIdentifier="F3591DBA-E0EC-4564-896A-C6EFFABC7873" label="Repeat" paletteLabel="Repeat" image="repeatModeOffTemplate" sizingBehavior="auto" id="1639">
<nil key="toolTip"/>
<size key="minSize" width="28" height="25"/>
<size key="maxSize" width="28" height="25"/>
<button key="view" verticalHuggingPriority="750" id="1640">
<rect key="frame" x="8" y="14" width="28" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="6" y="14" width="32" height="23"/>
<autoresizingMask key="autoresizingMask"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="repeatModeOffTemplate" imagePosition="only" alignment="center" borderStyle="border" id="1641">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -528,13 +534,11 @@
</connections>
</button>
</toolbarItem>
<toolbarItem implicitItemIdentifier="F636F7BD-E049-4DF5-B758-35DF87C40AA0" label="Mini Mode" paletteLabel="Mini Mode" image="miniModeOnTemplate" id="2532">
<toolbarItem implicitItemIdentifier="F636F7BD-E049-4DF5-B758-35DF87C40AA0" label="Mini Mode" paletteLabel="Mini Mode" image="miniModeOnTemplate" sizingBehavior="auto" id="2532">
<nil key="toolTip"/>
<size key="minSize" width="28" height="25"/>
<size key="maxSize" width="28" height="25"/>
<button key="view" verticalHuggingPriority="750" id="2533">
<rect key="frame" x="17" y="14" width="28" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="17" y="14" width="28" height="23"/>
<autoresizingMask key="autoresizingMask"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="miniModeOnTemplate" imagePosition="only" alignment="center" borderStyle="border" id="2534">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -578,7 +582,7 @@
</connections>
<point key="canvasLocation" x="107" y="131"/>
</window>
<window title="Cog" allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="Mini Window" animationBehavior="default" id="2234" userLabel="Mini Window (Window)" customClass="MiniWindow">
<window title="Cog" allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="Mini Window" animationBehavior="default" toolbarStyle="expanded" id="2234" userLabel="Mini Window (Window)" customClass="MiniWindow">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" texturedBackground="YES"/>
<rect key="contentRect" x="192" y="547" width="480" height="0.0"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
@ -592,13 +596,11 @@
<allowedToolbarItems>
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="2227"/>
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="2228"/>
<toolbarItem implicitItemIdentifier="6F5A6C43-A09C-462A-AEE2-C86DC3C55128" label="Playback Buttons" paletteLabel="Playback Buttons" id="2272">
<toolbarItem implicitItemIdentifier="6F5A6C43-A09C-462A-AEE2-C86DC3C55128" label="Playback Buttons" paletteLabel="Playback Buttons" sizingBehavior="auto" id="2272">
<nil key="toolTip"/>
<size key="minSize" width="121" height="25"/>
<size key="maxSize" width="121" height="25"/>
<segmentedControl key="view" verticalHuggingPriority="750" id="2295" customClass="PlaybackButtons">
<rect key="frame" x="0.0" y="14" width="121" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="0.0" y="14" width="133" height="23"/>
<autoresizingMask key="autoresizingMask"/>
<segmentedCell key="cell" state="on" borderStyle="border" alignment="left" style="texturedSquare" trackingMode="momentary" id="2296">
<font key="font" metaFont="system"/>
<segments>
@ -615,13 +617,11 @@
</connections>
</segmentedControl>
</toolbarItem>
<toolbarItem implicitItemIdentifier="C10E329B-9AB7-47DB-B3BA-7C40B57792E8" label="Position" paletteLabel="Position" id="2273">
<toolbarItem implicitItemIdentifier="C10E329B-9AB7-47DB-B3BA-7C40B57792E8" label="Position" paletteLabel="Position" sizingBehavior="auto" id="2273">
<nil key="toolTip"/>
<size key="minSize" width="96" height="15"/>
<size key="maxSize" width="2048" height="15"/>
<slider key="view" verticalHuggingPriority="750" id="2293" customClass="PositionSlider">
<rect key="frame" x="0.0" y="14" width="96" height="15"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="0.0" y="14" width="96" height="20"/>
<autoresizingMask key="autoresizingMask"/>
<sliderCell key="cell" controlSize="small" enabled="NO" alignment="left" maxValue="10000" tickMarkPosition="above" sliderType="linear" id="2294" customClass="TrackingCell">
<font key="font" metaFont="message" size="11"/>
</sliderCell>
@ -634,13 +634,11 @@
</connections>
</slider>
</toolbarItem>
<toolbarItem implicitItemIdentifier="C0FF70A3-EE67-43F6-9956-95B89425CF0E" label="Current Time" paletteLabel="Current Time" id="2274">
<toolbarItem implicitItemIdentifier="C0FF70A3-EE67-43F6-9956-95B89425CF0E" label="Current Time" paletteLabel="Current Time" sizingBehavior="auto" id="2274">
<nil key="toolTip"/>
<size key="minSize" width="38" height="15"/>
<size key="maxSize" width="56" height="15"/>
<textField key="view" verticalHuggingPriority="750" id="2291" customClass="TimeField">
<rect key="frame" x="19" y="14" width="38" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textField key="view" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2291" customClass="TimeField">
<rect key="frame" x="14" y="14" width="49" height="19"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" sendsActionOnEndEditing="YES" borderStyle="bezel" alignment="center" title="0:00" bezelStyle="round" id="2292">
<font key="font" metaFont="message" size="11"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -648,13 +646,11 @@
</textFieldCell>
</textField>
</toolbarItem>
<toolbarItem implicitItemIdentifier="BBA4D635-FC27-42FC-B346-CE553195CA7C" label="Volume" paletteLabel="Volume" image="volume3Template" id="2275">
<toolbarItem implicitItemIdentifier="BBA4D635-FC27-42FC-B346-CE553195CA7C" label="Volume" paletteLabel="Volume" image="volume3Template" sizingBehavior="auto" id="2275">
<nil key="toolTip"/>
<size key="minSize" width="26" height="25"/>
<size key="maxSize" width="28" height="25"/>
<button key="view" verticalHuggingPriority="750" id="2289" customClass="VolumeButton">
<rect key="frame" x="10" y="14" width="26" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="9" y="14" width="29" height="23"/>
<autoresizingMask key="autoresizingMask"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="volume3Template" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="2290">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -664,13 +660,11 @@
</connections>
</button>
</toolbarItem>
<toolbarItem implicitItemIdentifier="EE7CA50B-9B79-414A-A257-7AC385032675" label="Shuffle" paletteLabel="Shuffle" image="shuffleOffTemplate" id="2278">
<toolbarItem implicitItemIdentifier="EE7CA50B-9B79-414A-A257-7AC385032675" label="Shuffle" paletteLabel="Shuffle" image="shuffleOffTemplate" sizingBehavior="auto" id="2278">
<nil key="toolTip"/>
<size key="minSize" width="26" height="25"/>
<size key="maxSize" width="28" height="25"/>
<button key="view" verticalHuggingPriority="750" id="2283">
<rect key="frame" x="10" y="14" width="26" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="7" y="14" width="32" height="23"/>
<autoresizingMask key="autoresizingMask"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="shuffleOffTemplate" imagePosition="only" alignment="center" borderStyle="border" id="2284">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -685,13 +679,11 @@
</connections>
</button>
</toolbarItem>
<toolbarItem implicitItemIdentifier="9A52F396-9BBC-4791-AC12-664859F26F89" label="Repeat" paletteLabel="Repeat" image="repeatModeOffTemplate" id="2279">
<toolbarItem implicitItemIdentifier="9A52F396-9BBC-4791-AC12-664859F26F89" label="Repeat" paletteLabel="Repeat" image="repeatModeOffTemplate" sizingBehavior="auto" id="2279">
<nil key="toolTip"/>
<size key="minSize" width="26" height="25"/>
<size key="maxSize" width="28" height="25"/>
<button key="view" verticalHuggingPriority="750" id="2281">
<rect key="frame" x="9" y="14" width="26" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="6" y="14" width="32" height="23"/>
<autoresizingMask key="autoresizingMask"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="repeatModeOffTemplate" imagePosition="only" alignment="center" borderStyle="border" id="2282">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -706,13 +698,11 @@
</connections>
</button>
</toolbarItem>
<toolbarItem implicitItemIdentifier="2064CD41-7C2B-4EE0-BCE9-8E18E09F02EF" label="Normal Mode" paletteLabel="Normal Mode" image="miniModeOffTemplate" id="2526">
<toolbarItem implicitItemIdentifier="2064CD41-7C2B-4EE0-BCE9-8E18E09F02EF" label="Normal Mode" paletteLabel="Normal Mode" image="miniModeOffTemplate" sizingBehavior="auto" id="2526">
<nil key="toolTip"/>
<size key="minSize" width="26" height="25"/>
<size key="maxSize" width="28" height="25"/>
<button key="view" verticalHuggingPriority="750" id="2527">
<rect key="frame" x="26" y="14" width="26" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="25" y="14" width="28" height="23"/>
<autoresizingMask key="autoresizingMask"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="miniModeOffTemplate" imagePosition="only" alignment="center" borderStyle="border" id="2528">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -725,13 +715,11 @@
<action selector="toggleMiniMode:" target="226" id="2531"/>
</connections>
</toolbarItem>
<toolbarItem implicitItemIdentifier="0649F8CF-02D0-4D43-9FB4-CCAFAFA03B49" label="Info Inspector" paletteLabel="Info Inspector" image="infoTemplate" id="2429">
<toolbarItem implicitItemIdentifier="0649F8CF-02D0-4D43-9FB4-CCAFAFA03B49" label="Info Inspector" paletteLabel="Info Inspector" image="infoTemplate" sizingBehavior="auto" id="2429">
<nil key="toolTip"/>
<size key="minSize" width="26" height="25"/>
<size key="maxSize" width="28" height="25"/>
<button key="view" verticalHuggingPriority="750" id="2430">
<rect key="frame" x="27" y="14" width="26" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<rect key="frame" x="26" y="14" width="28" height="23"/>
<autoresizingMask key="autoresizingMask"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="infoTemplate" imagePosition="only" alignment="center" borderStyle="border" id="2431">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -765,6 +753,7 @@
</binding>
<outlet property="playbackController" destination="705" id="vo7-mK-yQe"/>
</connections>
<point key="canvasLocation" x="-35" y="444"/>
</window>
<menu title="MainMenu" systemMenu="main" id="29" userLabel="MainMenu">
<items>
@ -785,20 +774,46 @@
<menuItem isSeparatorItem="YES" id="1100">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Support Cog..." id="751">
<menuItem title="Donate" id="751">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" id="kue-p2-G0Y">
<menu key="submenu" title="Donate" id="kue-p2-G0Y">
<items>
<menuItem title="LiberaPay" id="nyW-nI-abw">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="openLiberapayPage:" target="226" id="pS6-Hj-tIm"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="Mbf-yW-WGC"/>
<menuItem title="One time" enabled="NO" id="wLp-NA-5u2">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="PayPal" id="xcs-tx-Viz">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="donate:" target="-1" id="4Br-dF-by5"/>
<action selector="openPaypalPage:" target="226" id="oxr-P1-35O"/>
</connections>
</menuItem>
<menuItem title="Bitcoin" id="xtG-EN-CR6">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="openBitcoinPage:" target="226" id="nK8-Vz-Qnc"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="txC-Jd-Gez"/>
<menuItem title="Recurring" enabled="NO" id="iRb-7e-iMC">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Patreon" id="Bls-an-3wW">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="patreon:" target="-1" id="Hgn-8M-pW2"/>
<action selector="openPatreonPage:" target="226" id="AdW-US-V3l"/>
</connections>
</menuItem>
<menuItem title="Ko-fi" id="CVM-rp-UJe">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="openKofiPage:" target="226" id="gax-6q-SuW"/>
</connections>
</menuItem>
</items>
@ -1325,36 +1340,19 @@ CA
<menuItem isSeparatorItem="YES" id="1079">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Filter Playlist" keyEquivalent="f" id="1824">
<attributedString key="attributedTitle">
<fragment content="Filter Playlist">
<attributes>
<font key="NSFont" size="14" name="LucidaGrande"/>
<font key="NSOriginalFont" size="14" name="LucidaGrande"/>
<paragraphStyle key="NSParagraphStyle" alignment="natural" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
</attributes>
</fragment>
</attributedString>
<menuItem title="Filter Playlist" keyEquivalent="f" id="UAk-Gc-lT4">
<connections>
<action selector="selectText:" target="1531" id="1876"/>
<action selector="selectText:" target="1531" id="T6e-Sw-Axi"/>
</connections>
</menuItem>
<menuItem title="Show All Songs" id="1132">
<attributedString key="attributedTitle">
<fragment content="Show All Songs">
<attributes>
<font key="NSFont" size="14" name="LucidaGrande"/>
<font key="NSOriginalFont" size="14" name="LucidaGrande"/>
</attributes>
</fragment>
</attributedString>
<menuItem title="Show All Songs" id="pU1-ci-9uB">
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="clearFilterPredicate:" target="218" id="1430"/>
<binding destination="218" name="enabled" keyPath="filterPredicate" id="1434">
<action selector="clearFilterPredicate:" target="218" id="kQ1-26-2yp"/>
<binding destination="218" name="enabled" keyPath="filterPredicate" id="dnL-jv-TR1">
<dictionary key="options">
<string key="NSValueTransformerName">NSIsNotNil</string>
</dictionary>
@ -1601,6 +1599,7 @@ Gw
</connections>
</menuItem>
</items>
<point key="canvasLocation" x="-439" y="76"/>
</menu>
<customObject id="705" userLabel="PlaybackController" customClass="PlaybackController">
<connections>
@ -1805,152 +1804,152 @@ Gw
<image name="imageCell:1801:image" width="17" height="17">
<mutableData key="keyedArchiveRepresentation">
YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05T
S2V5ZWRBcmNoaXZlctEICVRyb290gAGuCwwZGh8UJCgpMDM2PD9VJG51bGzWDQ4PEBESExQVFhcYVk5T
S2V5ZWRBcmNoaXZlctEICVRyb290gAGuCwwZGh8UJCkqMTQ3PUBVJG51bGzWDQ4PEBESExQVFhcYVk5T
U2l6ZV5OU1Jlc2l6aW5nTW9kZVYkY2xhc3NcTlNJbWFnZUZsYWdzVk5TUmVwc1dOU0NvbG9ygAIQAIAN
EiDAAACAA4ALWHsxNywgMTd90hsPHB5aTlMub2JqZWN0c6EdgASACtIbDyAjoiEigAWABoAJ0iUPJidf
EBROU1RJRkZSZXByZXNlbnRhdGlvboAHgAhPER/eTU0AKgAAEhjo6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo
6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/ABIBAAADAAAAAQAiAAABAQAD
AAAAAQAiAAABAgADAAAABAAAEwYBAwADAAAAAQABAAABBgADAAAAAQACAAABCgADAAAAAQABAAABEQAE
AAAAAQAAAAgBEgADAAAAAQABAAABFQADAAAAAQAEAAABFgADAAAAAQAiAAABFwAEAAAAAQAAEhABGgAF
AAAAAQAAEvYBGwAFAAAAAQAAEv4BHAADAAAAAQABAAABKAADAAAAAQACAAABUgADAAAAAQABAAABUwAD
AAAABAAAEw6HcwAHAAAMyAAAExYAAAAAAAAAkAAAAAEAAACQAAAAAQAIAAgACAAIAAEAAQABAAEAAAzI
YXBwbAIQAABtbnRyUkdCIFhZWiAH4AABAA0AFwADAB1hY3NwQVBQTAAAAABBUFBMAAAAAAAAAAAAAAAA
AAAAAAAA9tYAAQAAAADTLWFwcGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAABFkZXNjAAABUAAAAGJkc2NtAAABtAAAAbBjcHJ0AAADZAAAACN3dHB0AAADiAAAABRyWFla
AAADnAAAABRnWFlaAAADsAAAABRiWFlaAAADxAAAABRyVFJDAAAD2AAACAxhYXJnAAAL5AAAACB2Y2d0
AAAMBAAAADBuZGluAAAMNAAAAD5jaGFkAAAMdAAAACxtbW9kAAAMoAAAAChiVFJDAAAD2AAACAxnVFJD
AAAD2AAACAxhYWJnAAAL5AAAACBhYWdnAAAL5AAAACBkZXNjAAAAAAAAAAhEaXNwbGF5AAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAbWx1YwAAAAAAAAAiAAAADGhySFIAAAAIAAABqGtvS1IAAAAIAAABqG5iTk8AAAAI
AAABqGlkAAAAAAAIAAABqGh1SFUAAAAIAAABqGNzQ1oAAAAIAAABqGRhREsAAAAIAAABqHVrVUEAAAAI
AAABqGFyAAAAAAAIAAABqGl0SVQAAAAIAAABqHJvUk8AAAAIAAABqG5sTkwAAAAIAAABqGhlSUwAAAAI
AAABqGVzRVMAAAAIAAABqGZpRkkAAAAIAAABqHpoVFcAAAAIAAABqHZpVk4AAAAIAAABqHNrU0sAAAAI
AAABqHpoQ04AAAAIAAABqHJ1UlUAAAAIAAABqGZyRlIAAAAIAAABqG1zAAAAAAAIAAABqGNhRVMAAAAI
AAABqHRoVEgAAAAIAAABqGVzWEwAAAAIAAABqGRlREUAAAAIAAABqGVuVVMAAAAIAAABqHB0QlIAAAAI
AAABqHBsUEwAAAAIAAABqGVsR1IAAAAIAAABqHN2U0UAAAAIAAABqHRyVFIAAAAIAAABqGphSlAAAAAI
AAABqHB0UFQAAAAIAAABqABpAE0AYQBjdGV4dAAAAABDb3B5cmlnaHQgQXBwbGUgSW5jLiwgMjAxNgAA
WFlaIAAAAAAAAPPYAAEAAAABFghYWVogAAAAAAAAc9QAADomAAABblhZWiAAAAAAAABehgAAujcAABPt
WFlaIAAAAAAAACR8AAALowAAvdJjdXJ2AAAAAAAABAAAAAAFAAoADwAUABkAHgAjACgALQAyADYAOwBA
AEUASgBPAFQAWQBeAGMAaABtAHIAdwB8AIEAhgCLAJAAlQCaAJ8AowCoAK0AsgC3ALwAwQDGAMsA0ADV
ANsA4ADlAOsA8AD2APsBAQEHAQ0BEwEZAR8BJQErATIBOAE+AUUBTAFSAVkBYAFnAW4BdQF8AYMBiwGS
AZoBoQGpAbEBuQHBAckB0QHZAeEB6QHyAfoCAwIMAhQCHQImAi8COAJBAksCVAJdAmcCcQJ6AoQCjgKY
AqICrAK2AsECywLVAuAC6wL1AwADCwMWAyEDLQM4A0MDTwNaA2YDcgN+A4oDlgOiA64DugPHA9MD4APs
A/kEBgQTBCAELQQ7BEgEVQRjBHEEfgSMBJoEqAS2BMQE0wThBPAE/gUNBRwFKwU6BUkFWAVnBXcFhgWW
BaYFtQXFBdUF5QX2BgYGFgYnBjcGSAZZBmoGewaMBp0GrwbABtEG4wb1BwcHGQcrBz0HTwdhB3QHhgeZ
B6wHvwfSB+UH+AgLCB8IMghGCFoIbgiCCJYIqgi+CNII5wj7CRAJJQk6CU8JZAl5CY8JpAm6Cc8J5Qn7
ChEKJwo9ClQKagqBCpgKrgrFCtwK8wsLCyILOQtRC2kLgAuYC7ALyAvhC/kMEgwqDEMMXAx1DI4MpwzA
DNkM8w0NDSYNQA1aDXQNjg2pDcMN3g34DhMOLg5JDmQOfw6bDrYO0g7uDwkPJQ9BD14Peg+WD7MPzw/s
EAkQJhBDEGEQfhCbELkQ1xD1ERMRMRFPEW0RjBGqEckR6BIHEiYSRRJkEoQSoxLDEuMTAxMjE0MTYxOD
E6QTxRPlFAYUJxRJFGoUixStFM4U8BUSFTQVVhV4FZsVvRXgFgMWJhZJFmwWjxayFtYW+hcdF0EXZReJ
F64X0hf3GBsYQBhlGIoYrxjVGPoZIBlFGWsZkRm3Gd0aBBoqGlEadxqeGsUa7BsUGzsbYxuKG7Ib2hwC
HCocUhx7HKMczBz1HR4dRx1wHZkdwx3sHhYeQB5qHpQevh7pHxMfPh9pH5Qfvx/qIBUgQSBsIJggxCDw
IRwhSCF1IaEhziH7IiciVSKCIq8i3SMKIzgjZiOUI8Ij8CQfJE0kfCSrJNolCSU4JWgllyXHJfcmJyZX
JocmtyboJxgnSSd6J6sn3CgNKD8ocSiiKNQpBik4KWspnSnQKgIqNSpoKpsqzysCKzYraSudK9EsBSw5
LG4soizXLQwtQS12Last4S4WLkwugi63Lu4vJC9aL5Evxy/+MDUwbDCkMNsxEjFKMYIxujHyMioyYzKb
MtQzDTNGM38zuDPxNCs0ZTSeNNg1EzVNNYc1wjX9Njc2cjauNuk3JDdgN5w31zgUOFA4jDjIOQU5Qjl/
Obw5+To2OnQ6sjrvOy07azuqO+g8JzxlPKQ84z0iPWE9oT3gPiA+YD6gPuA/IT9hP6I/4kAjQGRApkDn
QSlBakGsQe5CMEJyQrVC90M6Q31DwEQDREdEikTORRJFVUWaRd5GIkZnRqtG8Ec1R3tHwEgFSEtIkUjX
SR1JY0mpSfBKN0p9SsRLDEtTS5pL4kwqTHJMuk0CTUpNk03cTiVObk63TwBPSU+TT91QJ1BxULtRBlFQ
UZtR5lIxUnxSx1MTU19TqlP2VEJUj1TbVShVdVXCVg9WXFapVvdXRFeSV+BYL1h9WMtZGllpWbhaB1pW
WqZa9VtFW5Vb5Vw1XIZc1l0nXXhdyV4aXmxevV8PX2Ffs2AFYFdgqmD8YU9homH1YklinGLwY0Njl2Pr
ZEBklGTpZT1lkmXnZj1mkmboZz1nk2fpaD9olmjsaUNpmmnxakhqn2r3a09rp2v/bFdsr20IbWBtuW4S
bmtuxG8eb3hv0XArcIZw4HE6cZVx8HJLcqZzAXNdc7h0FHRwdMx1KHWFdeF2Pnabdvh3VnezeBF4bnjM
eSp5iXnnekZ6pXsEe2N7wnwhfIF84X1BfaF+AX5ifsJ/I3+Ef+WAR4CogQqBa4HNgjCCkoL0g1eDuoQd
hICE44VHhauGDoZyhteHO4efiASIaYjOiTOJmYn+imSKyoswi5aL/IxjjMqNMY2Yjf+OZo7OjzaPnpAG
kG6Q1pE/kaiSEZJ6kuOTTZO2lCCUipT0lV+VyZY0lp+XCpd1l+CYTJi4mSSZkJn8mmia1ZtCm6+cHJyJ
nPedZJ3SnkCerp8dn4uf+qBpoNihR6G2oiailqMGo3aj5qRWpMelOKWpphqmi6b9p26n4KhSqMSpN6mp
qhyqj6sCq3Wr6axcrNCtRK24ri2uoa8Wr4uwALB1sOqxYLHWskuywrM4s660JbSctRO1irYBtnm28Ldo
t+C4WbjRuUq5wro7urW7LrunvCG8m70VvY++Cr6Evv+/er/1wHDA7MFnwePCX8Lbw1jD1MRRxM7FS8XI
xkbGw8dBx7/IPci8yTrJuco4yrfLNsu2zDXMtc01zbXONs62zzfPuNA50LrRPNG+0j/SwdNE08bUSdTL
1U7V0dZV1tjXXNfg2GTY6Nls2fHadtr724DcBdyK3RDdlt4c3qLfKd+v4DbgveFE4cziU+Lb42Pj6+Rz
5PzlhOYN5pbnH+ep6DLovOlG6dDqW+rl63Dr++yG7RHtnO4o7rTvQO/M8Fjw5fFy8f/yjPMZ86f0NPTC
9VD13vZt9vv3ivgZ+Kj5OPnH+lf65/t3/Af8mP0p/br+S/7c/23//3BhcmEAAAAAAAMAAAACZmYAAPKn
AAANWQAAE9AAAAoOdmNndAAAAAAAAAABAAEAAAAAAAAAAQAAAAEAAAAAAAAAAQAAAAEAAAAAAAAAAQAA
bmRpbgAAAAAAAAA2AACnwAAAVQAAAEuAAACgAAAAJgAAAAwAAABQQAAAVEAAAjMzAAIzMwACMzMAAAAA
AAAAAHNmMzIAAAAAAAELtwAABZb///NXAAAHKQAA/df///u3///9pgAAA9oAAMD2bW1vZAAAAAAAAAYQ
AACuA5v0iCnPTo6AAAAAAAAAAAAAAAAAAAAAANIqKywtWiRjbGFzc25hbWVYJGNsYXNzZXNfEBBOU0Jp
dG1hcEltYWdlUmVwoywuL1pOU0ltYWdlUmVwWE5TT2JqZWN00iorMTJXTlNBcnJheaIxL9IqKzQ1Xk5T
TXV0YWJsZUFycmF5ozQxL9M3OA85OjtXTlNXaGl0ZVxOU0NvbG9yU3BhY2VEMCAwABADgAzSKis9PldO
U0NvbG9yoj0v0iorQEFXTlNJbWFnZaJALwAIABEAGgAkACkAMgA3AEkATABRAFMAYgBoAHUAfACLAJIA
nwCmAK4AsACyALQAuQC7AL0AxgDLANYA2ADaANwA4QDkAOYA6ADqAO8BBgEIAQog7CDxIPwhBSEYIRwh
JyEwITUhPSFAIUUhVCFYIV8hZyF0IXkheyF9IYIhiiGNIZIhmgAAAAAAAAIBAAAAAAAAAEIAAAAAAAAA
AAAAAAAAACGdA
EiDAAACAA4ALWHsxNywgMTd90hsPHB5aTlMub2JqZWN0c6EdgASACtIbDyAjoiEigAWABoAJ0w8lJico
FF8QFE5TVElGRlJlcHJlc2VudGF0aW9uXxAZTlNJbnRlcm5hbExheW91dERpcmVjdGlvboAIgAdPER/e
TU0AKgAAEhjo6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/
6Ojo/+jo6P/o6Oj/ABIBAAADAAAAAQAiAAABAQADAAAAAQAiAAABAgADAAAABAAAEwYBAwADAAAAAQAB
AAABBgADAAAAAQACAAABCgADAAAAAQABAAABEQAEAAAAAQAAAAgBEgADAAAAAQABAAABFQADAAAAAQAE
AAABFgADAAAAAQAiAAABFwAEAAAAAQAAEhABGgAFAAAAAQAAEvYBGwAFAAAAAQAAEv4BHAADAAAAAQAB
AAABKAADAAAAAQACAAABUgADAAAAAQABAAABUwADAAAABAAAEw6HcwAHAAAMyAAAExYAAAAAAAAAkAAA
AAEAAACQAAAAAQAIAAgACAAIAAEAAQABAAEAAAzIYXBwbAIQAABtbnRyUkdCIFhZWiAH4AABAA0AFwAD
AB1hY3NwQVBQTAAAAABBUFBMAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWFwcGwAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFkZXNjAAABUAAAAGJkc2NtAAABtAAA
AbBjcHJ0AAADZAAAACN3dHB0AAADiAAAABRyWFlaAAADnAAAABRnWFlaAAADsAAAABRiWFlaAAADxAAA
ABRyVFJDAAAD2AAACAxhYXJnAAAL5AAAACB2Y2d0AAAMBAAAADBuZGluAAAMNAAAAD5jaGFkAAAMdAAA
ACxtbW9kAAAMoAAAAChiVFJDAAAD2AAACAxnVFJDAAAD2AAACAxhYWJnAAAL5AAAACBhYWdnAAAL5AAA
ACBkZXNjAAAAAAAAAAhEaXNwbGF5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbWx1YwAAAAAAAAAiAAAADGhy
SFIAAAAIAAABqGtvS1IAAAAIAAABqG5iTk8AAAAIAAABqGlkAAAAAAAIAAABqGh1SFUAAAAIAAABqGNz
Q1oAAAAIAAABqGRhREsAAAAIAAABqHVrVUEAAAAIAAABqGFyAAAAAAAIAAABqGl0SVQAAAAIAAABqHJv
Uk8AAAAIAAABqG5sTkwAAAAIAAABqGhlSUwAAAAIAAABqGVzRVMAAAAIAAABqGZpRkkAAAAIAAABqHpo
VFcAAAAIAAABqHZpVk4AAAAIAAABqHNrU0sAAAAIAAABqHpoQ04AAAAIAAABqHJ1UlUAAAAIAAABqGZy
RlIAAAAIAAABqG1zAAAAAAAIAAABqGNhRVMAAAAIAAABqHRoVEgAAAAIAAABqGVzWEwAAAAIAAABqGRl
REUAAAAIAAABqGVuVVMAAAAIAAABqHB0QlIAAAAIAAABqHBsUEwAAAAIAAABqGVsR1IAAAAIAAABqHN2
U0UAAAAIAAABqHRyVFIAAAAIAAABqGphSlAAAAAIAAABqHB0UFQAAAAIAAABqABpAE0AYQBjdGV4dAAA
AABDb3B5cmlnaHQgQXBwbGUgSW5jLiwgMjAxNgAAWFlaIAAAAAAAAPPYAAEAAAABFghYWVogAAAAAAAA
c9QAADomAAABblhZWiAAAAAAAABehgAAujcAABPtWFlaIAAAAAAAACR8AAALowAAvdJjdXJ2AAAAAAAA
BAAAAAAFAAoADwAUABkAHgAjACgALQAyADYAOwBAAEUASgBPAFQAWQBeAGMAaABtAHIAdwB8AIEAhgCL
AJAAlQCaAJ8AowCoAK0AsgC3ALwAwQDGAMsA0ADVANsA4ADlAOsA8AD2APsBAQEHAQ0BEwEZAR8BJQEr
ATIBOAE+AUUBTAFSAVkBYAFnAW4BdQF8AYMBiwGSAZoBoQGpAbEBuQHBAckB0QHZAeEB6QHyAfoCAwIM
AhQCHQImAi8COAJBAksCVAJdAmcCcQJ6AoQCjgKYAqICrAK2AsECywLVAuAC6wL1AwADCwMWAyEDLQM4
A0MDTwNaA2YDcgN+A4oDlgOiA64DugPHA9MD4APsA/kEBgQTBCAELQQ7BEgEVQRjBHEEfgSMBJoEqAS2
BMQE0wThBPAE/gUNBRwFKwU6BUkFWAVnBXcFhgWWBaYFtQXFBdUF5QX2BgYGFgYnBjcGSAZZBmoGewaM
Bp0GrwbABtEG4wb1BwcHGQcrBz0HTwdhB3QHhgeZB6wHvwfSB+UH+AgLCB8IMghGCFoIbgiCCJYIqgi+
CNII5wj7CRAJJQk6CU8JZAl5CY8JpAm6Cc8J5Qn7ChEKJwo9ClQKagqBCpgKrgrFCtwK8wsLCyILOQtR
C2kLgAuYC7ALyAvhC/kMEgwqDEMMXAx1DI4MpwzADNkM8w0NDSYNQA1aDXQNjg2pDcMN3g34DhMOLg5J
DmQOfw6bDrYO0g7uDwkPJQ9BD14Peg+WD7MPzw/sEAkQJhBDEGEQfhCbELkQ1xD1ERMRMRFPEW0RjBGq
EckR6BIHEiYSRRJkEoQSoxLDEuMTAxMjE0MTYxODE6QTxRPlFAYUJxRJFGoUixStFM4U8BUSFTQVVhV4
FZsVvRXgFgMWJhZJFmwWjxayFtYW+hcdF0EXZReJF64X0hf3GBsYQBhlGIoYrxjVGPoZIBlFGWsZkRm3
Gd0aBBoqGlEadxqeGsUa7BsUGzsbYxuKG7Ib2hwCHCocUhx7HKMczBz1HR4dRx1wHZkdwx3sHhYeQB5q
HpQevh7pHxMfPh9pH5Qfvx/qIBUgQSBsIJggxCDwIRwhSCF1IaEhziH7IiciVSKCIq8i3SMKIzgjZiOU
I8Ij8CQfJE0kfCSrJNolCSU4JWgllyXHJfcmJyZXJocmtyboJxgnSSd6J6sn3CgNKD8ocSiiKNQpBik4
KWspnSnQKgIqNSpoKpsqzysCKzYraSudK9EsBSw5LG4soizXLQwtQS12Last4S4WLkwugi63Lu4vJC9a
L5Evxy/+MDUwbDCkMNsxEjFKMYIxujHyMioyYzKbMtQzDTNGM38zuDPxNCs0ZTSeNNg1EzVNNYc1wjX9
Njc2cjauNuk3JDdgN5w31zgUOFA4jDjIOQU5Qjl/Obw5+To2OnQ6sjrvOy07azuqO+g8JzxlPKQ84z0i
PWE9oT3gPiA+YD6gPuA/IT9hP6I/4kAjQGRApkDnQSlBakGsQe5CMEJyQrVC90M6Q31DwEQDREdEikTO
RRJFVUWaRd5GIkZnRqtG8Ec1R3tHwEgFSEtIkUjXSR1JY0mpSfBKN0p9SsRLDEtTS5pL4kwqTHJMuk0C
TUpNk03cTiVObk63TwBPSU+TT91QJ1BxULtRBlFQUZtR5lIxUnxSx1MTU19TqlP2VEJUj1TbVShVdVXC
Vg9WXFapVvdXRFeSV+BYL1h9WMtZGllpWbhaB1pWWqZa9VtFW5Vb5Vw1XIZc1l0nXXhdyV4aXmxevV8P
X2Ffs2AFYFdgqmD8YU9homH1YklinGLwY0Njl2PrZEBklGTpZT1lkmXnZj1mkmboZz1nk2fpaD9olmjs
aUNpmmnxakhqn2r3a09rp2v/bFdsr20IbWBtuW4SbmtuxG8eb3hv0XArcIZw4HE6cZVx8HJLcqZzAXNd
c7h0FHRwdMx1KHWFdeF2Pnabdvh3VnezeBF4bnjMeSp5iXnnekZ6pXsEe2N7wnwhfIF84X1BfaF+AX5i
fsJ/I3+Ef+WAR4CogQqBa4HNgjCCkoL0g1eDuoQdhICE44VHhauGDoZyhteHO4efiASIaYjOiTOJmYn+
imSKyoswi5aL/IxjjMqNMY2Yjf+OZo7OjzaPnpAGkG6Q1pE/kaiSEZJ6kuOTTZO2lCCUipT0lV+VyZY0
lp+XCpd1l+CYTJi4mSSZkJn8mmia1ZtCm6+cHJyJnPedZJ3SnkCerp8dn4uf+qBpoNihR6G2oiailqMG
o3aj5qRWpMelOKWpphqmi6b9p26n4KhSqMSpN6mpqhyqj6sCq3Wr6axcrNCtRK24ri2uoa8Wr4uwALB1
sOqxYLHWskuywrM4s660JbSctRO1irYBtnm28Ldot+C4WbjRuUq5wro7urW7LrunvCG8m70VvY++Cr6E
vv+/er/1wHDA7MFnwePCX8Lbw1jD1MRRxM7FS8XIxkbGw8dBx7/IPci8yTrJuco4yrfLNsu2zDXMtc01
zbXONs62zzfPuNA50LrRPNG+0j/SwdNE08bUSdTL1U7V0dZV1tjXXNfg2GTY6Nls2fHadtr724DcBdyK
3RDdlt4c3qLfKd+v4DbgveFE4cziU+Lb42Pj6+Rz5PzlhOYN5pbnH+ep6DLovOlG6dDqW+rl63Dr++yG
7RHtnO4o7rTvQO/M8Fjw5fFy8f/yjPMZ86f0NPTC9VD13vZt9vv3ivgZ+Kj5OPnH+lf65/t3/Af8mP0p
/br+S/7c/23//3BhcmEAAAAAAAMAAAACZmYAAPKnAAANWQAAE9AAAAoOdmNndAAAAAAAAAABAAEAAAAA
AAAAAQAAAAEAAAAAAAAAAQAAAAEAAAAAAAAAAQAAbmRpbgAAAAAAAAA2AACnwAAAVQAAAEuAAACgAAAA
JgAAAAwAAABQQAAAVEAAAjMzAAIzMwACMzMAAAAAAAAAAHNmMzIAAAAAAAELtwAABZb///NXAAAHKQAA
/df///u3///9pgAAA9oAAMD2bW1vZAAAAAAAAAYQAACuA5v0iCnPTo6AAAAAAAAAAAAAAAAAAAAAANIr
LC0uWiRjbGFzc25hbWVYJGNsYXNzZXNfEBBOU0JpdG1hcEltYWdlUmVwoy0vMFpOU0ltYWdlUmVwWE5T
T2JqZWN00issMjNXTlNBcnJheaIyMNIrLDU2Xk5TTXV0YWJsZUFycmF5ozUyMNM4OQ86OzxXTlNXaGl0
ZVxOU0NvbG9yU3BhY2VEMCAwABADgAzSKyw+P1dOU0NvbG9yoj4w0issQUJXTlNJbWFnZaJBMAAIABEA
GgAkACkAMgA3AEkATABRAFMAYgBoAHUAfACLAJIAnwCmAK4AsACyALQAuQC7AL0AxgDLANYA2ADaANwA
4QDkAOYA6ADqAPEBCAEkASYBKCEKIQ8hGiEjITYhOiFFIU4hUyFbIV4hYyFyIXYhfSGFIZIhlyGZIZsh
oCGoIashsCG4AAAAAAAAAgEAAAAAAAAAQwAAAAAAAAAAAAAAAAAAIbs
</mutableData>
</image>
<image name="infoTemplate" width="16" height="16"/>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11129.15" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17132" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<development version="7000" identifier="xcode"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11129.15"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17132"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="SpotlightWindowController">
@ -15,18 +15,18 @@
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application"/>
<window title="Spotlight" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" hidesOnDeactivate="YES" oneShot="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="Spotlight" animationBehavior="default" id="1" customClass="NSPanel">
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Spotlight" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" hidesOnDeactivate="YES" visibleAtLaunch="NO" frameAutosaveName="Spotlight" animationBehavior="default" id="1" customClass="NSPanel">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" utility="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="192" width="480" height="320"/>
<rect key="screenRect" x="0.0" y="0.0" width="1280" height="1002"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="875"/>
<value key="minSize" type="size" width="400" height="260"/>
<view key="contentView" id="2">
<rect key="frame" x="0.0" y="0.0" width="480" height="320"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button verticalHuggingPriority="750" id="5">
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5">
<rect key="frame" x="335" y="275" width="131" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Add to Playlist" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6">
@ -41,15 +41,15 @@ DQ
<outlet property="nextKeyView" destination="28" id="205"/>
</connections>
</button>
<scrollView horizontalLineScroll="19" horizontalPageScroll="0.0" verticalLineScroll="19" verticalPageScroll="0.0" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="24">
<scrollView fixedFrame="YES" horizontalLineScroll="19" horizontalPageScroll="0.0" verticalLineScroll="19" verticalPageScroll="0.0" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="24">
<rect key="frame" x="20" y="44" width="440" height="228"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="zfU-bI-FkO">
<rect key="frame" x="1" y="0.0" width="438" height="227"/>
<rect key="frame" x="1" y="1" width="423" height="226"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" alternatingRowBackgroundColors="YES" autosaveName="CogSpotlightPlaylist" headerView="25" id="28" customClass="PlaylistView">
<rect key="frame" x="0.0" y="0.0" width="438" height="204"/>
<rect key="frame" x="0.0" y="0.0" width="447" height="203"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -57,7 +57,6 @@ DQ
<tableColumns>
<tableColumn identifier="title" editable="NO" width="129" minWidth="41" maxWidth="1000" id="36">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Title">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.33333299" alpha="1" colorSpace="calibratedWhite"/>
</tableHeaderCell>
@ -69,17 +68,16 @@ DQ
<sortDescriptor key="sortDescriptorPrototype" selector="caseInsensitiveCompare:" sortKey="title"/>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<connections>
<binding destination="186" name="fontSize" keyPath="values.fontSize" id="198"/>
<binding destination="16" name="value" keyPath="arrangedObjects.title" id="93">
<dictionary key="options">
<integer key="NSConditionallySetsEditable" value="1"/>
</dictionary>
</binding>
<binding destination="186" name="fontSize" keyPath="values.fontSize" id="198"/>
</connections>
</tableColumn>
<tableColumn identifier="artist" editable="NO" width="124" minWidth="36" maxWidth="1000" id="34">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Artist">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@ -91,17 +89,16 @@ DQ
<sortDescriptor key="sortDescriptorPrototype" selector="caseInsensitiveCompare:" sortKey="artist"/>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<connections>
<binding destination="186" name="fontSize" keyPath="values.fontSize" id="199"/>
<binding destination="16" name="value" keyPath="arrangedObjects.artist" id="104">
<dictionary key="options">
<integer key="NSConditionallySetsEditable" value="1"/>
</dictionary>
</binding>
<binding destination="186" name="fontSize" keyPath="values.fontSize" id="199"/>
</connections>
</tableColumn>
<tableColumn identifier="album" editable="NO" width="127" minWidth="39" maxWidth="1000" id="33">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Album">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@ -113,17 +110,16 @@ DQ
<sortDescriptor key="sortDescriptorPrototype" selector="caseInsensitiveCompare:" sortKey="album"/>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<connections>
<binding destination="186" name="fontSize" keyPath="values.fontSize" id="201"/>
<binding destination="16" name="value" keyPath="arrangedObjects.album" id="101">
<dictionary key="options">
<integer key="NSConditionallySetsEditable" value="1"/>
</dictionary>
</binding>
<binding destination="186" name="fontSize" keyPath="values.fontSize" id="201"/>
</connections>
</tableColumn>
<tableColumn identifier="length" editable="NO" width="50" minWidth="40.62012" maxWidth="1000" hidden="YES" id="32">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="Length">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@ -134,17 +130,16 @@ DQ
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<connections>
<binding destination="186" name="fontSize" keyPath="values.fontSize" id="208"/>
<binding destination="16" name="value" keyPath="arrangedObjects.length" id="105">
<dictionary key="options">
<integer key="NSConditionallySetsEditable" value="1"/>
</dictionary>
</binding>
<binding destination="186" name="fontSize" keyPath="values.fontSize" id="208"/>
</connections>
</tableColumn>
<tableColumn identifier="year" editable="NO" width="47" minWidth="10" maxWidth="1000" hidden="YES" id="31">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="Year">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@ -155,17 +150,16 @@ DQ
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<connections>
<binding destination="186" name="fontSize" keyPath="values.fontSize" id="211"/>
<binding destination="16" name="value" keyPath="arrangedObjects.year" id="94">
<dictionary key="options">
<integer key="NSConditionallySetsEditable" value="1"/>
</dictionary>
</binding>
<binding destination="186" name="fontSize" keyPath="values.fontSize" id="211"/>
</connections>
</tableColumn>
<tableColumn identifier="genre" editable="NO" width="46" minWidth="10" maxWidth="1000" hidden="YES" id="30">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Genre">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@ -177,17 +171,16 @@ DQ
<sortDescriptor key="sortDescriptorPrototype" selector="caseInsensitiveCompare:" sortKey="genre"/>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<connections>
<binding destination="186" name="fontSize" keyPath="values.fontSize" id="212"/>
<binding destination="16" name="value" keyPath="arrangedObjects.genre" id="102">
<dictionary key="options">
<integer key="NSConditionallySetsEditable" value="1"/>
</dictionary>
</binding>
<binding destination="186" name="fontSize" keyPath="values.fontSize" id="212"/>
</connections>
</tableColumn>
<tableColumn identifier="track" editable="NO" width="46" minWidth="8" maxWidth="46" id="29">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="Track">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@ -199,7 +192,6 @@ DQ
<sortDescriptor key="sortDescriptorPrototype" selector="compareTrackNumbers:" sortKey="spotlightTrack"/>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<connections>
<binding destination="186" name="fontSize" keyPath="values.fontSize" id="203"/>
<binding destination="16" name="value" keyPath="arrangedObjects.spotlightTrack" id="195">
<dictionary key="options">
<integer key="NSAllowsEditingMultipleValuesSelection" value="1"/>
@ -216,6 +208,7 @@ DQ
<integer key="NSValidatesImmediately" value="0"/>
</dictionary>
</binding>
<binding destination="186" name="fontSize" keyPath="values.fontSize" id="203"/>
</connections>
</tableColumn>
</tableColumns>
@ -231,25 +224,25 @@ DQ
</connections>
</tableView>
</subviews>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<nil key="backgroundColor"/>
</clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="26">
<rect key="frame" x="-100" y="-100" width="440" height="15"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" verticalHuggingPriority="750" horizontal="NO" id="27">
<rect key="frame" x="423" y="23" width="16" height="204"/>
<scroller key="verticalScroller" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="27">
<rect key="frame" x="424" y="24" width="15" height="203"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<tableHeaderView key="headerView" id="25">
<rect key="frame" x="0.0" y="0.0" width="438" height="23"/>
<tableHeaderView key="headerView" wantsLayer="YES" id="25">
<rect key="frame" x="0.0" y="0.0" width="447" height="23"/>
<autoresizingMask key="autoresizingMask"/>
</tableHeaderView>
<connections>
<outlet property="nextKeyView" destination="88" id="206"/>
</connections>
</scrollView>
<searchField wantsLayer="YES" verticalHuggingPriority="750" id="55">
<searchField wantsLayer="YES" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="55">
<rect key="frame" x="20" y="282" width="313" height="22"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" bezelStyle="round" id="56">
@ -262,7 +255,7 @@ DQ
<outlet property="nextKeyView" destination="5" id="204"/>
</connections>
</searchField>
<textField verticalHuggingPriority="750" id="79">
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="79">
<rect key="frame" x="174" y="13" width="108" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Search Location:" id="80">
@ -271,7 +264,7 @@ DQ
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<pathControl focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" id="88">
<pathControl focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="88">
<rect key="frame" x="284" y="9" width="176" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<pathCell key="cell" selectable="YES" editable="YES" focusRingType="none" alignment="left" pathStyle="popUp" id="89">
@ -293,6 +286,7 @@ DQ
<connections>
<outlet property="initialFirstResponder" destination="55" id="61"/>
</connections>
<point key="canvasLocation" x="17" y="109"/>
</window>
<arrayController objectClassName="SpotlightPlaylistEntry" preservesSelection="NO" selectsInsertedObjects="NO" avoidsEmptySelection="NO" clearsFilterPredicateOnInsertion="NO" id="16" customClass="SpotlightPlaylistController">
<declaredKeys>

5
Cog-Bridging-Header.h Normal file
View file

@ -0,0 +1,5 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import <CogAudio/Status.h>

View file

@ -143,8 +143,6 @@
838491231807F38A00E7332D /* NowPlayingBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8384911F1807F38A00E7332D /* NowPlayingBarController.m */; };
8384913C1808217300E7332D /* randomize.png in Resources */ = {isa = PBXBuildFile; fileRef = 8384913B1808217300E7332D /* randomize.png */; };
8384914018083E4E00E7332D /* filetype.icns in Resources */ = {isa = PBXBuildFile; fileRef = 8384913D18083E4E00E7332D /* filetype.icns */; };
8384914118083E4E00E7332D /* icon_blank.icns in Resources */ = {isa = PBXBuildFile; fileRef = 8384913E18083E4E00E7332D /* icon_blank.icns */; };
8384914218083E4E00E7332D /* icon_main.icns in Resources */ = {isa = PBXBuildFile; fileRef = 8384913F18083E4E00E7332D /* icon_main.icns */; };
8384915918083EAB00E7332D /* infoTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 8384914318083EAB00E7332D /* infoTemplate.pdf */; };
8384915A18083EAB00E7332D /* missingArt@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8384914418083EAB00E7332D /* missingArt@2x.png */; };
8384915B18083EAB00E7332D /* navigatorTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 8384914518083EAB00E7332D /* navigatorTemplate.pdf */; };
@ -172,8 +170,10 @@
83849174180843B200E7332D /* stopDockBadgeColorful.png in Resources */ = {isa = PBXBuildFile; fileRef = 83849171180843B200E7332D /* stopDockBadgeColorful.png */; };
838491871808591F00E7332D /* NDHotKey.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8384917E1808585D00E7332D /* NDHotKey.framework */; };
838491881808593200E7332D /* NDHotKey.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8384917E1808585D00E7332D /* NDHotKey.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
8398033A240B4AED003C54FA /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83980339240B4AED003C54FA /* Sparkle.framework */; };
8398033B240B4B0C003C54FA /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83980339240B4AED003C54FA /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
838F850125687C5C00C3E614 /* PlaybackStatusToHiddenTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 838F850025687C5C00C3E614 /* PlaybackStatusToHiddenTransformer.swift */; };
838F851C256B4AC400C3E614 /* icon_blank.icns in Resources */ = {isa = PBXBuildFile; fileRef = 838F851B256B4AC400C3E614 /* icon_blank.icns */; };
838F851E256B4E5E00C3E614 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838F851D256B4E5E00C3E614 /* Sparkle.framework */; };
838F851F256B4E8B00C3E614 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 838F851D256B4E5E00C3E614 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
8399D4E21805A55000B503B1 /* XmlContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8399D4E01805A55000B503B1 /* XmlContainer.m */; };
83A360B220E4E81D00192DAB /* Flac.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8303A30C20E4E3D000951EF8 /* Flac.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
83B06704180D579E008E3612 /* MIDI.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B066A1180D5669008E3612 /* MIDI.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
@ -185,6 +185,7 @@
83BC5AC320E4CE8D00631CD4 /* SpotlightPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = 178456C00F6320B5007E8021 /* SpotlightPanel.xib */; };
83BC5AC420E4CE9000631CD4 /* Feedback.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B1DA0F6330D400694C57 /* Feedback.xib */; };
83BCB8DE17FC971300760340 /* FFMPEG.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = B09E94350D747F7B0064F138 /* FFMPEG.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
83D0380F24A40DFB004CF90F /* CogAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83D0380E24A40DF2004CF90F /* CogAssets.xcassets */; };
83E5E54C18087CA5001F3284 /* miniModeOffTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 83E5E54A18087CA5001F3284 /* miniModeOffTemplate.pdf */; };
83E5E54D18087CA5001F3284 /* miniModeOnTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 83E5E54B18087CA5001F3284 /* miniModeOnTemplate.pdf */; };
83EEAB241C965C56002761C5 /* Syntrax.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83EEAAFA1C9651D8002761C5 /* Syntrax.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@ -669,7 +670,7 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
8398033B240B4B0C003C54FA /* Sparkle.framework in CopyFiles */,
838F851F256B4E8B00C3E614 /* Sparkle.framework in CopyFiles */,
838491881808593200E7332D /* NDHotKey.framework in CopyFiles */,
17F561400C3BD4F30019975C /* CogAudio.framework in CopyFiles */,
);
@ -683,7 +684,6 @@
07E18DF10D62B38400BB0E11 /* NSArray+ShuffleUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+ShuffleUtils.h"; sourceTree = "<group>"; };
07E18DF20D62B38400BB0E11 /* NSArray+ShuffleUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+ShuffleUtils.m"; sourceTree = "<group>"; };
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
170680620B950158006BA573 /* Growl.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Growl.framework; path = ThirdParty/Frameworks/Growl.framework; sourceTree = "<group>"; };
170B55920D6E5E7B006B9E92 /* StatusImageTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StatusImageTransformer.h; sourceTree = "<group>"; };
170B55930D6E5E7B006B9E92 /* StatusImageTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StatusImageTransformer.m; sourceTree = "<group>"; };
171B57D90C091F2B00F6AFAF /* flac.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = flac.icns; sourceTree = "<group>"; };
@ -896,8 +896,6 @@
8384912518080F2D00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = "<group>"; };
8384913B1808217300E7332D /* randomize.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = randomize.png; path = Images/randomize.png; sourceTree = "<group>"; };
8384913D18083E4E00E7332D /* filetype.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = filetype.icns; sourceTree = "<group>"; };
8384913E18083E4E00E7332D /* icon_blank.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = icon_blank.icns; sourceTree = "<group>"; };
8384913F18083E4E00E7332D /* icon_main.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = icon_main.icns; sourceTree = "<group>"; };
8384914318083EAB00E7332D /* infoTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = infoTemplate.pdf; path = Images/infoTemplate.pdf; sourceTree = "<group>"; };
8384914418083EAB00E7332D /* missingArt@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "missingArt@2x.png"; path = "Images/missingArt@2x.png"; sourceTree = "<group>"; };
8384914518083EAB00E7332D /* navigatorTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = navigatorTemplate.pdf; path = Images/navigatorTemplate.pdf; sourceTree = "<group>"; };
@ -925,7 +923,10 @@
83849171180843B200E7332D /* stopDockBadgeColorful.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = stopDockBadgeColorful.png; path = Images/stopDockBadgeColorful.png; sourceTree = "<group>"; };
838491791808585C00E7332D /* NDHotKey.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = NDHotKey.xcodeproj; path = Frameworks/NDHotKey/NDHotKey.xcodeproj; sourceTree = "<group>"; };
83859520234FEB35004E9946 /* Cog.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Cog.entitlements; sourceTree = "<group>"; };
83980339240B4AED003C54FA /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = ThirdParty/Sparkle/Sparkle.framework; sourceTree = "<group>"; };
838F84FF25687C5C00C3E614 /* Cog-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Cog-Bridging-Header.h"; sourceTree = "<group>"; };
838F850025687C5C00C3E614 /* PlaybackStatusToHiddenTransformer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PlaybackStatusToHiddenTransformer.swift; path = Transformers/PlaybackStatusToHiddenTransformer.swift; sourceTree = "<group>"; };
838F851B256B4AC400C3E614 /* icon_blank.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = icon_blank.icns; sourceTree = "<group>"; };
838F851D256B4E5E00C3E614 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = ThirdParty/Frameworks/Sparkle.framework; sourceTree = "<group>"; };
8399D4E01805A55000B503B1 /* XmlContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XmlContainer.m; sourceTree = "<group>"; };
8399D4E11805A55000B503B1 /* XmlContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XmlContainer.h; sourceTree = "<group>"; };
83AB9031237CEFD300A433D5 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };
@ -950,6 +951,7 @@
83BC5AD820E4D0D900631CD4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/SpotlightPanel.strings; sourceTree = "<group>"; };
83BC5ADA20E4D0E900631CD4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Feedback.strings; sourceTree = "<group>"; };
83BC5ADC20E4D0EC00631CD4 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Feedback.strings; sourceTree = "<group>"; };
83D0380E24A40DF2004CF90F /* CogAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = CogAssets.xcassets; sourceTree = "<group>"; };
83D3C5FC201C674D005564CB /* AdPlug.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AdPlug.xcodeproj; path = Plugins/AdPlug/AdPlug.xcodeproj; sourceTree = "<group>"; };
83E5E54A18087CA5001F3284 /* miniModeOffTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = miniModeOffTemplate.pdf; path = Images/miniModeOffTemplate.pdf; sourceTree = "<group>"; };
83E5E54B18087CA5001F3284 /* miniModeOnTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = miniModeOnTemplate.pdf; path = Images/miniModeOnTemplate.pdf; sourceTree = "<group>"; };
@ -994,7 +996,7 @@
17BB5CED0B8A86010009ACB1 /* AudioToolbox.framework in Frameworks */,
17BB5CF90B8A86350009ACB1 /* AudioUnit.framework in Frameworks */,
17BB5CFA0B8A86350009ACB1 /* CoreAudio.framework in Frameworks */,
8398033A240B4AED003C54FA /* Sparkle.framework in Frameworks */,
838F851E256B4E5E00C3E614 /* Sparkle.framework in Frameworks */,
17BB5CFB0B8A86350009ACB1 /* CoreAudioKit.framework in Frameworks */,
17BB5EA60B8A87850009ACB1 /* IOKit.framework in Frameworks */,
);
@ -1035,9 +1037,9 @@
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
isa = PBXGroup;
children = (
838F851D256B4E5E00C3E614 /* Sparkle.framework */,
838491791808585C00E7332D /* NDHotKey.xcodeproj */,
17F5612A0C3BD4DC0019975C /* CogAudio.xcodeproj */,
170680620B950158006BA573 /* Growl.framework */,
8E6889230AAA403C00AD3950 /* Carbon.framework */,
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
);
@ -1047,7 +1049,6 @@
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
isa = PBXGroup;
children = (
83980339240B4AED003C54FA /* Sparkle.framework */,
17BB5EA50B8A87850009ACB1 /* IOKit.framework */,
17BB5CF60B8A86350009ACB1 /* AudioUnit.framework */,
17BB5CF70B8A86350009ACB1 /* CoreAudio.framework */,
@ -1387,6 +1388,8 @@
17E0D6130F520F87005B6FED /* FontSizetoLineHeightTransformer.m */,
17E0D6140F520F87005B6FED /* StringToURLTransformer.h */,
17E0D6150F520F87005B6FED /* StringToURLTransformer.m */,
838F850025687C5C00C3E614 /* PlaybackStatusToHiddenTransformer.swift */,
838F84FF25687C5C00C3E614 /* Cog-Bridging-Header.h */,
);
name = Transformers;
sourceTree = "<group>";
@ -1426,6 +1429,7 @@
29B97314FDCFA39411CA2CEA /* Cog */ = {
isa = PBXGroup;
children = (
83D0380E24A40DF2004CF90F /* CogAssets.xcassets */,
83859520234FEB35004E9946 /* Cog.entitlements */,
080E96DDFE201D6D7F000001 /* Classes */,
29B97315FDCFA39411CA2CEA /* Other Sources */,
@ -1736,9 +1740,8 @@
8E75758E09F31D800080F1EE /* Icons */ = {
isa = PBXGroup;
children = (
838F851B256B4AC400C3E614 /* icon_blank.icns */,
8384913D18083E4E00E7332D /* filetype.icns */,
8384913E18083E4E00E7332D /* icon_blank.icns */,
8384913F18083E4E00E7332D /* icon_main.icns */,
17D1B2760CF8B2830028F5B5 /* cue.icns */,
17D1B2770CF8B2830028F5B5 /* it.icns */,
17D1B2780CF8B2830028F5B5 /* pls.icns */,
@ -1849,6 +1852,7 @@
TargetAttributes = {
8D1107260486CEB800E47090 = {
DevelopmentTeam = 4S876G9VCD;
LastSwiftMigration = 1220;
ProvisioningStyle = Automatic;
};
};
@ -2221,7 +2225,6 @@
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
17E41E070C130DFF00AC744D /* Credits.html in Resources */,
8384916618083EAB00E7332D /* repeatModeOneTemplate.pdf in Resources */,
8384914118083E4E00E7332D /* icon_blank.icns in Resources */,
8E7575DB09F31E930080F1EE /* Localizable.strings in Resources */,
177EC04B0B8BC2FF0000BC8C /* next.png in Resources */,
177EC04D0B8BC2FF0000BC8C /* pause.png in Resources */,
@ -2241,7 +2244,6 @@
8384916018083EAB00E7332D /* playTemplate.pdf in Resources */,
1766C8940B912FB4004A7AE4 /* info_off.png in Resources */,
1766C8950B912FB4004A7AE4 /* info_on.png in Resources */,
8384914218083E4E00E7332D /* icon_main.icns in Resources */,
8384915E18083EAB00E7332D /* pauseTemplate.pdf in Resources */,
1766C8980B912FB4004A7AE4 /* shuffle_off.png in Resources */,
8384916D18083EAB00E7332D /* volume1Template.pdf in Resources */,
@ -2260,6 +2262,7 @@
17818A980C0B27AC001C4916 /* mpc.icns in Resources */,
83E5E54D18087CA5001F3284 /* miniModeOnTemplate.pdf in Resources */,
17818A990C0B27AC001C4916 /* shn.icns in Resources */,
838F851C256B4AC400C3E614 /* icon_blank.icns in Resources */,
17818A9A0C0B27AC001C4916 /* wav.icns in Resources */,
17818A9B0C0B27AC001C4916 /* wv.icns in Resources */,
1791005E0CB44D6D0070BC5C /* Cog.scriptSuite in Resources */,
@ -2269,6 +2272,7 @@
8384913C1808217300E7332D /* randomize.png in Resources */,
8384915A18083EAB00E7332D /* missingArt@2x.png in Resources */,
17D1B27E0CF8B2830028F5B5 /* it.icns in Resources */,
83D0380F24A40DFB004CF90F /* CogAssets.xcassets in Resources */,
8384914018083E4E00E7332D /* filetype.icns in Resources */,
8384916918083EAB00E7332D /* shuffleOnTemplate.pdf in Resources */,
17D1B27F0CF8B2830028F5B5 /* pls.icns in Resources */,
@ -2307,7 +2311,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PROJECT_DIR}/Scripts/genversion.sh\"\nif [ \"${EXPANDED_CODE_SIGN_IDENTITY_NAME}\" != \"\" ]; then codesign --verbose --force --deep -o runtime --sign \"${EXPANDED_CODE_SIGN_IDENTITY_NAME}\" \"${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/AutoUpdate.app\"; fi\n";
shellScript = "\"${PROJECT_DIR}/Scripts/genversion.sh\"\n";
};
/* End PBXShellScriptBuildPhase section */
@ -2349,6 +2353,7 @@
07E18DF30D62B38400BB0E11 /* NSArray+ShuffleUtils.m in Sources */,
56C63D910D647DF300EAE25A /* NSComparisonPredicate+CogPredicate.m in Sources */,
56DB084C0D6717DC00453B6A /* NSNumber+CogSort.m in Sources */,
838F850125687C5C00C3E614 /* PlaybackStatusToHiddenTransformer.swift in Sources */,
56DB08550D67185300453B6A /* NSArray+CogSort.m in Sources */,
170B55940D6E5E7B006B9E92 /* StatusImageTransformer.m in Sources */,
17249F0F0D82E17700F33392 /* ToggleQueueTitleTransformer.m in Sources */,
@ -2641,6 +2646,9 @@
C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "Cog Icon Precomposed";
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = "Cog color";
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Cog.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
@ -2659,7 +2667,7 @@
INSTALL_PATH = "$(HOME)/Applications";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(inherited)";
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
OTHER_CFLAGS = (
"-D__MACOSX__",
"-DHAVE_CONFIG_H",
@ -2679,6 +2687,9 @@
PRODUCT_NAME = Cog;
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SWIFT_OBJC_BRIDGING_HEADER = "Cog-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
WRAPPER_EXTENSION = app;
};
name = Debug;
@ -2686,6 +2697,9 @@
C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "Cog Icon Precomposed";
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = "Cog color";
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Cog.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
@ -2701,7 +2715,7 @@
INSTALL_PATH = "$(HOME)/Applications";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(inherited)";
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
OTHER_CFLAGS = (
"-D__MACOSX__",
"-DHAVE_CONFIG_H",
@ -2721,6 +2735,8 @@
PRODUCT_NAME = Cog;
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SWIFT_OBJC_BRIDGING_HEADER = "Cog-Bridging-Header.h";
SWIFT_VERSION = 5.0;
WRAPPER_EXTENSION = app;
};
name = Release;
@ -2760,7 +2776,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.7;
MACOSX_DEPLOYMENT_TARGET = 10.9;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
@ -2799,7 +2815,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.7;
MACOSX_DEPLOYMENT_TARGET = 10.9;
SDKROOT = macosx;
};
name = Release;

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 KiB

View file

@ -0,0 +1,68 @@
{
"images" : [
{
"filename" : "Cog Icon Precomposed_16.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"filename" : "Cog Icon Precomposed_16@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"filename" : "Cog Icon Precomposed_32.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"filename" : "Cog Icon Precomposed_32@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"filename" : "Cog Icon Precomposed_128.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"filename" : "Cog Icon Precomposed_128@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"filename" : "Cog Icon Precomposed_256.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"filename" : "Cog Icon Precomposed_256@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"filename" : "Cog Icon Precomposed_512.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"filename" : "Cog Icon Precomposed_512@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1,56 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.003",
"green" : "0.506",
"red" : "1.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.003",
"green" : "0.431",
"red" : "0.869"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.003",
"green" : "0.620",
"red" : "1.000"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -566,7 +566,7 @@
TargetAttributes = {
83D3C4D3201C654F005564CB = {
CreatedOnToolsVersion = 9.2;
ProvisioningStyle = Manual;
ProvisioningStyle = Automatic;
};
};
};
@ -742,7 +742,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
@ -796,7 +796,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
VERSIONING_SYSTEM = "apple-generic";
@ -807,10 +807,10 @@
83D3C4DD201C6550005564CB /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -836,10 +836,10 @@
83D3C4DE201C6550005564CB /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;

View file

@ -424,8 +424,8 @@
LastUpgradeCheck = 1020;
TargetAttributes = {
8DC2EF4F0486A6940098B216 = {
DevelopmentTeam = N6E749HJ2X;
ProvisioningStyle = Manual;
DevelopmentTeam = 4S876G9VCD;
ProvisioningStyle = Automatic;
};
};
};
@ -489,8 +489,11 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -520,6 +523,7 @@
PRIVATE_HEADERS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)/PrivateHeaders";
PRODUCT_BUNDLE_IDENTIFIER = org.xiph.libflac;
PRODUCT_NAME = FLAC;
PROVISIONING_PROFILE_SPECIFIER = "";
PUBLIC_HEADERS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)/Headers";
SKIP_INSTALL = YES;
USER_HEADER_SEARCH_PATHS = "";
@ -533,7 +537,10 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -561,6 +568,7 @@
PRIVATE_HEADERS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)/PrivateHeaders";
PRODUCT_BUNDLE_IDENTIFIER = org.xiph.libflac;
PRODUCT_NAME = FLAC;
PROVISIONING_PROFILE_SPECIFIER = "";
PUBLIC_HEADERS_FOLDER_PATH = "$(CONTENTS_FOLDER_PATH)/Headers";
SKIP_INSTALL = YES;
USER_HEADER_SEARCH_PATHS = "";
@ -602,7 +610,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SYMROOT = ../../build;
@ -641,7 +649,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
SDKROOT = macosx;
SYMROOT = ../../build;
USE_SEPERATE_HEADERMAPS = YES;

View file

@ -623,8 +623,8 @@
ORGANIZATIONNAME = "Christopher Snowhill";
TargetAttributes = {
8359FF3B17FEF39F0060F3ED = {
DevelopmentTeam = N6E749HJ2X;
ProvisioningStyle = Manual;
DevelopmentTeam = 4S876G9VCD;
ProvisioningStyle = Automatic;
};
};
};
@ -791,7 +791,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
@ -837,7 +837,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
SDKROOT = macosx;
};
name = Release;
@ -845,7 +845,10 @@
8359FF6517FEF39F0060F3ED /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -859,6 +862,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.fileextractor;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SKIP_INSTALL = YES;
WRAPPER_EXTENSION = framework;
@ -868,7 +872,10 @@
8359FF6617FEF39F0060F3ED /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -882,6 +889,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.fileextractor;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SKIP_INSTALL = YES;
WRAPPER_EXTENSION = framework;

View file

@ -1284,8 +1284,8 @@
LastUpgradeCheck = 1020;
TargetAttributes = {
8DC2EF4F0486A6940098B216 = {
DevelopmentTeam = N6E749HJ2X;
ProvisioningStyle = Manual;
DevelopmentTeam = 4S876G9VCD;
ProvisioningStyle = Automatic;
};
};
};
@ -1492,8 +1492,11 @@
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -1512,6 +1515,7 @@
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.lib.gme;
PRODUCT_NAME = GME;
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SHARED_PRECOMPS_DIR = "";
SKIP_INSTALL = YES;
@ -1526,7 +1530,10 @@
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -1543,6 +1550,7 @@
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.lib.gme;
PRODUCT_NAME = GME;
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SHARED_PRECOMPS_DIR = "";
SKIP_INSTALL = YES;
@ -1585,7 +1593,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
OBJROOT = ../../build;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
@ -1625,7 +1633,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
OBJROOT = ../../build;
SDKROOT = macosx;
SYMROOT = ../../build;

View file

@ -32,8 +32,12 @@
#ifndef _WIN32
#define __cdecl
#ifdef __aarch64__
#define __fastcall
#else
#define __fastcall __attribute__((regparm(3)))
#endif
#endif
/* No dynarec for x86_64 yet */
#if defined(_WIN32) || defined(__i386__)

View file

@ -239,8 +239,8 @@
ORGANIZATIONNAME = "Christopher Snowhill";
TargetAttributes = {
8343793417F97BDB00584396 = {
DevelopmentTeam = N6E749HJ2X;
ProvisioningStyle = Manual;
DevelopmentTeam = 4S876G9VCD;
ProvisioningStyle = Automatic;
};
};
};
@ -353,7 +353,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
@ -398,7 +398,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
SDKROOT = macosx;
};
name = Release;
@ -406,7 +406,10 @@
8343795E17F97BDB00584396 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -419,6 +422,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.highlyadvanced;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SKIP_INSTALL = YES;
WRAPPER_EXTENSION = framework;
@ -428,7 +432,10 @@
8343795F17F97BDB00584396 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -438,6 +445,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.highlyadvanced;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SKIP_INSTALL = YES;
WRAPPER_EXTENSION = framework;

View file

@ -178,8 +178,8 @@
ORGANIZATIONNAME = "Christopher Snowhill";
TargetAttributes = {
8360EF0F17F92C91005208A4 = {
DevelopmentTeam = N6E749HJ2X;
ProvisioningStyle = Manual;
DevelopmentTeam = 4S876G9VCD;
ProvisioningStyle = Automatic;
};
};
};
@ -290,7 +290,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
ONLY_ACTIVE_ARCH = YES;
};
name = Debug;
@ -334,14 +334,17 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
};
name = Release;
};
8360EF3917F92C91005208A4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -357,6 +360,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.highlyexperimental;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
WRAPPER_EXTENSION = framework;
};
@ -365,7 +369,10 @@
8360EF3A17F92C91005208A4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -380,6 +387,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.highlyexperimental;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
WRAPPER_EXTENSION = framework;
};

View file

@ -150,8 +150,8 @@
ORGANIZATIONNAME = "Christopher Snowhill";
TargetAttributes = {
834378DD17F96E2600584396 = {
DevelopmentTeam = N6E749HJ2X;
ProvisioningStyle = Manual;
DevelopmentTeam = 4S876G9VCD;
ProvisioningStyle = Automatic;
};
};
};
@ -260,7 +260,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SKIP_INSTALL = YES;
@ -311,7 +311,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
SDKROOT = macosx;
SKIP_INSTALL = YES;
};
@ -320,7 +320,10 @@
8343790717F96E2600584396 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -329,6 +332,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.highlyquixotic;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
WRAPPER_EXTENSION = framework;
};
@ -337,7 +341,10 @@
8343790817F96E2600584396 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -346,6 +353,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.highlyquixotic;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
WRAPPER_EXTENSION = framework;
};

View file

@ -192,8 +192,8 @@
ORGANIZATIONNAME = "Christopher Snowhill";
TargetAttributes = {
8343786D17F9658E00584396 = {
DevelopmentTeam = N6E749HJ2X;
ProvisioningStyle = Manual;
DevelopmentTeam = 4S876G9VCD;
ProvisioningStyle = Automatic;
};
};
};
@ -308,7 +308,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
@ -361,7 +361,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
SDKROOT = macosx;
};
name = Release;
@ -369,7 +369,10 @@
8343789717F9658E00584396 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -378,6 +381,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.highlytheoretical;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SKIP_INSTALL = YES;
WRAPPER_EXTENSION = framework;
@ -387,7 +391,10 @@
8343789817F9658E00584396 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -396,6 +403,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.highlytheoretical;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SKIP_INSTALL = YES;
WRAPPER_EXTENSION = framework;

View file

@ -24,8 +24,12 @@
#ifndef _WIN32
#define __cdecl
#ifdef __aarch64__
#define __fastcall
#else
#define __fastcall __attribute__((regparm(3)))
#endif
#endif
/* No dynarec for x86_64 yet */
#if defined(_WIN32) || defined(__i386__)

View file

@ -132,8 +132,8 @@
ORGANIZATIONNAME = "Christopher Snowhill";
TargetAttributes = {
836FB555182053D700B3AD2D = {
DevelopmentTeam = N6E749HJ2X;
ProvisioningStyle = Manual;
DevelopmentTeam = 4S876G9VCD;
ProvisioningStyle = Automatic;
};
};
};
@ -238,7 +238,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SKIP_INSTALL = YES;
@ -285,7 +285,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
SDKROOT = macosx;
SKIP_INSTALL = YES;
};
@ -294,7 +294,10 @@
836FB57F182053D700B3AD2D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -302,6 +305,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.hivelyplayer;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
WRAPPER_EXTENSION = framework;
};
@ -310,7 +314,10 @@
836FB580182053D700B3AD2D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -318,6 +325,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.hivelyplayer;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
WRAPPER_EXTENSION = framework;
};

View file

@ -18,8 +18,13 @@ typedef char TEXT;
#ifdef _WIN32
typedef int BOOL;
#else
#ifdef __aarch64__
#include <stdbool.h>
typedef bool BOOL;
#else
typedef signed char BOOL;
#endif
#endif
#define TRUE 1
#define FALSE 0

View file

@ -232,8 +232,8 @@
LastUpgradeCheck = 1020;
TargetAttributes = {
8DC2EF4F0486A6940098B216 = {
DevelopmentTeam = N6E749HJ2X;
ProvisioningStyle = Manual;
DevelopmentTeam = 4S876G9VCD;
ProvisioningStyle = Automatic;
};
};
};
@ -306,8 +306,11 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -321,6 +324,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.lib.mpcdec;
PRODUCT_NAME = mpcdec;
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SKIP_INSTALL = YES;
WRAPPER_EXTENSION = framework;
@ -332,7 +336,10 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -343,6 +350,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.lib.mpcdec;
PRODUCT_NAME = mpcdec;
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SKIP_INSTALL = YES;
USER_HEADER_SEARCH_PATHS = Files/include/;
@ -383,7 +391,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SYMROOT = ../../build;
@ -421,7 +429,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
SDKROOT = macosx;
SYMROOT = ../../build;
};

View file

@ -155,8 +155,8 @@
ORGANIZATIONNAME = "dmitry.promsky@gmail.com";
TargetAttributes = {
32F1615514E6BB3B00D6AB2F = {
DevelopmentTeam = N6E749HJ2X;
ProvisioningStyle = Manual;
DevelopmentTeam = 4S876G9VCD;
ProvisioningStyle = Automatic;
};
};
};
@ -260,7 +260,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SYMROOT = ../../build;
@ -303,7 +303,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
SDKROOT = macosx;
SYMROOT = ../../build;
};
@ -312,7 +312,10 @@
32F1616C14E6BB3B00D6AB2F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -322,6 +325,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "ND.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SKIP_INSTALL = YES;
WRAPPER_EXTENSION = framework;
@ -331,7 +335,10 @@
32F1616D14E6BB3B00D6AB2F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -341,6 +348,7 @@
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "ND.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SKIP_INSTALL = YES;
WRAPPER_EXTENSION = framework;

View file

@ -176,8 +176,8 @@
DevelopmentTeam = N6E749HJ2X;
};
8D07F2BC0486CC7A007CD1D0 = {
DevelopmentTeam = N6E749HJ2X;
ProvisioningStyle = Manual;
DevelopmentTeam = 4S876G9VCD;
ProvisioningStyle = Automatic;
};
};
};
@ -259,11 +259,11 @@
730F235509181A3A00AB638C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
DEVELOPMENT_TEAM = N6E749HJ2X;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -273,7 +273,7 @@
GCC_PREFIX_HEADER = Ogg_Prefix.pch;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "@loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
PRODUCT_BUNDLE_IDENTIFIER = org.xiph.ogg;
PRODUCT_NAME = Ogg;
PROVISIONING_PROFILE_SPECIFIER = "";
@ -286,11 +286,11 @@
730F235609181A3A00AB638C /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
DEVELOPMENT_TEAM = N6E749HJ2X;
DEVELOPMENT_TEAM = 4S876G9VCD;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -299,7 +299,7 @@
GCC_PREFIX_HEADER = Ogg_Prefix.pch;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "@loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.13;
PRODUCT_BUNDLE_IDENTIFIER = org.xiph.ogg;
PRODUCT_NAME = Ogg;
PROVISIONING_PROFILE_SPECIFIER = "";

View file

@ -1,4 +1,4 @@
Copyright (c) 2004-2019, OpenMPT contributors
Copyright (c) 2004-2020, OpenMPT contributors
Copyright (c) 1997-2003, Olivier Lapicque
All rights reserved.

View file

@ -54,7 +54,7 @@
# ONLY_TEST=0 Only build the test suite.
# STRICT=0 Treat warnings as errors.
# MODERN=0 Pass more modern compiler options.
# STDCXX=c++11 C++ standard version (only for GCC and clang)
# STDCXX=c++14 C++ standard version (only for GCC and clang)
# CHECKED=0 Enable run-time assertions.
# CHECKED_ADDRESS=0 Enable address sanitizer
# CHECKED_UNDEFINED=0 Enable undefined behaviour sanitizer
@ -69,6 +69,11 @@
# NO_VORBIS=1 Avoid using libvorbis, even if found
# NO_VORBISFILE=1 Avoid using libvorbisfile, even if found
#
# LOCAL_ZLIB=1 Build local copy of zlib, even if found
# LOCAL_MPG123=1 Build local copy of libmpg123, even if found
# LOCAL_OGG=1 Build local copy of libogg, even if found
# LOCAL_VORBIS=1 Build local copy of libvorbis, even if found
#
# NO_MINIMP3=1 Do not fallback to minimp3
# NO_STBVORBIS=1 Do not fallback to stb_vorbis
#
@ -86,7 +91,6 @@
# (defaults are 0):
#
# NO_PULSEAUDIO=1 Avoid using PulseAudio, even if found
# NO_SDL=1 Avoid using SDL, even if found
# NO_SDL2=1 Avoid using SDL2, even if found
# NO_FLAC=1 Avoid using FLAC, even if found
# NO_SNDFILE=1 Avoid using libsndfile, even if found
@ -158,6 +162,7 @@ TEST=1
ONLY_TEST=0
SOSUFFIX=.so
SOSUFFIXWINDOWS=0
NO_SHARED_LINKER_FLAG=0
OPENMPT123=1
MODERN=0
STRICT=0
@ -290,7 +295,7 @@ INSTALL_LIB = $(INSTALL) -m 0644
INSTALL_DATA_DIR = $(INSTALL_DIR)
INSTALL_MAKE_DIR += -m 0755
CPPFLAGS += -Icommon -I. -Iinclude/modplug/include -Iinclude
CPPFLAGS += -Icommon -I. -Iinclude
ifeq ($(MPT_COMPILER_GENERIC),1)
@ -407,6 +412,30 @@ ifeq ($(HACK_ARCHIVE_SUPPORT),1)
NO_ZLIB:=1
endif
ifeq ($(LOCAL_ZLIB),1)
CPPFLAGS_ZLIB := -DMPT_WITH_ZLIB
LDFLAGS_ZLIB :=
LDLIBS_ZLIB :=
CPPFLAGS_ZLIB += -Iinclude/zlib/
LOCAL_ZLIB_SOURCES :=
LOCAL_ZLIB_SOURCES += include/zlib/adler32.c
LOCAL_ZLIB_SOURCES += include/zlib/compress.c
LOCAL_ZLIB_SOURCES += include/zlib/crc32.c
LOCAL_ZLIB_SOURCES += include/zlib/deflate.c
LOCAL_ZLIB_SOURCES += include/zlib/gzclose.c
LOCAL_ZLIB_SOURCES += include/zlib/gzlib.c
LOCAL_ZLIB_SOURCES += include/zlib/gzread.c
LOCAL_ZLIB_SOURCES += include/zlib/gzwrite.c
LOCAL_ZLIB_SOURCES += include/zlib/infback.c
LOCAL_ZLIB_SOURCES += include/zlib/inffast.c
LOCAL_ZLIB_SOURCES += include/zlib/inflate.c
LOCAL_ZLIB_SOURCES += include/zlib/inftrees.c
LOCAL_ZLIB_SOURCES += include/zlib/trees.c
LOCAL_ZLIB_SOURCES += include/zlib/uncompr.c
LOCAL_ZLIB_SOURCES += include/zlib/zutil.c
include/zlib/%.o : CFLAGS+=$(CFLAGS_SILENT) -DSTDC -DZ_HAVE_UNISTD_H
include/zlib/%.test.o : CFLAGS+=$(CFLAGS_SILENT) -DSTDC -DZ_HAVE_UNISTD_H
else
ifeq ($(NO_ZLIB),1)
else
#LDLIBS += -lz
@ -424,7 +453,44 @@ endif
NO_ZLIB:=1
endif
endif
endif
ifeq ($(LOCAL_MPG123),1)
CPPFLAGS_MPG123 := -DMPT_WITH_MPG123
LDFLAGS_MPG123 :=
LDLIBS_MPG123 :=
CPPFLAGS_MPG123 += -Iinclude/mpg123/src/libmpg123/ -Iinclude/mpg123/src/compat/ -Iinclude/mpg123/src/ -Iinclude/mpg123/ports/makefile/
LOCAL_MPG123_SOURCES :=
LOCAL_MPG123_SOURCES += include/mpg123/src/compat/compat.c
LOCAL_MPG123_SOURCES += include/mpg123/src/compat/compat_str.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/dct64.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/equalizer.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/feature.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/format.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/frame.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/icy.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/icy2utf8.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/id3.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/index.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/layer1.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/layer2.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/layer3.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/libmpg123.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/ntom.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/optimize.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/parse.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/readers.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/stringbuf.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/synth.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/synth_8bit.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/synth_real.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/synth_s32.c
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/tabinit.c
include/mpg123/src/compat/%.o : CFLAGS+=$(CFLAGS_SILENT) -DOPT_GENERIC
include/mpg123/src/compat/%.test.o : CFLAGS+=$(CFLAGS_SILENT) -DOPT_GENERIC
include/mpg123/src/libmpg123/%.o : CFLAGS+=$(CFLAGS_SILENT) -DOPT_GENERIC
include/mpg123/src/libmpg123/%.test.o : CFLAGS+=$(CFLAGS_SILENT) -DOPT_GENERIC
else
ifeq ($(NO_MPG123),1)
else
#LDLIBS += -lmpg123
@ -442,7 +508,19 @@ endif
NO_MPG123:=1
endif
endif
endif
ifeq ($(LOCAL_OGG),1)
CPPFLAGS_OGG := -DMPT_WITH_OGG
LDFLAGS_OGG :=
LDLIBS_OGG :=
CPPFLAGS_OGG += -Iinclude/ogg/include/ -Iinclude/ogg/ports/makefile/
LOCAL_OGG_SOURCES :=
LOCAL_OGG_SOURCES += include/ogg/src/bitwise.c
LOCAL_OGG_SOURCES += include/ogg/src/framing.c
include/ogg/src/%.o : CFLAGS+=$(CFLAGS_SILENT)
include/ogg/src/%.test.o : CFLAGS+=$(CFLAGS_SILENT)
else
ifeq ($(NO_OGG),1)
else
#LDLIBS += -logg
@ -460,7 +538,39 @@ endif
NO_OGG:=1
endif
endif
endif
ifeq ($(LOCAL_VORBIS),1)
CPPFLAGS_VORBIS := -DMPT_WITH_VORBIS
LDFLAGS_VORBIS :=
LDLIBS_VORBIS :=
CPPFLAGS_VORBIS += -Iinclude/vorbis/include/ -Iinclude/vorbis/lib/ -DHAVE_ALLOCA_H
LOCAL_VORBIS_SOURCES :=
LOCAL_VORBIS_SOURCES += include/vorbis/lib/analysis.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/bitrate.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/block.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/codebook.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/envelope.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/floor0.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/floor1.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/info.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/lookup.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/lpc.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/lsp.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/mapping0.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/mdct.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/psy.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/registry.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/res0.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/sharedbook.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/smallft.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/synthesis.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/vorbisenc.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/vorbisfile.c
LOCAL_VORBIS_SOURCES += include/vorbis/lib/window.c
include/vorbis/lib/%.o : CFLAGS+=$(CFLAGS_SILENT)
include/vorbis/lib/%.test.o : CFLAGS+=$(CFLAGS_SILENT)
else
ifeq ($(NO_VORBIS),1)
else
#LDLIBS += -lvorbis
@ -478,7 +588,13 @@ endif
NO_VORBIS:=1
endif
endif
endif
ifeq ($(LOCAL_VORBIS),1)
CPPFLAGS_VORBISFILE := -DMPT_WITH_VORBISFILE
LDFLAGS_VORBISFILE :=
LDLIBS_VORBISFILE :=
else
ifeq ($(NO_VORBISFILE),1)
else
#LDLIBS += -lvorbisfile
@ -496,15 +612,15 @@ endif
NO_VORBISFILE:=1
endif
endif
endif
ifeq ($(NO_SDL2),1)
else
#LDLIBS += -lsdl2
ifeq ($(shell pkg-config$(TOOLCHAIN_SUFFIX) --exists sdl2 && echo yes),yes)
CPPFLAGS_SDL := $(shell pkg-config$(TOOLCHAIN_SUFFIX) --cflags-only-I sdl2 ) -DMPT_WITH_SDL2
LDFLAGS_SDL := $(shell pkg-config$(TOOLCHAIN_SUFFIX) --libs-only-L sdl2 ) $(shell pkg-config$(TOOLCHAIN_SUFFIX) --libs-only-other sdl2 )
LDLIBS_SDL := $(shell pkg-config$(TOOLCHAIN_SUFFIX) --libs-only-l sdl2 )
NO_SDL:=1
ifeq ($(shell pkg-config$(TOOLCHAIN_SUFFIX) --exists 'sdl2 >= 2.0.4' && echo yes),yes)
CPPFLAGS_SDL2 := $(shell pkg-config$(TOOLCHAIN_SUFFIX) --cflags-only-I 'sdl2 >= 2.0.4' ) -DMPT_WITH_SDL2
LDFLAGS_SDL2 := $(shell pkg-config$(TOOLCHAIN_SUFFIX) --libs-only-L 'sdl2 >= 2.0.4' ) $(shell pkg-config$(TOOLCHAIN_SUFFIX) --libs-only-other 'sdl2 >= 2.0.4' )
LDLIBS_SDL2 := $(shell pkg-config$(TOOLCHAIN_SUFFIX) --libs-only-l 'sdl2 >= 2.0.4' )
else
ifeq ($(FORCE_DEPS),1)
$(error sdl2 not found)
@ -515,23 +631,6 @@ NO_SDL2:=1
endif
endif
ifeq ($(NO_SDL),1)
else
#LDLIBS += -lsdl
ifeq ($(shell pkg-config$(TOOLCHAIN_SUFFIX) --exists sdl && echo yes),yes)
CPPFLAGS_SDL := $(shell pkg-config$(TOOLCHAIN_SUFFIX) --cflags-only-I sdl ) -DMPT_WITH_SDL
LDFLAGS_SDL := $(shell pkg-config$(TOOLCHAIN_SUFFIX) --libs-only-L sdl ) $(shell pkg-config$(TOOLCHAIN_SUFFIX) --libs-only-other sdl )
LDLIBS_SDL := $(shell pkg-config$(TOOLCHAIN_SUFFIX) --libs-only-l sdl )
else
ifeq ($(FORCE_DEPS),1)
$(error sdl not found)
else
$(warning warning: sdl not found)
endif
NO_SDL:=1
endif
endif
ifeq ($(NO_PORTAUDIO),1)
else
#LDLIBS += -lportaudio
@ -629,7 +728,7 @@ CPPFLAGS += -DMPT_BUILD_HACK_ARCHIVE_SUPPORT
endif
CPPCHECK_FLAGS += -j $(NUMTHREADS)
CPPCHECK_FLAGS += --std=c99 --std=c++11
CPPCHECK_FLAGS += --std=c99 --std=c++14
CPPCHECK_FLAGS += --quiet
CPPCHECK_FLAGS += --enable=warning --inline-suppr --template='{file}:{line}: warning: {severity}: {message} [{id}]'
CPPCHECK_FLAGS += --suppress=missingIncludeSystem
@ -639,9 +738,9 @@ CPPFLAGS += $(CPPFLAGS_ZLIB) $(CPPFLAGS_MPG123) $(CPPFLAGS_OGG) $(CPPFLAGS_VORBI
LDFLAGS += $(LDFLAGS_ZLIB) $(LDFLAGS_MPG123) $(LDFLAGS_OGG) $(LDFLAGS_VORBIS) $(LDFLAGS_VORBISFILE)
LDLIBS += $(LDLIBS_ZLIB) $(LDLIBS_MPG123) $(LDLIBS_OGG) $(LDLIBS_VORBIS) $(LDLIBS_VORBISFILE)
CPPFLAGS_OPENMPT123 += $(CPPFLAGS_SDL2) $(CPPFLAGS_SDL) $(CPPFLAGS_PORTAUDIO) $(CPPFLAGS_PULSEAUDIO) $(CPPFLAGS_FLAC) $(CPPFLAGS_SNDFILE) $(CPPFLAGS_ALLEGRO42)
LDFLAGS_OPENMPT123 += $(LDFLAGS_SDL2) $(LDFLAGS_SDL) $(LDFLAGS_PORTAUDIO) $(LDFLAGS_PULSEAUDIO) $(LDFLAGS_FLAC) $(LDFLAGS_SNDFILE) $(LDFLAGS_ALLEGRO42)
LDLIBS_OPENMPT123 += $(LDLIBS_SDL2) $(LDLIBS_SDL) $(LDLIBS_PORTAUDIO) $(LDLIBS_PULSEAUDIO) $(LDLIBS_FLAC) $(LDLIBS_SNDFILE) $(LDLIBS_ALLEGRO42)
CPPFLAGS_OPENMPT123 += $(CPPFLAGS_SDL2) $(CPPFLAGS_PORTAUDIO) $(CPPFLAGS_PULSEAUDIO) $(CPPFLAGS_FLAC) $(CPPFLAGS_SNDFILE) $(CPPFLAGS_ALLEGRO42)
LDFLAGS_OPENMPT123 += $(LDFLAGS_SDL2) $(LDFLAGS_PORTAUDIO) $(LDFLAGS_PULSEAUDIO) $(LDFLAGS_FLAC) $(LDFLAGS_SNDFILE) $(LDFLAGS_ALLEGRO42)
LDLIBS_OPENMPT123 += $(LDLIBS_SDL2) $(LDLIBS_PORTAUDIO) $(LDLIBS_PULSEAUDIO) $(LDLIBS_FLAC) $(LDLIBS_SNDFILE) $(LDLIBS_ALLEGRO42)
%: %.o
@ -761,14 +860,23 @@ LIBOPENMPT_CXX_SOURCES += \
include/miniz/miniz.o : CFLAGS+=$(CFLAGS_SILENT)
include/miniz/miniz.test.o : CFLAGS+=$(CFLAGS_SILENT)
ifeq ($(LOCAL_ZLIB),1)
LIBOPENMPT_C_SOURCES += $(LOCAL_ZLIB_SOURCES)
LIBOPENMPTTEST_C_SOURCES += $(LOCAL_ZLIB_SOURCES)
else
ifeq ($(NO_ZLIB),1)
LIBOPENMPT_C_SOURCES += include/miniz/miniz.c
LIBOPENMPTTEST_C_SOURCES += include/miniz/miniz.c
CPPFLAGS += -DMPT_WITH_MINIZ
endif
endif
include/minimp3/minimp3.o : CFLAGS+=$(CFLAGS_SILENT)
include/minimp3/minimp3.test.o : CFLAGS+=$(CFLAGS_SILENT)
ifeq ($(LOCAL_MPG123),1)
LIBOPENMPT_C_SOURCES += $(LOCAL_MPG123_SOURCES)
LIBOPENMPTTEST_C_SOURCES += $(LOCAL_MPG123_SOURCES)
else
ifeq ($(NO_MPG123),1)
ifeq ($(NO_MINIMP3),1)
else
@ -777,9 +885,18 @@ LIBOPENMPTTEST_C_SOURCES += include/minimp3/minimp3.c
CPPFLAGS += -DMPT_WITH_MINIMP3
endif
endif
endif
include/stb_vorbis/stb_vorbis.o : CFLAGS+=$(CFLAGS_SILENT)
include/stb_vorbis/stb_vorbis.test.o : CFLAGS+=$(CFLAGS_SILENT)
ifeq ($(LOCAL_VORBIS),1)
ifeq ($(LOCAL_OGG),1)
LIBOPENMPT_C_SOURCES += $(LOCAL_OGG_SOURCES)
LIBOPENMPTTEST_C_SOURCES += $(LOCAL_OGG_SOURCES)
endif
LIBOPENMPT_C_SOURCES += $(LOCAL_VORBIS_SOURCES)
LIBOPENMPTTEST_C_SOURCES += $(LOCAL_VORBIS_SOURCES)
else
ifeq ($(NO_OGG),1)
ifeq ($(NO_STBVORBIS),1)
else
@ -807,6 +924,7 @@ else
endif
endif
endif
endif
LIBOPENMPT_OBJECTS += $(LIBOPENMPT_CXX_SOURCES:.cpp=.o) $(LIBOPENMPT_C_SOURCES:.c=.o)
LIBOPENMPT_DEPENDS = $(LIBOPENMPT_OBJECTS:.o=.d)
@ -820,18 +938,6 @@ OBJECTS_LIBOPENMPT += $(LIBOPENMPT_OBJECTS)
endif
LIBOPENMPT_MODPLUG_C_SOURCES += \
libopenmpt/libopenmpt_modplug.c \
LIBOPENMPT_MODPLUG_CPP_SOURCES += \
libopenmpt/libopenmpt_modplug_cpp.cpp \
LIBOPENMPT_MODPLUG_OBJECTS = $(LIBOPENMPT_MODPLUG_C_SOURCES:.c=.o) $(LIBOPENMPT_MODPLUG_CPP_SOURCES:.cpp=.o)
LIBOPENMPT_MODPLUG_DEPENDS = $(LIBOPENMPT_MODPLUG_OBJECTS:.o=.d)
ALL_OBJECTS += $(LIBOPENMPT_MODPLUG_OBJECTS)
ALL_DEPENDS += $(LIBOPENMPT_MODPLUG_DEPENDS)
OPENMPT123_CXX_SOURCES += \
$(sort $(wildcard openmpt123/*.cpp)) \
@ -879,7 +985,6 @@ all:
ifeq ($(DYNLINK),1)
OUTPUTS += bin/libopenmpt$(SOSUFFIX)
OUTPUTS += bin/libopenmpt_modplug$(SOSUFFIX)
endif
ifeq ($(SHARED_LIB),1)
OUTPUTS += bin/libopenmpt$(SOSUFFIX)
@ -937,22 +1042,30 @@ MISC_OUTPUTS += libopenmpt$(SOSUFFIX)
MISC_OUTPUTS += bin/.docs
MISC_OUTPUTS += bin/libopenmpt_test$(EXESUFFIX)
MISC_OUTPUTS += bin/libopenmpt_test.wasm
MISC_OUTPUTS += bin/libopenmpt_test.wasm.js
MISC_OUTPUTS += bin/libopenmpt_test.js.mem
MISC_OUTPUTS += bin/made.docs
MISC_OUTPUTS += bin/$(LIBOPENMPT_SONAME)
MISC_OUTPUTS += bin/libopenmpt.wasm
MISC_OUTPUTS += bin/libopenmpt.wasm.js
MISC_OUTPUTS += bin/libopenmpt.js.mem
MISC_OUTPUTS += bin/libopenmpt_example_c.wasm
MISC_OUTPUTS += bin/libopenmpt_example_c.wasm.js
MISC_OUTPUTS += bin/libopenmpt_example_c.js.mem
MISC_OUTPUTS += bin/libopenmpt_example_c_mem.wasm
MISC_OUTPUTS += bin/libopenmpt_example_c_mem.wasm.js
MISC_OUTPUTS += bin/libopenmpt_example_c_mem.js.mem
MISC_OUTPUTS += bin/libopenmpt_example_c_pipe.wasm
MISC_OUTPUTS += bin/libopenmpt_example_c_pipe.wasm.js
MISC_OUTPUTS += bin/libopenmpt_example_c_pipe.js.mem
MISC_OUTPUTS += bin/libopenmpt_example_c_probe.wasm
MISC_OUTPUTS += bin/libopenmpt_example_c_probe.wasm.js
MISC_OUTPUTS += bin/libopenmpt_example_c_probe.js.mem
MISC_OUTPUTS += bin/libopenmpt_example_c_stdout.wasm
MISC_OUTPUTS += bin/libopenmpt_example_c_stdout.wasm.js
MISC_OUTPUTS += bin/libopenmpt_example_c_stdout.js.mem
MISC_OUTPUTS += bin/libopenmpt_example_c_unsafe.wasm
MISC_OUTPUTS += bin/libopenmpt_example_c_unsafe.wasm.js
MISC_OUTPUTS += bin/libopenmpt_example_c_unsafe.js.mem
MISC_OUTPUTS += bin/openmpt.a
#old
@ -1095,24 +1208,6 @@ ifeq ($(MPT_WITH_DOXYGEN),1)
$(INSTALL_DATA_DIR) bin/docs/html $(DESTDIR)$(PREFIX)/share/doc/libopenmpt/html
endif
.PHONY: install-openmpt-modplug
install-openmpt-modplug: $(OUTPUTS)
ifeq ($(SHARED_LIB),1)
$(INSTALL_MAKE_DIR) $(DESTDIR)$(PREFIX)/lib
$(INSTALL_LIB) bin/libopenmpt_modplug$(SOSUFFIX) $(DESTDIR)$(PREFIX)/lib/libopenmpt_modplug$(SOSUFFIX)
$(INSTALL_LIB) bin/libopenmpt_modplug$(SOSUFFIX) $(DESTDIR)$(PREFIX)/lib/libopenmpt_modplug$(SOSUFFIX).1
$(INSTALL_LIB) bin/libopenmpt_modplug$(SOSUFFIX) $(DESTDIR)$(PREFIX)/lib/libopenmpt_modplug$(SOSUFFIX).1.0.0
endif
.PHONY: install-modplug
install-modplug: $(OUTPUTS)
ifeq ($(SHARED_LIB),1)
$(INSTALL_MAKE_DIR) $(DESTDIR)$(PREFIX)/lib
$(INSTALL_LIB) bin/libopenmpt_modplug$(SOSUFFIX) $(DESTDIR)$(PREFIX)/lib/libmodplug$(SOSUFFIX)
$(INSTALL_LIB) bin/libopenmpt_modplug$(SOSUFFIX) $(DESTDIR)$(PREFIX)/lib/libmodplug$(SOSUFFIX).1
$(INSTALL_LIB) bin/libopenmpt_modplug$(SOSUFFIX) $(DESTDIR)$(PREFIX)/lib/libmodplug$(SOSUFFIX).1.0.0
endif
.PHONY: dist
dist: bin/dist-tar.tar bin/dist-zip.tar bin/dist-doc.tar
@ -1209,6 +1304,7 @@ bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION).makefile.tar: bin/dist.mk bin
svn export ./LICENSE bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/LICENSE
svn export ./README.md bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/README.md
svn export ./Makefile bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/Makefile
svn export ./.clang-format bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/.clang-format
svn export ./bin bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin
svn export ./build/android_ndk bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/android_ndk
svn export ./build/make bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/make
@ -1229,7 +1325,6 @@ bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION).makefile.tar: bin/dist.mk bin
svn export ./include/cwsdpmi bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/include/cwsdpmi
svn export ./include/minimp3 bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/include/minimp3
svn export ./include/miniz bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/include/miniz
svn export ./include/modplug bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/include/modplug
svn export ./include/stb_vorbis bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/include/stb_vorbis
cp bin/dist.mk bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/dist.mk
cp bin/svn_version_dist.h bin/dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/svn_version/svn_version.h
@ -1248,6 +1343,7 @@ bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION).msvc.zip: bin/dist.mk bin/svn
svn export ./LICENSE bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/LICENSE --native-eol CRLF
svn export ./README.md bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/README.md --native-eol CRLF
svn export ./Makefile bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/Makefile --native-eol CRLF
svn export ./.clang-format bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/.clang-format --native-eol CRLF
svn export ./bin bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin --native-eol CRLF
svn export ./build/genie/def bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/genie/def --native-eol CRLF
svn export ./build/premake/def bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/premake/def --native-eol CRLF
@ -1257,13 +1353,14 @@ bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION).msvc.zip: bin/dist.mk bin/svn
svn export ./build/svn_version bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/svn_version --native-eol CRLF
svn export ./build/vcpkg bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vcpkg --native-eol CRLF
svn export ./build/vs bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs --native-eol CRLF
svn export ./build/vs2015 bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2015 --native-eol CRLF
svn export ./build/vs2015xp bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2015xp --native-eol CRLF
svn export ./build/vs2017 bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2017 --native-eol CRLF
svn export ./build/vs2017win10 bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2017win10
svn export ./build/vs2017xp bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2017xp --native-eol CRLF
svn export ./build/windesktop81 bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/windesktop81 --native-eol CRLF
svn export ./build/winstore82 bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/winstore82 --native-eol CRLF
svn export ./build/vs2017win7 bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2017win7 --native-eol CRLF
svn export ./build/vs2017win81 bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2017win81 --native-eol CRLF
svn export ./build/vs2017win10 bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2017win10 --native-eol CRLF
svn export ./build/vs2017uwp bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2017uwp --native-eol CRLF
svn export ./build/vs2019win7 bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2019win7 --native-eol CRLF
svn export ./build/vs2019win81 bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2019win81 --native-eol CRLF
svn export ./build/vs2019win10 bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2019win10 --native-eol CRLF
svn export ./build/vs2019uwp bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2019uwp --native-eol CRLF
svn export ./build/download_externals.cmd bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/download_externals.cmd --native-eol CRLF
svn export ./common bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/common --native-eol CRLF
svn export ./doc/contributing.md bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/doc/contributing.md --native-eol CRLF
@ -1282,8 +1379,6 @@ bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION).msvc.zip: bin/dist.mk bin/svn
svn export ./include/mpg123 bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/include/mpg123 --native-eol CRLF
svn export ./include/flac bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/include/flac --native-eol CRLF
svn export ./include/portaudio bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/include/portaudio --native-eol CRLF
svn export ./include/modplug bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/include/modplug --native-eol CRLF
svn export ./include/foobar2000sdk bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/include/foobar2000sdk --native-eol CRLF
svn export ./include/ogg bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/include/ogg --native-eol CRLF
svn export ./include/pugixml bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/include/pugixml --native-eol CRLF
svn export ./include/stb_vorbis bin/dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/include/stb_vorbis --native-eol CRLF
@ -1314,15 +1409,14 @@ bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION).dev.js.tar:
svn export ./include/miniz/miniz.c bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/licenses/license.miniz.txt
svn export ./include/stb_vorbis/stb_vorbis.c bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/licenses/license.stb_vorbis.txt
mkdir -p bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin
mkdir -p bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/all
cp bin/stage/all/libopenmpt.js bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/all/libopenmpt.js
cp bin/stage/all/libopenmpt.js.mem bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/all/libopenmpt.js.mem
cp bin/stage/all/libopenmpt.wasm bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/all/libopenmpt.wasm
cp bin/stage/all/libopenmpt.wasm.js bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/all/libopenmpt.wasm.js
mkdir -p bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/wasm
cp bin/stage/wasm/libopenmpt.js bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/wasm/libopenmpt.js
cp bin/stage/wasm/libopenmpt.wasm bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/wasm/libopenmpt.wasm
mkdir -p bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/asmjs128m
cp bin/stage/asmjs128m/libopenmpt.js bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/asmjs128m/libopenmpt.js
cp bin/stage/asmjs128m/libopenmpt.js.mem bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/asmjs128m/libopenmpt.js.mem
mkdir -p bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/asmjs
cp bin/stage/asmjs/libopenmpt.js bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/asmjs/libopenmpt.js
cp bin/stage/asmjs/libopenmpt.js.mem bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/asmjs/libopenmpt.js.mem
mkdir -p bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/js
cp bin/stage/js/libopenmpt.js bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/js/libopenmpt.js
cp bin/stage/js/libopenmpt.js.mem bin/dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/js/libopenmpt.js.mem
@ -1361,16 +1455,16 @@ bin/libopenmpt.a: $(LIBOPENMPT_OBJECTS)
bin/libopenmpt$(SOSUFFIX): $(LIBOPENMPT_OBJECTS)
$(INFO) [LD] $@
ifeq ($(NO_SHARED_LINKER_FLAG),1)
$(SILENT)$(LINK.cc) $(LIBOPENMPT_LDFLAGS) $(SO_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
else
$(SILENT)$(LINK.cc) -shared $(LIBOPENMPT_LDFLAGS) $(SO_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
endif
ifeq ($(SHARED_SONAME),1)
$(SILENT)mv bin/libopenmpt$(SOSUFFIX) bin/$(LIBOPENMPT_SONAME)
$(SILENT)ln -sf $(LIBOPENMPT_SONAME) bin/libopenmpt$(SOSUFFIX)
endif
bin/libopenmpt_modplug$(SOSUFFIX): $(LIBOPENMPT_MODPLUG_OBJECTS) $(OUTPUT_LIBOPENMPT)
$(INFO) [LD] $@
$(SILENT)$(LINK.cc) -shared $(SO_LDFLAGS) $(LDFLAGS_LIBOPENMPT) $(LIBOPENMPT_MODPLUG_OBJECTS) $(OBJECTS_LIBOPENMPT) $(LOADLIBES) $(LDLIBS) $(LDLIBS_LIBOPENMPT) -o $@
bin/openmpt123.1: bin/openmpt123$(EXESUFFIX) openmpt123/openmpt123.h2m
$(INFO) [HELP2MAN] $@
$(SILENT)help2man --no-discard-stderr --no-info --version-option=--man-version --help-option=--man-help --include=openmpt123/openmpt123.h2m $< > $@

View file

@ -35,44 +35,19 @@ How to compile
- Supported Visual Studio versions:
- Visual Studio 2015 Update 3 Community/Professional/Enterprise
- Visual Studio 2017 and 2019 Community/Professional/Enterprise
To compile the project, open `build/vs2015/OpenMPT.sln` and hit the
compile button.
- Visual Studio 2017 Community/Professional/Enterprise
To compile the project, open `build/vs2017/OpenMPT.sln` and hit the
compile button.
To compile the project, open `build/vsVERSIONwin7/OpenMPT.sln` (VERSION
being 2017 or 2019) and hit the compile button. Other target systems can
be found in the `vs2017*` and `vs2019*` sibling folders.
- OpenMPT requires the compile host system to be 64bit x86-64.
- The Windows 8.1 SDK and Microsoft Foundation Classes (MFC) are required to
build OpenMPT (both are included with Visual Studio, however may need to be
selected explicitly during setup). In order to build OpenMPT for Windows XP,
the XP targetting toolset also needs to be installed.
- The Windows 8.1 SDK is required to build OpenMPT with Visual Studio 2017
(this is included with Visual Studio, however may need to be selected
explicitly during setup).
- The ASIO SDK is needed for compiling with ASIO support.
If you don't want this, comment out `#define MPT_WITH_ASIO` in the file
`common/BuildSettings.h`.
The ASIO SDK can be downloaded automatically on Windows 7 or later by just
running the `build/download_externals.cmd` script.
If you do not want to or cannot use this script, you may follow these manual
steps instead:
- Visit
[steinberg.net](https://www.steinberg.net/en/company/developers.html) to
download the SDK.
- Put the ASIO SDK in the `include/ASIOSDK2` folder. The top level
directory of the SDK is already named `ASIOSDK2`, so simply move that
directory in the include folder.
If you need further help with the ASIO SDK, get in touch with the
main OpenMPT developers.
- Microsoft Foundation Classes (MFC) are required to build OpenMPT.
### libopenmpt and openmpt123
@ -104,15 +79,13 @@ For detailed requirements, see `libopenmpt/dox/quickstart.md`.
- Visual Studio:
- You will find solutions for Visual Studio 2015 to 2017 in the
corresponding `build/vsVERSION/` folder.
Projects that target Windows versions before Windows 7 are available in
`build/vsVERSIONxp/`.
Projects that target Windows 10 1709 Desktop (10.0.16299.0, including
ARM and ARM64) or later versions are available in
`build/vsVERSIONwin10/`.
- You will find solutions for Visual Studio 2017 and 2019 in the
corresponding `build/vsVERSIONwin7/` folder.
Projects that target Windows 10 Desktop (including ARM and ARM64) are
available in `build/vsVERSIONwin10/` (Visual Studio 2017 requires SDK
version 10.0.16299).
Minimal projects that target Windows 10 UWP are available in
`build/winstore82/`.
`build/vsVERSIONuwp/`.
Most projects are supported with any of the mentioned Visual Studio
verions, with the following exceptions:
@ -161,7 +134,7 @@ For detailed requirements, see `libopenmpt/dox/quickstart.md`.
- mingw-w64:
The required version is at least 4.8.
The required compiler version is at least GCC 7.
make CONFIG=mingw64-win32 # for win32
@ -172,9 +145,9 @@ For detailed requirements, see `libopenmpt/dox/quickstart.md`.
The minimum required compiler versions are:
- gcc 4.8
- gcc 7
- clang 3.6
- clang 5
The Makefile requires pkg-config for native builds.
For sound output in openmpt123, PortAudio or SDL is required.
@ -256,7 +229,7 @@ For detailed requirements, see `libopenmpt/dox/quickstart.md`.
- other compilers:
To compile libopenmpt with other C++11 compliant compilers, run:
To compile libopenmpt with other C++14 compliant compilers, run:
make CONFIG=generic

View file

@ -7,7 +7,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE := openmpt
LOCAL_CFLAGS +=#-std=c99
LOCAL_CPPFLAGS += -std=c++11 -fexceptions -frtti
LOCAL_CPPFLAGS += -std=c++17 -fexceptions -frtti
LOCAL_CPP_FEATURES += exceptions rtti
@ -111,12 +111,12 @@ LOCAL_SRC_FILES += \
libopenmpt/libopenmpt_cxx.cpp \
libopenmpt/libopenmpt_impl.cpp \
libopenmpt/libopenmpt_ext_impl.cpp \
soundbase/Dither.cpp \
soundlib/AudioCriticalSection.cpp \
soundlib/ContainerMMCMP.cpp \
soundlib/ContainerPP20.cpp \
soundlib/ContainerUMX.cpp \
soundlib/ContainerXPK.cpp \
soundlib/Dither.cpp \
soundlib/Dlsbank.cpp \
soundlib/Fastmix.cpp \
soundlib/InstrumentExtensions.cpp \
@ -178,10 +178,12 @@ LOCAL_SRC_FILES += \
soundlib/RowVisitor.cpp \
soundlib/S3MTools.cpp \
soundlib/SampleFormats.cpp \
soundlib/SampleFormatBRR.cpp \
soundlib/SampleFormatFLAC.cpp \
soundlib/SampleFormatMediaFoundation.cpp \
soundlib/SampleFormatMP3.cpp \
soundlib/SampleFormatOpus.cpp \
soundlib/SampleFormatSFZ.cpp \
soundlib/SampleFormatVorbis.cpp \
soundlib/SampleIO.cpp \
soundlib/Sndfile.cpp \
@ -193,7 +195,7 @@ LOCAL_SRC_FILES += \
soundlib/UpgradeModule.cpp \
soundlib/Tables.cpp \
soundlib/Tagging.cpp \
soundlib/tuningbase.cpp \
soundlib/TinyFFT.cpp \
soundlib/tuningCollection.cpp \
soundlib/tuning.cpp \
soundlib/WAVTools.cpp \

View file

@ -1,5 +1,5 @@
APP_CFLAGS :=#-std=c99
APP_CPPFLAGS := -std=c++11 -fexceptions -frtti
APP_CPPFLAGS := -std=c++17 -fexceptions -frtti
APP_LDFLAGS :=
APP_STL := c++_shared

View file

@ -3,7 +3,7 @@
This is preliminary documentation.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
0. The minimum required Android NDK version is r16b.
0. The minimum required Android NDK version is r18b.
1. Copy the whole libopenmpt source tree below your jni directory.
2. Copy build/android_ndk/* into the root of libopenmpt, i.e. also into the
jni directory and adjust as needed.

View file

@ -1,4 +1,4 @@
MPT_SVNVERSION=12263
MPT_SVNURL=https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.4.10
MPT_SVNDATE=2019-10-30T10:43:15.521271Z
MPT_SVNVERSION=13775
MPT_SVNURL=https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.5.3
MPT_SVNDATE=2020-10-25T14:02:16.624929Z

View file

@ -9,14 +9,6 @@ CXXFLAGS_STDCXX = -std=$(STDCXX)
else
ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++17 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++17' ; fi ), c++17)
CXXFLAGS_STDCXX = -std=c++17
else
ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++14 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++14' ; fi ), c++14)
CXXFLAGS_STDCXX = -std=c++14
else
ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++11 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++11' ; fi ), c++11)
CXXFLAGS_STDCXX = -std=c++11
endif
endif
endif
endif
CFLAGS_STDC = -std=c99

View file

@ -12,10 +12,6 @@ CXXFLAGS_STDCXX = -std=c++17
else
ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++14 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++14' ; fi ), c++14)
CXXFLAGS_STDCXX = -std=c++14
else
ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++11 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++11' ; fi ), c++11)
CXXFLAGS_STDCXX = -std=c++11
endif
endif
endif
endif
@ -43,20 +39,27 @@ endif
CXXFLAGS_WARNINGS += -Wmissing-declarations -Wshift-count-negative -Wshift-count-overflow -Wshift-overflow -Wshift-sign-overflow -Wshift-op-parentheses
CFLAGS_WARNINGS += -Wmissing-prototypes -Wshift-count-negative -Wshift-count-overflow -Wshift-overflow -Wshift-sign-overflow -Wshift-op-parentheses
CXXFLAGS_WARNINGS += -Wdeprecated -Wextra-semi -Wnon-virtual-dtor -Wreserved-id-macro -Wglobal-constructors -Wimplicit-fallthrough
#CXXFLAGS_WARNINGS += -Wdocumentation
#CXXFLAGS_WARNINGS += -Wconversion
#CXXFLAGS_WARNINGS += -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-padded -Wno-shadow -Wno-sign-conversion -Wno-weak-vtables
ifeq ($(MODERN),1)
LDFLAGS += -fuse-ld=lld
CXXFLAGS_WARNINGS += -Wpedantic -Wframe-larger-than=20000
#CXXFLAGS_WARNINGS += -Wdouble-promotion -Wframe-larger-than=16000
CXXFLAGS_WARNINGS += -Wpedantic -Wframe-larger-than=16000
CFLAGS_WARNINGS += -Wpedantic -Wframe-larger-than=4000
#CFLAGS_WARNINGS += -Wdouble-promotion
LDFLAGS_WARNINGS += -Wl,-no-undefined -Wl,--detect-odr-violations
CXXFLAGS_WARNINGS += -Wdeprecated -Wextra-semi -Wnon-virtual-dtor -Wreserved-id-macro
# re-renable after 1.29 branch
#CXXFLAGS_WARNINGS += -Wdouble-promotion
#CFLAGS_WARNINGS += -Wdouble-promotion
endif
CFLAGS_SILENT += -Wno-unused-parameter -Wno-unused-function -Wno-cast-qual
CFLAGS_SILENT += -Wno-cast-align
CFLAGS_SILENT += -Wno-cast-qual
CFLAGS_SILENT += -Wno-missing-prototypes
CFLAGS_SILENT += -Wno-sign-compare
CFLAGS_SILENT += -Wno-unused-function
CFLAGS_SILENT += -Wno-unused-parameter
EXESUFFIX=

View file

@ -7,9 +7,6 @@ include build/make/config-clang.mk
# Mac OS X overrides
DYNLINK=0
SHARED_SONAME=0
# when using iconv
#CPPFLAGS += -DMPT_WITH_ICONV
#LDLIBS += -liconv
else ifeq ($(HOST_FLAVOUR),LINUX)

View file

@ -1,19 +1,19 @@
CC = i586-pc-msdosdjgpp-gcc
CXX = i586-pc-msdosdjgpp-g++
LD = i586-pc-msdosdjgpp-g++
AR = i586-pc-msdosdjgpp-ar
CC = i386-pc-msdosdjgpp-gcc
CXX = i386-pc-msdosdjgpp-g++
LD = i386-pc-msdosdjgpp-g++
AR = i386-pc-msdosdjgpp-ar
# Note that we are using GNU extensions instead of 100% standards-compliant
# mode, because otherwise DJGPP-specific headers/functions are unavailable.
CXXFLAGS_STDCXX = -std=gnu++11
CXXFLAGS_STDCXX = -std=gnu++17
CFLAGS_STDC = -std=gnu99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)
CPPFLAGS +=
CXXFLAGS += -march=pentium -mtune=pentium
CFLAGS += -march=pentium -mtune=pentium
CXXFLAGS += -march=i386 -m80387 -mtune=pentium
CFLAGS += -march=i386 -m80387 -mtune=pentium
LDFLAGS +=
LDLIBS += -lm
ARFLAGS := rcs

View file

@ -1,8 +1,9 @@
CC = emcc
CXX = em++
CC = emcc -c
CXX = em++ -c
LD = em++
AR = emar
LINK.cc = em++ $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
EMSCRIPTEN_TARGET?=default
@ -11,14 +12,6 @@ CXXFLAGS_STDCXX = -std=$(STDCXX)
else
ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++17 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++17' ; fi ), c++17)
CXXFLAGS_STDCXX = -std=c++17
else
ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++14 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++14' ; fi ), c++14)
CXXFLAGS_STDCXX = -std=c++14
else
ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++11 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++11' ; fi ), c++11)
CXXFLAGS_STDCXX = -std=c++11
endif
endif
endif
endif
CFLAGS_STDC = -std=c99
@ -45,50 +38,49 @@ LDFLAGS +=
LDFLAGS += -s ALLOW_MEMORY_GROWTH=1
else ifeq ($(EMSCRIPTEN_TARGET),wasm)
# emits native wasm AND an emulator for running wasm in asmjs/js with full wasm optimizations.
else ifeq ($(EMSCRIPTEN_TARGET),all)
# emits native wasm AND javascript with full wasm optimizations.
# as of emscripten 1.38, this is equivalent to default.
CPPFLAGS += -DMPT_BUILD_WASM
CXXFLAGS += -s WASM=1 -s BINARYEN_METHOD='native-wasm'
CFLAGS += -s WASM=1 -s BINARYEN_METHOD='native-wasm'
LDFLAGS += -s WASM=1 -s BINARYEN_METHOD='native-wasm'
CXXFLAGS += -s WASM=2 -s LEGACY_VM_SUPPORT=1
CFLAGS += -s WASM=2 -s LEGACY_VM_SUPPORT=1
LDFLAGS += -s WASM=2 -s LEGACY_VM_SUPPORT=1
LDFLAGS += -s ALLOW_MEMORY_GROWTH=1
else ifeq ($(EMSCRIPTEN_TARGET),asmjs128m)
# emits only asmjs
CPPFLAGS += -DMPT_BUILD_ASMJS
CXXFLAGS += -s WASM=0 -s ASM_JS=1
CFLAGS += -s WASM=0 -s ASM_JS=1
LDFLAGS += -s WASM=0 -s ASM_JS=1
else ifeq ($(EMSCRIPTEN_TARGET),wasm)
# emits native wasm.
CPPFLAGS += -DMPT_BUILD_WASM
CXXFLAGS += -s WASM=1
CFLAGS += -s WASM=1
LDFLAGS += -s WASM=1
LDFLAGS += -s ALLOW_MEMORY_GROWTH=0 -s ABORTING_MALLOC=0 -s TOTAL_MEMORY=134217728
else ifeq ($(EMSCRIPTEN_TARGET),asmjs)
# emits only asmjs
CPPFLAGS += -DMPT_BUILD_ASMJS
CXXFLAGS += -s WASM=0 -s ASM_JS=1
CFLAGS += -s WASM=0 -s ASM_JS=1
LDFLAGS += -s WASM=0 -s ASM_JS=1
LDFLAGS += -s ALLOW_MEMORY_GROWTH=0 -s ABORTING_MALLOC=0
LDFLAGS += -s ALLOW_MEMORY_GROWTH=1
else ifeq ($(EMSCRIPTEN_TARGET),js)
# emits only plain javascript with plain javascript focused optimizations.
CPPFLAGS += -DMPT_BUILD_ASMJS
CXXFLAGS += -s WASM=0 -s ASM_JS=2 -s LEGACY_VM_SUPPORT=1
CFLAGS += -s WASM=0 -s ASM_JS=2 -s LEGACY_VM_SUPPORT=1
LDFLAGS += -s WASM=0 -s ASM_JS=2 -s LEGACY_VM_SUPPORT=1
CXXFLAGS += -s WASM=0 -s LEGACY_VM_SUPPORT=1
CFLAGS += -s WASM=0 -s LEGACY_VM_SUPPORT=1
LDFLAGS += -s WASM=0 -s LEGACY_VM_SUPPORT=1
LDFLAGS += -s ALLOW_MEMORY_GROWTH=1
endif
CXXFLAGS += -s DISABLE_EXCEPTION_CATCHING=0 -s ERROR_ON_UNDEFINED_SYMBOLS=1 -ffast-math
CFLAGS += -s DISABLE_EXCEPTION_CATCHING=0 -s ERROR_ON_UNDEFINED_SYMBOLS=1 -ffast-math -fno-strict-aliasing
LDFLAGS += -s DISABLE_EXCEPTION_CATCHING=0 -s ERROR_ON_UNDEFINED_SYMBOLS=1 -s EXPORT_NAME="'libopenmpt'"
CXXFLAGS += -s DISABLE_EXCEPTION_CATCHING=0 -s ERROR_ON_UNDEFINED_SYMBOLS=1 -s ERROR_ON_MISSING_LIBRARIES=1 -ffast-math
CFLAGS += -s DISABLE_EXCEPTION_CATCHING=0 -s ERROR_ON_UNDEFINED_SYMBOLS=1 -s ERROR_ON_MISSING_LIBRARIES=1 -ffast-math -fno-strict-aliasing
LDFLAGS += -s DISABLE_EXCEPTION_CATCHING=0 -s ERROR_ON_UNDEFINED_SYMBOLS=1 -s ERROR_ON_MISSING_LIBRARIES=1 -s EXPORT_NAME="'libopenmpt'"
CFLAGS_SILENT += -Wno-unused-parameter -Wno-unused-function -Wno-cast-qual
CFLAGS_SILENT += -Wno-\#warnings
CFLAGS_SILENT += -Wno-cast-align
CFLAGS_SILENT += -Wno-cast-qual
CFLAGS_SILENT += -Wno-format
CFLAGS_SILENT += -Wno-missing-prototypes
CFLAGS_SILENT += -Wno-sign-compare
CFLAGS_SILENT += -Wno-unused-function
CFLAGS_SILENT += -Wno-unused-parameter
CFLAGS_SILENT += -Wno-unused-variable
CXXFLAGS_WARNINGS += -Wmissing-declarations
CFLAGS_WARNINGS += -Wmissing-prototypes
@ -98,7 +90,7 @@ REQUIRES_RUNPREFIX=1
EXESUFFIX=.js
SOSUFFIX=.js
RUNPREFIX=node
TEST_LDFLAGS= --pre-js build/make/test-pre.js
TEST_LDFLAGS= --pre-js build/make/test-pre.js -lnodefs.js
DYNLINK=0
SHARED_LIB=1
@ -106,6 +98,7 @@ STATIC_LIB=0
EXAMPLES=1
OPENMPT123=0
SHARED_SONAME=0
NO_SHARED_LINKER_FLAG=1
# Disable the generic compiler optimization flags as emscripten is sufficiently different.
# Optimization flags are hard-coded for emscripten in this file.

View file

@ -9,14 +9,6 @@ CXXFLAGS_STDCXX = -std=$(STDCXX)
else
ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++17 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++17' ; fi ), c++17)
CXXFLAGS_STDCXX = -std=c++17
else
ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++14 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++14' ; fi ), c++14)
CXXFLAGS_STDCXX = -std=c++14
else
ifeq ($(shell printf '\n' > bin/empty.cpp ; if $(CXX) -std=c++11 -c bin/empty.cpp -o bin/empty.out > /dev/null 2>&1 ; then echo 'c++11' ; fi ), c++11)
CXXFLAGS_STDCXX = -std=c++11
endif
endif
endif
endif
CFLAGS_STDC = -std=c99
@ -40,17 +32,27 @@ CXXFLAGS += -fsanitize=undefined
CFLAGS += -fsanitize=undefined
endif
CXXFLAGS_WARNINGS += -Wsuggest-override -Wno-psabi
ifeq ($(MODERN),1)
LDFLAGS += -fuse-ld=gold
CXXFLAGS_WARNINGS += -Wpedantic -Wlogical-op -Wframe-larger-than=16000
#CXXFLAGS_WARNINGS += -Wdouble-promotion
CFLAGS_WARNINGS += -Wpedantic -Wlogical-op -Wframe-larger-than=4000
#CFLAGS_WARNINGS += -Wdouble-promotion
LDFLAGS_WARNINGS += -Wl,-no-undefined -Wl,--detect-odr-violations
CXXFLAGS_WARNINGS += -Wsuggest-override
# re-renable after 1.29 branch
#CXXFLAGS_WARNINGS += -Wdouble-promotion
#CFLAGS_WARNINGS += -Wdouble-promotion
endif
CFLAGS_SILENT += -Wno-unused-parameter -Wno-unused-function -Wno-cast-qual -Wno-old-style-declaration -Wno-type-limits -Wno-unused-but-set-variable
CFLAGS_SILENT += -Wno-cast-qual
CFLAGS_SILENT += -Wno-empty-body
CFLAGS_SILENT += -Wno-implicit-fallthrough
CFLAGS_SILENT += -Wno-old-style-declaration
CFLAGS_SILENT += -Wno-sign-compare
CFLAGS_SILENT += -Wno-type-limits
CFLAGS_SILENT += -Wno-unused-but-set-variable
CFLAGS_SILENT += -Wno-unused-function
CFLAGS_SILENT += -Wno-unused-parameter
EXESUFFIX=

View file

@ -4,7 +4,7 @@ CXX ?= c++
LD ?= c++
AR = ar
CXXFLAGS_STDCXX = -std=c++11
CXXFLAGS_STDCXX = -std=c++17
CFLAGS_STDC = -std=c99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)

View file

@ -4,7 +4,7 @@ CXX = i686-w64-mingw32-g++$(MINGW_FLAVOUR)
LD = i686-w64-mingw32-g++$(MINGW_FLAVOUR)
AR = i686-w64-mingw32-ar$(MINGW_FLAVOUR)
CXXFLAGS_STDCXX = -std=c++11
CXXFLAGS_STDCXX = -std=c++17
CFLAGS_STDC = -std=c99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)

View file

@ -4,7 +4,7 @@ CXX = x86_64-w64-mingw32-g++$(MINGW_FLAVOUR)
LD = x86_64-w64-mingw32-g++$(MINGW_FLAVOUR)
AR = x86_64-w64-mingw32-ar$(MINGW_FLAVOUR)
CXXFLAGS_STDCXX = -std=c++11
CXXFLAGS_STDCXX = -std=c++17
CFLAGS_STDC = -std=c99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)

View file

@ -4,7 +4,7 @@ CXX = x86_64-w64-mingw32-g++$(MINGW_FLAVOUR)
LD = x86_64-w64-mingw32-g++$(MINGW_FLAVOUR)
AR = x86_64-w64-mingw32-ar$(MINGW_FLAVOUR)
CXXFLAGS_STDCXX = -std=c++11
CXXFLAGS_STDCXX = -std=c++17
CFLAGS_STDC = -std=c99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)

View file

@ -4,7 +4,7 @@ CXX = i686-w64-mingw32-g++$(MINGW_FLAVOUR)
LD = i686-w64-mingw32-g++$(MINGW_FLAVOUR)
AR = i686-w64-mingw32-ar$(MINGW_FLAVOUR)
CXXFLAGS_STDCXX = -std=c++11
CXXFLAGS_STDCXX = -std=c++17
CFLAGS_STDC = -std=c99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)

View file

@ -4,7 +4,7 @@ CXX ?= c++
LD ?= c++
AR = ar
CXXFLAGS_STDCXX = -std=c++11
CXXFLAGS_STDCXX = -std=c++17
CFLAGS_STDC = -std=c99
CXXFLAGS += $(CXXFLAGS_STDCXX)
CFLAGS += $(CFLAGS_STDC)

View file

@ -1,10 +1,10 @@
#pragma once
#define OPENMPT_VERSION_SVNVERSION "12263"
#define OPENMPT_VERSION_REVISION 12263
#define OPENMPT_VERSION_SVNVERSION "13775"
#define OPENMPT_VERSION_REVISION 13775
#define OPENMPT_VERSION_DIRTY 0
#define OPENMPT_VERSION_MIXEDREVISIONS 0
#define OPENMPT_VERSION_URL "https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.4.10"
#define OPENMPT_VERSION_DATE "2019-10-30T10:43:15.521271Z"
#define OPENMPT_VERSION_URL "https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.5.3"
#define OPENMPT_VERSION_DATE "2020-10-25T14:02:16.624929Z"
#define OPENMPT_VERSION_IS_PACKAGE 1

View file

@ -20,36 +20,10 @@
#if MPT_OS_WINDOWS
#if defined(MPT_BUILD_MSVC)
#if defined(MPT_BUILD_TARGET_XP)
#if defined(_M_X64)
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0502 // _WIN32_WINNT_WS03
#endif
#else // !_M_X64
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 // _WIN32_WINNT_WINXP
#endif
#endif // _M_X64
#else // MPT_BUILD_TARGET
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0601 // _WIN32_WINNT_WIN7
#endif
#endif // MPT_BUILD_TARGET
#else // !MPT_BUILD_MSVC
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 // _WIN32_WINNT_WINXP
#endif
#endif // MPT_BUILD_MSVC
#ifndef WINVER
#define WINVER _WIN32_WINNT
#endif
@ -98,8 +72,15 @@
#if defined(MODPLUG_TRACKER)
#if MPT_OS_WINDOWS
#if !defined(MPT_BUILD_WINESUPPORT)
#define MPT_WITH_MFC
#endif // !MPT_BUILD_WINESUPPORT
#endif // MPT_OS_WINDOWS
// OpenMPT-only dependencies
#define MPT_WITH_ASIO
#define MPT_WITH_DMO
#define MPT_WITH_LAME
#define MPT_WITH_LHASA
#define MPT_WITH_MINIZIP
@ -118,13 +99,10 @@
// OpenMPT and libopenmpt dependencies (not for openmp123, player plugins or examples)
//#define MPT_WITH_DL
#define MPT_WITH_FLAC
//#define MPT_WITH_ICONV
//#define MPT_WITH_LTDL
#if MPT_OS_WINDOWS
#if (_WIN32_WINNT >= 0x0601)
#define MPT_WITH_MEDIAFOUNDATION
#endif
#endif
//#define MPT_WITH_MINIMP3
//#define MPT_WITH_MINIZ
#define MPT_WITH_MPG123
@ -132,6 +110,11 @@
//#define MPT_WITH_STBVORBIS
#define MPT_WITH_VORBIS
#define MPT_WITH_VORBISFILE
#if MPT_OS_WINDOWS
#if (_WIN32_WINNT >= 0x0A00)
#define MPT_WITH_WINDOWS10
#endif
#endif
#define MPT_WITH_ZLIB
#endif // MODPLUG_TRACKER
@ -147,7 +130,6 @@
//#define MPT_WITH_DL
//#define MPT_WITH_FLAC
//#define MPT_WITH_ICONV
//#define MPT_WITH_LTDL
//#define MPT_WITH_MEDIAFOUNDATION
#define MPT_WITH_MINIMP3
@ -163,7 +145,6 @@
//#define MPT_WITH_DL
//#define MPT_WITH_FLAC
//#define MPT_WITH_ICONV
//#define MPT_WITH_LTDL
//#define MPT_WITH_MEDIAFOUNDATION
//#define MPT_WITH_MINIMP3
@ -194,7 +175,6 @@
//#define MPT_WITH_DL
//#define MPT_WITH_FLAC
//#define MPT_WITH_ICONV
//#define MPT_WITH_LTDL
//#define MPT_WITH_MEDIAFOUNDATION
//#define MPT_WITH_MINIMP3
@ -229,14 +209,14 @@
#define MPT_LOG_GLOBAL_LEVEL 0
#endif
// Enable all individual logging macros and MPT_LOG calls
//#define MPT_ALL_LOGGING
// Disable all runtime asserts
#if !defined(MPT_BUILD_DEBUG) && !defined(MPT_BUILD_CHECKED) && !defined(MPT_BUILD_WINESUPPORT)
#define NO_ASSERTS
#endif
// Enable std::istream support in class FileReader (this is generally not needed for the tracker, local files can easily be mmapped as they have been before introducing std::istream support)
//#define MPT_FILEREADER_STD_ISTREAM
// Enable callback stream wrapper for FileReader (required by libopenmpt C API).
//#define MPT_FILEREADER_CALLBACK_STREAM
@ -267,9 +247,6 @@
// Define to build without VST plugin support; makes build possible without VST SDK.
//#define NO_VST
// Define to build without DMO plugin support
//#define NO_DMO
// (HACK) Define to build without any plugin support
//#define NO_PLUGINS
@ -300,7 +277,7 @@
#define NO_ASSERTS
#endif
//#define NO_LOGGING
#define MPT_FILEREADER_STD_ISTREAM
//#define MPT_ALL_LOGGING
#define MPT_FILEREADER_CALLBACK_STREAM
//#define MPT_EXTERNAL_SAMPLES
#if defined(ENABLE_TESTS) || defined(MPT_BUILD_HACK_ARCHIVE_SUPPORT)
@ -320,9 +297,6 @@
#define NO_EQ
#define NO_AGC
#define NO_VST
//#if !MPT_OS_WINDOWS || MPT_OS_WINDOWS_WINRT || !MPT_COMPILER_MSVC || !defined(LIBOPENMPT_BUILD_FULL)
#define NO_DMO
//#endif
//#define NO_PLUGINS
//#define NO_LIBOPENMPT_C
//#define NO_LIBOPENMPT_CXX
@ -333,51 +307,28 @@
#if MPT_OS_WINDOWS
#define MPT_CHARSET_WIN32
#ifndef MPT_ENABLE_CHARSET_LOCALE
#define MPT_ENABLE_CHARSET_LOCALE
#endif
#elif MPT_OS_LINUX
#define MPT_CHARSET_ICONV
#elif MPT_OS_ANDROID
#define MPT_CHARSET_INTERNAL
#elif MPT_OS_EMSCRIPTEN
#define MPT_CHARSET_INTERNAL
#ifndef MPT_LOCALE_ASSUME_CHARSET
#define MPT_LOCALE_ASSUME_CHARSET CharsetUTF8
#define MPT_LOCALE_ASSUME_CHARSET Charset::UTF8
#endif
#elif MPT_OS_MACOSX_OR_IOS
#if defined(MPT_WITH_ICONV)
#define MPT_CHARSET_ICONV
#ifndef MPT_ICONV_NO_WCHAR
#define MPT_ICONV_NO_WCHAR
#endif
#else
#define MPT_CHARSET_INTERNAL
#endif
//#ifndef MPT_LOCALE_ASSUME_CHARSET
//#define MPT_LOCALE_ASSUME_CHARSET CharsetUTF8
//#endif
#elif MPT_OS_DJGPP
#define MPT_CHARSET_INTERNAL
#ifndef MPT_LOCALE_ASSUME_CHARSET
#define MPT_LOCALE_ASSUME_CHARSET CharsetCP437
#define MPT_LOCALE_ASSUME_CHARSET Charset::CP437
#endif
#elif defined(MPT_WITH_ICONV)
#define MPT_CHARSET_ICONV
#endif
@ -457,6 +408,7 @@
#if defined(ENABLE_ASM)
#if MPT_COMPILER_MSVC && defined(_M_IX86)
#define ENABLE_CPUID
// Generate general x86 inline assembly and intrinsics.
#define ENABLE_X86
// Generate MMX instructions (only used when the CPU supports it).
@ -469,14 +421,14 @@
#define ENABLE_SSE3
// Generate SSE4 instructions (only used when the CPU supports it).
#define ENABLE_SSE4
#if defined(MPT_BUILD_TARGET_XP)
// Generate AMD specific instruction set extensions (only used when the CPU supports it).
#define ENABLE_X86_AMD
#endif
// Generate AVX instructions (only used when the CPU supports it).
#define ENABLE_AVX
// Generate AVX2 instructions (only used when the CPU supports it).
#define ENABLE_AVX2
#elif MPT_COMPILER_MSVC && defined(_M_X64)
#define ENABLE_CPUID
// Generate general x64 intrinsics.
#define ENABLE_X64
// Generate SSE instructions (only used when the CPU supports it).
@ -487,18 +439,14 @@
#define ENABLE_SSE3
// Generate SSE4 instructions (only used when the CPU supports it).
#define ENABLE_SSE4
// Generate AVX instructions (only used when the CPU supports it).
#define ENABLE_AVX
// Generate AVX2 instructions (only used when the CPU supports it).
#define ENABLE_AVX2
#endif // arch
#endif // ENABLE_ASM
#if defined(MPT_WITH_LAME) && defined(MPT_BUILD_MSVC) && defined(MPT_BUILD_MSVC_STATIC) && defined(MODPLUG_TRACKER) && !MPT_OS_WINDOWS_WINRT
#define MPT_ENABLE_LAME_DELAYLOAD
#endif
#if defined(MPT_WITH_MPG123) && defined(MPT_BUILD_MSVC) && defined(MPT_BUILD_MSVC_STATIC) && defined(MODPLUG_TRACKER) && !MPT_OS_WINDOWS_WINRT
#define MPT_ENABLE_MPG123_DELAYLOAD
#endif
#if defined(ENABLE_TESTS) && defined(MODPLUG_NO_FILESAVE)
#undef MODPLUG_NO_FILESAVE // tests recommend file saving
#endif
@ -524,26 +472,10 @@
#define MPT_ENABLE_TEMPFILE
#endif
#if MPT_CXX_AT_LEAST(17) && defined(MPT_CHARSET_CODECVTUTF8)
#undef MPT_CHARSET_CODECVTUTF8 // std::codecvt_utf8 is deprecated in c++17
#endif
#if !defined(MPT_CHARSET_WIN32) && !defined(MPT_CHARSET_ICONV) && !defined(MPT_CHARSET_CODECVTUTF8) && !defined(MPT_CHARSET_INTERNAL)
#define MPT_CHARSET_INTERNAL
#endif
#if defined(MODPLUG_TRACKER) && !defined(MPT_ENABLE_DYNBIND)
#define MPT_ENABLE_DYNBIND // Tracker requires dynamic library loading for export codecs
#endif
#if defined(MPT_ENABLE_LAME_DELAYLOAD) && !defined(MPT_ENABLE_DYNBIND)
#define MPT_ENABLE_DYNBIND // static MSVC builds require dynbind to load delay-loaded DLLs
#endif
#if defined(MPT_ENABLE_MPG123_DELAYLOAD) && !defined(MPT_ENABLE_DYNBIND)
#define MPT_ENABLE_DYNBIND // static MSVC builds require dynbind to load delay-loaded DLLs
#endif
#if defined(MPT_WITH_MEDIAFOUNDATION) && !defined(MPT_ENABLE_DYNBIND)
#define MPT_ENABLE_DYNBIND // MediaFoundation needs dynamic loading in order to test availability of delay loaded libs
#endif
@ -556,10 +488,6 @@
#define MPT_ENABLE_FILEIO // Test suite requires PathString for file loading.
#endif
#if !MPT_OS_WINDOWS && !defined(MPT_FILEREADER_STD_ISTREAM)
#define MPT_FILEREADER_STD_ISTREAM // MMAP is only supported on Windows
#endif
#if defined(MODPLUG_TRACKER) && !defined(MPT_ENABLE_FILEIO)
#define MPT_ENABLE_FILEIO // Tracker requires disk file io
#endif
@ -575,7 +503,6 @@
#if defined(NO_PLUGINS)
// Any plugin type requires NO_PLUGINS to not be defined.
#define NO_VST
#define NO_DMO
#endif
#if defined(ENABLE_ASM) || !defined(NO_VST)
@ -626,6 +553,10 @@
// platform configuration
#ifdef MPT_WITH_MFC
//#define MPT_MFC_FULL // use full MFC, including MFC controls
#endif // MPT_WITH_MFC
#if defined(MODPLUG_TRACKER)
#if MPT_OS_WINDOWS
#if !defined(MPT_BUILD_WINESUPPORT)
@ -721,11 +652,13 @@
#pragma warning(disable:4512) // assignment operator could not be generated
#pragma warning(error:4309) // Treat "truncation of constant value"-warning as error.
#pragma warning(error:4463) // Treat overflow; assigning value to bit-field that can only hold values from low_value to high_value"-warning as error.
#ifdef MPT_BUILD_ANALYZED
// Disable Visual Studio static analyzer warnings that generate too many false positives in VS2010.
//#pragma warning(disable:6246)
//#pragma warning(disable:6262)
#pragma warning(disable:6297) // 32-bit value is shifted, then cast to 64-bit value. Results might not be an expected value.
#pragma warning(disable:6326) // Potential comparison of a constant with another constant
//#pragma warning(disable:6385)
//#pragma warning(disable:6386)
@ -733,32 +666,30 @@
#endif // MPT_COMPILER_MSVC
#if MPT_COMPILER_CLANG
#if defined(MPT_BUILD_MSVC)
#pragma clang diagnostic warning "-Wimplicit-fallthrough"
#endif // MPT_BUILD_MSVC
#if defined(MODPLUG_TRACKER)
#pragma clang diagnostic ignored "-Wunused-local-typedef"
#endif // MODPLUG_TRACKER
#endif // MPT_COMPILER_CLANG
// standard library quirks
#if MPT_CXX_AT_LEAST(17)
#if (MPT_COMPILER_GCC || MPT_COMPILER_CLANG)
// we need to detect the standard library via macro __GLIBCXX__
#include <vector>
#endif
#if MPT_COMPILER_MSVC || MPT_GCC_BEFORE(8,1,0) || MPT_CLANG_BEFORE(5,0,0) || (MPT_COMPILER_GCC && defined(__GLIBCXX__) && (defined(__MINGW32__) || defined(__MINGW64__))) || (MPT_COMPILER_CLANG && defined(__GLIBCXX__)) || (MPT_COMPILER_CLANG && MPT_OS_MACOSX_OR_IOS) || MPT_OS_OPENBSD || MPT_OS_EMSCRIPTEN || MPT_OS_HAIKU || (defined(__clang__) && defined(_MSC_VER))
#define MPT_COMPILER_QUIRK_NO_ALIGNEDALLOC
#endif
#endif
// third-party library configuration
#if defined(MODPLUG_TRACKER)
//#define MPT_MFC_FULL // use full MFC, including MFC controls
#endif
#ifdef MPT_WITH_FLAC
#ifdef MPT_BUILD_MSVC_STATIC
#define FLAC__NO_DLL

View file

@ -34,8 +34,8 @@
#define MPT_CLANG_AT_LEAST(major,minor,patch) (MPT_COMPILER_CLANG_VERSION >= MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch)))
#define MPT_CLANG_BEFORE(major,minor,patch) (MPT_COMPILER_CLANG_VERSION < MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch)))
#if MPT_CLANG_BEFORE(3,6,0)
#error "clang version 3.6 required"
#if MPT_CLANG_BEFORE(5,0,0)
#error "clang version 5 required"
#endif
#if defined(__clang_analyzer__)
@ -51,14 +51,22 @@
#define MPT_GCC_AT_LEAST(major,minor,patch) (MPT_COMPILER_GCC_VERSION >= MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch)))
#define MPT_GCC_BEFORE(major,minor,patch) (MPT_COMPILER_GCC_VERSION < MPT_COMPILER_MAKE_VERSION3((major),(minor),(patch)))
#if MPT_GCC_BEFORE(4,8,0)
#error "GCC version 4.8 required"
#if MPT_GCC_BEFORE(7,1,0)
#error "GCC version 7.1 required"
#endif
#elif defined(_MSC_VER)
#define MPT_COMPILER_MSVC 1
#if (_MSC_VER >= 1922)
#if (_MSC_VER >= 1926)
#define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2019,6)
#elif (_MSC_VER >= 1925)
#define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2019,5)
#elif (_MSC_VER >= 1924)
#define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2019,4)
#elif (_MSC_VER >= 1923)
#define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2019,3)
#elif (_MSC_VER >= 1922)
#define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2019,2)
#elif (_MSC_VER >= 1921)
#define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2019,1)
@ -96,8 +104,8 @@
#define MPT_MSVC_AT_LEAST(version,sp) (MPT_COMPILER_MSVC_VERSION >= MPT_COMPILER_MAKE_VERSION2((version),(sp)))
#define MPT_MSVC_BEFORE(version,sp) (MPT_COMPILER_MSVC_VERSION < MPT_COMPILER_MAKE_VERSION2((version),(sp)))
#if MPT_MSVC_BEFORE(2015,0)
#error "MSVC version 2015 required"
#if MPT_MSVC_BEFORE(2017,9)
#error "MSVC version 2017 15.9 required"
#endif
#if defined(_PREFAST_)
@ -139,29 +147,21 @@
#if (__cplusplus >= 201703)
#define MPT_CXX 17
#elif (__cplusplus >= 201402)
#define MPT_CXX 14
#else
#define MPT_CXX 11
#define MPT_CXX 17
#endif
#elif MPT_COMPILER_MSVC
#if MPT_MSVC_AT_LEAST(2015,3)
#if (_MSVC_LANG >= 201703)
#define MPT_CXX 17
#elif (_MSVC_LANG >= 201402)
#define MPT_CXX 14
#else
#define MPT_CXX 11
#endif
#else
#define MPT_CXX 11
#define MPT_CXX 17
#endif
#else
#define MPT_CXX 11
#define MPT_CXX 17
#endif
@ -205,11 +205,13 @@
#define MPT_OS_EMSCRIPTEN 1
#if defined(__EMSCRIPTEN_major__) && defined(__EMSCRIPTEN_minor__)
#if (__EMSCRIPTEN_major__ > 1)
// ok
#elif (__EMSCRIPTEN_major__ == 1) && (__EMSCRIPTEN_minor__ >= 38)
// ok
// ok
#elif (__EMSCRIPTEN_major__ == 1) && (__EMSCRIPTEN_minor__ > 39)
// ok
#elif (__EMSCRIPTEN_major__ == 1) && (__EMSCRIPTEN_minor__ == 39) && (__EMSCRIPTEN_tiny__ >= 7)
// ok
#else
#error "Emscripten >= 1.38 is required."
#error "Emscripten >= 1.39.7 is required."
#endif
#endif
#elif defined(_WIN32)
@ -306,13 +308,59 @@
#define MPT_PLATFORM_MULTITHREADED 0
#endif
#if MPT_OS_DJGPP
#define MPT_COMPILER_QUIRK_NO_WCHAR
#endif
#if MPT_MSVC_BEFORE(2017,8)
// fixed in VS2017 15.8
// see <https://blogs.msdn.microsoft.com/vcblog/2018/09/18/stl-features-and-fixes-in-vs-2017-15-8/>
#define MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
#if defined(__arm__)
#if defined(__SOFTFP__)
#define MPT_COMPILER_QUIRK_FLOAT_EMULATED 1
#else
#define MPT_COMPILER_QUIRK_FLOAT_EMULATED 0
#endif
#if defined(__VFP_FP__)
// native-endian IEEE754
#define MPT_COMPILER_QUIRK_FLOAT_NOTNATIVEENDIAN 0
#define MPT_COMPILER_QUIRK_FLOAT_NOTIEEE754 0
#elif defined(__MAVERICK__)
// little-endian IEEE754, we assume native-endian though
#define MPT_COMPILER_QUIRK_FLOAT_NOTNATIVEENDIAN 1
#define MPT_COMPILER_QUIRK_FLOAT_NOTIEEE754 0
#else
// not IEEE754
#define MPT_COMPILER_QUIRK_FLOAT_NOTNATIVEENDIAN 1
#define MPT_COMPILER_QUIRK_FLOAT_NOTIEEE754 1
#endif
#elif defined(__mips__)
#if defined(__mips_soft_float)
#define MPT_COMPILER_QUIRK_FLOAT_EMULATED 1
#else
#define MPT_COMPILER_QUIRK_FLOAT_EMULATED 0
#endif
#endif
#if MPT_OS_EMSCRIPTEN
#define MPT_COMPILER_QUIRK_FLOAT_PREFER64 1
#endif
#ifndef MPT_COMPILER_QUIRK_FLOAT_PREFER32
#define MPT_COMPILER_QUIRK_FLOAT_PREFER32 0
#endif
#ifndef MPT_COMPILER_QUIRK_FLOAT_PREFER64
#define MPT_COMPILER_QUIRK_FLOAT_PREFER64 0
#endif
#ifndef MPT_COMPILER_QUIRK_FLOAT_EMULATED
#define MPT_COMPILER_QUIRK_FLOAT_EMULATED 0
#endif
#ifndef MPT_COMPILER_QUIRK_FLOAT_NOTNATIVEENDIAN
#define MPT_COMPILER_QUIRK_FLOAT_NOTNATIVEENDIAN 0
#endif
#ifndef MPT_COMPILER_QUIRK_FLOAT_NOTIEEE754
#define MPT_COMPILER_QUIRK_FLOAT_NOTIEEE754 0
#endif

View file

@ -191,7 +191,7 @@ void ComponentFactoryBase::PreConstruct() const
{
MPT_LOG(LogInformation, "Components",
mpt::format(U_("Constructing Component %1"))
( mpt::ToUnicode(mpt::CharsetASCII, m_ID)
( mpt::ToUnicode(mpt::Charset::ASCII, m_ID)
)
);
}
@ -233,7 +233,7 @@ static ComponentListEntry * & ComponentListHead()
bool ComponentListPush(ComponentListEntry *entry)
{
MPT_LOCK_GUARD<mpt::mutex> guard(ComponentListMutex());
mpt::lock_guard<mpt::mutex> guard(ComponentListMutex());
entry->next = ComponentListHead();
ComponentListHead() = entry;
return true;
@ -267,7 +267,7 @@ std::shared_ptr<ComponentManager> ComponentManager::Instance()
ComponentManager::ComponentManager(const IComponentManagerSettings &settings)
: m_Settings(settings)
{
MPT_LOCK_GUARD<mpt::mutex> guard(ComponentListMutex());
mpt::lock_guard<mpt::mutex> guard(ComponentListMutex());
for(ComponentListEntry *entry = ComponentListHead(); entry; entry = entry->next)
{
entry->reg(*this);

View file

@ -318,6 +318,8 @@ public:
virtual bool KeepLoaded() const = 0;
virtual bool IsBlocked(const std::string &key) const = 0;
virtual mpt::PathString Path() const = 0;
protected:
virtual ~IComponentManagerSettings() = default;
};
@ -440,7 +442,7 @@ std::shared_ptr<const type> GetComponent()
{
static std::weak_ptr<type> cache;
static mpt::mutex m;
MPT_LOCK_GUARD<mpt::mutex> l(m);
mpt::lock_guard<mpt::mutex> l(m);
std::shared_ptr<type> component = cache.lock();
if(!component)
{

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -16,17 +16,9 @@ OPENMPT_NAMESPACE_BEGIN
class FileReaderTraitsMemory;
#if defined(MPT_FILEREADER_STD_ISTREAM)
class FileReaderTraitsStdStream;
typedef FileReaderTraitsStdStream FileReaderTraitsDefault;
#else // !MPT_FILEREADER_STD_ISTREAM
typedef FileReaderTraitsMemory FileReaderTraitsDefault;
#endif // MPT_FILEREADER_STD_ISTREAM
using FileReaderTraitsDefault = FileReaderTraitsStdStream;
namespace detail {
@ -35,9 +27,9 @@ class FileReader;
} // namespace detail
typedef detail::FileReader<FileReaderTraitsDefault> FileReader;
using FileReader = detail::FileReader<FileReaderTraitsDefault>;
typedef detail::FileReader<FileReaderTraitsMemory> MemoryFileReader;
using MemoryFileReader = detail::FileReader<FileReaderTraitsMemory>;
OPENMPT_NAMESPACE_END

View file

@ -24,7 +24,7 @@ OPENMPT_NAMESPACE_BEGIN
template <typename Tenum>
struct enum_traits
{
typedef typename std::make_unsigned<Tenum>::type store_type;
using store_type = typename std::make_unsigned<Tenum>::type;
};
@ -35,9 +35,9 @@ template <typename enum_t>
class enum_value_type
{
public:
typedef enum_t enum_type;
typedef enum_value_type value_type;
typedef typename enum_traits<enum_t>::store_type store_type;
using enum_type = enum_t;
using value_type = enum_value_type;
using store_type = typename enum_traits<enum_t>::store_type;
private:
store_type bits;
public:
@ -94,10 +94,10 @@ template <typename enum_t>
class Enum
{
public:
typedef Enum self_type;
typedef enum_t enum_type;
typedef enum_value_type<enum_t> value_type;
typedef typename value_type::store_type store_type;
using self_type = Enum;
using enum_type = enum_t;
using value_type = enum_value_type<enum_t>;
using store_type = typename value_type::store_type;
private:
enum_type value;
public:
@ -150,10 +150,10 @@ template <typename enum_t, typename store_t = typename enum_value_type<enum_t>::
class FlagSet
{
public:
typedef FlagSet self_type;
typedef enum_t enum_type;
typedef enum_value_type<enum_t> value_type;
typedef store_t store_type;
using self_type = FlagSet;
using enum_type = enum_t;
using value_type = enum_value_type<enum_t>;
using store_type = store_t;
private:
@ -195,8 +195,7 @@ public:
{
return load();
}
// The macro-based extended instrument fields writer in InstrumentExtensions.cpp currently needs this conversion.
/*MPT_DEPRECATED*/ MPT_CONSTEXPR11_FUN operator store_type () const noexcept
MPT_CONSTEXPR11_FUN explicit operator store_type () const noexcept
{
return load().as_bits();
}

View file

@ -110,8 +110,8 @@ void Logger::SendLogMessage(const mpt::source_location &loc, LogLevel level, con
#endif // MODPLUG_TRACKER
// remove eol if already present and add log level prefix
const mpt::ustring message = LogLevelToString(level) + U_(": ") + mpt::String::RTrim(text, U_("\r\n"));
const mpt::ustring file = mpt::ToUnicode(mpt::CharsetASCII, loc.file_name() ? loc.file_name() : "");
const mpt::ustring function = mpt::ToUnicode(mpt::CharsetASCII, loc.function_name() ? loc.function_name() : "");
const mpt::ustring file = mpt::ToUnicode(mpt::CharsetSource, loc.file_name() ? loc.file_name() : "");
const mpt::ustring function = mpt::ToUnicode(mpt::CharsetSource, loc.function_name() ? loc.function_name() : "");
const mpt::ustring line = mpt::ufmt::dec(loc.line());
#if defined(MODPLUG_TRACKER) && !defined(MPT_BUILD_WINESUPPORT)
#if MPT_OS_WINDOWS
@ -132,7 +132,7 @@ void Logger::SendLogMessage(const mpt::source_location &loc, LogLevel level, con
}
if(s_logfile)
{
mpt::IO::WriteText(s_logfile, mpt::ToCharset(mpt::CharsetUTF8, mpt::format(U_("%1+%2 %3(%4): %5 [%6]\n"))
mpt::IO::WriteText(s_logfile, mpt::ToCharset(mpt::CharsetLogfile, mpt::format(U_("%1+%2 %3(%4): %5 [%6]\n"))
( mpt::Date::ANSI::ToUString(cur)
, mpt::ufmt::right(6, mpt::ufmt::dec(diff))
, file
@ -168,42 +168,21 @@ void Logger::SendLogMessage(const mpt::source_location &loc, LogLevel level, con
#elif defined(MODPLUG_TRACKER) && defined(MPT_BUILD_WINESUPPORT)
std::clog
<< "NativeSupport: "
<< mpt::ToCharset(mpt::CharsetLocaleOrUTF8, file) << "(" << mpt::ToCharset(mpt::CharsetLocaleOrUTF8, line) << ")" << ": "
<< mpt::ToCharset(mpt::CharsetLocaleOrUTF8, message)
<< " [" << mpt::ToCharset(mpt::CharsetLocaleOrUTF8, function) << "]"
<< mpt::ToCharset(mpt::CharsetStdIO, file) << "(" << mpt::ToCharset(mpt::CharsetStdIO, line) << ")" << ": "
<< mpt::ToCharset(mpt::CharsetStdIO, message)
<< " [" << mpt::ToCharset(mpt::CharsetStdIO, function) << "]"
<< std::endl;
#else // !MODPLUG_TRACKER
std::clog
<< "libopenmpt: "
<< mpt::ToCharset(mpt::CharsetLocaleOrUTF8, file) << "(" << mpt::ToCharset(mpt::CharsetLocaleOrUTF8, line) << ")" << ": "
<< mpt::ToCharset(mpt::CharsetLocaleOrUTF8, message)
<< " [" << mpt::ToCharset(mpt::CharsetLocaleOrUTF8, function) << "]"
<< mpt::ToCharset(mpt::CharsetStdIO, file) << "(" << mpt::ToCharset(mpt::CharsetStdIO, line) << ")" << ": "
<< mpt::ToCharset(mpt::CharsetStdIO, message)
<< " [" << mpt::ToCharset(mpt::CharsetStdIO, function) << "]"
<< std::endl;
#endif // MODPLUG_TRACKER
#endif // MPT_LOG_IS_DISABLED
}
void LegacyLogger::operator () (const AnyStringLocale &text)
{
SendLogMessage(loc, MPT_LEGACY_LOGLEVEL, "", text);
}
void LegacyLogger::operator () (const char *format, ...)
{
static const std::size_t LOGBUF_SIZE = 1024;
char message[LOGBUF_SIZE];
va_list va;
va_start(va, format);
vsnprintf(message, LOGBUF_SIZE, format, va);
va_end(va);
message[LOGBUF_SIZE - 1] = '\0';
SendLogMessage(loc, MPT_LEGACY_LOGLEVEL, "", mpt::ToUnicode(mpt::CharsetLocaleOrUTF8, message));
}
void LegacyLogger::operator () (LogLevel level, const mpt::ustring &text)
{
SendLogMessage(loc, level, "", text);
}
@ -219,7 +198,7 @@ namespace Trace {
// Debugging functionality will use simple globals.
bool volatile g_Enabled = false;
std::atomic<bool> g_Enabled = ATOMIC_VAR_INIT(false);
static bool g_Sealed = false;
@ -338,7 +317,7 @@ bool Dump(const mpt::PathString &filename)
mpt::ofstream f(filename);
f << "Build: OpenMPT " << mpt::ToCharset(mpt::CharsetUTF8, Build::GetVersionStringExtended()) << std::endl;
f << "Build: OpenMPT " << mpt::ToCharset(mpt::CharsetLogfile, Build::GetVersionStringExtended()) << std::endl;
bool qpcValid = false;
@ -350,7 +329,7 @@ bool Dump(const mpt::PathString &filename)
qpcValid = true;
}
f << "Dump: " << mpt::ToCharset(mpt::CharsetUTF8, mpt::Date::ANSI::ToUString(ftNow)) << std::endl;
f << "Dump: " << mpt::ToCharset(mpt::CharsetLogfile, mpt::Date::ANSI::ToUString(ftNow)) << std::endl;
f << "Captured events: " << Entries.size() << std::endl;
if(qpcValid && (Entries.size() > 0))
{
@ -367,7 +346,7 @@ bool Dump(const mpt::PathString &filename)
std::string time;
if(qpcValid)
{
time = mpt::ToCharset(mpt::CharsetUTF8, mpt::Date::ANSI::ToUString( ftNow - static_cast<int64>( static_cast<double>(qpcNow.QuadPart - entry.Timestamp) * (10000000.0 / static_cast<double>(qpcFreq.QuadPart) ) ) ) );
time = mpt::ToCharset(mpt::CharsetLogfile, mpt::Date::ANSI::ToUString( ftNow - static_cast<int64>( static_cast<double>(qpcNow.QuadPart - entry.Timestamp) * (10000000.0 / static_cast<double>(qpcFreq.QuadPart) ) ) ) );
} else
{
time = mpt::format("0x%1")(mpt::fmt::hex0<16>(entry.Timestamp));

View file

@ -11,6 +11,9 @@
#include "BuildSettings.h"
#if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
#include <atomic>
#endif
OPENMPT_NAMESPACE_BEGIN
@ -110,7 +113,7 @@ namespace log
// All logging code gets compiled and immediately dead-code eliminated.
#define MPT_LOG_IS_DISABLED
#endif
static const int GlobalLogLevel = MPT_LOG_GLOBAL_LEVEL ;
static constexpr int GlobalLogLevel = MPT_LOG_GLOBAL_LEVEL ;
#else
extern int GlobalLogLevel;
#endif
@ -155,35 +158,11 @@ public:
/**/
#define MPT_LEGACY_LOGLEVEL LogDebug
class LegacyLogger : public Logger
{
private:
const mpt::source_location loc;
public:
constexpr LegacyLogger(mpt::source_location loc) noexcept : loc(loc) {}
/* MPT_DEPRECATED */ void MPT_PRINTF_FUNC(2,3) operator () (const char *format, ...); // migrate to type-safe MPT_LOG
/* MPT_DEPRECATED */ void operator () (const AnyStringLocale &text); // migrate to properly namespaced MPT_LOG
/* MPT_DEPRECATED */ void operator () (LogLevel level, const mpt::ustring &text); // migrate to properly namespaced MPT_LOG
};
#define Log MPT_MAYBE_CONSTANT_IF(mpt::log::GlobalLogLevel < MPT_LEGACY_LOGLEVEL) { } else MPT_MAYBE_CONSTANT_IF(!mpt::log::IsFacilityActive("")) { } else mpt::log::LegacyLogger(MPT_SOURCE_LOCATION_CURRENT())
#else // !NO_LOGGING
#define MPT_LOG(level, facility, text) MPT_DO { } MPT_WHILE_0
struct LegacyLogger
{
inline void MPT_PRINTF_FUNC(2,3) operator () (const char * /*format*/ , ...) {}
inline void operator () (const AnyStringLocale & /*text*/ ) {}
inline void operator () (LogLevel /*level*/ , const mpt::ustring & /*text*/ ) {}
};
#define Log MPT_CONSTANT_IF(true) {} else mpt::log::LegacyLogger() // completely compile out arguments to Log() so that they do not even get evaluated
#endif // NO_LOGGING
@ -199,7 +178,7 @@ namespace Trace {
// This cacheline bouncing does not matter at all
// if there are not multiple thread adding trace points at high frequency (way greater than 1000Hz),
// which, in OpenMPT, is only ever the case for just a single thread (the audio thread), if at all.
extern bool volatile g_Enabled;
extern std::atomic<bool> g_Enabled;
static inline bool IsEnabled() { return g_Enabled; }
enum class Direction : int8

View file

@ -52,7 +52,7 @@ struct ProfileBlock
class Statistics * stats;
};
static const std::size_t MAX_PROFILES = 1024;
static constexpr std::size_t MAX_PROFILES = 1024;
static ProfileBlock Profiles[ MAX_PROFILES ];

View file

@ -98,7 +98,7 @@ public:
/**/
#define OPENMPT_PROFILE_FUNCTION(cat) OPENMPT_PROFILE_SCOPE(cat, __FUNCTION__)
#define OPENMPT_PROFILE_FUNCTION(cat) OPENMPT_PROFILE_SCOPE(cat, __func__)
#else // !USE_PROFILER

View file

@ -20,13 +20,13 @@ namespace Util
{
static const MPT_UCHAR_TYPE EncodeNibble[16] = {
static constexpr mpt::uchar EncodeNibble[16] = {
UC_('0'), UC_('1'), UC_('2'), UC_('3'),
UC_('4'), UC_('5'), UC_('6'), UC_('7'),
UC_('8'), UC_('9'), UC_('A'), UC_('B'),
UC_('C'), UC_('D'), UC_('E'), UC_('F') };
static inline bool DecodeByte(uint8 &byte, MPT_UCHAR_TYPE c1, MPT_UCHAR_TYPE c2)
static inline bool DecodeByte(uint8 &byte, mpt::uchar c1, mpt::uchar c2)
{
byte = 0;
if(UC_('0') <= c1 && c1 <= UC_('9'))
@ -62,7 +62,7 @@ mpt::ustring BinToHex(mpt::const_byte_span src)
{
mpt::ustring result;
result.reserve(src.size() * 2);
for(mpt::byte byte : src)
for(std::byte byte : src)
{
result.push_back(EncodeNibble[(mpt::byte_cast<uint8>(byte) & 0xf0) >> 4]);
result.push_back(EncodeNibble[mpt::byte_cast<uint8>(byte) & 0x0f]);
@ -70,9 +70,9 @@ mpt::ustring BinToHex(mpt::const_byte_span src)
return result;
}
std::vector<mpt::byte> HexToBin(const mpt::ustring &src)
std::vector<std::byte> HexToBin(const mpt::ustring &src)
{
std::vector<mpt::byte> result;
std::vector<std::byte> result;
result.reserve(src.size() / 2);
for(std::size_t i = 0; (i + 1) < src.size(); i += 2)
{
@ -81,7 +81,7 @@ std::vector<mpt::byte> HexToBin(const mpt::ustring &src)
{
return result;
}
result.push_back(mpt::byte_cast<mpt::byte>(byte));
result.push_back(mpt::byte_cast<std::byte>(byte));
}
return result;
}

View file

@ -207,7 +207,7 @@ namespace Util
namespace Util
{
std::vector<mpt::byte> HexToBin(const mpt::ustring &src);
std::vector<std::byte> HexToBin(const mpt::ustring &src);
mpt::ustring BinToHex(mpt::const_byte_span src);
template <typename T> inline mpt::ustring BinToHex(mpt::span<T> src) { return Util::BinToHex(mpt::byte_cast<mpt::const_byte_span>(src)); }

View file

@ -12,18 +12,6 @@
#include "stdafx.h"
#include "mptAlloc.h"
#include "mptBaseTypes.h"
#include <memory>
#include <new>
#include <cstddef>
#include <cstdlib>
#if MPT_COMPILER_MSVC
#include <malloc.h>
#endif
OPENMPT_NAMESPACE_BEGIN
@ -37,87 +25,6 @@ OPENMPT_NAMESPACE_BEGIN
namespace mpt
{
#if MPT_CXX_AT_LEAST(17)
#else
void* align(std::size_t alignment, std::size_t size, void* &ptr, std::size_t &space) noexcept
{
std::size_t offset = static_cast<std::size_t>(reinterpret_cast<std::uintptr_t>(ptr) & (alignment - 1));
if(offset != 0)
{
offset = alignment - offset;
}
if((space < offset) || ((space - offset) < size))
{
return nullptr;
}
ptr = static_cast<mpt::byte*>(ptr) + offset;
space -= offset;
return ptr;
}
#endif
aligned_raw_memory aligned_alloc_impl(std::size_t size, std::size_t count, std::size_t alignment)
{
#if MPT_CXX_AT_LEAST(17) && !defined(MPT_COMPILER_QUIRK_NO_ALIGNEDALLOC)
std::size_t space = count * size;
void* mem = std::aligned_alloc(alignment, space);
if(!mem)
{
MPT_EXCEPTION_THROW_OUT_OF_MEMORY();
}
return aligned_raw_memory{mem, mem};
#elif MPT_COMPILER_MSVC || (defined(__clang__) && defined(_MSC_VER))
std::size_t space = count * size;
void* mem = _aligned_malloc(space, alignment);
if(!mem)
{
MPT_EXCEPTION_THROW_OUT_OF_MEMORY();
}
return aligned_raw_memory{mem, mem};
#else
if(alignment > alignof(mpt::max_align_t))
{
std::size_t space = count * size + (alignment - 1);
void* mem = std::malloc(space);
if(!mem)
{
MPT_EXCEPTION_THROW_OUT_OF_MEMORY();
}
void* aligned_mem = mem;
void* aligned = mpt::align(alignment, size * count, aligned_mem, space);
if(!aligned)
{
MPT_EXCEPTION_THROW_OUT_OF_MEMORY();
}
return aligned_raw_memory{aligned, mem};
} else
{
std::size_t space = count * size;
void* mem = std::malloc(space);
if(!mem)
{
MPT_EXCEPTION_THROW_OUT_OF_MEMORY();
}
return aligned_raw_memory{mem, mem};
}
#endif
}
void aligned_free(aligned_raw_memory raw)
{
#if MPT_CXX_AT_LEAST(17) && !defined(MPT_COMPILER_QUIRK_NO_ALIGNEDALLOC)
std::free(raw.mem);
#elif MPT_COMPILER_MSVC || (defined(__clang__) && defined(_MSC_VER))
_aligned_free(raw.mem);
#else
std::free(raw.mem);
#endif
}
} // namespace mpt

View file

@ -18,8 +18,9 @@
#include "mptMemory.h"
#include "mptSpan.h"
#include <array>
#include <memory>
#include <utility>
#include <new>
#include <vector>
@ -32,9 +33,9 @@ namespace mpt {
template <typename T> inline span<T> as_span(std::vector<T> & cont) { return span<T>(cont); }
template <typename T> inline mpt::span<T> as_span(std::vector<T> & cont) { return mpt::span<T>(cont); }
template <typename T> inline span<const T> as_span(const std::vector<T> & cont) { return span<const T>(cont); }
template <typename T> inline mpt::span<const T> as_span(const std::vector<T> & cont) { return mpt::span<const T>(cont); }
@ -53,13 +54,13 @@ struct GetRawBytesFunctor<std::vector<T>>
{
inline mpt::const_byte_span operator () (const std::vector<T> & v) const
{
STATIC_ASSERT(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<const mpt::byte *>(v.data()), v.size() * sizeof(T));
static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<const std::byte *>(v.data()), v.size() * sizeof(T));
}
inline mpt::byte_span operator () (std::vector<T> & v) const
{
STATIC_ASSERT(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<mpt::byte *>(v.data()), v.size() * sizeof(T));
static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<std::byte *>(v.data()), v.size() * sizeof(T));
}
};
@ -68,8 +69,8 @@ struct GetRawBytesFunctor<const std::vector<T>>
{
inline mpt::const_byte_span operator () (const std::vector<T> & v) const
{
STATIC_ASSERT(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<const mpt::byte *>(v.data()), v.size() * sizeof(T));
static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<const std::byte *>(v.data()), v.size() * sizeof(T));
}
};
@ -79,22 +80,6 @@ struct GetRawBytesFunctor<const std::vector<T>>
#if MPT_CXX_AT_LEAST(14)
namespace mpt {
using std::make_unique;
} // namespace mpt
#else
namespace mpt {
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
} // namespace mpt
#endif
#if defined(MPT_ENABLE_ALIGNED_ALLOC)
@ -104,7 +89,7 @@ namespace mpt
#if MPT_CXX_AT_LEAST(17) && !(MPT_COMPILER_CLANG && defined(__GLIBCXX__)) && !(MPT_COMPILER_CLANG && MPT_OS_MACOSX_OR_IOS)
#if !(MPT_COMPILER_CLANG && defined(__GLIBCXX__)) && !(MPT_COMPILER_CLANG && MPT_OS_MACOSX_OR_IOS)
using std::launder;
#else
template <class T>
@ -115,147 +100,17 @@ MPT_NOINLINE T* launder(T* p) noexcept
#endif
#if MPT_CXX_AT_LEAST(17)
using std::align;
#else
// pre-C++17, std::align does not support over-alignement
void* align(std::size_t alignment, std::size_t size, void* &ptr, std::size_t &space) noexcept;
#endif
struct aligned_raw_memory
template <typename T, std::size_t count, std::align_val_t alignment>
struct alignas(static_cast<std::size_t>(alignment)) aligned_array
: std::array<T, count>
{
void* aligned;
void* mem;
static_assert(static_cast<std::size_t>(alignment) >= alignof(T));
static_assert(((count * sizeof(T)) % static_cast<std::size_t>(alignment)) == 0);
static_assert(sizeof(std::array<T, count>) == (sizeof(T) * count));
};
aligned_raw_memory aligned_alloc_impl(std::size_t size, std::size_t count, std::size_t alignment);
template <std::size_t alignment>
inline aligned_raw_memory aligned_alloc(std::size_t size, std::size_t count)
{
MPT_STATIC_ASSERT(alignment > 0);
MPT_CONSTEXPR14_ASSERT(mpt::weight(alignment) == 1);
return aligned_alloc_impl(size, count, alignment);
}
void aligned_free(aligned_raw_memory raw);
template <typename T>
struct aligned_raw_buffer
{
T* elements;
void* mem;
};
template <typename T, std::size_t alignment>
inline aligned_raw_buffer<T> aligned_alloc(std::size_t count)
{
MPT_STATIC_ASSERT(alignment >= alignof(T));
aligned_raw_memory raw = aligned_alloc<alignment>(sizeof(T), count);
return aligned_raw_buffer<T>{mpt::launder(reinterpret_cast<T*>(raw.aligned)), raw.mem};
}
template <typename T>
inline void aligned_free(aligned_raw_buffer<T> buf)
{
aligned_free(aligned_raw_memory{buf.elements, buf.mem});
}
template <typename T>
struct aligned_raw_objects
{
T* elements;
std::size_t count;
void* mem;
};
template <typename T, std::size_t alignment>
inline aligned_raw_objects<T> aligned_new(std::size_t count, T init = T())
{
aligned_raw_buffer<T> buf = aligned_alloc<T, alignment>(count);
std::size_t constructed = 0;
try
{
for(std::size_t i = 0; i < count; ++i)
{
new(&(buf.elements[i])) T(init);
constructed++;
}
} MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)
{
while(constructed--)
{
mpt::launder(&(buf.elements[constructed - 1]))->~T();
}
aligned_free(buf);
MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e);
} catch(...)
{
while(constructed--)
{
mpt::launder(&(buf.elements[constructed - 1]))->~T();
}
aligned_free(buf);
throw;
}
return aligned_raw_objects<T>{mpt::launder(buf.elements), count, buf.mem};
}
template <typename T>
inline void aligned_delete(aligned_raw_objects<T> objs)
{
if(objs.elements)
{
std::size_t constructed = objs.count;
while(constructed--)
{
objs.elements[constructed - 1].~T();
}
}
aligned_free(aligned_raw_buffer<T>{objs.elements, objs.mem});
}
template <typename T, std::size_t alignment>
class aligned_buffer
{
private:
aligned_raw_objects<T> objs;
public:
explicit aligned_buffer(std::size_t count = 0)
: objs(aligned_new<T, alignment>(count))
{
}
aligned_buffer(const aligned_buffer&) = delete;
aligned_buffer& operator=(const aligned_buffer&) = delete;
~aligned_buffer()
{
aligned_delete(objs);
}
public:
void destructive_resize(std::size_t count)
{
aligned_raw_objects<T> tmpobjs = aligned_new<T, alignment>(count);
{
using namespace std;
swap(objs, tmpobjs);
}
aligned_delete(tmpobjs);
}
public:
T* begin() noexcept { return objs.elements; }
const T* begin() const noexcept { return objs.elements; }
T* end() noexcept { return objs.elements + objs.count; }
const T* end() const noexcept { return objs.elements + objs.count; }
const T* cbegin() const noexcept { return objs.elements; }
const T* cend() const noexcept { return objs.elements + objs.count; }
T& operator[](std::size_t i) noexcept { return objs.elements[i]; }
const T& operator[](std::size_t i) const noexcept { return objs.elements[i]; }
T* data() noexcept { return objs.elements; }
const T* data() const noexcept { return objs.elements; }
std::size_t size() const noexcept { return objs.count; }
};
static_assert(sizeof(mpt::aligned_array<float, 4, std::align_val_t{sizeof(float) * 4}>) == sizeof(std::array<float, 4>));

View file

@ -56,7 +56,7 @@ OPENMPT_NAMESPACE_BEGIN
#if defined(_MFC_VER) && !defined(MPT_CPPCHECK_CUSTOM)
#if defined(MPT_WITH_MFC) && !defined(MPT_CPPCHECK_CUSTOM)
#if !defined(ASSERT)
#error "MFC is expected to #define ASSERT"
@ -72,7 +72,7 @@ OPENMPT_NAMESPACE_BEGIN
// let MFC handle our asserts
#define MPT_ASSERT_USE_FRAMEWORK 1
#else // !_MFC_VER
#else // !MPT_WITH_MFC
#if defined(ASSERT)
#define MPT_FRAMEWORK_ASSERT_IS_DEFINED
@ -86,7 +86,7 @@ OPENMPT_NAMESPACE_BEGIN
// handle assert in our own way without relying on some platform-/framework-specific assert implementation
#define MPT_ASSERT_USE_FRAMEWORK 0
#endif // _MFC_VER
#endif // MPT_WITH_MFC
#if defined(MPT_FRAMEWORK_ASSERT_IS_DEFINED) && (MPT_ASSERT_USE_FRAMEWORK == 1)
@ -117,7 +117,7 @@ OPENMPT_NAMESPACE_BEGIN
#else // !NO_ASSERTS
#define MPT_ASSERT_NOTREACHED() MPT_DO { MPT_CONSTANT_IF(!(0)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), "0"); } MPT_CHECKER_ASSUME(0); } MPT_WHILE_0
#define MPT_ASSERT_NOTREACHED() MPT_DO { if constexpr(!(0)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), "0"); } MPT_CHECKER_ASSUME(0); } MPT_WHILE_0
#define MPT_ASSERT(expr) MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
#define MPT_ASSERT_MSG(expr, msg) MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr, msg); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
#define MPT_ASSERT_ALWAYS(expr) MPT_DO { if(!(expr)) { AssertHandler(MPT_SOURCE_LOCATION_CURRENT(), #expr); } MPT_CHECKER_ASSUME(expr); } MPT_WHILE_0
@ -136,17 +136,9 @@ MPT_NOINLINE void AssertHandler(const mpt::source_location &loc, const char *exp
#define MPT_CONSTEXPR11_ASSERT MPT_STATIC_ASSERT
#if MPT_CXX_AT_LEAST(14) && !MPT_MSVC_BEFORE(2017,5)
#define MPT_CONSTEXPR14_ASSERT MPT_STATIC_ASSERT
#else
#define MPT_CONSTEXPR14_ASSERT MPT_ASSERT
#endif
#if MPT_CXX_AT_LEAST(17) && !MPT_MSVC_BEFORE(2017,5)
#define MPT_CONSTEXPR17_ASSERT MPT_STATIC_ASSERT
#else
#define MPT_CONSTEXPR17_ASSERT MPT_ASSERT
#endif
#define MPT_CONSTEXPR11_ASSERT static_assert
#define MPT_CONSTEXPR14_ASSERT static_assert
#define MPT_CONSTEXPR17_ASSERT static_assert

View file

@ -14,7 +14,9 @@
#include <array>
#include <iterator>
#include <type_traits>
#include <cstddef>
#include <cstdint>
@ -28,14 +30,44 @@ OPENMPT_NAMESPACE_BEGIN
// Compile time assert.
#if (MPT_CXX >= 17)
#define MPT_STATIC_ASSERT static_assert
#define MPT_PP_DEFER(m, ...) m(__VA_ARGS__)
#define MPT_PP_STRINGIFY(x) #x
#define MPT_PP_JOIN_HELPER(a, b) a ## b
#define MPT_PP_JOIN(a, b) MPT_PP_JOIN_HELPER(a, b)
#define MPT_PP_UNIQUE_IDENTIFIER(prefix) MPT_PP_JOIN(prefix , __LINE__)
#if MPT_COMPILER_MSVC
#define MPT_WARNING(text) __pragma(message(__FILE__ "(" MPT_PP_DEFER(MPT_PP_STRINGIFY, __LINE__) "): Warning: " text))
#define MPT_WARNING_STATEMENT(text) __pragma(message(__FILE__ "(" MPT_PP_DEFER(MPT_PP_STRINGIFY, __LINE__) "): Warning: " text))
#elif MPT_COMPILER_GCC || MPT_COMPILER_CLANG
#define MPT_WARNING(text) _Pragma(MPT_PP_STRINGIFY(GCC warning text))
#define MPT_WARNING_STATEMENT(text) _Pragma(MPT_PP_STRINGIFY(GCC warning text))
#else
#define MPT_STATIC_ASSERT(expr) static_assert((expr), "compile time assertion failed: " #expr)
// portable #pragma message or #warning replacement
#define MPT_WARNING(text) \
static inline int MPT_PP_UNIQUE_IDENTIFIER(MPT_WARNING_NAME) () noexcept { \
int warning [[deprecated("Warning: " text)]] = 0; \
return warning; \
} \
/**/
#define MPT_WARNING_STATEMENT(text) \
int MPT_PP_UNIQUE_IDENTIFIER(MPT_WARNING_NAME) = [](){ \
int warning [[deprecated("Warning: " text)]] = 0; \
return warning; \
}() \
/**/
#endif
// legacy
#define STATIC_ASSERT(x) MPT_STATIC_ASSERT(x)
@ -55,43 +87,76 @@ OPENMPT_NAMESPACE_BEGIN
// constexpr
#define MPT_CONSTEXPR11_FUN constexpr MPT_FORCEINLINE
#define MPT_CONSTEXPR11_VAR constexpr
#if MPT_CXX_AT_LEAST(14) && !MPT_MSVC_BEFORE(2017,5)
#define MPT_CONSTEXPR14_FUN constexpr MPT_FORCEINLINE
#define MPT_CONSTEXPR14_VAR constexpr
#else
#define MPT_CONSTEXPR14_FUN MPT_FORCEINLINE
#define MPT_CONSTEXPR14_VAR const
#endif
#if MPT_CXX_AT_LEAST(17) && !MPT_MSVC_BEFORE(2017,5)
#define MPT_CONSTEXPR17_FUN constexpr MPT_FORCEINLINE
#define MPT_CONSTEXPR17_VAR constexpr
#else
#define MPT_CONSTEXPR17_FUN MPT_FORCEINLINE
#define MPT_CONSTEXPR17_VAR const
#endif
#if MPT_CXX_AT_LEAST(20)
#define MPT_CONSTEXPR20_FUN constexpr MPT_FORCEINLINE
#define MPT_CONSTEXPR20_VAR constexpr
#else // !C++20
#define MPT_CONSTEXPR20_FUN MPT_FORCEINLINE
#define MPT_CONSTEXPR20_VAR const
#endif // C++20
// C++17 std::size
#if MPT_CXX_AT_LEAST(17)
namespace mpt {
using std::size;
} // namespace mpt
#else
namespace mpt {
namespace mpt
{
template <auto V> struct constant_value { static constexpr decltype(V) value() { return V; } };
#define MPT_FORCE_CONSTEXPR(expr) (mpt::constant_value<( expr )>::value())
} // namespace mpt
#if MPT_CXX_AT_LEAST(20)
#define MPT_IS_CONSTANT_EVALUATED20() std::is_constant_evaluated()
#define MPT_IS_CONSTANT_EVALUATED() std::is_constant_evaluated()
#else // !C++20
#define MPT_IS_CONSTANT_EVALUATED20() false
// this pessimizes the case for C++17 by always assuming constexpr context, which implies always running constexpr-friendly code
#define MPT_IS_CONSTANT_EVALUATED() true
#endif // C++20
namespace mpt
{
template <typename T>
MPT_CONSTEXPR11_FUN auto size(const T & v) -> decltype(v.size())
{
return v.size();
}
struct stdarray_extent : std::integral_constant<std::size_t, 0> {};
template <typename T, std::size_t N>
MPT_CONSTEXPR11_FUN std::size_t size(const T(&)[N]) noexcept
struct stdarray_extent<std::array<T, N>> : std::integral_constant<std::size_t, N> {};
template <typename T>
struct is_stdarray : std::false_type {};
template <typename T, std::size_t N>
struct is_stdarray<std::array<T, N>> : std::true_type {};
// mpt::extent is the same as std::extent,
// but also works for std::array,
// and asserts that the given type is actually an array type instead of returning 0.
// use as:
// mpt::extent<decltype(expr)>()
// mpt::extent<decltype(variable)>()
// mpt::extent<decltype(type)>()
// mpt::extent<type>()
template <typename T>
constexpr std::size_t extent() noexcept
{
return N;
using Tarray = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
static_assert(std::is_array<Tarray>::value || mpt::is_stdarray<Tarray>::value);
if constexpr(mpt::is_stdarray<Tarray>::value)
{
return mpt::stdarray_extent<Tarray>();
} else
{
return std::extent<Tarray>();
}
}
} // namespace mpt
#endif
// legacy
#if MPT_COMPILER_MSVC
OPENMPT_NAMESPACE_END
@ -115,41 +180,12 @@ OPENMPT_NAMESPACE_BEGIN
// Some functions might be deprecated although they are still in use.
// Tag them with "MPT_DEPRECATED".
#if MPT_COMPILER_MSVC
#define MPT_DEPRECATED __declspec(deprecated)
#elif MPT_COMPILER_GCC || MPT_COMPILER_CLANG
#define MPT_DEPRECATED __attribute__((deprecated))
#else
#define MPT_DEPRECATED
#endif
#if defined(MODPLUG_TRACKER)
#define MPT_DEPRECATED_TRACKER MPT_DEPRECATED
#define MPT_DEPRECATED_LIBOPENMPT
#elif defined(LIBOPENMPT_BUILD)
#define MPT_DEPRECATED_TRACKER
#define MPT_DEPRECATED_LIBOPENMPT MPT_DEPRECATED
#else
#define MPT_DEPRECATED_TRACKER MPT_DEPRECATED
#define MPT_DEPRECATED_LIBOPENMPT MPT_DEPRECATED
#endif
#define MPT_ATTR_NODISCARD [[nodiscard]]
#define MPT_DISCARD(expr) static_cast<void>(expr)
#if MPT_CXX_AT_LEAST(17)
#define MPT_CONSTANT_IF if constexpr
#endif
#if MPT_COMPILER_MSVC
#if !defined(MPT_CONSTANT_IF)
#define MPT_CONSTANT_IF(x) \
__pragma(warning(push)) \
__pragma(warning(disable:4127)) \
if(x) \
__pragma(warning(pop)) \
/**/
#endif
#define MPT_MAYBE_CONSTANT_IF(x) \
__pragma(warning(push)) \
__pragma(warning(disable:4127)) \
@ -178,11 +214,6 @@ OPENMPT_NAMESPACE_BEGIN
/**/
#endif
#if !defined(MPT_CONSTANT_IF)
// MPT_CONSTANT_IF disables compiler warnings for conditions that are either always true or always false for some reason (dependent on template arguments for example)
#define MPT_CONSTANT_IF(x) if(x)
#endif
#if !defined(MPT_MAYBE_CONSTANT_IF)
// MPT_MAYBE_CONSTANT_IF disables compiler warnings for conditions that may in some case be either always false or always true (this may turn out to be useful in ASSERTions in some cases).
#define MPT_MAYBE_CONSTANT_IF(x) if(x)
@ -217,35 +248,6 @@ OPENMPT_NAMESPACE_BEGIN
// Macro for marking intentional fall-throughs in switch statements - can be used for static analysis if supported.
#if (MPT_CXX >= 17)
#define MPT_FALLTHROUGH [[fallthrough]]
#elif MPT_COMPILER_MSVC
#define MPT_FALLTHROUGH __fallthrough
#elif MPT_COMPILER_CLANG
#define MPT_FALLTHROUGH [[clang::fallthrough]]
#elif MPT_COMPILER_GCC && MPT_GCC_AT_LEAST(7,1,0)
#define MPT_FALLTHROUGH __attribute__((fallthrough))
#elif defined(__has_cpp_attribute)
#if __has_cpp_attribute(fallthrough)
#define MPT_FALLTHROUGH [[fallthrough]]
#else
#define MPT_FALLTHROUGH MPT_DO { } MPT_WHILE_0
#endif
#else
#define MPT_FALLTHROUGH MPT_DO { } MPT_WHILE_0
#endif
#if MPT_COMPILER_GCC || MPT_COMPILER_CLANG
#define MPT_PRINTF_FUNC(formatstringindex,varargsindex) __attribute__((format(printf, formatstringindex, varargsindex)))
#else
#define MPT_PRINTF_FUNC(formatstringindex,varargsindex)
#endif
#if MPT_COMPILER_MSVC
// warning LNK4221: no public symbols found; archive member will be inaccessible
// There is no way to selectively disable linker warnings.

View file

@ -18,13 +18,13 @@
#include <array>
#include <limits>
#if MPT_CXX_AT_LEAST(20)
#include <source_location>
#endif // C++20
#include <cstddef>
#include <cstdint>
#if MPT_GCC_BEFORE(4,9,0)
#include <stddef.h>
#endif
#include <stdint.h>
@ -33,14 +33,34 @@ OPENMPT_NAMESPACE_BEGIN
typedef std::int8_t int8;
typedef std::int16_t int16;
typedef std::int32_t int32;
typedef std::int64_t int64;
typedef std::uint8_t uint8;
typedef std::uint16_t uint16;
typedef std::uint32_t uint32;
typedef std::uint64_t uint64;
namespace mpt
{
template <bool cond, typename Ta, typename Tb>
struct select_type
{
};
template <typename Ta, typename Tb>
struct select_type<true, Ta, Tb>
{
using type = Ta;
};
template <typename Ta, typename Tb>
struct select_type<false, Ta, Tb>
{
using type = Tb;
};
} // namespace mpt
using int8 = std::int8_t;
using int16 = std::int16_t;
using int32 = std::int32_t;
using int64 = std::int64_t;
using uint8 = std::uint8_t;
using uint16 = std::uint16_t;
using uint32 = std::uint32_t;
using uint64 = std::uint64_t;
constexpr int8 int8_min = std::numeric_limits<int8>::min();
constexpr int16 int16_min = std::numeric_limits<int16>::min();
@ -58,45 +78,124 @@ constexpr uint32 uint32_max = std::numeric_limits<uint32>::max();
constexpr uint64 uint64_max = std::numeric_limits<uint64>::max();
typedef float float32;
MPT_STATIC_ASSERT(sizeof(float32) == 4);
typedef double float64;
MPT_STATIC_ASSERT(sizeof(float64) == 8);
// fp half
// n/a
// fp single
using single = float;
constexpr single operator"" _fs(long double lit)
{
return static_cast<single>(lit);
}
MPT_STATIC_ASSERT(sizeof(std::uintptr_t) == sizeof(void*));
// fp double
constexpr double operator"" _fd(long double lit)
{
return static_cast<double>(lit);
}
// fp extended
constexpr long double operator"" _fe(long double lit)
{
return static_cast<long double>(lit);
}
MPT_STATIC_ASSERT(std::numeric_limits<unsigned char>::digits == 8);
// fp quad
// n/a
MPT_STATIC_ASSERT(sizeof(char) == 1);
using float32 = mpt::select_type<sizeof(float) == 4,
float
,
mpt::select_type<sizeof(double) == 4,
double
,
mpt::select_type<sizeof(long double) == 4,
long double
,
float
>::type
>::type
>::type;
constexpr float32 operator"" _f32(long double lit)
{
return static_cast<float32>(lit);
}
#if MPT_CXX_AT_LEAST(17)
namespace mpt {
using byte = std::byte;
} // namespace mpt
#define MPT_BYTE_IS_STD_BYTE 1
using float64 = mpt::select_type<sizeof(float) == 8,
float
,
mpt::select_type<sizeof(double) == 8,
double
,
mpt::select_type<sizeof(long double) == 8,
long double
,
double
>::type
>::type
>::type;
constexpr float64 operator"" _f64(long double lit)
{
return static_cast<float64>(lit);
}
namespace mpt
{
template <typename T>
struct float_traits
{
static constexpr bool is_float = !std::numeric_limits<T>::is_integer;
static constexpr bool is_hard = is_float && !MPT_COMPILER_QUIRK_FLOAT_EMULATED;
static constexpr bool is_soft = is_float && MPT_COMPILER_QUIRK_FLOAT_EMULATED;
static constexpr bool is_float32 = is_float && (sizeof(T) == 4);
static constexpr bool is_float64 = is_float && (sizeof(T) == 8);
static constexpr bool is_native_endian = is_float && !MPT_COMPILER_QUIRK_FLOAT_NOTNATIVEENDIAN;
static constexpr bool is_ieee754_binary = is_float && std::numeric_limits<T>::is_iec559 && !MPT_COMPILER_QUIRK_FLOAT_NOTIEEE754;
static constexpr bool is_ieee754_binary32 = is_float && is_ieee754_binary && is_float32;
static constexpr bool is_ieee754_binary64 = is_float && is_ieee754_binary && is_float64;
static constexpr bool is_ieee754_binary32ne = is_float && is_ieee754_binary && is_float32 && is_native_endian;
static constexpr bool is_ieee754_binary64ne = is_float && is_ieee754_binary && is_float64 && is_native_endian;
};
} // namespace mpt
#if MPT_COMPILER_QUIRK_FLOAT_PREFER32
using nativefloat = float32;
#elif MPT_COMPILER_QUIRK_FLOAT_PREFER64
using nativefloat = float64;
#else
// In C++11 and C++14, a C++17 compatible definition of byte would not be required to be allowed to alias other types,
// thus just use a typedef for unsigned char which is guaranteed to be allowed to alias.
//enum class byte : unsigned char { };
namespace mpt {
typedef unsigned char byte;
} // namespace mpt
#define MPT_BYTE_IS_STD_BYTE 0
// prefer smaller floats, but try to use IEEE754 floats
using nativefloat = mpt::select_type<std::numeric_limits<float>::is_iec559,
float
,
mpt::select_type<std::numeric_limits<double>::is_iec559,
double
,
mpt::select_type<std::numeric_limits<long double>::is_iec559,
long double
,
float
>::type
>::type
>::type;
#endif
MPT_STATIC_ASSERT(sizeof(mpt::byte) == 1);
MPT_STATIC_ASSERT(alignof(mpt::byte) == 1);
constexpr nativefloat operator"" _nf(long double lit)
{
return static_cast<nativefloat>(lit);
}
namespace mpt {
#if MPT_GCC_BEFORE(4,9,0)
typedef ::max_align_t max_align_t;
#else
typedef std::max_align_t max_align_t;
#endif
} // namespace mpt
static_assert(sizeof(std::uintptr_t) == sizeof(void*));
static_assert(std::numeric_limits<unsigned char>::digits == 8);
static_assert(sizeof(char) == 1);
static_assert(sizeof(std::byte) == 1);
static_assert(alignof(std::byte) == 1);
namespace mpt {
@ -104,7 +203,7 @@ constexpr int arch_bits = sizeof(void*) * 8;
constexpr std::size_t pointer_size = sizeof(void*);
} // namespace mpt
MPT_STATIC_ASSERT(mpt::arch_bits == static_cast<int>(mpt::pointer_size) * 8);
static_assert(mpt::arch_bits == static_cast<int>(mpt::pointer_size) * 8);
@ -124,6 +223,14 @@ struct limits
namespace mpt
{
#if MPT_CXX_AT_LEAST(20)
using std::source_location;
#define MPT_SOURCE_LOCATION_CURRENT() std::source_location::current()
#else // !C++20
// compatible with std::experimental::source_location from Library Fundamentals TS v2.
struct source_location
{
@ -172,7 +279,9 @@ public:
}
};
#define MPT_SOURCE_LOCATION_CURRENT() mpt::source_location::current( __FILE__ , __FUNCTION__ , __LINE__ , 0 )
#define MPT_SOURCE_LOCATION_CURRENT() mpt::source_location::current( __FILE__ , __func__ , __LINE__ , 0 )
#endif // C++20
} // namespace mpt

View file

@ -30,6 +30,10 @@
#include <math.h>
#include <stdlib.h>
#if MPT_COMPILER_MSVC
#include <intrin.h>
#endif
OPENMPT_NAMESPACE_BEGIN
@ -49,46 +53,66 @@ OPENMPT_NAMESPACE_BEGIN
namespace mpt
{
template <typename T, std::size_t N, typename Tx>
MPT_CONSTEXPR14_FUN std::array<T, N> init_array(const Tx & x)
{
std::array<T, N> result{};
for(std::size_t i = 0; i < N; ++i)
{
result[i] = x;
}
return result;
}
} // namespace mpt
namespace mpt
{
// Work-around for the requirement of at least 1 non-throwing function argument combination in C++ (17,2a).
template <typename Exception>
MPT_CONSTEXPR14_FUN bool constexpr_throw_helper(Exception && e, bool really = true)
{
//return !really ? really : throw std::forward<Exception>(e);
if(really)
{
throw std::forward<Exception>(e);
}
// cppcheck-suppress identicalConditionAfterEarlyExit
return really;
}
template <typename Exception>
MPT_CONSTEXPR14_FUN bool constexpr_throw(Exception && e)
{
return mpt::constexpr_throw_helper(std::forward<Exception>(e));
}
template <typename T, typename Exception>
constexpr T constexpr_throw_helper(Exception && e, bool really = true)
{
//return !really ? really : throw std::forward<Exception>(e);
if(really)
{
throw std::forward<Exception>(e);
}
return T{};
}
template <typename T, typename Exception>
constexpr T constexpr_throw(Exception && e)
{
return mpt::constexpr_throw_helper<T>(std::forward<Exception>(e));
}
} // namespace mpt
namespace mpt {
// GCC 4.5 and up provides templated overloads of std::abs that convert
// integer type narrower than int to double.
// This is fixed as of GCC 7.1.
// As this is apparently valid by the current standard, Library Working Group
// Issue #2735 has been filed (see
// <https://cplusplus.github.io/LWG/lwg-defects.html#2735>).
// In any case, avoid this insanity and provide our own mpt::abs implementation
// for signed integer and floating point types.
// Note: We stick to a C++98-style implementation only overloading int and
// greater types in order to keep promotion rules consistent for narrower types,
// which a templated version returning the argument type would not do. OpenMPT
// probably assumes this semantic when calling abs(int8) in various places.
inline int abs(int x)
{
return std::abs(x);
}
inline long abs(long x)
{
return std::abs(x);
}
inline long long abs(long long x)
{
return std::abs(x);
}
inline float abs(float x)
{
return std::fabs(x);
}
inline double abs(double x)
{
return std::fabs(x);
}
inline long double abs(long double x)
{
return std::fabs(x);
}
// Modulo with more intuitive behaviour for some contexts:
// Instead of being symmetrical around 0, the pattern for positive numbers is repeated in the negative range.
// For example, wrapping_modulo(-1, m) == (m - 1).
@ -118,46 +142,46 @@ template <typename Tdst, typename Tsrc>
inline Tdst saturate_cast(Tsrc src)
{
// This code tries not only to obviously avoid overflows but also to avoid signed/unsigned comparison warnings and type truncation warnings (which in fact would be safe here) by explicit casting.
STATIC_ASSERT(std::numeric_limits<Tdst>::is_integer);
STATIC_ASSERT(std::numeric_limits<Tsrc>::is_integer);
MPT_CONSTANT_IF(std::numeric_limits<Tdst>::is_signed && std::numeric_limits<Tsrc>::is_signed)
static_assert(std::numeric_limits<Tdst>::is_integer);
static_assert(std::numeric_limits<Tsrc>::is_integer);
if constexpr(std::numeric_limits<Tdst>::is_signed && std::numeric_limits<Tsrc>::is_signed)
{
MPT_CONSTANT_IF(sizeof(Tdst) >= sizeof(Tsrc))
if constexpr(sizeof(Tdst) >= sizeof(Tsrc))
{
return static_cast<Tdst>(src);
} else
{
return static_cast<Tdst>(std::max<Tsrc>(static_cast<Tsrc>(std::numeric_limits<Tdst>::min()), std::min<Tsrc>(src, static_cast<Tsrc>(std::numeric_limits<Tdst>::max()))));
return static_cast<Tdst>(std::max(static_cast<Tsrc>(std::numeric_limits<Tdst>::min()), std::min(src, static_cast<Tsrc>(std::numeric_limits<Tdst>::max()))));
}
} else MPT_CONSTANT_IF(!std::numeric_limits<Tdst>::is_signed && !std::numeric_limits<Tsrc>::is_signed)
} else if constexpr(!std::numeric_limits<Tdst>::is_signed && !std::numeric_limits<Tsrc>::is_signed)
{
MPT_CONSTANT_IF(sizeof(Tdst) >= sizeof(Tsrc))
if constexpr(sizeof(Tdst) >= sizeof(Tsrc))
{
return static_cast<Tdst>(src);
} else
{
return static_cast<Tdst>(std::min<Tsrc>(src, static_cast<Tsrc>(std::numeric_limits<Tdst>::max())));
return static_cast<Tdst>(std::min(src, static_cast<Tsrc>(std::numeric_limits<Tdst>::max())));
}
} else MPT_CONSTANT_IF(std::numeric_limits<Tdst>::is_signed && !std::numeric_limits<Tsrc>::is_signed)
} else if constexpr(std::numeric_limits<Tdst>::is_signed && !std::numeric_limits<Tsrc>::is_signed)
{
MPT_CONSTANT_IF(sizeof(Tdst) > sizeof(Tsrc))
if constexpr(sizeof(Tdst) > sizeof(Tsrc))
{
return static_cast<Tdst>(src);
} else MPT_CONSTANT_IF(sizeof(Tdst) == sizeof(Tsrc))
} else if constexpr(sizeof(Tdst) == sizeof(Tsrc))
{
return static_cast<Tdst>(std::min<Tsrc>(src, static_cast<Tsrc>(std::numeric_limits<Tdst>::max())));
return static_cast<Tdst>(std::min(src, static_cast<Tsrc>(std::numeric_limits<Tdst>::max())));
} else
{
return static_cast<Tdst>(std::min<Tsrc>(src, static_cast<Tsrc>(std::numeric_limits<Tdst>::max())));
return static_cast<Tdst>(std::min(src, static_cast<Tsrc>(std::numeric_limits<Tdst>::max())));
}
} else // Tdst unsigned, Tsrc signed
{
MPT_CONSTANT_IF(sizeof(Tdst) >= sizeof(Tsrc))
if constexpr(sizeof(Tdst) >= sizeof(Tsrc))
{
return static_cast<Tdst>(std::max<Tsrc>(0, src));
return static_cast<Tdst>(std::max(static_cast<Tsrc>(0), src));
} else
{
return static_cast<Tdst>(std::max<Tsrc>(0, std::min<Tsrc>(src, static_cast<Tsrc>(std::numeric_limits<Tdst>::max()))));
return static_cast<Tdst>(std::max(static_cast<Tsrc>(0), std::min(src, static_cast<Tsrc>(std::numeric_limits<Tdst>::max()))));
}
}
}
@ -165,11 +189,11 @@ inline Tdst saturate_cast(Tsrc src)
template <typename Tdst>
inline Tdst saturate_cast(double src)
{
if(src >= std::numeric_limits<Tdst>::max())
if(src >= static_cast<double>(std::numeric_limits<Tdst>::max()))
{
return std::numeric_limits<Tdst>::max();
}
if(src <= std::numeric_limits<Tdst>::min())
if(src <= static_cast<double>(std::numeric_limits<Tdst>::min()))
{
return std::numeric_limits<Tdst>::min();
}
@ -179,11 +203,11 @@ inline Tdst saturate_cast(double src)
template <typename Tdst>
inline Tdst saturate_cast(float src)
{
if(src >= std::numeric_limits<Tdst>::max())
if(src >= static_cast<float>(std::numeric_limits<Tdst>::max()))
{
return std::numeric_limits<Tdst>::max();
}
if(src <= std::numeric_limits<Tdst>::min())
if(src <= static_cast<float>(std::numeric_limits<Tdst>::min()))
{
return std::numeric_limits<Tdst>::min();
}
@ -191,51 +215,51 @@ inline Tdst saturate_cast(float src)
}
template <typename T>
MPT_CONSTEXPR14_FUN std::size_t weight(T val) noexcept
{
MPT_STATIC_ASSERT(std::numeric_limits<T>::is_integer);
typedef typename std::make_unsigned<T>::type Tunsigned;
Tunsigned uval = static_cast<Tunsigned>(val);
std::size_t result = 0;
while(uval > 0)
{
if(uval & 0x1)
{
result++;
}
uval >>= 1;
}
return result;
}
#if MPT_CXX_AT_LEAST(20)
using std::ispow2;
using std::ceil2;
using std::floor2;
using std::log2p1;
using std::popcount;
using std::has_single_bit;
using std::bit_ceil;
using std::bit_floor;
using std::bit_width;
using std::rotl;
using std::rotr;
#else
// C++20 <bit> header.
// Note that we do not use SFINAE here but instead rely on static_assert.
// Also note that for C++11 compilers, these functions are not constexpr.
// They could be implemented recursively to make them C++11 constexpr compatible if needed.
template <typename T>
MPT_CONSTEXPR14_FUN bool ispow2(T x) noexcept
MPT_CONSTEXPR14_FUN int popcount(T val) noexcept
{
MPT_STATIC_ASSERT(std::numeric_limits<T>::is_integer);
MPT_STATIC_ASSERT(std::is_unsigned<T>::value);
return mpt::weight(x) == 1;
static_assert(std::numeric_limits<T>::is_integer);
static_assert(std::is_unsigned<T>::value);
int result = 0;
while(val > 0)
{
if(val & 0x1)
{
result++;
}
val >>= 1;
}
return result;
}
template <typename T>
MPT_CONSTEXPR14_FUN T ceil2(T x) noexcept
MPT_CONSTEXPR14_FUN bool has_single_bit(T x) noexcept
{
MPT_STATIC_ASSERT(std::numeric_limits<T>::is_integer);
MPT_STATIC_ASSERT(std::is_unsigned<T>::value);
static_assert(std::numeric_limits<T>::is_integer);
static_assert(std::is_unsigned<T>::value);
return mpt::popcount(x) == 1;
}
template <typename T>
MPT_CONSTEXPR14_FUN T bit_ceil(T x) noexcept
{
static_assert(std::numeric_limits<T>::is_integer);
static_assert(std::is_unsigned<T>::value);
T result = 1;
while(result < x)
{
@ -250,10 +274,10 @@ MPT_CONSTEXPR14_FUN T ceil2(T x) noexcept
}
template <typename T>
MPT_CONSTEXPR14_FUN T floor2(T x) noexcept
MPT_CONSTEXPR14_FUN T bit_floor(T x) noexcept
{
MPT_STATIC_ASSERT(std::numeric_limits<T>::is_integer);
MPT_STATIC_ASSERT(std::is_unsigned<T>::value);
static_assert(std::numeric_limits<T>::is_integer);
static_assert(std::is_unsigned<T>::value);
if(x == 0)
{
return 0;
@ -272,10 +296,10 @@ MPT_CONSTEXPR14_FUN T floor2(T x) noexcept
}
template <typename T>
MPT_CONSTEXPR14_FUN T log2p1(T x) noexcept
MPT_CONSTEXPR14_FUN T bit_width(T x) noexcept
{
MPT_STATIC_ASSERT(std::numeric_limits<T>::is_integer);
MPT_STATIC_ASSERT(std::is_unsigned<T>::value);
static_assert(std::numeric_limits<T>::is_integer);
static_assert(std::is_unsigned<T>::value);
T result = 0;
while(x > 0)
{
@ -285,58 +309,50 @@ MPT_CONSTEXPR14_FUN T log2p1(T x) noexcept
return result;
}
namespace detail
{
template <typename T>
MPT_CONSTEXPR14_FUN T rotl(T x, int r) noexcept
{
auto N = std::numeric_limits<T>::digits;
return (x >> (N - r)) | (x << r);
}
template <typename T>
MPT_CONSTEXPR14_FUN T rotr(T x, int r) noexcept
{
auto N = std::numeric_limits<T>::digits;
return (x << (N - r)) | (x >> r);
}
} // namespace detail
template <typename T>
MPT_CONSTEXPR14_FUN T rotl(T x, int s) noexcept
{
static_assert(std::numeric_limits<T>::is_integer);
static_assert(std::is_unsigned<T>::value);
auto N = std::numeric_limits<T>::digits;
auto r = s % N;
return (s < 0) ? detail::rotr(x, -s) : ((x >> (N - r)) | (x << r));
}
template <typename T>
MPT_CONSTEXPR14_FUN T rotr(T x, int s) noexcept
{
static_assert(std::numeric_limits<T>::is_integer);
static_assert(std::is_unsigned<T>::value);
auto N = std::numeric_limits<T>::digits;
auto r = s % N;
return (s < 0) ? detail::rotl(x, -s) : ((x << (N - r)) | (x >> r));
}
#endif
} // namespace mpt
#if defined(MODPLUG_TRACKER)
// Tracker code requires MIN/MAX to work in constexpr contexts.
// We could make MIN/MAX constexpr for supporting compilers,
// but that would just needlessly complicate the support matrix
// for now.
#ifndef MPT_MINMAX_MACROS
#define MPT_MINMAX_MACROS
#endif
#endif
#if MPT_COMPILER_MSVC
// MSVC disables a bunch of type conversion warnings once a macro is involved.
// Replacing the macro with a template thus spews a TON OF WARNINGS for now.
#ifndef MPT_MINMAX_MACROS
#define MPT_MINMAX_MACROS
#endif
#endif
#if defined(MPT_MINMAX_MACROS)
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#else
namespace mpt { namespace Legacy {
template <typename Ta, typename Tb>
MPT_FORCEINLINE auto MAX(const Ta &a, const Tb &b) -> decltype((a>b)?a:b)
{
return (a > b) ? a : b;
}
template <typename Ta, typename Tb>
MPT_FORCEINLINE auto MIN(const Ta &a, const Tb &b) -> decltype((a<b)?a:b)
{
return (a < b) ? a : b;
}
} } // namespace mpt::Legacy
using namespace mpt::Legacy;
#endif
namespace Util
{
@ -348,10 +364,10 @@ struct ModIfNotZeroImpl
template <typename Tval>
inline Tval mod(Tval x)
{
STATIC_ASSERT(std::numeric_limits<Tmod>::is_integer);
STATIC_ASSERT(!std::numeric_limits<Tmod>::is_signed);
STATIC_ASSERT(std::numeric_limits<Tval>::is_integer);
STATIC_ASSERT(!std::numeric_limits<Tval>::is_signed);
static_assert(std::numeric_limits<Tmod>::is_integer);
static_assert(!std::numeric_limits<Tmod>::is_signed);
static_assert(std::numeric_limits<Tval>::is_integer);
static_assert(!std::numeric_limits<Tval>::is_signed);
return static_cast<Tval>(x % m);
}
};
@ -389,8 +405,8 @@ inline T ExponentialGrow(const T &x, const Tlimit &limit)
{
return 2;
}
T add = std::min<T>(x >> 1, std::numeric_limits<T>::max() - x);
return std::min<T>(x + add, mpt::saturate_cast<T>(limit));
T add = std::min(x >> 1, std::numeric_limits<T>::max() - x);
return std::min(x + add, mpt::saturate_cast<T>(limit));
}
template <typename T>
@ -402,34 +418,6 @@ inline T ExponentialGrow(const T &x)
} //namespace Util
namespace mpt
{
// C++17 clamp
#if MPT_CXX_AT_LEAST(17)
using std::clamp;
#else
template<typename T, typename Compare>
MPT_CONSTEXPR11_FUN const T & clamp(const T & v, const T & lo, const T & hi, Compare comp)
{
return comp(v, lo) ? lo : comp(hi, v) ? hi : v;
}
template<typename T>
MPT_CONSTEXPR11_FUN const T & clamp(const T & v, const T & lo, const T & hi)
{
return mpt::clamp(v, lo, hi, std::less<T>());
}
#endif
} // namespace mpt
// Limits 'val' to given range. If 'val' is less than 'lowerLimit', 'val' is set to value 'lowerLimit'.
// Similarly if 'val' is greater than 'upperLimit', 'val' is set to value 'upperLimit'.
// If 'lowerLimit' > 'upperLimit', 'val' won't be modified.
@ -489,8 +477,8 @@ namespace mpt
template <typename T>
MPT_FORCEINLINE auto rshift_signed_standard(T x, int y) -> decltype(x >> y)
{
MPT_STATIC_ASSERT(std::numeric_limits<T>::is_integer);
MPT_STATIC_ASSERT(std::numeric_limits<T>::is_signed);
static_assert(std::numeric_limits<T>::is_integer);
static_assert(std::numeric_limits<T>::is_signed);
typedef decltype(x >> y) result_type;
typedef typename std::make_unsigned<result_type>::type unsigned_result_type;
const unsigned_result_type roffset = static_cast<unsigned_result_type>(1) << ((sizeof(result_type) * 8) - 1);
@ -505,8 +493,8 @@ MPT_FORCEINLINE auto rshift_signed_standard(T x, int y) -> decltype(x >> y)
template <typename T>
MPT_FORCEINLINE auto lshift_signed_standard(T x, int y) -> decltype(x << y)
{
MPT_STATIC_ASSERT(std::numeric_limits<T>::is_integer);
MPT_STATIC_ASSERT(std::numeric_limits<T>::is_signed);
static_assert(std::numeric_limits<T>::is_integer);
static_assert(std::numeric_limits<T>::is_signed);
typedef decltype(x << y) result_type;
typedef typename std::make_unsigned<result_type>::type unsigned_result_type;
const unsigned_result_type roffset = static_cast<unsigned_result_type>(1) << ((sizeof(result_type) * 8) - 1);
@ -523,16 +511,16 @@ MPT_FORCEINLINE auto lshift_signed_standard(T x, int y) -> decltype(x << y)
template <typename T>
MPT_FORCEINLINE auto rshift_signed_undefined(T x, int y) -> decltype(x >> y)
{
MPT_STATIC_ASSERT(std::numeric_limits<T>::is_integer);
MPT_STATIC_ASSERT(std::numeric_limits<T>::is_signed);
static_assert(std::numeric_limits<T>::is_integer);
static_assert(std::numeric_limits<T>::is_signed);
return x >> y;
}
template <typename T>
MPT_FORCEINLINE auto lshift_signed_undefined(T x, int y) -> decltype(x << y)
{
MPT_STATIC_ASSERT(std::numeric_limits<T>::is_integer);
MPT_STATIC_ASSERT(std::numeric_limits<T>::is_signed);
static_assert(std::numeric_limits<T>::is_integer);
static_assert(std::numeric_limits<T>::is_signed);
return x << y;
}
@ -564,9 +552,22 @@ MPT_FORCEINLINE auto lshift_signed(T x, int y) -> decltype(x << y)
#endif
} // namespace mpt
template<typename>
struct array_size;
template <typename T, std::size_t N>
struct array_size<std::array<T, N>>
{
static constexpr std::size_t size = N;
};
template <typename T, std::size_t N>
struct array_size<T[N]>
{
static constexpr std::size_t size = N;
};
} // namespace mpt
namespace Util
{
@ -574,8 +575,7 @@ namespace Util
// Returns maximum value of given integer type.
template <class T> constexpr T MaxValueOfType(const T&) {static_assert(std::numeric_limits<T>::is_integer == true, "Only integer types are allowed."); return (std::numeric_limits<T>::max)();}
}
} // namespace Util
namespace mpt
{
@ -677,58 +677,4 @@ namespace Util {
namespace mpt
{
#if MPT_CXX_AT_LEAST(17)
using std::gcd;
using std::lcm;
#else
// Greatest Common Divisor. Always returns non-negative number.
// compatible with C++17 std::gcd
template <typename A, typename B>
inline typename std::common_type<A, B>::type gcd(A a_, B b_)
{
typename std::common_type<A, B>::type a = a_;
typename std::common_type<A, B>::type b = b_;
if(a < 0)
a = -a;
if(b < 0)
b = -b;
for(;;)
{
if(a == 0)
return b;
b %= a;
if(b == 0)
return a;
a %= b;
}
}
// Least Common Multiple. Always returns non-negative number.
// compatible with C++17 std::lcm
template <typename A, typename B>
inline typename std::common_type<A, B>::type lcm(A a_, B b_)
{
typename std::common_type<A, B>::type a = a_;
typename std::common_type<A, B>::type b = b_;
if(a < 0)
a = -a;
if(b < 0)
b = -b;
if((a | b) == 0)
return 0;
return a / mpt::gcd(a, b) * b;
}
#endif
} // namespace mpt
OPENMPT_NAMESPACE_END

View file

@ -1,177 +0,0 @@
/*
* mptBufferIO.h
* -------------
* Purpose: A wrapper around std::stringstream, fixing MSVC tell/seek problems with empty streams.
* Notes : You should only ever use these wrappers instead of plain std::stringstream classes.
* Authors: OpenMPT Devs
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
#pragma once
#include "BuildSettings.h"
#include <ios>
#include <istream>
#include <ostream>
#include <sstream>
#include <streambuf>
OPENMPT_NAMESPACE_BEGIN
// MSVC std::stringbuf (and thereby std::ostringstream, std::istringstream and
// std::stringstream) fail seekpos() and seekoff() when the stringbuf is
// currently empty.
// seekpos() and seekoff() can get called via tell*() or seek*() iostream
// members. seekoff() (and thereby tell*()), but not seekpos(), has been fixed
// from VS2010 onwards to handle this specific case and changed to not fail
// when the stringbuf is empty.
// Work-around strategy:
// As re-implementing or duplicating the whole std::stringbuf semantics would be
// rather convoluted, we make use of the knowledge of specific inner workings of
// the MSVC implementation here and just fix-up where it causes problems. This
// keeps the additional code at a minimum size.
namespace mpt
{
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
class stringbuf
: public std::stringbuf
{
public:
stringbuf(std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
: std::stringbuf(mode)
{
return;
}
stringbuf(const std::string &str, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
: std::stringbuf(str, mode)
{
return;
}
public:
virtual pos_type seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out)
{
pos_type result = std::stringbuf::seekoff(off, way, which);
if(result == pos_type(-1))
{
if((which & std::ios_base::in) || (which & std::ios_base::out))
{
if(off == 0)
{
result = 0;
}
}
}
return result;
}
virtual pos_type seekpos(pos_type ptr, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
{
pos_type result = std::stringbuf::seekpos(ptr, mode);
if(result == pos_type(-1))
{
if((mode & std::ios_base::in) || (mode & std::ios_base::out))
{
if(static_cast<std::streamoff>(ptr) == 0)
{
result = 0;
}
}
}
return result;
}
};
class istringstream
: public std::basic_istream<char>
{
private:
mpt::stringbuf buf;
public:
istringstream(std::ios_base::openmode mode = std::ios_base::in)
: std::basic_istream<char>(&buf)
, buf(mode | std::ios_base::in)
{
}
istringstream(const std::string &str, std::ios_base::openmode mode = std::ios_base::in)
: std::basic_istream<char>(&buf)
, buf(str, mode | std::ios_base::in)
{
}
~istringstream()
{
}
public:
mpt::stringbuf *rdbuf() const { return const_cast<mpt::stringbuf*>(&buf); }
std::string str() const { return buf.str(); }
void str(const std::string &str) { buf.str(str); }
};
class ostringstream
: public std::basic_ostream<char>
{
private:
mpt::stringbuf buf;
public:
ostringstream(std::ios_base::openmode mode = std::ios_base::out)
: std::basic_ostream<char>(&buf)
, buf(mode | std::ios_base::out)
{
}
ostringstream(const std::string &str, std::ios_base::openmode mode = std::ios_base::out)
: std::basic_ostream<char>(&buf)
, buf(str, mode | std::ios_base::out)
{
}
~ostringstream()
{
}
public:
mpt::stringbuf *rdbuf() const { return const_cast<mpt::stringbuf*>(&buf); }
std::string str() const { return buf.str(); }
void str(const std::string &str) { buf.str(str); }
};
class stringstream
: public std::basic_iostream<char>
{
private:
mpt::stringbuf buf;
public:
stringstream(std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
: std::basic_iostream<char>(&buf)
, buf(mode | std::ios_base::in | std::ios_base::out)
{
}
stringstream(const std::string &str, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
: std::basic_iostream<char>(&buf)
, buf(str, mode | std::ios_base::in | std::ios_base::out)
{
}
~stringstream()
{
}
public:
mpt::stringbuf *rdbuf() const { return const_cast<mpt::stringbuf*>(&buf); }
std::string str() const { return buf.str(); }
void str(const std::string &str) { buf.str(str); }
};
#else
typedef std::stringbuf stringbuf;
typedef std::istringstream istringstream;
typedef std::ostringstream ostringstream;
typedef std::stringstream stringstream;
#endif
} // namespace mpt
OPENMPT_NAMESPACE_END

View file

@ -29,7 +29,7 @@ uint8 ProcModel = 0;
uint8 ProcStepping = 0;
#if MPT_COMPILER_MSVC && (defined(ENABLE_X86) || defined(ENABLE_X64))
#if MPT_COMPILER_MSVC && (defined(ENABLE_X86) || defined(ENABLE_X64)) && defined(ENABLE_CPUID)
#include <intrin.h>
@ -97,42 +97,25 @@ static cpuid_result cpuid(uint32 function)
}
#if 0
static cpuid_result cpuidex(uint32 function_a, uint32 function_c)
{
cpuid_result result;
int CPUInfo[4];
__cpuidex(CPUInfo, function_a, function_c);
result.a = CPUInfo[0];
result.b = CPUInfo[1];
result.c = CPUInfo[2];
result.d = CPUInfo[3];
return result;
}
#endif
void InitProcSupport()
{
RealProcSupport = 0;
ProcSupport = 0;
MemsetZero(ProcVendorID);
MemsetZero(ProcBrandID);
mpt::String::WriteAutoBuf(ProcVendorID) = "";
mpt::String::WriteAutoBuf(ProcBrandID) = "";
ProcFamily = 0;
ProcModel = 0;
ProcStepping = 0;
ProcSupport |= PROCSUPPORT_ASM_INTRIN;
ProcSupport |= PROCSUPPORT_CPUID;
{
cpuid_result VendorString = cpuid(0x00000000u);
mpt::String::WriteAutoBuf(ProcVendorID) = VendorString.as_string();
// Cyrix 6x86 and 6x86MX do not specify the value returned in eax.
// They both support 0x00000001u however.
if((VendorString.as_string() == "CyrixInstead") || (VendorString.a >= 0x00000001u))
if(VendorString.a >= 0x00000001u)
{
cpuid_result StandardFeatureFlags = cpuid(0x00000001u);
uint32 Stepping = (StandardFeatureFlags.a >> 0) & 0x0f;
@ -140,40 +123,21 @@ void InitProcSupport()
uint32 BaseFamily = (StandardFeatureFlags.a >> 8) & 0x0f;
uint32 ExtModel = (StandardFeatureFlags.a >> 16) & 0x0f;
uint32 ExtFamily = (StandardFeatureFlags.a >> 20) & 0xff;
if(VendorString.as_string() == "GenuineIntel")
if(BaseFamily == 0xf)
{
if(BaseFamily == 0xf)
{
ProcFamily = static_cast<uint16>(ExtFamily + BaseFamily);
} else
{
ProcFamily = static_cast<uint16>(BaseFamily);
}
if(BaseFamily == 0x6 || BaseFamily == 0xf)
{
ProcModel = static_cast<uint8>((ExtModel << 4) | (BaseModel << 0));
} else
{
ProcModel = static_cast<uint8>(BaseModel);
}
} else if(VendorString.as_string() == "AuthenticAMD")
{
if(BaseFamily == 0xf)
{
ProcFamily = static_cast<uint16>(ExtFamily + BaseFamily);
ProcModel = static_cast<uint8>((ExtModel << 4) | (BaseModel << 0));
} else
{
ProcFamily = static_cast<uint16>(BaseFamily);
ProcModel = static_cast<uint8>(BaseModel);
}
ProcFamily = static_cast<uint16>(ExtFamily + BaseFamily);
} else
{
ProcFamily = static_cast<uint16>(BaseFamily);
}
if((BaseFamily == 0x6) || (BaseFamily == 0xf))
{
ProcModel = static_cast<uint8>((ExtModel << 4) | (BaseModel << 0));
} else
{
ProcModel = static_cast<uint8>(BaseModel);
}
ProcStepping = static_cast<uint8>(Stepping);
if(StandardFeatureFlags.d & (1<<15)) ProcSupport |= PROCSUPPORT_CMOV;
if(StandardFeatureFlags.d & (1<<23)) ProcSupport |= PROCSUPPORT_MMX;
if(StandardFeatureFlags.d & (1<<25)) ProcSupport |= PROCSUPPORT_SSE;
if(StandardFeatureFlags.d & (1<<26)) ProcSupport |= PROCSUPPORT_SSE2;
@ -181,115 +145,56 @@ void InitProcSupport()
if(StandardFeatureFlags.c & (1<< 9)) ProcSupport |= PROCSUPPORT_SSSE3;
if(StandardFeatureFlags.c & (1<<19)) ProcSupport |= PROCSUPPORT_SSE4_1;
if(StandardFeatureFlags.c & (1<<20)) ProcSupport |= PROCSUPPORT_SSE4_2;
if(StandardFeatureFlags.c & (1<<28)) ProcSupport |= PROCSUPPORT_AVX;
}
bool canExtended = false;
// 3DNow! manual recommends to just execute 0x80000000u.
// It is totally unknown how earlier CPUs from other vendors
// would behave.
// Thus we only execute 0x80000000u on other vendors CPUs for the earliest
// that we found it documented for and that actually supports 3DNow!.
// We only need 0x80000000u in order to detect 3DNow!.
// Thus, this is enough for us.
if(VendorString.as_string() == "GenuineIntel")
{ // Intel
// 5.9.x : Quark
// 6.11.x: P3-S (Tualatin)
if((ProcFamily > 6) || ((ProcFamily == 6) && (ProcModel >= 11)) || ((ProcFamily == 5) && (ProcModel >= 9)))
{
canExtended = true;
}
} else if((VendorString.as_string() == "AuthenticAMD") || (VendorString.as_string() == "AMDisbetter!"))
{ // AMD
if((ProcFamily > 5) || ((ProcFamily == 5) && (ProcModel >= 8)))
{ // >= K6-2 (K6 = Family 5, K6-2 = Model 8)
// Not sure if earlier AMD CPUs support 0x80000000u.
// AMD 5k86 and AMD K5 manuals do not mention it.
canExtended = true;
}
} else if(VendorString.as_string() == "CentaurHauls")
{ // Centaur (IDT WinChip or VIA C3)
if(ProcFamily == 5)
{ // IDT
if(ProcModel >= 8)
{ // >= WinChip 2
canExtended = true;
}
} else if(ProcFamily >= 6)
{ // VIA
if((ProcFamily >= 7) || ((ProcFamily == 6) && (ProcModel >= 7)))
{ // >= C3 Samuel 2
canExtended = true;
}
}
} else if(VendorString.as_string() == "CyrixInstead")
{ // Cyrix
// 6x86 : 5.2.x
// 6x86L : 5.2.x
// MediaGX : 4.4.x
// 6x86MX : 6.0.x
// MII : 6.0.x
// MediaGXm: 5.4.x
// well, doh ...
if((ProcFamily == 5) && (ProcModel >= 4))
{ // Cyrix MediaGXm
canExtended = true;
}
} else if(VendorString.as_string() == "Geode by NSC")
{ // National Semiconductor
if((ProcFamily > 5) || ((ProcFamily == 5) && (ProcModel >= 5)))
{ // >= Geode GX2
canExtended = true;
}
} else
{ // unknown, which nowadays most likely means some virtualized CPU
// we assume extended flags present in this case
canExtended = true;
}
if(canExtended)
cpuid_result ExtendedVendorString = cpuid(0x80000000u);
if(ExtendedVendorString.a >= 0x80000001u)
{
cpuid_result ExtendedVendorString = cpuid(0x80000000u);
if(ExtendedVendorString.a >= 0x80000001u)
cpuid_result ExtendedFeatureFlags = cpuid(0x80000001u);
if(ExtendedFeatureFlags.d & (1<<29)) ProcSupport |= PROCSUPPORT_LM;
}
if(ExtendedVendorString.a >= 0x80000004u)
{
mpt::String::WriteAutoBuf(ProcBrandID) = cpuid(0x80000002u).as_string4() + cpuid(0x80000003u).as_string4() + cpuid(0x80000004u).as_string4();
if(ExtendedVendorString.a >= 0x80000007u)
{
cpuid_result ExtendedFeatureFlags = cpuid(0x80000001u);
if(ExtendedFeatureFlags.d & (1<<29)) ProcSupport |= PROCSUPPORT_LM;
if((VendorString.as_string() == "AuthenticAMD") || (VendorString.as_string() == "AMDisbetter!"))
{
if(ExtendedFeatureFlags.d & (1<<15)) ProcSupport |= PROCSUPPORT_CMOV;
if(ExtendedFeatureFlags.d & (1<<23)) ProcSupport |= PROCSUPPORT_MMX;
}
if(ExtendedFeatureFlags.d & (1<<22)) ProcSupport |= PROCSUPPORT_AMD_MMXEXT;
if(ExtendedFeatureFlags.d & (1<<31)) ProcSupport |= PROCSUPPORT_AMD_3DNOW;
if(ExtendedFeatureFlags.d & (1<<30)) ProcSupport |= PROCSUPPORT_AMD_3DNOWEXT;
}
if(ExtendedVendorString.a >= 0x80000004u)
{
mpt::String::WriteAutoBuf(ProcBrandID) = cpuid(0x80000002u).as_string4() + cpuid(0x80000003u).as_string4() + cpuid(0x80000004u).as_string4();
cpuid_result ExtendedFeatures = cpuid(0x80000007u);
if(ExtendedFeatures.b & (1<< 5)) ProcSupport |= PROCSUPPORT_AVX2;
}
}
}
// We do not have to check if SSE got enabled by the OS because we only do
// support Windows >= XP. Windows will always enable SSE since Windows 98 SE.
RealProcSupport = ProcSupport;
}
#elif MPT_COMPILER_MSVC && (defined(ENABLE_X86) || defined(ENABLE_X64))
void InitProcSupport()
{
RealProcSupport = 0;
ProcSupport = 0;
mpt::String::WriteAutoBuf(ProcVendorID) = "";
mpt::String::WriteAutoBuf(ProcBrandID) = "";
ProcFamily = 0;
ProcModel = 0;
ProcStepping = 0;
ProcSupport |= PROCSUPPORT_ASM_INTRIN;
{
if(IsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE) != 0) ProcSupport |= PROCSUPPORT_MMX;
if(IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE) != 0) ProcSupport |= PROCSUPPORT_SSE;
if(IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE) != 0) ProcSupport |= PROCSUPPORT_SSE2;
if(IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE) != 0) ProcSupport |= PROCSUPPORT_SSE3;
}
RealProcSupport = ProcSupport;

View file

@ -16,26 +16,30 @@
OPENMPT_NAMESPACE_BEGIN
#ifdef ENABLE_ASM
#ifdef MODPLUG_TRACKER
#define PROCSUPPORT_LM 0x00001 // Processor supports long mode (amd64)
#define PROCSUPPORT_CMOV 0x00004 // Processor supports conditional move instructions (i686)
#define PROCSUPPORT_ASM_INTRIN 0x00001 // assembly and intrinsics are enabled at runtime
#define PROCSUPPORT_CPUID 0x00002 // Processor supports modern cpuid
#define PROCSUPPORT_LM 0x00004 // Processor supports long mode (amd64)
#define PROCSUPPORT_MMX 0x00010 // Processor supports MMX instructions
#define PROCSUPPORT_AMD_MMXEXT 0x00020 // Processor supports AMD MMX extensions
#define PROCSUPPORT_AMD_3DNOW 0x00040 // Processor supports AMD 3DNow! instructions
#define PROCSUPPORT_AMD_3DNOWEXT 0x00080 // Processor supports AMD 3DNow!2 instructions
#define PROCSUPPORT_SSE 0x00100 // Processor supports SSE instructions
#define PROCSUPPORT_SSE2 0x00200 // Processor supports SSE2 instructions
#define PROCSUPPORT_SSE3 0x00400 // Processor supports SSE3 instructions
#define PROCSUPPORT_SSSE3 0x00800 // Processor supports SSSE3 instructions
#define PROCSUPPORT_SSE4_1 0x01000 // Processor supports SSE4.1 instructions
#define PROCSUPPORT_SSE4_2 0x02000 // Processor supports SSE4.2 instructions
#define PROCSUPPORT_AVX 0x10000 // Processor supports AVX instructions
#define PROCSUPPORT_AVX2 0x20000 // Processor supports AVX2 instructions
static const uint32 PROCSUPPORT_i586 = 0u ;
static const uint32 PROCSUPPORT_i686 = 0u | PROCSUPPORT_CMOV ;
static const uint32 PROCSUPPORT_x86_SSE = 0u | PROCSUPPORT_CMOV | PROCSUPPORT_SSE ;
static const uint32 PROCSUPPORT_x86_SSE2 = 0u | PROCSUPPORT_CMOV | PROCSUPPORT_SSE | PROCSUPPORT_SSE2 ;
static const uint32 PROCSUPPORT_AMD64 = 0u | PROCSUPPORT_CMOV | PROCSUPPORT_SSE | PROCSUPPORT_SSE2 | PROCSUPPORT_LM;
static constexpr uint32 PROCSUPPORT_i586 = 0u ;
static constexpr uint32 PROCSUPPORT_x86_SSE = 0u | PROCSUPPORT_SSE ;
static constexpr uint32 PROCSUPPORT_x86_SSE2 = 0u | PROCSUPPORT_SSE | PROCSUPPORT_SSE2 ;
static constexpr uint32 PROCSUPPORT_AMD64 = 0u | PROCSUPPORT_SSE | PROCSUPPORT_SSE2 | PROCSUPPORT_LM;
#endif
#ifdef ENABLE_ASM
extern uint32 RealProcSupport;
extern uint32 ProcSupport;

View file

@ -113,7 +113,7 @@ public:
inline void processByte(byte_type byte)
{
MPT_CONSTANT_IF(reverseData)
if constexpr(reverseData)
{
value = (value >> 8) ^ read_table(static_cast<byte_type>((value & 0xff) ^ byte));
} else
@ -152,13 +152,11 @@ public:
return *this;
}
#if MPT_BYTE_IS_STD_BYTE
inline crc & process(mpt::byte c)
inline crc & process(std::byte c)
{
processByte(mpt::byte_cast<byte_type>(c));
return *this;
}
#endif
template <typename InputIt>
crc & process(InputIt beg, InputIt end)
@ -196,13 +194,11 @@ public:
return *this;
}
#if MPT_BYTE_IS_STD_BYTE
inline crc & operator () (mpt::byte c)
inline crc & operator () (std::byte c)
{
processByte(mpt::byte_cast<byte_type>(c));
return *this;
}
#endif
template <typename InputIt>
crc & operator () (InputIt beg, InputIt end)

View file

@ -17,14 +17,14 @@
#include "mptBaseMacros.h"
#include <exception>
#if !defined(_MFC_VER)
#if !defined(MPT_WITH_MFC)
#include <new>
#endif // !_MFC_VER
#endif // !MPT_WITH_MFC
#if defined(_MFC_VER)
#if defined(MPT_WITH_MFC)
// cppcheck-suppress missingInclude
#include <afx.h>
#endif // _MFC_VER
#endif // MPT_WITH_MFC
@ -35,21 +35,21 @@ OPENMPT_NAMESPACE_BEGIN
// Exception handling helpers, because MFC requires explicit deletion of the exception object,
// Thus, always call exactly one of MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY() or MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e).
#if defined(_MFC_VER)
#if defined(MPT_WITH_MFC)
#define MPT_EXCEPTION_THROW_OUT_OF_MEMORY() MPT_DO { AfxThrowMemoryException(); } MPT_WHILE_0
#define MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) catch ( CMemoryException * e )
#define MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e) MPT_DO { MPT_UNUSED_VARIABLE(e); throw; } MPT_WHILE_0
#define MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e) MPT_DO { if(e) { e->Delete(); e = nullptr; } } MPT_WHILE_0
#else // !_MFC_VER
#else // !MPT_WITH_MFC
#define MPT_EXCEPTION_THROW_OUT_OF_MEMORY() MPT_DO { throw std::bad_alloc(); } MPT_WHILE_0
#define MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) catch ( const std::bad_alloc & e )
#define MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e) MPT_DO { MPT_UNUSED_VARIABLE(e); throw; } MPT_WHILE_0
#define MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e) MPT_DO { MPT_UNUSED_VARIABLE(e); } MPT_WHILE_0
#endif // _MFC_VER
#endif // MPT_WITH_MFC

View file

@ -53,19 +53,19 @@ template <> inline std::string get_exception_text<std::string>(const std::except
#if defined(MPT_ENABLE_CHARSET_LOCALE)
template <> inline mpt::lstring get_exception_text<mpt::lstring>(const std::exception & e)
{
return mpt::ToLocale(mpt::CharsetLocaleOrUTF8, mpt::get_exception_text_impl<std::string>(e));
return mpt::ToLocale(mpt::CharsetException, mpt::get_exception_text_impl<std::string>(e));
}
#endif
#if MPT_WSTRING_FORMAT
template <> inline std::wstring get_exception_text<std::wstring>(const std::exception & e)
{
return mpt::ToWide(mpt::CharsetLocaleOrUTF8, mpt::get_exception_text_impl<std::string>(e));
return mpt::ToWide(mpt::CharsetException, mpt::get_exception_text_impl<std::string>(e));
}
#endif
#if MPT_USTRING_MODE_UTF8
template <> inline mpt::ustring get_exception_text<mpt::ustring>(const std::exception & e)
{
return mpt::ToUnicode(mpt::CharsetLocaleOrUTF8, mpt::get_exception_text_impl<std::string>(e));
return mpt::ToUnicode(mpt::CharsetException, mpt::get_exception_text_impl<std::string>(e));
}
#endif

View file

@ -99,12 +99,12 @@ mpt::tstring SafeOutputFile::convert_mode(std::ios_base::openmode mode, FlushMod
fopen_mode = _T("r");
break;
case std::ios_base::out:
MPT_FALLTHROUGH;
[[fallthrough]];
case std::ios_base::out | std::ios_base::trunc:
fopen_mode = _T("w");
break;
case std::ios_base::app:
MPT_FALLTHROUGH;
[[fallthrough]];
case std::ios_base::out | std::ios_base::app:
fopen_mode = _T("a");
break;
@ -115,7 +115,7 @@ mpt::tstring SafeOutputFile::convert_mode(std::ios_base::openmode mode, FlushMod
fopen_mode = _T("w+");
break;
case std::ios_base::out | std::ios_base::in | std::ios_base::app:
MPT_FALLTHROUGH;
[[fallthrough]];
case std::ios_base::in | std::ios_base::app:
fopen_mode = _T("a+");
break;
@ -171,12 +171,25 @@ FILE * SafeOutputFile::internal_fopen(const mpt::PathString &filename, std::ios_
// cppcheck-suppress exceptThrowInDestructor
SafeOutputFile::~SafeOutputFile() noexcept(false)
{
const bool mayThrow = (std::uncaught_exceptions() == 0);
if(!stream())
{
#if MPT_COMPILER_MSVC
if(m_f)
{
fclose(m_f);
}
#endif // MPT_COMPILER_MSVC
return;
}
if(!stream().rdbuf())
{
#if MPT_COMPILER_MSVC
if(m_f)
{
fclose(m_f);
}
#endif // MPT_COMPILER_MSVC
return;
}
#if MPT_COMPILER_MSVC
@ -210,8 +223,12 @@ SafeOutputFile::~SafeOutputFile() noexcept(false)
errorOnFlush = true;
}
#endif // MPT_COMPILER_MSVC
// ignore errorOnFlush here, and re-throw the earlier exception
throw;
if(mayThrow)
{
// ignore errorOnFlush here, and re-throw the earlier exception
// cppcheck-suppress exceptThrowInDestructor
throw;
}
}
}
#if MPT_COMPILER_MSVC
@ -227,8 +244,9 @@ SafeOutputFile::~SafeOutputFile() noexcept(false)
errorOnFlush = true;
}
#endif // MPT_COMPILER_MSVC
if(errorOnFlush && (stream().exceptions() & (std::ios::badbit | std::ios::failbit)))
if(mayThrow && errorOnFlush && (stream().exceptions() & (std::ios::badbit | std::ios::failbit)))
{
// cppcheck-suppress exceptThrowInDestructor
throw std::ios_base::failure(std::string("Error flushing file buffers."));
}
}
@ -243,11 +261,11 @@ SafeOutputFile::~SafeOutputFile() noexcept(false)
namespace mpt {
LazyFileRef & LazyFileRef::operator = (const std::vector<mpt::byte> &data)
LazyFileRef & LazyFileRef::operator = (const std::vector<std::byte> &data)
{
mpt::ofstream file(m_Filename, std::ios::binary);
file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
mpt::IO::WriteRaw(file, data.data(), data.size());
mpt::IO::WriteRaw(file, mpt::as_span(data));
mpt::IO::Flush(file);
return *this;
}
@ -256,7 +274,7 @@ LazyFileRef & LazyFileRef::operator = (const std::vector<char> &data)
{
mpt::ofstream file(m_Filename, std::ios::binary);
file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
mpt::IO::WriteRaw(file, data.data(), data.size());
mpt::IO::WriteRaw(file, mpt::as_span(data));
mpt::IO::Flush(file);
return *this;
}
@ -265,23 +283,23 @@ LazyFileRef & LazyFileRef::operator = (const std::string &data)
{
mpt::ofstream file(m_Filename, std::ios::binary);
file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
mpt::IO::WriteRaw(file, data.data(), data.size());
mpt::IO::WriteRaw(file, mpt::as_span(data));
mpt::IO::Flush(file);
return *this;
}
LazyFileRef::operator std::vector<mpt::byte> () const
LazyFileRef::operator std::vector<std::byte> () const
{
mpt::ifstream file(m_Filename, std::ios::binary);
if(!mpt::IO::IsValid(file))
{
return std::vector<mpt::byte>();
return std::vector<std::byte>();
}
file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
mpt::IO::SeekEnd(file);
std::vector<mpt::byte> buf(mpt::saturate_cast<std::size_t>(mpt::IO::TellRead(file)));
std::vector<std::byte> buf(mpt::saturate_cast<std::size_t>(mpt::IO::TellRead(file)));
mpt::IO::SeekBegin(file);
mpt::IO::ReadRaw(file, buf.data(), buf.size());
mpt::IO::ReadRaw(file, mpt::as_span(buf));
return buf;
}
@ -296,7 +314,7 @@ LazyFileRef::operator std::vector<char> () const
mpt::IO::SeekEnd(file);
std::vector<char> buf(mpt::saturate_cast<std::size_t>(mpt::IO::TellRead(file)));
mpt::IO::SeekBegin(file);
mpt::IO::ReadRaw(file, buf.data(), buf.size());
mpt::IO::ReadRaw(file, mpt::as_span(buf));
return buf;
}
@ -311,7 +329,7 @@ LazyFileRef::operator std::string () const
mpt::IO::SeekEnd(file);
std::vector<char> buf(mpt::saturate_cast<std::size_t>(mpt::IO::TellRead(file)));
mpt::IO::SeekBegin(file);
mpt::IO::ReadRaw(file, buf.data(), buf.size());
mpt::IO::ReadRaw(file, mpt::as_span(buf));
return std::string(buf.begin(), buf.end());
}
@ -320,149 +338,22 @@ LazyFileRef::operator std::string () const
#endif // MODPLUG_TRACKER
#ifdef MODPLUG_TRACKER
#if MPT_OS_WINDOWS
CMappedFile::~CMappedFile()
bool InputFile::DefaultToLargeAddressSpaceUsage()
{
Close();
return false;
}
bool CMappedFile::Open(const mpt::PathString &filename)
{
m_hFile = CreateFile(
filename.AsNativePrefixed().c_str(),
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(m_hFile == INVALID_HANDLE_VALUE)
{
m_hFile = nullptr;
return false;
}
m_FileName = filename;
return true;
}
void CMappedFile::Close()
{
m_FileName = mpt::PathString();
// Unlock file
if(m_hFMap)
{
if(m_pData)
{
UnmapViewOfFile(m_pData);
m_pData = nullptr;
}
CloseHandle(m_hFMap);
m_hFMap = nullptr;
} else if(m_pData)
{
free(m_pData);
m_pData = nullptr;
}
// Close file handle
if(m_hFile)
{
CloseHandle(m_hFile);
m_hFile = nullptr;
}
}
size_t CMappedFile::GetLength()
{
LARGE_INTEGER size;
if(GetFileSizeEx(m_hFile, &size) == FALSE)
{
return 0;
}
return mpt::saturate_cast<size_t>(size.QuadPart);
}
const mpt::byte *CMappedFile::Lock()
{
size_t length = GetLength();
if(!length) return nullptr;
void *lpStream;
HANDLE hmf = CreateFileMapping(
m_hFile,
NULL,
PAGE_READONLY,
0, 0,
NULL);
// Try memory-mapping first
if(hmf)
{
lpStream = MapViewOfFile(
hmf,
FILE_MAP_READ,
0, 0,
length);
if(lpStream)
{
m_hFMap = hmf;
m_pData = lpStream;
return mpt::void_cast<const mpt::byte*>(lpStream);
}
CloseHandle(hmf);
hmf = nullptr;
}
// Fallback if memory-mapping fails for some weird reason
if((lpStream = malloc(length)) == nullptr) return nullptr;
memset(lpStream, 0, length);
size_t bytesToRead = length;
size_t bytesRead = 0;
while(bytesToRead > 0)
{
DWORD chunkToRead = mpt::saturate_cast<DWORD>(length);
DWORD chunkRead = 0;
if(ReadFile(m_hFile, mpt::void_cast<mpt::byte*>(lpStream) + bytesRead, chunkToRead, &chunkRead, NULL) == FALSE)
{
// error
free(lpStream);
return nullptr;
}
bytesRead += chunkRead;
bytesToRead -= chunkRead;
}
m_pData = lpStream;
return mpt::void_cast<const mpt::byte*>(lpStream);
}
#endif // MPT_OS_WINDOWS
#endif // MODPLUG_TRACKER
InputFile::InputFile()
: m_IsCached(false)
{
return;
}
InputFile::InputFile(const mpt::PathString &filename)
: m_Filename(filename)
InputFile::InputFile(const mpt::PathString &filename, bool allowWholeFileCaching)
: m_IsCached(false)
{
#if defined(MPT_FILEREADER_STD_ISTREAM)
m_File.open(m_Filename, std::ios::binary | std::ios::in);
#else
m_File.Open(m_Filename);
#endif
Open(filename, allowWholeFileCaching);
}
InputFile::~InputFile()
@ -471,57 +362,82 @@ InputFile::~InputFile()
}
bool InputFile::Open(const mpt::PathString &filename)
bool InputFile::Open(const mpt::PathString &filename, bool allowWholeFileCaching)
{
m_IsCached = false;
m_Cache.resize(0);
m_Cache.shrink_to_fit();
m_Filename = filename;
#if defined(MPT_FILEREADER_STD_ISTREAM)
m_File.open(m_Filename, std::ios::binary | std::ios::in);
if(allowWholeFileCaching)
{
if(mpt::IO::IsReadSeekable(m_File))
{
if(!mpt::IO::SeekEnd(m_File))
{
m_File.close();
return false;
}
mpt::IO::Offset filesize = mpt::IO::TellRead(m_File);
if(!mpt::IO::SeekBegin(m_File))
{
m_File.close();
return false;
}
if(Util::TypeCanHoldValue<std::size_t>(filesize))
{
std::size_t buffersize = mpt::saturate_cast<std::size_t>(filesize);
m_Cache.resize(buffersize);
if(mpt::IO::ReadRaw(m_File, mpt::as_span(m_Cache)) != filesize)
{
m_File.close();
return false;
}
if(!mpt::IO::SeekBegin(m_File))
{
m_File.close();
return false;
}
m_IsCached = true;
return true;
}
}
}
return m_File.good();
#else
return m_File.Open(m_Filename);
#endif
}
bool InputFile::IsValid() const
{
#if defined(MPT_FILEREADER_STD_ISTREAM)
return m_File.good();
#else
return m_File.IsOpen();
#endif
}
#if defined(MPT_FILEREADER_STD_ISTREAM)
InputFile::ContentsRef InputFile::Get()
bool InputFile::IsCached() const
{
InputFile::ContentsRef result;
result.first = &m_File;
result.second = m_File.good() ? &m_Filename : nullptr;
return result;
return m_IsCached;
}
#else
InputFile::ContentsRef InputFile::Get()
const mpt::PathString& InputFile::GetFilenameRef() const
{
InputFile::ContentsRef result;
result.first.data = nullptr;
result.first.size = 0;
result.second = nullptr;
if(!m_File.IsOpen())
{
return result;
}
result.first.data = m_File.Lock();
if(result.first.data)
result.first.size = m_File.GetLength();
result.second = &m_Filename;
return result;
return m_Filename;
}
std::istream* InputFile::GetStream()
{
MPT_ASSERT(!m_IsCached);
return &m_File;
}
mpt::const_byte_span InputFile::GetCache()
{
MPT_ASSERT(m_IsCached);
return mpt::as_span(m_Cache);
}
#endif
#else // !MPT_ENABLE_FILEIO

View file

@ -68,7 +68,7 @@ template<typename Tbase>
inline void fstream_open(Tbase & base, const mpt::PathString & filename, std::ios_base::openmode mode)
{
#if defined(MPT_FSTREAM_DO_CONVERSIONS_ANSI)
base.open(mpt::ToCharset(mpt::CharsetLocale, filename.AsNative()).c_str(), mode);
base.open(mpt::ToCharset(mpt::Charset::Locale, filename.AsNative()).c_str(), mode);
#else
base.open(filename.AsNativePrefixed().c_str(), mode);
#endif
@ -181,7 +181,7 @@ class SafeOutputFile
private:
FlushMode m_FlushMode;
#if MPT_COMPILER_MSVC
FILE *m_f;
FILE *m_f = nullptr;
#endif // MPT_COMPILER_MSVC
mpt::ofstream m_s;
#if MPT_COMPILER_MSVC
@ -198,6 +198,8 @@ public:
, m_s(filename, mode)
#endif // MPT_COMPILER_MSVC
{
if(!stream().is_open())
stream().setstate(mpt::ofstream::failbit);
}
mpt::ofstream& stream()
{
@ -245,10 +247,10 @@ public:
return;
}
public:
LazyFileRef & operator = (const std::vector<mpt::byte> &data);
LazyFileRef & operator = (const std::vector<std::byte> &data);
LazyFileRef & operator = (const std::vector<char> &data);
LazyFileRef & operator = (const std::string &data);
operator std::vector<mpt::byte> () const;
operator std::vector<std::byte> () const;
operator std::vector<char> () const;
operator std::string () const;
};
@ -259,59 +261,25 @@ public:
} // namespace mpt
#ifdef MODPLUG_TRACKER
#if MPT_OS_WINDOWS
class CMappedFile
{
protected:
HANDLE m_hFile;
HANDLE m_hFMap;
void *m_pData;
mpt::PathString m_FileName;
public:
CMappedFile() : m_hFile(nullptr), m_hFMap(nullptr), m_pData(nullptr) { }
~CMappedFile();
public:
bool Open(const mpt::PathString &filename);
bool IsOpen() const { return m_hFile != NULL && m_hFile != INVALID_HANDLE_VALUE; }
const mpt::PathString * GetpFilename() const { return &m_FileName; }
void Close();
size_t GetLength();
const mpt::byte *Lock();
};
#endif // MPT_OS_WINDOWS
#endif // MODPLUG_TRACKER
class InputFile
{
private:
mpt::PathString m_Filename;
#ifdef MPT_FILEREADER_STD_ISTREAM
mpt::ifstream m_File;
#else
CMappedFile m_File;
#endif
mpt::ifstream m_File;
bool m_IsCached;
std::vector<std::byte> m_Cache;
public:
static bool DefaultToLargeAddressSpaceUsage();
public:
InputFile();
InputFile(const mpt::PathString &filename);
InputFile(const mpt::PathString &filename, bool allowWholeFileCaching = DefaultToLargeAddressSpaceUsage());
~InputFile();
bool Open(const mpt::PathString &filename);
bool Open(const mpt::PathString &filename, bool allowWholeFileCaching = DefaultToLargeAddressSpaceUsage());
bool IsValid() const;
#if defined(MPT_FILEREADER_STD_ISTREAM)
typedef std::pair<std::istream*, const mpt::PathString*> ContentsRef;
#else
struct Data
{
const mpt::byte *data;
std::size_t size;
};
typedef std::pair<InputFile::Data, const mpt::PathString*> ContentsRef;
#endif
InputFile::ContentsRef Get();
bool IsCached() const;
const mpt::PathString& GetFilenameRef() const;
std::istream* GetStream();
mpt::const_byte_span GetCache();
};

View file

@ -17,9 +17,6 @@
#include <istream>
#include <ostream>
#include <sstream>
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
#include <typeinfo>
#endif // MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
OPENMPT_NAMESPACE_BEGIN
@ -30,100 +27,84 @@ namespace mpt {
namespace IO {
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
// MSVC std::stringbuf (and thereby std::ostringstream, std::istringstream and
// std::stringstream) fail seekoff() when the stringbuf is currently empty.
// seekoff() can get called via tell*() or seek*() iostream members. tell*() has
// been special cased from VS2010 onwards to handle this specific case and
// changed to not fail when the stringbuf is empty.
// In addition to using out own wrapper around std::stringstream and
// std::stringbuf, we also work-around the plain native type's problem in case
// we get handed such an object from third party code. This mitigation of course
// requires using our consolidated and normalized IO functions.
// We use the following work-around strategy:
// * If the stream is already in failed state, we do not do any work-around
// and bail out early.
// * If the underlying streambuf is not a std::stringbuf, the work-around is
// not necessary and we skip it.
// * If querying the current position does not fail and returns a
// position > 0, the underlying stringbuf is not empty and we also bail out.
// * Otherwise, we actually query the string contained in the stringbuf to be
// empty. This operation is slow as it has to copy the string into a
// temporary.
// Note, however, that this is only ever necessary if the current position
// is 0. If it always has been 0, the stringbuf will be empty anyway and the
// copy does not cost anything measurable. If it got seeked to position 0,
// we have to pay the price. However, this should be relatively uncommmon in
// pratice.
// * The actual work-around consists of performing or emulating the requested
// operation and resetting the failed state afterwards.
static bool StreamIsStringStreamAndValidAndEmpty(std::ostream & f)
{
if(f.fail() || !f.rdbuf())
{ // failed
return false;
}
if(!dynamic_cast<std::stringbuf*>(f.rdbuf()) || (typeid(*(f.rdbuf())) != typeid(std::stringbuf)))
{ // no stringbuf
return false;
}
std::streampos pos = f.tellp();
f.clear(f.rdstate() & ~std::ios::failbit);
if(pos != std::streampos(-1) && pos > 0)
{ // if the position is not 0, the streambuf is not empty
return false;
}
return dynamic_cast<std::stringbuf*>(f.rdbuf())->str().empty(); // slow
}
static bool StreamIsStringStreamAndValidAndEmpty(std::istream & f)
{
if(f.fail() || !f.rdbuf())
{ // failed
return false;
}
if(!dynamic_cast<std::stringbuf*>(f.rdbuf()) || (typeid(*(f.rdbuf())) != typeid(std::stringbuf)))
{ // no stringbuf
return false;
}
std::streampos pos = f.tellg();
f.clear(f.rdstate() & ~std::ios::failbit);
if(pos != std::streampos(-1) && pos > 0)
{ // if the position is not 0, the streambuf is not empty
return false;
}
return dynamic_cast<std::stringbuf*>(f.rdbuf())->str().empty(); // slow
}
static bool StreamIsStringStreamAndValidAndEmpty(std::iostream & f)
{
if(f.fail() || !f.rdbuf())
{ // failed
return false;
}
if(!dynamic_cast<std::stringbuf*>(f.rdbuf()) || (typeid(*(f.rdbuf())) != typeid(std::stringbuf)))
{ // no stringbuf
return false;
}
std::streampos ipos = f.tellg();
f.clear(f.rdstate() & ~std::ios::failbit);
std::streampos opos = f.tellp();
f.clear(f.rdstate() & ~std::ios::failbit);
if((ipos != std::streampos(-1) && ipos > 0) || (opos != std::streampos(-1) && opos > 0))
{ // if the position is not 0, the streambuf is not empty
return false;
}
return dynamic_cast<std::stringbuf*>(f.rdbuf())->str().empty(); // slow
}
#endif // MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
//STATIC_ASSERT(sizeof(std::streamoff) == 8); // Assert 64bit file support.
//static_assert(sizeof(std::streamoff) == 8); // Assert 64bit file support.
bool IsValid(std::ostream & f) { return !f.fail(); }
bool IsValid(std::istream & f) { return !f.fail(); }
bool IsValid(std::iostream & f) { return !f.fail(); }
bool IsReadSeekable(std::istream & f)
{
f.clear();
std::streampos oldpos = f.tellg();
if(f.fail() || oldpos == std::streampos(-1))
{
f.clear();
return false;
}
f.seekg(0, std::ios::beg);
if(f.fail())
{
f.clear();
f.seekg(oldpos);
f.clear();
return false;
}
f.seekg(0, std::ios::end);
if(f.fail())
{
f.clear();
f.seekg(oldpos);
f.clear();
return false;
}
std::streampos length = f.tellg();
if(f.fail() || length == std::streampos(-1))
{
f.clear();
f.seekg(oldpos);
f.clear();
return false;
}
f.seekg(oldpos);
f.clear();
return true;
}
bool IsWriteSeekable(std::ostream & f)
{
f.clear();
std::streampos oldpos = f.tellp();
if(f.fail() || oldpos == std::streampos(-1))
{
f.clear();
return false;
}
f.seekp(0, std::ios::beg);
if(f.fail())
{
f.clear();
f.seekp(oldpos);
f.clear();
return false;
}
f.seekp(0, std::ios::end);
if(f.fail())
{
f.clear();
f.seekp(oldpos);
f.clear();
return false;
}
std::streampos length = f.tellp();
if(f.fail() || length == std::streampos(-1))
{
f.clear();
f.seekp(oldpos);
f.clear();
return false;
}
f.seekp(oldpos);
f.clear();
return true;
}
IO::Offset TellRead(std::istream & f)
{
return f.tellg();
@ -134,150 +115,60 @@ IO::Offset TellWrite(std::ostream & f)
}
bool SeekBegin(std::ostream & f)
{
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
if(StreamIsStringStreamAndValidAndEmpty(f))
{ // VS std::stringbuf fail seek when the internal buffer is empty. Work-around it in case the stream is not already in failed state.
f.seekp(0); f.clear(f.rdstate() & ~std::ios::failbit); return true;
}
#endif
f.seekp(0); return !f.fail();
}
bool SeekBegin(std::istream & f)
{
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
if(StreamIsStringStreamAndValidAndEmpty(f))
{
f.seekg(0); f.clear(f.rdstate() & ~std::ios::failbit); return true;
}
#endif
f.seekg(0); return !f.fail();
}
bool SeekBegin(std::iostream & f)
{
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
if(StreamIsStringStreamAndValidAndEmpty(f))
{
f.seekg(0); f.clear(f.rdstate() & ~std::ios::failbit); f.seekp(0); f.clear(f.rdstate() & ~std::ios::failbit); return true;
}
#endif
f.seekg(0); f.seekp(0); return !f.fail();
}
bool SeekEnd(std::ostream & f)
{
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
if(StreamIsStringStreamAndValidAndEmpty(f))
{
f.seekp(0); f.clear(f.rdstate() & ~std::ios::failbit); return true;
}
#endif
f.seekp(0, std::ios::end); return !f.fail();
}
bool SeekEnd(std::istream & f)
{
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
if(StreamIsStringStreamAndValidAndEmpty(f))
{
f.seekg(0); f.clear(f.rdstate() & ~std::ios::failbit); return true;
}
#endif
f.seekg(0, std::ios::end); return !f.fail();
}
bool SeekEnd(std::iostream & f)
{
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
if(StreamIsStringStreamAndValidAndEmpty(f))
{
f.seekg(0); f.clear(f.rdstate() & ~std::ios::failbit); f.seekp(0); f.clear(f.rdstate() & ~std::ios::failbit); return true;
}
#endif
f.seekg(0, std::ios::end); f.seekp(0, std::ios::end); return !f.fail();
}
bool SeekAbsolute(std::ostream & f, IO::Offset pos)
{
if(!OffsetFits<std::streamoff>(pos)) { return false; }
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
if(StreamIsStringStreamAndValidAndEmpty(f))
{
if(pos == 0)
{
f.seekp(static_cast<std::streamoff>(pos), std::ios::beg); f.clear(f.rdstate() & ~std::ios::failbit); return true;
}
}
#endif
f.seekp(static_cast<std::streamoff>(pos), std::ios::beg); return !f.fail();
}
bool SeekAbsolute(std::istream & f, IO::Offset pos)
{
if(!OffsetFits<std::streamoff>(pos)) { return false; }
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
if(StreamIsStringStreamAndValidAndEmpty(f))
{
if(pos == 0)
{
f.seekg(static_cast<std::streamoff>(pos), std::ios::beg); f.clear(f.rdstate() & ~std::ios::failbit); return true;
}
}
#endif
f.seekg(static_cast<std::streamoff>(pos), std::ios::beg); return !f.fail();
}
bool SeekAbsolute(std::iostream & f, IO::Offset pos)
{
if(!OffsetFits<std::streamoff>(pos)) { return false; }
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
if(StreamIsStringStreamAndValidAndEmpty(f))
{
if(pos == 0)
{
f.seekg(static_cast<std::streamoff>(pos), std::ios::beg); f.clear(f.rdstate() & ~std::ios::failbit); f.seekp(static_cast<std::streamoff>(pos), std::ios::beg); f.clear(f.rdstate() & ~std::ios::failbit); return true;
}
}
#endif
f.seekg(static_cast<std::streamoff>(pos), std::ios::beg); f.seekp(static_cast<std::streamoff>(pos), std::ios::beg); return !f.fail();
}
bool SeekRelative(std::ostream & f, IO::Offset off)
{
if(!OffsetFits<std::streamoff>(off)) { return false; }
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
if(StreamIsStringStreamAndValidAndEmpty(f))
{
if(off == 0)
{
f.seekp(static_cast<std::streamoff>(off), std::ios::cur); f.clear(f.rdstate() & ~std::ios::failbit); return true;
}
}
#endif
f.seekp(static_cast<std::streamoff>(off), std::ios::cur); return !f.fail();
}
bool SeekRelative(std::istream & f, IO::Offset off)
{
if(!OffsetFits<std::streamoff>(off)) { return false; }
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
if(StreamIsStringStreamAndValidAndEmpty(f))
{
if(off == 0)
{
f.seekg(static_cast<std::streamoff>(off), std::ios::cur); f.clear(f.rdstate() & ~std::ios::failbit); return true;
}
}
#endif
f.seekg(static_cast<std::streamoff>(off), std::ios::cur); return !f.fail();
}
bool SeekRelative(std::iostream & f, IO::Offset off)
{
if(!OffsetFits<std::streamoff>(off)) { return false; }
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
if(StreamIsStringStreamAndValidAndEmpty(f))
{
if(off == 0)
{
f.seekg(static_cast<std::streamoff>(off), std::ios::cur); f.clear(f.rdstate() & ~std::ios::failbit); f.seekp(static_cast<std::streamoff>(off), std::ios::cur); f.clear(f.rdstate() & ~std::ios::failbit); return true;
}
}
#endif
f.seekg(static_cast<std::streamoff>(off), std::ios::cur); f.seekp(static_cast<std::streamoff>(off), std::ios::cur); return !f.fail();
}
IO::Offset ReadRawImpl(std::istream & f, mpt::byte * data, std::size_t size) { return f.read(mpt::byte_cast<char *>(data), size) ? f.gcount() : std::streamsize(0); }
bool WriteRawImpl(std::ostream & f, const mpt::byte * data, std::size_t size) { f.write(mpt::byte_cast<const char *>(data), size); return !f.fail(); }
IO::Offset ReadRawImpl(std::istream & f, mpt::byte_span data) { f.read(mpt::byte_cast<char *>(data.data()), data.size()); return f.gcount(); }
bool WriteRawImpl(std::ostream & f, mpt::const_byte_span data) { f.write(mpt::byte_cast<const char *>(data.data()), data.size()); return !f.fail(); }
bool IsEof(std::istream & f) { return f.eof(); }
bool Flush(std::ostream & f) { f.flush(); return !f.fail(); }
@ -289,15 +180,19 @@ bool Flush(std::ostream & f) { f.flush(); return !f.fail(); }
#if defined(MPT_FILEREADER_STD_ISTREAM)
FileDataContainerSeekable::FileDataContainerSeekable(off_t streamLength)
FileDataContainerSeekable::FileDataContainerSeekable(off_t streamLength, bool buffered)
: streamLength(streamLength)
, cached(false)
, m_Buffered(buffered)
, m_Buffer(m_Buffered ? static_cast<off_t>(BUFFER_SIZE) : 0)
{
return;
if(m_Buffered)
{
for(std::size_t chunkIndex = 0; chunkIndex < NUM_CHUNKS; ++chunkIndex)
{
m_ChunkIndexLRU[chunkIndex] = chunkIndex;
}
}
}
void FileDataContainerSeekable::CacheStream() const
@ -306,11 +201,48 @@ void FileDataContainerSeekable::CacheStream() const
{
return;
}
if(m_Buffered)
{
m_Buffered = false;
for (std::size_t chunkIndex = 0; chunkIndex < NUM_CHUNKS; ++chunkIndex)
{
m_ChunkInfo[chunkIndex].ChunkValid = false;
}
m_Buffer.resize(0);
m_Buffer.shrink_to_fit();
}
cache.resize(streamLength);
InternalRead(cache.data(), 0, streamLength);
cached = true;
}
std::size_t FileDataContainerSeekable::InternalFillPageAndReturnIndex(off_t pos) const
{
pos = Util::AlignDown(pos, static_cast<off_t>(CHUNK_SIZE));
for(std::size_t chunkLRUIndex = 0; chunkLRUIndex < NUM_CHUNKS; ++chunkLRUIndex)
{
std::size_t chunkIndex = m_ChunkIndexLRU[chunkLRUIndex];
if(m_ChunkInfo[chunkIndex].ChunkValid && (m_ChunkInfo[chunkIndex].ChunkOffset == pos))
{
std::size_t chunk = std::move(m_ChunkIndexLRU[chunkLRUIndex]);
std::move_backward(m_ChunkIndexLRU.begin(), m_ChunkIndexLRU.begin() + chunkLRUIndex, m_ChunkIndexLRU.begin() + (chunkLRUIndex + 1));
m_ChunkIndexLRU[0] = std::move(chunk);
return chunkIndex;
}
}
{
std::size_t chunk = std::move(m_ChunkIndexLRU[NUM_CHUNKS - 1]);
std::move_backward(m_ChunkIndexLRU.begin(), m_ChunkIndexLRU.begin() + (NUM_CHUNKS - 1), m_ChunkIndexLRU.begin() + NUM_CHUNKS);
m_ChunkIndexLRU[0] = std::move(chunk);
}
std::size_t chunkIndex = m_ChunkIndexLRU[0];
chunk_info& chunk = m_ChunkInfo[chunkIndex];
chunk.ChunkOffset = pos;
chunk.ChunkLength = InternalRead(chunk_data(chunkIndex).data(), pos, CHUNK_SIZE);
chunk.ChunkValid = true;
return chunkIndex;
}
bool FileDataContainerSeekable::IsValid() const
{
return true;
@ -326,7 +258,7 @@ bool FileDataContainerSeekable::HasPinnedView() const
return cached;
}
const mpt::byte *FileDataContainerSeekable::GetRawData() const
const std::byte *FileDataContainerSeekable::GetRawData() const
{
CacheStream();
return cache.data();
@ -337,57 +269,51 @@ IFileDataContainer::off_t FileDataContainerSeekable::GetLength() const
return streamLength;
}
IFileDataContainer::off_t FileDataContainerSeekable::Read(mpt::byte *dst, IFileDataContainer::off_t pos, IFileDataContainer::off_t count) const
IFileDataContainer::off_t FileDataContainerSeekable::Read(std::byte *dst, IFileDataContainer::off_t pos, IFileDataContainer::off_t count) const
{
if(cached)
{
IFileDataContainer::off_t cache_avail = std::min<IFileDataContainer::off_t>(IFileDataContainer::off_t(cache.size()) - pos, count);
IFileDataContainer::off_t cache_avail = std::min(IFileDataContainer::off_t(cache.size()) - pos, count);
std::copy(cache.begin() + pos, cache.begin() + pos + cache_avail, dst);
return cache_avail;
} else
{
return InternalReadBuffered(dst, pos, count);
}
}
IFileDataContainer::off_t FileDataContainerSeekable::InternalReadBuffered(std::byte* dst, off_t pos, off_t count) const
{
if(!m_Buffered)
{
return InternalRead(dst, pos, count);
}
off_t totalRead = 0;
while (count > 0)
{
std::size_t chunkIndex = InternalFillPageAndReturnIndex(pos);
off_t pageSkip = pos - m_ChunkInfo[chunkIndex].ChunkOffset;
off_t chunkWanted = std::min(static_cast<off_t>(CHUNK_SIZE) - pageSkip, count);
off_t chunkGot = (m_ChunkInfo[chunkIndex].ChunkLength > pageSkip) ? (m_ChunkInfo[chunkIndex].ChunkLength - pageSkip) : 0;
off_t chunk = std::min(chunkWanted, chunkGot);
std::copy(chunk_data(chunkIndex).data() + pageSkip, chunk_data(chunkIndex).data() + pageSkip + chunk, dst);
pos += chunk;
dst += chunk;
totalRead += chunk;
count -= chunk;
if (chunkWanted > chunk)
{
return totalRead;
}
}
return totalRead;
}
bool FileDataContainerStdStreamSeekable::IsSeekable(std::istream *stream)
{
stream->clear();
std::streampos oldpos = stream->tellg();
if(stream->fail() || oldpos == std::streampos(-1))
{
stream->clear();
return false;
}
stream->seekg(0, std::ios::beg);
if(stream->fail())
{
stream->clear();
stream->seekg(oldpos);
stream->clear();
return false;
}
stream->seekg(0, std::ios::end);
if(stream->fail())
{
stream->clear();
stream->seekg(oldpos);
stream->clear();
return false;
}
std::streampos length = stream->tellg();
if(stream->fail() || length == std::streampos(-1))
{
stream->clear();
stream->seekg(oldpos);
stream->clear();
return false;
}
stream->seekg(oldpos);
stream->clear();
return true;
return mpt::IO::IsReadSeekable(*stream);
}
IFileDataContainer::off_t FileDataContainerStdStreamSeekable::GetLength(std::istream *stream)
@ -401,13 +327,13 @@ IFileDataContainer::off_t FileDataContainerStdStreamSeekable::GetLength(std::ist
}
FileDataContainerStdStreamSeekable::FileDataContainerStdStreamSeekable(std::istream *s)
: FileDataContainerSeekable(GetLength(s))
: FileDataContainerSeekable(GetLength(s), true)
, stream(s)
{
return;
}
IFileDataContainer::off_t FileDataContainerStdStreamSeekable::InternalRead(mpt::byte *dst, off_t pos, off_t count) const
IFileDataContainer::off_t FileDataContainerStdStreamSeekable::InternalRead(std::byte *dst, off_t pos, off_t count) const
{
stream->clear(); // tellg needs eof and fail bits unset
std::streampos currentpos = stream->tellg();
@ -487,7 +413,7 @@ void FileDataContainerUnseekable::CacheStreamUpTo(off_t pos, off_t length) const
streamFullyCached = true;
}
void FileDataContainerUnseekable::ReadCached(mpt::byte *dst, IFileDataContainer::off_t pos, IFileDataContainer::off_t count) const
void FileDataContainerUnseekable::ReadCached(std::byte *dst, IFileDataContainer::off_t pos, IFileDataContainer::off_t count) const
{
std::copy(cache.begin() + pos, cache.begin() + pos + count, dst);
}
@ -507,7 +433,7 @@ bool FileDataContainerUnseekable::HasPinnedView() const
return true; // we have the cache which is required for seeking anyway
}
const mpt::byte *FileDataContainerUnseekable::GetRawData() const
const std::byte *FileDataContainerUnseekable::GetRawData() const
{
CacheStream();
return cache.data();
@ -519,14 +445,14 @@ IFileDataContainer::off_t FileDataContainerUnseekable::GetLength() const
return cachesize;
}
IFileDataContainer::off_t FileDataContainerUnseekable::Read(mpt::byte *dst, IFileDataContainer::off_t pos, IFileDataContainer::off_t count) const
IFileDataContainer::off_t FileDataContainerUnseekable::Read(std::byte *dst, IFileDataContainer::off_t pos, IFileDataContainer::off_t count) const
{
CacheStreamUpTo(pos, count);
if(pos >= IFileDataContainer::off_t(cachesize))
{
return 0;
}
IFileDataContainer::off_t cache_avail = std::min<IFileDataContainer::off_t>(IFileDataContainer::off_t(cachesize) - pos, count);
IFileDataContainer::off_t cache_avail = std::min(IFileDataContainer::off_t(cachesize) - pos, count);
ReadCached(dst, pos, cache_avail);
return cache_avail;
}
@ -552,7 +478,7 @@ IFileDataContainer::off_t FileDataContainerUnseekable::GetReadableLength(IFileDa
{
return 0;
}
return std::min<IFileDataContainer::off_t>(cachesize - pos, length);
return std::min(static_cast<IFileDataContainer::off_t>(cachesize) - pos, length);
}
@ -574,7 +500,7 @@ bool FileDataContainerStdStream::InternalEof() const
}
}
IFileDataContainer::off_t FileDataContainerStdStream::InternalRead(mpt::byte *dst, off_t count) const
IFileDataContainer::off_t FileDataContainerStdStream::InternalRead(std::byte *dst, off_t count) const
{
stream->read(mpt::byte_cast<char*>(dst), count);
return static_cast<std::size_t>(stream->gcount());
@ -664,13 +590,13 @@ IFileDataContainer::off_t FileDataContainerCallbackStreamSeekable::GetLength(Cal
}
FileDataContainerCallbackStreamSeekable::FileDataContainerCallbackStreamSeekable(CallbackStream s)
: FileDataContainerSeekable(GetLength(s))
: FileDataContainerSeekable(GetLength(s), false)
, stream(s)
{
return;
}
IFileDataContainer::off_t FileDataContainerCallbackStreamSeekable::InternalRead(mpt::byte *dst, off_t pos, off_t count) const
IFileDataContainer::off_t FileDataContainerCallbackStreamSeekable::InternalRead(std::byte *dst, off_t pos, off_t count) const
{
if(!stream.read)
{
@ -710,7 +636,7 @@ bool FileDataContainerCallbackStream::InternalEof() const
return eof_reached;
}
IFileDataContainer::off_t FileDataContainerCallbackStream::InternalRead(mpt::byte *dst, off_t count) const
IFileDataContainer::off_t FileDataContainerCallbackStream::InternalRead(std::byte *dst, off_t count) const
{
if(eof_reached)
{
@ -741,8 +667,5 @@ IFileDataContainer::off_t FileDataContainerCallbackStream::InternalRead(mpt::byt
#endif // MPT_FILEREADER_CALLBACK_STREAM
#endif
OPENMPT_NAMESPACE_END

View file

@ -50,6 +50,8 @@ inline bool OffsetFits(IO::Offset off)
bool IsValid(std::ostream & f);
bool IsValid(std::istream & f);
bool IsValid(std::iostream & f);
bool IsReadSeekable(std::istream& f);
bool IsWriteSeekable(std::ostream& f);
IO::Offset TellRead(std::istream & f);
IO::Offset TellWrite(std::ostream & f);
bool SeekBegin(std::ostream & f);
@ -64,8 +66,8 @@ bool SeekAbsolute(std::iostream & f, IO::Offset pos);
bool SeekRelative(std::ostream & f, IO::Offset off);
bool SeekRelative(std::istream & f, IO::Offset off);
bool SeekRelative(std::iostream & f, IO::Offset off);
IO::Offset ReadRawImpl(std::istream & f, mpt::byte * data, std::size_t size);
bool WriteRawImpl(std::ostream & f, const mpt::byte * data, std::size_t size);
IO::Offset ReadRawImpl(std::istream & f, mpt::byte_span data);
bool WriteRawImpl(std::ostream & f, mpt::const_byte_span data);
bool IsEof(std::istream & f);
bool Flush(std::ostream & f);
@ -74,14 +76,16 @@ bool Flush(std::ostream & f);
template <typename Tfile> class WriteBuffer;
template <typename Tfile> bool IsValid(WriteBuffer<Tfile> & f) { return IsValid(f.file()); }
template <typename Tfile> bool IsReadSeekable(WriteBuffer<Tfile> & f) { return IsReadSeekable(f.file()); }
template <typename Tfile> bool IsWriteSeekable(WriteBuffer<Tfile> & f) { return IsWriteSeekable(f.file()); }
template <typename Tfile> IO::Offset TellRead(WriteBuffer<Tfile> & f) { f.FlushLocal(); return TellRead(f.file()); }
template <typename Tfile> IO::Offset TellWrite(WriteBuffer<Tfile> & f) { return TellWrite(f.file()) + f.GetCurrentSize(); }
template <typename Tfile> bool SeekBegin(WriteBuffer<Tfile> & f) { f.FlushLocal(); return SeekBegin(f.file()); }
template <typename Tfile> bool SeekEnd(WriteBuffer<Tfile> & f) { f.FlushLocal(); return SeekEnd(f.file()); }
template <typename Tfile> bool SeekAbsolute(WriteBuffer<Tfile> & f, IO::Offset pos) { return f.FlushLocal(); SeekAbsolute(f.file(), pos); }
template <typename Tfile> bool SeekRelative(WriteBuffer<Tfile> & f, IO::Offset off) { return f.FlushLocal(); SeekRelative(f.file(), off); }
template <typename Tfile> IO::Offset ReadRawImpl(WriteBuffer<Tfile> & f, mpt::byte * data, std::size_t size) { f.FlushLocal(); return ReadRawImpl(f.file(), data, size); }
template <typename Tfile> bool WriteRawImpl(WriteBuffer<Tfile> & f, const mpt::byte * data, std::size_t size) { return f.Write(mpt::as_span(data, size)); }
template <typename Tfile> bool SeekAbsolute(WriteBuffer<Tfile> & f, IO::Offset pos) { f.FlushLocal(); return SeekAbsolute(f.file(), pos); }
template <typename Tfile> bool SeekRelative(WriteBuffer<Tfile> & f, IO::Offset off) { f.FlushLocal(); return SeekRelative(f.file(), off); }
template <typename Tfile> IO::Offset ReadRawImpl(WriteBuffer<Tfile> & f, mpt::byte_span data) { f.FlushLocal(); return ReadRawImpl(f.file(), data); }
template <typename Tfile> bool WriteRawImpl(WriteBuffer<Tfile> & f, mpt::const_byte_span data) { return f.Write(data); }
template <typename Tfile> bool IsEof(WriteBuffer<Tfile> & f) { f.FlushLocal(); return IsEof(f.file()); }
template <typename Tfile> bool Flush(WriteBuffer<Tfile> & f) { f.FlushLocal(); return Flush(f.file()); }
@ -125,7 +129,7 @@ template <typename Tbyte> bool SeekRelative(std::pair<mpt::span<Tbyte>, IO::Offs
f.second += off;
return true;
}
template <typename Tbyte> IO::Offset ReadRawImpl(std::pair<mpt::span<Tbyte>, IO::Offset> & f, mpt::byte * data, std::size_t size)
template <typename Tbyte> IO::Offset ReadRawImpl(std::pair<mpt::span<Tbyte>, IO::Offset> & f, mpt::byte_span data)
{
if(f.second < 0)
{
@ -135,27 +139,27 @@ template <typename Tbyte> IO::Offset ReadRawImpl(std::pair<mpt::span<Tbyte>, IO:
{
return 0;
}
std::size_t num = mpt::saturate_cast<std::size_t>(std::min<IO::Offset>(f.first.size() - f.second, size));
std::copy(mpt::byte_cast<const mpt::byte*>(f.first.data() + f.second), mpt::byte_cast<const mpt::byte*>(f.first.data() + f.second + num), data);
std::size_t num = mpt::saturate_cast<std::size_t>(std::min(static_cast<IO::Offset>(f.first.size()) - f.second, static_cast<IO::Offset>(data.size())));
std::copy(mpt::byte_cast<const std::byte*>(f.first.data() + f.second), mpt::byte_cast<const std::byte*>(f.first.data() + f.second + num), data.data());
f.second += num;
return num;
}
template <typename Tbyte> bool WriteRawImpl(std::pair<mpt::span<Tbyte>, IO::Offset> & f, const mpt::byte * data, std::size_t size)
template <typename Tbyte> bool WriteRawImpl(std::pair<mpt::span<Tbyte>, IO::Offset> & f, mpt::const_byte_span data)
{
if(f.second < 0)
{
return false;
}
if(f.second >= static_cast<IO::Offset>(f.first.size()))
if(f.second > static_cast<IO::Offset>(f.first.size()))
{
return false;
}
std::size_t num = mpt::saturate_cast<std::size_t>(std::min<IO::Offset>(f.first.size() - f.second, size));
if(num != size)
std::size_t num = mpt::saturate_cast<std::size_t>(std::min(static_cast<IO::Offset>(f.first.size()) - f.second, static_cast<IO::Offset>(data.size())));
if(num != data.size())
{
return false;
}
std::copy(data, data + num, mpt::byte_cast<mpt::byte*>(f.first.data() + f.second));
std::copy(data.data(), data.data() + num, mpt::byte_cast<std::byte*>(f.first.data() + f.second));
f.second += num;
return true;
}
@ -165,7 +169,7 @@ template <typename Tbyte> bool IsEof(std::pair<mpt::span<Tbyte>, IO::Offset> & f
}
template <typename Tbyte> bool Flush(std::pair<mpt::span<Tbyte>, IO::Offset> & f)
{
MPT_UNREFERENCED_PARAMTER(f);
MPT_UNREFERENCED_PARAMETER(f);
return true;
}
@ -174,25 +178,25 @@ template <typename Tbyte> bool Flush(std::pair<mpt::span<Tbyte>, IO::Offset> & f
template <typename Tbyte, typename Tfile>
inline IO::Offset ReadRaw(Tfile & f, Tbyte * data, std::size_t size)
{
return IO::ReadRawImpl(f, mpt::byte_cast<mpt::byte*>(data), size);
return IO::ReadRawImpl(f, mpt::as_span(mpt::byte_cast<std::byte*>(data), size));
}
template <typename Tbyte, typename Tfile>
inline IO::Offset ReadRaw(Tfile & f, mpt::span<Tbyte> data)
{
return IO::ReadRawImpl(f, mpt::byte_cast<mpt::byte*>(data.data()), data.size());
return IO::ReadRawImpl(f, mpt::byte_cast<mpt::byte_span>(data));
}
template <typename Tbyte, typename Tfile>
inline bool WriteRaw(Tfile & f, const Tbyte * data, std::size_t size)
{
return IO::WriteRawImpl(f, mpt::byte_cast<const mpt::byte*>(data), size);
return IO::WriteRawImpl(f, mpt::as_span(mpt::byte_cast<const std::byte*>(data), size));
}
template <typename Tbyte, typename Tfile>
inline bool WriteRaw(Tfile & f, mpt::span<Tbyte> data)
{
return IO::WriteRawImpl(f, mpt::byte_cast<const mpt::byte*>(data.data()), data.size());
return IO::WriteRawImpl(f, mpt::byte_cast<mpt::const_byte_span>(data));
}
template <typename Tbinary, typename Tfile>
@ -210,7 +214,7 @@ inline bool Write(Tfile & f, const Tbinary & v)
template <typename Tbinary, typename Tfile>
inline bool Write(Tfile & f, const std::vector<Tbinary> & v)
{
STATIC_ASSERT(mpt::is_binary_safe<Tbinary>::value);
static_assert(mpt::is_binary_safe<Tbinary>::value);
return IO::WriteRaw(f, mpt::as_raw_memory(v));
}
@ -222,17 +226,17 @@ inline bool WritePartial(Tfile & f, const T & v, size_t size = sizeof(T))
}
template <typename Tfile>
inline bool ReadByte(Tfile & f, mpt::byte & v)
inline bool ReadByte(Tfile & f, std::byte & v)
{
bool result = false;
mpt::byte byte = mpt::as_byte(0);
const IO::Offset readResult = IO::ReadRaw(f, &byte, sizeof(mpt::byte));
std::byte byte = mpt::as_byte(0);
const IO::Offset readResult = IO::ReadRaw(f, &byte, sizeof(std::byte));
if(readResult < 0)
{
result = false;
} else
{
result = (static_cast<uint64>(readResult) == sizeof(mpt::byte));
result = (static_cast<uint64>(readResult) == sizeof(std::byte));
}
v = byte;
return result;
@ -242,7 +246,7 @@ template <typename T, typename Tfile>
inline bool ReadBinaryTruncatedLE(Tfile & f, T & v, std::size_t size)
{
bool result = false;
MPT_STATIC_ASSERT(std::numeric_limits<T>::is_integer);
static_assert(std::numeric_limits<T>::is_integer);
uint8 bytes[sizeof(T)];
std::memset(bytes, 0, sizeof(T));
const IO::Offset readResult = IO::ReadRaw(f, bytes, std::min(size, sizeof(T)));
@ -263,7 +267,7 @@ template <typename T, typename Tfile>
inline bool ReadIntLE(Tfile & f, T & v)
{
bool result = false;
STATIC_ASSERT(std::numeric_limits<T>::is_integer);
static_assert(std::numeric_limits<T>::is_integer);
uint8 bytes[sizeof(T)];
std::memset(bytes, 0, sizeof(T));
const IO::Offset readResult = IO::ReadRaw(f, bytes, sizeof(T));
@ -284,7 +288,7 @@ template <typename T, typename Tfile>
inline bool ReadIntBE(Tfile & f, T & v)
{
bool result = false;
STATIC_ASSERT(std::numeric_limits<T>::is_integer);
static_assert(std::numeric_limits<T>::is_integer);
uint8 bytes[sizeof(T)];
std::memset(bytes, 0, sizeof(T));
const IO::Offset readResult = IO::ReadRaw(f, bytes, sizeof(T));
@ -364,7 +368,7 @@ inline bool ReadAdaptiveInt64LE(Tfile & f, uint64 & v)
template <typename Tsize, typename Tfile>
inline bool ReadSizedStringLE(Tfile & f, std::string & str, Tsize maxSize = std::numeric_limits<Tsize>::max())
{
STATIC_ASSERT(std::numeric_limits<Tsize>::is_integer);
static_assert(std::numeric_limits<Tsize>::is_integer);
str.clear();
Tsize size = 0;
if(!mpt::IO::ReadIntLE(f, size))
@ -391,14 +395,14 @@ inline bool ReadSizedStringLE(Tfile & f, std::string & str, Tsize maxSize = std:
template <typename T, typename Tfile>
inline bool WriteIntLE(Tfile & f, const T v)
{
STATIC_ASSERT(std::numeric_limits<T>::is_integer);
static_assert(std::numeric_limits<T>::is_integer);
return IO::Write(f, mpt::as_le(v));
}
template <typename T, typename Tfile>
inline bool WriteIntBE(Tfile & f, const T v)
{
STATIC_ASSERT(std::numeric_limits<T>::is_integer);
static_assert(std::numeric_limits<T>::is_integer);
return IO::Write(f, mpt::as_be(v));
}
@ -448,10 +452,10 @@ inline bool WriteAdaptiveInt32LE(Tfile & f, const uint32 v, std::size_t fixedSiz
} else if(v < 0x400000 && minSize <= 3 && 3 <= maxSize)
{
uint32 value = static_cast<uint32>(v << 2) | 0x02;
mpt::byte bytes[3];
bytes[0] = static_cast<mpt::byte>(value >> 0);
bytes[1] = static_cast<mpt::byte>(value >> 8);
bytes[2] = static_cast<mpt::byte>(value >> 16);
std::byte bytes[3];
bytes[0] = static_cast<std::byte>(value >> 0);
bytes[1] = static_cast<std::byte>(value >> 8);
bytes[2] = static_cast<std::byte>(value >> 16);
return IO::WriteRaw(f, bytes, 3);
} else if(v < 0x40000000 && minSize <= 4 && 4 <= maxSize)
{
@ -498,19 +502,19 @@ inline bool WriteAdaptiveInt64LE(Tfile & f, const uint64 v, std::size_t fixedSiz
template <typename Tfile, typename T>
bool WriteVarInt(Tfile & f, const T v, size_t *bytesWritten = nullptr)
{
STATIC_ASSERT(std::numeric_limits<T>::is_integer);
STATIC_ASSERT(!std::numeric_limits<T>::is_signed);
mpt::byte out[(sizeof(T) * 8 + 6) / 7];
static_assert(std::numeric_limits<T>::is_integer);
static_assert(!std::numeric_limits<T>::is_signed);
std::byte out[(sizeof(T) * 8 + 6) / 7];
size_t numBytes = 0;
for(uint32 n = (sizeof(T) * 8) / 7; n > 0; n--)
{
if(v >= (static_cast<T>(1) << (n * 7u)))
{
out[numBytes++] = static_cast<mpt::byte>(((v >> (n * 7u)) & 0x7F) | 0x80);
out[numBytes++] = static_cast<std::byte>(((v >> (n * 7u)) & 0x7F) | 0x80);
}
}
out[numBytes++] = static_cast<mpt::byte>(v & 0x7F);
MPT_ASSERT(numBytes <= mpt::size(out));
out[numBytes++] = static_cast<std::byte>(v & 0x7F);
MPT_ASSERT(numBytes <= std::size(out));
if(bytesWritten != nullptr) *bytesWritten = numBytes;
return mpt::IO::WriteRaw(f, out, numBytes);
}
@ -518,7 +522,7 @@ bool WriteVarInt(Tfile & f, const T v, size_t *bytesWritten = nullptr)
template <typename Tsize, typename Tfile>
inline bool WriteSizedStringLE(Tfile & f, const std::string & str)
{
STATIC_ASSERT(std::numeric_limits<Tsize>::is_integer);
static_assert(std::numeric_limits<Tsize>::is_integer);
if(str.size() > std::numeric_limits<Tsize>::max())
{
return false;
@ -675,8 +679,6 @@ public:
#if defined(MPT_FILEREADER_STD_ISTREAM)
class IFileDataContainer {
public:
typedef std::size_t off_t;
@ -690,9 +692,9 @@ public:
virtual bool IsValid() const = 0;
virtual bool HasFastGetLength() const = 0;
virtual bool HasPinnedView() const = 0;
virtual const mpt::byte *GetRawData() const = 0;
virtual const std::byte *GetRawData() const = 0;
virtual off_t GetLength() const = 0;
virtual off_t Read(mpt::byte *dst, off_t pos, off_t count) const = 0;
virtual off_t Read(std::byte *dst, off_t pos, off_t count) const = 0;
virtual off_t Read(off_t pos, mpt::byte_span dst) const
{
@ -720,7 +722,7 @@ public:
{
return 0;
}
return std::min<off_t>(length, dataLength - pos);
return std::min(length, dataLength - pos);
}
};
@ -744,7 +746,7 @@ public:
return true;
}
const mpt::byte *GetRawData() const override
const std::byte *GetRawData() const override
{
return nullptr;
}
@ -753,7 +755,7 @@ public:
{
return 0;
}
off_t Read(mpt::byte * /*dst*/, off_t /*pos*/, off_t /*count*/) const override
off_t Read(std::byte * /*dst*/, off_t /*pos*/, off_t /*count*/) const override
{
return 0;
}
@ -781,7 +783,7 @@ public:
{
return data->HasPinnedView();
}
const mpt::byte *GetRawData() const override
const std::byte *GetRawData() const override
{
return data->GetRawData() + dataOffset;
}
@ -789,7 +791,7 @@ public:
{
return dataLength;
}
off_t Read(mpt::byte *dst, off_t pos, off_t count) const override
off_t Read(std::byte *dst, off_t pos, off_t count) const override
{
if(pos >= dataLength)
{
@ -827,11 +829,36 @@ private:
off_t streamLength;
mutable bool cached;
mutable std::vector<mpt::byte> cache;
mutable std::vector<std::byte> cache;
private:
mutable bool m_Buffered;
enum : std::size_t {
CHUNK_SIZE = mpt::IO::BUFFERSIZE_SMALL,
BUFFER_SIZE = mpt::IO::BUFFERSIZE_NORMAL
};
enum : std::size_t {
NUM_CHUNKS = BUFFER_SIZE / CHUNK_SIZE
};
struct chunk_info {
off_t ChunkOffset = 0;
off_t ChunkLength = 0;
bool ChunkValid = false;
};
mutable std::vector<std::byte> m_Buffer;
mpt::byte_span chunk_data(std::size_t chunkIndex) const
{
return mpt::byte_span(m_Buffer.data() + (chunkIndex * CHUNK_SIZE), CHUNK_SIZE);
}
mutable std::array<chunk_info, NUM_CHUNKS> m_ChunkInfo;
mutable std::array<std::size_t, NUM_CHUNKS> m_ChunkIndexLRU;
std::size_t InternalFillPageAndReturnIndex(off_t pos) const;
protected:
FileDataContainerSeekable(off_t length);
FileDataContainerSeekable(off_t length, bool buffered);
private:
@ -842,13 +869,15 @@ public:
bool IsValid() const override;
bool HasFastGetLength() const override;
bool HasPinnedView() const override;
const mpt::byte *GetRawData() const override;
const std::byte *GetRawData() const override;
off_t GetLength() const override;
off_t Read(mpt::byte *dst, off_t pos, off_t count) const override;
off_t Read(std::byte *dst, off_t pos, off_t count) const override;
private:
virtual off_t InternalRead(mpt::byte *dst, off_t pos, off_t count) const = 0;
off_t InternalReadBuffered(std::byte* dst, off_t pos, off_t count) const;
virtual off_t InternalRead(std::byte *dst, off_t pos, off_t count) const = 0;
};
@ -868,7 +897,7 @@ public:
private:
off_t InternalRead(mpt::byte *dst, off_t pos, off_t count) const override;
off_t InternalRead(std::byte *dst, off_t pos, off_t count) const override;
};
@ -877,7 +906,7 @@ class FileDataContainerUnseekable : public IFileDataContainer {
private:
mutable std::vector<mpt::byte> cache;
mutable std::vector<std::byte> cache;
mutable std::size_t cachesize;
mutable bool streamFullyCached;
@ -898,23 +927,23 @@ private:
private:
void ReadCached(mpt::byte *dst, off_t pos, off_t count) const;
void ReadCached(std::byte *dst, off_t pos, off_t count) const;
public:
bool IsValid() const override;
bool HasFastGetLength() const override;
bool HasPinnedView() const override;
const mpt::byte *GetRawData() const override;
const std::byte *GetRawData() const override;
off_t GetLength() const override;
off_t Read(mpt::byte *dst, off_t pos, off_t count) const override;
off_t Read(std::byte *dst, off_t pos, off_t count) const override;
bool CanRead(off_t pos, off_t length) const override;
off_t GetReadableLength(off_t pos, off_t length) const override;
private:
virtual bool InternalEof() const = 0;
virtual off_t InternalRead(mpt::byte *dst, off_t count) const = 0;
virtual off_t InternalRead(std::byte *dst, off_t count) const = 0;
};
@ -932,7 +961,7 @@ public:
private:
bool InternalEof() const override;
off_t InternalRead(mpt::byte *dst, off_t count) const override;
off_t InternalRead(std::byte *dst, off_t count) const override;
};
@ -963,7 +992,7 @@ public:
static off_t GetLength(CallbackStream stream);
FileDataContainerCallbackStreamSeekable(CallbackStream s);
private:
off_t InternalRead(mpt::byte *dst, off_t pos, off_t count) const override;
off_t InternalRead(std::byte *dst, off_t pos, off_t count) const override;
};
@ -976,36 +1005,20 @@ public:
FileDataContainerCallbackStream(CallbackStream s);
private:
bool InternalEof() const override;
off_t InternalRead(mpt::byte *dst, off_t count) const override;
off_t InternalRead(std::byte *dst, off_t count) const override;
};
#endif // MPT_FILEREADER_CALLBACK_STREAM
#endif
class FileDataContainerMemory
#if defined(MPT_FILEREADER_STD_ISTREAM)
: public IFileDataContainer
#endif
{
#if defined(MPT_FILEREADER_STD_ISTREAM)
#define MPT_FILEDATACONTAINERMEMORY_OVERRIDE override
#else
#define MPT_FILEDATACONTAINERMEMORY_OVERRIDE
#endif
#if !defined(MPT_FILEREADER_STD_ISTREAM)
public:
typedef std::size_t off_t;
#endif
private:
const mpt::byte *streamData; // Pointer to memory-mapped file
const std::byte *streamData; // Pointer to memory-mapped file
off_t streamLength; // Size of memory-mapped file in bytes
public:
@ -1014,48 +1027,48 @@ public:
public:
bool IsValid() const MPT_FILEDATACONTAINERMEMORY_OVERRIDE
bool IsValid() const override
{
return streamData != nullptr;
}
bool HasFastGetLength() const MPT_FILEDATACONTAINERMEMORY_OVERRIDE
bool HasFastGetLength() const override
{
return true;
}
bool HasPinnedView() const MPT_FILEDATACONTAINERMEMORY_OVERRIDE
bool HasPinnedView() const override
{
return true;
}
const mpt::byte *GetRawData() const MPT_FILEDATACONTAINERMEMORY_OVERRIDE
const std::byte *GetRawData() const override
{
return streamData;
}
off_t GetLength() const MPT_FILEDATACONTAINERMEMORY_OVERRIDE
off_t GetLength() const override
{
return streamLength;
}
off_t Read(mpt::byte *dst, off_t pos, off_t count) const MPT_FILEDATACONTAINERMEMORY_OVERRIDE
off_t Read(std::byte *dst, off_t pos, off_t count) const override
{
if(pos >= streamLength)
{
return 0;
}
off_t avail = std::min<off_t>(streamLength - pos, count);
off_t avail = std::min(streamLength - pos, count);
std::copy(streamData + pos, streamData + pos + avail, dst);
return avail;
}
off_t Read(off_t pos, mpt::byte_span dst) const MPT_FILEDATACONTAINERMEMORY_OVERRIDE
off_t Read(off_t pos, mpt::byte_span dst) const override
{
return Read(dst.data(), pos, dst.size());
}
bool CanRead(off_t pos, off_t length) const MPT_FILEDATACONTAINERMEMORY_OVERRIDE
bool CanRead(off_t pos, off_t length) const override
{
if((pos == streamLength) && (length == 0))
{
@ -1068,13 +1081,13 @@ public:
return (length <= streamLength - pos);
}
off_t GetReadableLength(off_t pos, off_t length) const MPT_FILEDATACONTAINERMEMORY_OVERRIDE
off_t GetReadableLength(off_t pos, off_t length) const override
{
if(pos >= streamLength)
{
return 0;
}
return std::min<off_t>(length, streamLength - pos);
return std::min(length, streamLength - pos);
}
};

View file

@ -100,7 +100,7 @@ public:
if(WindowsVersion.IsAtLeast(mpt::Windows::Version::Win8))
{
hasKB2533623 = true;
} else if(WindowsVersion.IsAtLeast(mpt::Windows::Version::WinVista))
} else
{
HMODULE hKernel32DLL = LoadLibraryW(L"kernel32.dll");
if(hKernel32DLL)
@ -133,7 +133,7 @@ public:
// Just rely on the default search path here.
case mpt::LibrarySearchPathApplication:
{
const mpt::PathString dllPath = mpt::GetAppPath();
const mpt::PathString dllPath = mpt::GetExecutablePath();
if(!dllPath.empty() && mpt::PathIsAbsolute(dllPath) && dllPath.IsDirectory())
{
hModule = LoadLibrary((dllPath + path.GetFileName()).AsNative().c_str());
@ -165,7 +165,7 @@ public:
break;
case mpt::LibrarySearchPathApplication:
{
const mpt::PathString dllPath = mpt::GetAppPath();
const mpt::PathString dllPath = mpt::GetExecutablePath();
if(!dllPath.empty() && mpt::PathIsAbsolute(dllPath) && dllPath.IsDirectory())
{
hModule = LoadLibrary((dllPath + path.GetFileName()).AsNative().c_str());
@ -194,6 +194,10 @@ public:
}
LibraryHandle(const LibraryHandle &) = delete;
LibraryHandle & operator=(const LibraryHandle &) = delete;
~LibraryHandle()
{
if(IsValid())
@ -237,6 +241,10 @@ public:
return;
}
LibraryHandle(const LibraryHandle &) = delete;
LibraryHandle & operator=(const LibraryHandle &) = delete;
~LibraryHandle()
{
return;
@ -287,6 +295,10 @@ public:
handle = lt_dlopenext(path.GetFileName().AsNative().c_str());
}
LibraryHandle(const LibraryHandle &) = delete;
LibraryHandle & operator=(const LibraryHandle &) = delete;
~LibraryHandle()
{
if(IsValid())
@ -338,6 +350,10 @@ public:
handle = dlopen(path.GetFileName().AsNative().c_str(), RTLD_NOW);
}
LibraryHandle(const LibraryHandle &) = delete;
LibraryHandle & operator=(const LibraryHandle &) = delete;
~LibraryHandle()
{
if(IsValid())
@ -381,6 +397,10 @@ public:
return;
}
LibraryHandle(const LibraryHandle &) = delete;
LibraryHandle & operator=(const LibraryHandle &) = delete;
~LibraryHandle()
{
return;

View file

@ -104,7 +104,7 @@ public:
#if !(MPT_OS_WINDOWS && MPT_COMPILER_GCC)
// MinGW64 std::is_function is always false for non __cdecl functions.
// See https://connect.microsoft.com/VisualStudio/feedback/details/774720/stl-is-function-bug .
STATIC_ASSERT(std::is_function<Tfunc>::value);
static_assert(std::is_function<Tfunc>::value);
#endif
const FuncPtr addr = GetProcAddress(symbol);
f = reinterpret_cast<Tfunc*>(addr);

View file

@ -21,6 +21,7 @@
#include <bit>
#endif
#include <utility>
#include <type_traits>
#include <cstring>
@ -36,8 +37,8 @@ namespace mpt {
typedef mpt::span<mpt::byte> byte_span;
typedef mpt::span<const mpt::byte> const_byte_span;
typedef mpt::span<std::byte> byte_span;
typedef mpt::span<const std::byte> const_byte_span;
@ -49,19 +50,15 @@ typedef mpt::span<const mpt::byte> const_byte_span;
template <typename T> struct is_byte_castable : public std::false_type { };
template <> struct is_byte_castable<char> : public std::true_type { };
template <> struct is_byte_castable<unsigned char> : public std::true_type { };
#if MPT_BYTE_IS_STD_BYTE
template <> struct is_byte_castable<mpt::byte> : public std::true_type { };
#endif
template <> struct is_byte_castable<std::byte> : public std::true_type { };
template <> struct is_byte_castable<const char> : public std::true_type { };
template <> struct is_byte_castable<const unsigned char> : public std::true_type { };
#if MPT_BYTE_IS_STD_BYTE
template <> struct is_byte_castable<const mpt::byte> : public std::true_type { };
#endif
template <> struct is_byte_castable<const std::byte> : public std::true_type { };
template <typename T> struct is_byte : public std::false_type { };
template <> struct is_byte<mpt::byte> : public std::true_type { };
template <> struct is_byte<const mpt::byte> : public std::true_type { };
template <> struct is_byte<std::byte> : public std::true_type { };
template <> struct is_byte<const std::byte> : public std::true_type { };
// Tell which types are safe to binary write into files.
@ -74,9 +71,7 @@ template <typename T> struct is_binary_safe : public std::false_type { };
template <> struct is_binary_safe<char> : public std::true_type { };
template <> struct is_binary_safe<uint8> : public std::true_type { };
template <> struct is_binary_safe<int8> : public std::true_type { };
#if MPT_BYTE_IS_STD_BYTE
template <> struct is_binary_safe<mpt::byte> : public std::true_type { };
#endif
template <> struct is_binary_safe<std::byte> : public std::true_type { };
// Generic Specialization for arrays.
template <typename T, std::size_t N> struct is_binary_safe<T[N]> : public is_binary_safe<T> { };
@ -88,9 +83,9 @@ template <typename T, std::size_t N> struct is_binary_safe<const std::array<T, N
} // namespace mpt
#define MPT_BINARY_STRUCT(type, size) \
MPT_STATIC_ASSERT(sizeof( type ) == (size) ); \
MPT_STATIC_ASSERT(alignof( type ) == 1); \
MPT_STATIC_ASSERT(std::is_standard_layout< type >::value); \
static_assert(sizeof( type ) == (size) ); \
static_assert(alignof( type ) == 1); \
static_assert(std::is_standard_layout< type >::value); \
namespace mpt { \
template <> struct is_binary_safe< type > : public std::true_type { }; \
} \
@ -122,7 +117,7 @@ struct value_initializer<T[N]>
template <typename T>
inline void Clear(T & x)
{
MPT_STATIC_ASSERT(!std::is_pointer<T>::value);
static_assert(!std::is_pointer<T>::value);
value_initializer<T>()(x);
}
@ -132,13 +127,8 @@ template <class T>
inline void MemsetZero(T &a)
{
static_assert(std::is_pointer<T>::value == false, "Won't memset pointers.");
#if MPT_GCC_BEFORE(5,1,0) || (MPT_COMPILER_CLANG && defined(__GLIBCXX__))
MPT_STATIC_ASSERT(std::is_standard_layout<T>::value);
MPT_STATIC_ASSERT(std::is_trivial<T>::value || mpt::is_binary_safe<T>::value); // approximation
#else // default
MPT_STATIC_ASSERT(std::is_standard_layout<T>::value);
MPT_STATIC_ASSERT((std::is_trivially_default_constructible<T>::value && std::is_trivially_copyable<T>::value) || mpt::is_binary_safe<T>::value); // C++11, but not supported on most compilers we care about
#endif
static_assert(std::is_standard_layout<T>::value);
static_assert((std::is_trivially_default_constructible<T>::value && std::is_trivially_copyable<T>::value) || mpt::is_binary_safe<T>::value);
std::memset(&a, 0, sizeof(T));
}
@ -152,39 +142,13 @@ namespace mpt {
using std::bit_cast;
#else
// C++2a compatible bit_cast.
// See <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0476r1.html>.
// Not implementing constexpr because this is not easily possible pre C++2a.
// Not implementing constexpr because this is not easily possible pre C++20.
template <typename Tdst, typename Tsrc>
MPT_FORCEINLINE Tdst bit_cast(const Tsrc & src) noexcept
MPT_FORCEINLINE typename std::enable_if<(sizeof(Tdst) == sizeof(Tsrc)) && std::is_trivially_copyable<Tsrc>::value && std::is_trivially_copyable<Tdst>::value, Tdst>::type bit_cast(const Tsrc & src) noexcept
{
MPT_STATIC_ASSERT(sizeof(Tdst) == sizeof(Tsrc));
#if MPT_GCC_BEFORE(5,1,0) || (MPT_COMPILER_CLANG && defined(__GLIBCXX__))
MPT_STATIC_ASSERT(std::is_trivial<Tdst>::value); // approximation
MPT_STATIC_ASSERT(std::is_trivial<Tsrc>::value); // approximation
#else // default
MPT_STATIC_ASSERT(std::is_trivially_copyable<Tdst>::value);
MPT_STATIC_ASSERT(std::is_trivially_copyable<Tsrc>::value);
#endif
#if MPT_COMPILER_GCC || MPT_COMPILER_MSVC
// Compiler supports type-punning through unions. This is not stricly standard-conforming.
// For GCC, this is documented, for MSVC this is apparently not documented, but we assume it.
union {
Tsrc src;
Tdst dst;
} conv;
conv.src = src;
return conv.dst;
#else // MPT_COMPILER
// Compiler does not support type-punning through unions. std::memcpy is used instead.
// This is the safe fallback and strictly standard-conforming.
// Another standard-compliant alternative would be casting pointers to a character type pointer.
// This results in rather unreadable code and,
// in most cases, compilers generate better code by just inlining the memcpy anyway.
// (see <http://blog.regehr.org/archives/959>).
Tdst dst{};
std::memcpy(&dst, &src, sizeof(Tdst));
return dst;
#endif // MPT_COMPILER
Tdst dst{};
std::memcpy(&dst, &src, sizeof(Tdst));
return dst;
}
#endif
@ -195,12 +159,12 @@ struct byte_cast_impl
{
inline Tdst operator () (Tsrc src) const
{
STATIC_ASSERT(sizeof(Tsrc) == sizeof(mpt::byte));
STATIC_ASSERT(sizeof(Tdst) == sizeof(mpt::byte));
static_assert(sizeof(Tsrc) == sizeof(std::byte));
static_assert(sizeof(Tdst) == sizeof(std::byte));
// not checking is_byte_castable here because we are actually
// doing a static_cast and converting the value
STATIC_ASSERT(std::is_integral<Tsrc>::value || mpt::is_byte<Tsrc>::value);
STATIC_ASSERT(std::is_integral<Tdst>::value || mpt::is_byte<Tdst>::value);
static_assert(std::is_integral<Tsrc>::value || mpt::is_byte<Tsrc>::value);
static_assert(std::is_integral<Tdst>::value || mpt::is_byte<Tdst>::value);
return static_cast<Tdst>(src);
}
};
@ -209,13 +173,13 @@ struct byte_cast_impl<mpt::span<Tdst>, mpt::span<Tsrc> >
{
inline mpt::span<Tdst> operator () (mpt::span<Tsrc> src) const
{
STATIC_ASSERT(sizeof(Tsrc) == sizeof(mpt::byte));
STATIC_ASSERT(sizeof(Tdst) == sizeof(mpt::byte));
STATIC_ASSERT(mpt::is_byte_castable<Tsrc>::value);
STATIC_ASSERT(mpt::is_byte_castable<Tdst>::value);
STATIC_ASSERT(std::is_integral<Tsrc>::value || mpt::is_byte<Tsrc>::value);
STATIC_ASSERT(std::is_integral<Tdst>::value || mpt::is_byte<Tdst>::value);
return mpt::as_span(mpt::byte_cast_impl<Tdst*, Tsrc*>()(src.begin()), mpt::byte_cast_impl<Tdst*, Tsrc*>()(src.end()));
static_assert(sizeof(Tsrc) == sizeof(std::byte));
static_assert(sizeof(Tdst) == sizeof(std::byte));
static_assert(mpt::is_byte_castable<Tsrc>::value);
static_assert(mpt::is_byte_castable<Tdst>::value);
static_assert(std::is_integral<Tsrc>::value || mpt::is_byte<Tsrc>::value);
static_assert(std::is_integral<Tdst>::value || mpt::is_byte<Tdst>::value);
return mpt::as_span(mpt::byte_cast_impl<Tdst*, Tsrc*>()(src.data()), mpt::byte_cast_impl<Tdst*, Tsrc*>()(src.data() + src.size()));
}
};
template <typename Tdst, typename Tsrc>
@ -223,12 +187,12 @@ struct byte_cast_impl<Tdst*, Tsrc*>
{
inline Tdst* operator () (Tsrc* src) const
{
STATIC_ASSERT(sizeof(Tsrc) == sizeof(mpt::byte));
STATIC_ASSERT(sizeof(Tdst) == sizeof(mpt::byte));
STATIC_ASSERT(mpt::is_byte_castable<Tsrc>::value);
STATIC_ASSERT(mpt::is_byte_castable<Tdst>::value);
STATIC_ASSERT(std::is_integral<Tsrc>::value || mpt::is_byte<Tsrc>::value);
STATIC_ASSERT(std::is_integral<Tdst>::value || mpt::is_byte<Tdst>::value);
static_assert(sizeof(Tsrc) == sizeof(std::byte));
static_assert(sizeof(Tdst) == sizeof(std::byte));
static_assert(mpt::is_byte_castable<Tsrc>::value);
static_assert(mpt::is_byte_castable<Tdst>::value);
static_assert(std::is_integral<Tsrc>::value || mpt::is_byte<Tsrc>::value);
static_assert(std::is_integral<Tdst>::value || mpt::is_byte<Tdst>::value);
return reinterpret_cast<Tdst*>(src);
}
};
@ -241,9 +205,9 @@ struct void_cast_impl<Tdst*, void*>
{
inline Tdst* operator () (void* src) const
{
STATIC_ASSERT(sizeof(Tdst) == sizeof(mpt::byte));
STATIC_ASSERT(mpt::is_byte_castable<Tdst>::value);
STATIC_ASSERT(std::is_integral<Tdst>::value || mpt::is_byte<Tdst>::value);
static_assert(sizeof(Tdst) == sizeof(std::byte));
static_assert(mpt::is_byte_castable<Tdst>::value);
static_assert(std::is_integral<Tdst>::value || mpt::is_byte<Tdst>::value);
return reinterpret_cast<Tdst*>(src);
}
};
@ -252,9 +216,9 @@ struct void_cast_impl<Tdst*, const void*>
{
inline Tdst* operator () (const void* src) const
{
STATIC_ASSERT(sizeof(Tdst) == sizeof(mpt::byte));
STATIC_ASSERT(mpt::is_byte_castable<Tdst>::value);
STATIC_ASSERT(std::is_integral<Tdst>::value || mpt::is_byte<Tdst>::value);
static_assert(sizeof(Tdst) == sizeof(std::byte));
static_assert(mpt::is_byte_castable<Tdst>::value);
static_assert(std::is_integral<Tdst>::value || mpt::is_byte<Tdst>::value);
return reinterpret_cast<Tdst*>(src);
}
};
@ -263,9 +227,9 @@ struct void_cast_impl<void*, Tsrc*>
{
inline void* operator () (Tsrc* src) const
{
STATIC_ASSERT(sizeof(Tsrc) == sizeof(mpt::byte));
STATIC_ASSERT(mpt::is_byte_castable<Tsrc>::value);
STATIC_ASSERT(std::is_integral<Tsrc>::value || mpt::is_byte<Tsrc>::value);
static_assert(sizeof(Tsrc) == sizeof(std::byte));
static_assert(mpt::is_byte_castable<Tsrc>::value);
static_assert(std::is_integral<Tsrc>::value || mpt::is_byte<Tsrc>::value);
return reinterpret_cast<void*>(src);
}
};
@ -274,9 +238,9 @@ struct void_cast_impl<const void*, Tsrc*>
{
inline const void* operator () (Tsrc* src) const
{
STATIC_ASSERT(sizeof(Tsrc) == sizeof(mpt::byte));
STATIC_ASSERT(mpt::is_byte_castable<Tsrc>::value);
STATIC_ASSERT(std::is_integral<Tsrc>::value || mpt::is_byte<Tsrc>::value);
static_assert(sizeof(Tsrc) == sizeof(std::byte));
static_assert(mpt::is_byte_castable<Tsrc>::value);
static_assert(std::is_integral<Tsrc>::value || mpt::is_byte<Tsrc>::value);
return reinterpret_cast<const void*>(src);
}
};
@ -298,10 +262,10 @@ inline Tdst void_cast(Tsrc src)
template <typename T>
MPT_CONSTEXPR14_FUN mpt::byte as_byte(T src) noexcept
MPT_CONSTEXPR14_FUN std::byte as_byte(T src) noexcept
{
MPT_STATIC_ASSERT(std::is_integral<T>::value);
return static_cast<mpt::byte>(static_cast<uint8>(src));
static_assert(std::is_integral<T>::value);
return static_cast<std::byte>(static_cast<uint8>(src));
}
@ -311,13 +275,13 @@ struct GetRawBytesFunctor
{
inline mpt::const_byte_span operator () (const T & v) const
{
STATIC_ASSERT(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<const mpt::byte *>(&v), sizeof(T));
static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<const std::byte *>(&v), sizeof(T));
}
inline mpt::byte_span operator () (T & v) const
{
STATIC_ASSERT(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<mpt::byte *>(&v), sizeof(T));
static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<std::byte *>(&v), sizeof(T));
}
};
@ -326,13 +290,13 @@ struct GetRawBytesFunctor<T[N]>
{
inline mpt::const_byte_span operator () (const T (&v)[N]) const
{
STATIC_ASSERT(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<const mpt::byte *>(v), N * sizeof(T));
static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<const std::byte *>(v), N * sizeof(T));
}
inline mpt::byte_span operator () (T (&v)[N]) const
{
STATIC_ASSERT(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<mpt::byte *>(v), N * sizeof(T));
static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<std::byte *>(v), N * sizeof(T));
}
};
@ -341,15 +305,15 @@ struct GetRawBytesFunctor<const T[N]>
{
inline mpt::const_byte_span operator () (const T (&v)[N]) const
{
STATIC_ASSERT(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<const mpt::byte *>(v), N * sizeof(T));
static_assert(mpt::is_binary_safe<typename std::remove_const<T>::type>::value);
return mpt::as_span(reinterpret_cast<const std::byte *>(v), N * sizeof(T));
}
};
// In order to be able to partially specialize it,
// as_raw_memory is implemented via a class template.
// Do not overload or specialize as_raw_memory directly.
// Using a wrapper (by default just around a cast to const mpt::byte *),
// Using a wrapper (by default just around a cast to const std::byte *),
// allows for implementing raw memory access
// via on-demand generating a cached serialized representation.
template <typename T> inline mpt::const_byte_span as_raw_memory(const T & v)

View file

@ -174,7 +174,7 @@ public:
#if MPT_MUTEX_STD
#define MPT_LOCK_GUARD std::lock_guard
template <typename T> using lock_guard = std::lock_guard<T>;
#else // !MPT_MUTEX_STD
@ -188,8 +188,6 @@ public:
~lock_guard() { mutex.unlock(); }
};
#define MPT_LOCK_GUARD mpt::lock_guard
#endif // MPT_MUTEX_STD
#ifdef MODPLUG_TRACKER

View file

@ -15,10 +15,71 @@
#include <windows.h>
#endif
#if defined(MODPLUG_TRACKER)
#if !MPT_OS_WINDOWS
#include <sys/utsname.h>
#endif // !MPT_OS_WINDOWS
#endif // MODPLUG_TRACKER
OPENMPT_NAMESPACE_BEGIN
#if defined(MODPLUG_TRACKER)
namespace mpt
{
namespace OS
{
mpt::OS::Class GetClassFromSysname(mpt::ustring sysname)
{
mpt::OS::Class result = mpt::OS::Class::Unknown;
if(sysname == U_(""))
{
result = mpt::OS::Class::Unknown;
} else if(sysname == U_("Windows") || sysname == U_("WindowsNT") || sysname == U_("Windows_NT"))
{
result = mpt::OS::Class::Windows;
} else if(sysname == U_("Linux"))
{
result = mpt::OS::Class::Linux;
} else if(sysname == U_("Darwin"))
{
result = mpt::OS::Class::Darwin;
} else if(sysname == U_("FreeBSD") || sysname == U_("DragonFly") || sysname == U_("NetBSD") || sysname == U_("OpenBSD") || sysname == U_("MidnightBSD"))
{
result = mpt::OS::Class::BSD;
} else if(sysname == U_("Haiku"))
{
result = mpt::OS::Class::Haiku;
} else if(sysname == U_("MS-DOS"))
{
result = mpt::OS::Class::DOS;
}
return result;
}
mpt::OS::Class GetClass()
{
#if MPT_OS_WINDOWS
return mpt::OS::Class::Windows;
#else // !MPT_OS_WINDOWS
utsname uname_result;
if(uname(&uname_result) != 0)
{
return mpt::OS::Class::Unknown;
}
return mpt::OS::GetClassFromSysname(mpt::ToUnicode(mpt::Charset::ASCII, mpt::String::ReadAutoBuf(uname_result.sysname)));
#endif // MPT_OS_WINDOWS
}
} // namespace OS
} // namespace mpt
#endif // MODPLUG_TRACKER
namespace mpt
{
namespace Windows
@ -52,7 +113,7 @@ static mpt::Windows::Version VersionFromNTDDI_VERSION() noexcept
mpt::Windows::Version::WinNT4
#endif
;
return mpt::Windows::Version(System, mpt::Windows::Version::ServicePack(((NTDDI_VERSION & 0xffffu) >> 8) & 0xffu, ((NTDDI_VERSION & 0xffffu) >> 0) & 0xffu), 0);
return mpt::Windows::Version(System, mpt::Windows::Version::ServicePack(((NTDDI_VERSION & 0xffffu) >> 8) & 0xffu, ((NTDDI_VERSION & 0xffffu) >> 0) & 0xffu), 0, 0);
}
@ -77,6 +138,7 @@ static mpt::Windows::Version GatherWindowsVersion() noexcept
#if MPT_COMPILER_MSVC
#pragma warning(push)
#pragma warning(disable:4996) // 'GetVersionExW': was declared deprecated
#pragma warning(disable:28159) // Consider using 'IsWindows*' instead of 'GetVersionExW'. Reason: Deprecated. Use VerifyVersionInfo* or IsWindows* macros from VersionHelpers.
#endif // MPT_COMPILER_MSVC
#if MPT_COMPILER_CLANG
#pragma clang diagnostic push
@ -96,10 +158,17 @@ static mpt::Windows::Version GatherWindowsVersion() noexcept
{
return VersionFromNTDDI_VERSION();
}
DWORD dwProductType = 0;
dwProductType = PRODUCT_UNDEFINED;
if(GetProductInfo(versioninfoex.dwMajorVersion, versioninfoex.dwMinorVersion, versioninfoex.wServicePackMajor, versioninfoex.wServicePackMinor, &dwProductType) == FALSE)
{
dwProductType = PRODUCT_UNDEFINED;
}
return mpt::Windows::Version(
mpt::Windows::Version::System(versioninfoex.dwMajorVersion, versioninfoex.dwMinorVersion),
mpt::Windows::Version::ServicePack(versioninfoex.wServicePackMajor, versioninfoex.wServicePackMinor),
versioninfoex.dwBuildNumber
versioninfoex.dwBuildNumber,
dwProductType
);
#endif // MPT_OS_WINDOWS_WINRT
}
@ -135,6 +204,7 @@ Version::Version() noexcept
, m_System()
, m_ServicePack()
, m_Build()
, m_Type()
{
}
@ -145,11 +215,12 @@ Version Version::NoWindows() noexcept
}
Version::Version(mpt::Windows::Version::System system, mpt::Windows::Version::ServicePack servicePack, mpt::Windows::Version::Build build) noexcept
Version::Version(mpt::Windows::Version::System system, mpt::Windows::Version::ServicePack servicePack, mpt::Windows::Version::Build build, mpt::Windows::Version::TypeId type) noexcept
: m_SystemIsWindows(true)
, m_System(system)
, m_ServicePack(servicePack)
, m_Build(build)
, m_Type(type)
{
}
@ -284,7 +355,13 @@ mpt::Windows::Version::Build Version::GetBuild() const noexcept
}
static MPT_CONSTEXPR11_VAR struct { Version::System version; const MPT_UCHAR_TYPE * name; bool showDetails; } versionMap[] =
mpt::Windows::Version::TypeId Version::GetTypeId() const noexcept
{
return m_Type;
}
static constexpr struct { Version::System version; const mpt::uchar * name; bool showDetails; } versionMap[] =
{
{ mpt::Windows::Version::WinNewer, UL_("Windows 10 (or newer)"), false },
{ mpt::Windows::Version::Win10, UL_("Windows 10"), true },
@ -369,7 +446,7 @@ mpt::ustring Version::GetName() const
} else
{
result = mpt::format(U_("Wine (unknown version: '%1') (%2)"))(
mpt::ToUnicode(mpt::CharsetUTF8, v.RawVersion())
mpt::ToUnicode(mpt::Charset::UTF8, v.RawVersion())
, name
);
}
@ -410,11 +487,7 @@ mpt::Windows::Version::System Version::GetMinimumKernelLevel() noexcept
{
uint64 minimumKernelVersion = 0;
#if MPT_OS_WINDOWS && MPT_COMPILER_MSVC
#if !defined(MPT_BUILD_TARGET_XP)
minimumKernelVersion = std::max<uint64>(minimumKernelVersion, mpt::Windows::Version::WinVista);
#else
minimumKernelVersion = std::max<uint64>(minimumKernelVersion, mpt::Windows::Version::WinXP);
#endif
minimumKernelVersion = std::max(minimumKernelVersion, static_cast<uint64>(mpt::Windows::Version::WinVista));
#endif
return mpt::Windows::Version::System(minimumKernelVersion);
}
@ -502,7 +575,7 @@ struct ArchitectureInfo
{
Architecture Arch;
int Bitness;
const MPT_UCHAR_TYPE * Name;
const mpt::uchar * Name;
};
static constexpr ArchitectureInfo architectureInfo [] = {
{ Architecture::x86 , 32, UL_("x86") },
@ -836,8 +909,7 @@ mpt::Wine::Version GetMinimumWineVersion()
VersionContext::VersionContext()
: m_IsWine(false)
, m_HostIsLinux(false)
, m_HostIsBSD(false)
, m_HostClass(mpt::OS::Class::Unknown)
{
#if MPT_OS_WINDOWS
m_IsWine = mpt::Windows::IsWine();
@ -869,9 +941,8 @@ VersionContext::VersionContext()
m_RawHostSysName = wine_host_sysname ? wine_host_sysname : "";
m_RawHostRelease = wine_host_release ? wine_host_release : "";
}
m_Version = mpt::Wine::Version(mpt::ToUnicode(mpt::CharsetUTF8, m_RawVersion));
m_HostIsLinux = (m_RawHostSysName == "Linux");
m_HostIsBSD = (m_RawHostSysName == "FreeBSD" || m_RawHostSysName == "DragonFly" || m_RawHostSysName == "NetBSD" || m_RawHostSysName == "OpenBSD");
m_Version = mpt::Wine::Version(mpt::ToUnicode(mpt::Charset::UTF8, m_RawVersion));
m_HostClass = mpt::OS::GetClassFromSysname(mpt::ToUnicode(mpt::Charset::UTF8, m_RawHostSysName));
#endif // MPT_OS_WINDOWS
}

View file

@ -19,6 +19,34 @@
OPENMPT_NAMESPACE_BEGIN
#if defined(MODPLUG_TRACKER)
namespace mpt
{
namespace OS
{
enum class Class
{
Unknown,
Windows,
Linux,
Darwin,
BSD,
Haiku,
DOS,
};
mpt::OS::Class GetClassFromSysname(mpt::ustring sysname);
mpt::OS::Class GetClass();
} // namespace OS
} // namespace mpt
#endif // MODPLUG_TRACKER
namespace mpt
{
namespace Windows
@ -92,6 +120,8 @@ public:
typedef uint32 Build;
typedef uint32 TypeId;
static mpt::ustring VersionToString(mpt::Windows::Version::System version);
private:
@ -101,6 +131,7 @@ private:
System m_System;
ServicePack m_ServicePack;
Build m_Build;
TypeId m_Type;
private:
@ -110,7 +141,7 @@ public:
static Version NoWindows() noexcept;
Version(mpt::Windows::Version::System system, mpt::Windows::Version::ServicePack servicePack, mpt::Windows::Version::Build build) noexcept;
Version(mpt::Windows::Version::System system, mpt::Windows::Version::ServicePack servicePack, mpt::Windows::Version::Build build, mpt::Windows::Version::TypeId type) noexcept;
public:
@ -131,6 +162,7 @@ public:
mpt::Windows::Version::System GetSystem() const noexcept;
mpt::Windows::Version::ServicePack GetServicePack() const noexcept;
mpt::Windows::Version::Build GetBuild() const noexcept;
mpt::Windows::Version::TypeId GetTypeId() const noexcept;
mpt::ustring GetName() const;
#ifdef MODPLUG_TRACKER
@ -248,8 +280,7 @@ protected:
std::string m_RawHostSysName;
std::string m_RawHostRelease;
mpt::Wine::Version m_Version;
bool m_HostIsLinux;
bool m_HostIsBSD;
mpt::OS::Class m_HostClass;
public:
VersionContext();
public:
@ -260,8 +291,7 @@ public:
std::string RawHostSysName() const { return m_RawHostSysName; }
std::string RawHostRelease() const { return m_RawHostRelease; }
mpt::Wine::Version Version() const { return m_Version; }
bool HostIsLinux() const { return m_HostIsLinux; }
bool HostIsBSD() const { return m_HostIsBSD; }
mpt::OS::Class HostClass() const { return m_HostClass; }
};
} // namespace Wine

View file

@ -0,0 +1,99 @@
/*
* mptOSError.h
* ------------
* Purpose: OS-specific error message handling.
* Notes : (currently none)
* Authors: OpenMPT Devs
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
#pragma once
#include "BuildSettings.h"
#include "mptBaseMacros.h"
#include "mptException.h"
#include "mptString.h"
#include "mptStringFormat.h"
#if defined(MODPLUG_TRACKER)
#if MPT_OS_WINDOWS
#include <stdexcept>
#endif // MPT_OS_WINDOWS
#endif // MODPLUG_TRACKER
#if defined(MODPLUG_TRACKER)
#if MPT_OS_WINDOWS
#include <windows.h>
#endif // MPT_OS_WINDOWS
#endif // MODPLUG_TRACKER
OPENMPT_NAMESPACE_BEGIN
#if defined(MODPLUG_TRACKER)
#if MPT_OS_WINDOWS
namespace Windows
{
inline mpt::ustring GetErrorMessage(DWORD errorCode, HANDLE hModule = NULL)
{
mpt::ustring message;
void *lpMsgBuf = nullptr;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | (hModule ? FORMAT_MESSAGE_FROM_HMODULE : 0) | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
hModule,
errorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0,
NULL);
if(!lpMsgBuf)
{
DWORD e = GetLastError();
if((e == ERROR_NOT_ENOUGH_MEMORY) || (e == ERROR_OUTOFMEMORY))
{
MPT_EXCEPTION_THROW_OUT_OF_MEMORY();
}
return {};
}
try
{
message = mpt::ToUnicode(mpt::winstring((LPTSTR)lpMsgBuf));
} MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)
{
LocalFree(lpMsgBuf);
MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e);
}
LocalFree(lpMsgBuf);
return message;
}
class Error
: public std::runtime_error
{
public:
Error(DWORD errorCode, HANDLE hModule = NULL)
: std::runtime_error(mpt::ToCharset(mpt::CharsetException, mpt::format(U_("Windows Error: 0x%1: %2"))(mpt::ufmt::hex0<8>(errorCode), GetErrorMessage(errorCode, hModule))))
{
return;
}
};
} // namespace Windows
#endif // MPT_OS_WINDOWS
#endif // MODPLUG_TRACKER
OPENMPT_NAMESPACE_END

View file

@ -0,0 +1,188 @@
/*
* mptOSException.h
* ----------------
* Purpose: platform-specific exception/signal handling
* Notes : (currently none)
* Authors: OpenMPT Devs
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
#pragma once
#include "BuildSettings.h"
#include "mptBaseMacros.h"
#include "mptBaseTypes.h"
#if defined(MODPLUG_TRACKER)
#if MPT_OS_WINDOWS
#include <windows.h>
#endif // MPT_OS_WINDOWS
#endif // MODPLUG_TRACKER
OPENMPT_NAMESPACE_BEGIN
#if defined(MODPLUG_TRACKER)
#if MPT_OS_WINDOWS
namespace Windows
{
namespace SEH
{
struct Code
{
private:
DWORD m_Code;
public:
constexpr Code(DWORD code) noexcept
: m_Code(code)
{
return;
}
public:
constexpr DWORD code() const noexcept
{
return m_Code;
}
};
template <typename Tfn, typename Tfilter, typename Thandler>
auto TryFilterHandleThrow(const Tfn &fn, const Tfilter &filter, const Thandler &handler) -> decltype(fn())
{
static_assert(std::is_trivially_copy_assignable<decltype(fn())>::value);
static_assert(std::is_trivially_copy_constructible<decltype(fn())>::value);
static_assert(std::is_trivially_move_assignable<decltype(fn())>::value);
static_assert(std::is_trivially_move_constructible<decltype(fn())>::value);
DWORD code = 0;
__try
{
return fn();
} __except(filter(GetExceptionCode(), GetExceptionInformation()))
{
code = GetExceptionCode();
}
throw Windows::SEH::Code(code);
}
template <typename Tfn, typename Tfilter, typename Thandler>
void TryFilterHandleVoid(const Tfn &fn, const Tfilter &filter, const Thandler &handler)
{
static_assert(std::is_same<decltype(fn()), void>::value || std::is_trivially_copy_assignable<decltype(fn())>::value);
static_assert(std::is_same<decltype(fn()), void>::value || std::is_trivially_copy_constructible<decltype(fn())>::value);
static_assert(std::is_same<decltype(fn()), void>::value || std::is_trivially_move_assignable<decltype(fn())>::value);
static_assert(std::is_same<decltype(fn()), void>::value || std::is_trivially_move_constructible<decltype(fn())>::value);
__try
{
fn();
return;
} __except(filter(GetExceptionCode(), GetExceptionInformation()))
{
DWORD code = GetExceptionCode();
handler(code);
}
return;
}
template <typename Tfn, typename Tfilter, typename Thandler>
auto TryFilterHandleDefault(const Tfn &fn, const Tfilter &filter, const Thandler &handler, decltype(fn()) def = decltype(fn()){}) -> decltype(fn())
{
static_assert(std::is_trivially_copy_assignable<decltype(fn())>::value);
static_assert(std::is_trivially_copy_constructible<decltype(fn())>::value);
static_assert(std::is_trivially_move_assignable<decltype(fn())>::value);
static_assert(std::is_trivially_move_constructible<decltype(fn())>::value);
auto result = def;
__try
{
result = fn();
} __except(filter(GetExceptionCode(), GetExceptionInformation()))
{
DWORD code = GetExceptionCode();
result = handler(code);
}
return result;
}
template <typename Tfn>
auto TryReturnOrThrow(const Tfn &fn) -> decltype(fn())
{
return TryFilterHandleThrow(
fn,
[](auto code, auto eptr)
{
MPT_UNREFERENCED_PARAMETER(code);
MPT_UNREFERENCED_PARAMETER(eptr);
return EXCEPTION_EXECUTE_HANDLER;
},
[](auto code)
{
throw Windows::SEH::Code(code);
});
}
template <typename Tfn>
DWORD TryOrError(const Tfn &fn)
{
DWORD result = DWORD{0};
TryFilterHandleVoid(
fn,
[](auto code, auto eptr)
{
MPT_UNREFERENCED_PARAMETER(code);
MPT_UNREFERENCED_PARAMETER(eptr);
return EXCEPTION_EXECUTE_HANDLER;
},
[&result](auto code)
{
result = code;
});
return result;
}
template <typename Tfn>
auto TryReturnOrDefault(const Tfn &fn, decltype(fn()) def = decltype(fn()){}) -> decltype(fn())
{
return TryFilterHandleDefault(
fn,
[](auto code, auto eptr)
{
MPT_UNREFERENCED_PARAMETER(code);
MPT_UNREFERENCED_PARAMETER(eptr);
return EXCEPTION_EXECUTE_HANDLER;
},
[def](auto code)
{
MPT_UNREFERENCED_PARAMETER(code);
return def;
});
}
} // namspace SEH
} // namespace Windows
#endif // MPT_OS_WINDOWS
#endif // MODPLUG_TRACKER
OPENMPT_NAMESPACE_END

View file

@ -524,7 +524,7 @@ bool DeleteWholeDirectoryTree(mpt::PathString path)
#if defined(MPT_ENABLE_DYNBIND) || defined(MPT_ENABLE_TEMPFILE)
mpt::PathString GetAppPath()
mpt::PathString GetExecutablePath()
{
std::vector<TCHAR> exeFileName(MAX_PATH);
while(GetModuleFileName(0, exeFileName.data(), mpt::saturate_cast<DWORD>(exeFileName.size())) >= exeFileName.size())
@ -578,8 +578,8 @@ mpt::PathString GetTempDirectory()
return mpt::PathString::FromNative(tempPath.data());
}
}
// use app directory as fallback
return mpt::GetAppPath();
// use exe directory as fallback
return mpt::GetExecutablePath();
}
mpt::PathString CreateTempFileName(const mpt::PathString &fileNamePrefix, const mpt::PathString &fileNameExtension)
@ -735,7 +735,7 @@ void SanitizeFilename(mpt::u8string &str)
}
#endif // MPT_USTRING_MODE_UTF8
#if defined(_MFC_VER)
#if defined(MPT_WITH_MFC)
void SanitizeFilename(CString &str)
{
for(int i = 0; i < str.GetLength(); i++)
@ -743,7 +743,7 @@ void SanitizeFilename(CString &str)
str.SetAt(i, SanitizeFilenameChar(str.GetAt(i)));
}
}
#endif // MFC
#endif // MPT_WITH_MFC
#endif // MODPLUG_TRACKER

View file

@ -21,7 +21,7 @@ OPENMPT_NAMESPACE_BEGIN
#define MPT_DEPRECATED_PATH
//#define MPT_DEPRECATED_PATH MPT_DEPRECATED
//#define MPT_DEPRECATED_PATH [[deprecated]]
@ -120,9 +120,9 @@ public:
PathString GetDrive() const; // Drive letter + colon, e.g. "C:" or \\server\\share
PathString GetDir() const; // Directory, e.g. "\OpenMPT\"
PathString GetPath() const; // Drive + Dir, e.g. "C:\OpenMPT\"
PathString GetFileName() const; // File name without extension, e.g. "mptrack"
PathString GetFileName() const; // File name without extension, e.g. "OpenMPT"
PathString GetFileExt() const; // Extension including dot, e.g. ".exe"
PathString GetFullFileName() const; // File name + extension, e.g. "mptrack.exe"
PathString GetFullFileName() const; // File name + extension, e.g. "OpenMPT.exe"
// Verify if this path represents a valid directory on the file system.
bool IsDirectory() const;
@ -204,27 +204,27 @@ public:
#endif
// conversions
#if defined(MPT_ENABLE_CHARSET_LOCALE)
MPT_DEPRECATED_PATH std::string ToLocale() const { return mpt::ToCharset(mpt::CharsetLocale, path); }
MPT_DEPRECATED_PATH std::string ToLocale() const { return mpt::ToCharset(mpt::Charset::Locale, path); }
#endif
std::string ToUTF8() const { return mpt::ToCharset(mpt::CharsetUTF8, path); }
std::string ToUTF8() const { return mpt::ToCharset(mpt::Charset::UTF8, path); }
std::wstring ToWide() const { return mpt::ToWide(path); }
mpt::ustring ToUnicode() const { return mpt::ToUnicode(path); }
#if defined(MPT_ENABLE_CHARSET_LOCALE)
MPT_DEPRECATED_PATH static PathString FromLocale(const std::string &path) { return PathString(mpt::ToWin(mpt::CharsetLocale, path)); }
static PathString FromLocaleSilent(const std::string &path) { return PathString(mpt::ToWin(mpt::CharsetLocale, path)); }
MPT_DEPRECATED_PATH static PathString FromLocale(const std::string &path) { return PathString(mpt::ToWin(mpt::Charset::Locale, path)); }
static PathString FromLocaleSilent(const std::string &path) { return PathString(mpt::ToWin(mpt::Charset::Locale, path)); }
#endif
static PathString FromUTF8(const std::string &path) { return PathString(mpt::ToWin(mpt::CharsetUTF8, path)); }
static PathString FromUTF8(const std::string &path) { return PathString(mpt::ToWin(mpt::Charset::UTF8, path)); }
static PathString FromWide(const std::wstring &path) { return PathString(mpt::ToWin(path)); }
static PathString FromUnicode(const mpt::ustring &path) { return PathString(mpt::ToWin(path)); }
RawPathString AsNative() const { return path; }
// Return native string, with possible \\?\ prefix if it exceeds MAX_PATH characters.
RawPathString AsNativePrefixed() const;
static PathString FromNative(const RawPathString &path) { return PathString(path); }
#if defined(_MFC_VER)
#if defined(MPT_WITH_MFC)
// CString TCHAR, so this is CHAR or WCHAR, depending on UNICODE
CString ToCString() const { return mpt::ToCString(path); }
static PathString FromCString(const CString &path) { return PathString(mpt::ToWin(path)); }
#endif
#endif // MPT_WITH_MFC
// Convert a path to its simplified form, i.e. remove ".\" and "..\" entries
mpt::PathString Simplify() const;
@ -234,39 +234,39 @@ public:
// conversions
#if defined(MPT_ENABLE_CHARSET_LOCALE)
std::string ToLocale() const { return path; }
std::string ToUTF8() const { return mpt::ToCharset(mpt::CharsetUTF8, mpt::CharsetLocale, path); }
std::string ToUTF8() const { return mpt::ToCharset(mpt::Charset::UTF8, mpt::Charset::Locale, path); }
#if MPT_WSTRING_CONVERT
std::wstring ToWide() const { return mpt::ToWide(mpt::CharsetLocale, path); }
std::wstring ToWide() const { return mpt::ToWide(mpt::Charset::Locale, path); }
#endif
mpt::ustring ToUnicode() const { return mpt::ToUnicode(mpt::CharsetLocale, path); }
mpt::ustring ToUnicode() const { return mpt::ToUnicode(mpt::Charset::Locale, path); }
static PathString FromLocale(const std::string &path) { return PathString(path); }
static PathString FromLocaleSilent(const std::string &path) { return PathString(path); }
static PathString FromUTF8(const std::string &path) { return PathString(mpt::ToCharset(mpt::CharsetLocale, mpt::CharsetUTF8, path)); }
static PathString FromUTF8(const std::string &path) { return PathString(mpt::ToCharset(mpt::Charset::Locale, mpt::Charset::UTF8, path)); }
#if MPT_WSTRING_CONVERT
static PathString FromWide(const std::wstring &path) { return PathString(mpt::ToCharset(mpt::CharsetLocale, path)); }
static PathString FromWide(const std::wstring &path) { return PathString(mpt::ToCharset(mpt::Charset::Locale, path)); }
#endif
static PathString FromUnicode(const mpt::ustring &path) { return PathString(mpt::ToCharset(mpt::CharsetLocale, path)); }
static PathString FromUnicode(const mpt::ustring &path) { return PathString(mpt::ToCharset(mpt::Charset::Locale, path)); }
RawPathString AsNative() const { return path; }
RawPathString AsNativePrefixed() const { return path; }
static PathString FromNative(const RawPathString &path) { return PathString(path); }
#else // !MPT_ENABLE_CHARSET_LOCALE
std::string ToUTF8() const { return path; }
#if MPT_WSTRING_CONVERT
std::wstring ToWide() const { return mpt::ToWide(mpt::CharsetUTF8, path); }
std::wstring ToWide() const { return mpt::ToWide(mpt::Charset::UTF8, path); }
#endif
mpt::ustring ToUnicode() const { return mpt::ToUnicode(mpt::CharsetUTF8, path); }
mpt::ustring ToUnicode() const { return mpt::ToUnicode(mpt::Charset::UTF8, path); }
static PathString FromUTF8(const std::string &path) { return PathString(path); }
#if MPT_WSTRING_CONVERT
static PathString FromWide(const std::wstring &path) { return PathString(mpt::ToCharset(mpt::CharsetUTF8, path)); }
static PathString FromWide(const std::wstring &path) { return PathString(mpt::ToCharset(mpt::Charset::UTF8, path)); }
#endif
static PathString FromUnicode(const mpt::ustring &path) { return PathString(mpt::ToCharset(mpt::CharsetUTF8, path)); }
static PathString FromUnicode(const mpt::ustring &path) { return PathString(mpt::ToCharset(mpt::Charset::UTF8, path)); }
RawPathString AsNative() const { return path; }
RawPathString AsNativePrefixed() const { return path; }
static PathString FromNative(const RawPathString &path) { return PathString(path); }
#endif // MPT_ENABLE_CHARSET_LOCALE
// Convert a path to its simplified form (currently only implemented on Windows)
MPT_DEPRECATED mpt::PathString Simplify() const { return PathString(path); }
[[deprecated]] mpt::PathString Simplify() const { return PathString(path); }
#endif // MPT_OS_WINDOWS
@ -277,12 +277,12 @@ public:
#if defined(MPT_ENABLE_CHARSET_LOCALE)
#if MPT_OS_WINDOWS
#ifdef UNICODE
MPT_DEPRECATED static inline std::string ToString(const mpt::PathString & x) { return mpt::ToCharset(mpt::CharsetLocale, x.ToUnicode()); }
[[deprecated]] static inline std::string ToString(const mpt::PathString & x) { return mpt::ToCharset(mpt::Charset::Locale, x.ToUnicode()); }
#else
MPT_DEPRECATED_PATH static inline std::string ToString(const mpt::PathString & x) { return mpt::ToCharset(mpt::CharsetLocale, x.AsNative()); }
MPT_DEPRECATED_PATH static inline std::string ToString(const mpt::PathString & x) { return mpt::ToCharset(mpt::Charset::Locale, x.AsNative()); }
#endif
#else
MPT_DEPRECATED_PATH static inline std::string ToString(const mpt::PathString & x) { return mpt::ToCharset(mpt::CharsetLocale, x.ToUnicode()); }
MPT_DEPRECATED_PATH static inline std::string ToString(const mpt::PathString & x) { return mpt::ToCharset(mpt::Charset::Locale, x.ToUnicode()); }
#endif
#endif
static inline mpt::ustring ToUString(const mpt::PathString & x) { return x.ToUnicode(); }
@ -339,8 +339,8 @@ bool DeleteWholeDirectoryTree(mpt::PathString path);
#if defined(MPT_ENABLE_DYNBIND) || defined(MPT_ENABLE_TEMPFILE)
// Returns the application path or an empty string (if unknown), e.g. "C:\mptrack\"
mpt::PathString GetAppPath();
// Returns the application executable path or an empty string (if unknown), e.g. "C:\mptrack\"
mpt::PathString GetExecutablePath();
#endif // MPT_ENABLE_DYNBIND || MPT_ENABLE_TEMPFILE
@ -418,20 +418,20 @@ void SanitizeFilename(mpt::u8string &str);
template <std::size_t size>
void SanitizeFilename(char (&buffer)[size])
{
STATIC_ASSERT(size > 0);
static_assert(size > 0);
SanitizeFilename(buffer, buffer + size);
}
template <std::size_t size>
void SanitizeFilename(wchar_t (&buffer)[size])
{
STATIC_ASSERT(size > 0);
static_assert(size > 0);
SanitizeFilename(buffer, buffer + size);
}
#if defined(_MFC_VER)
#if defined(MPT_WITH_MFC)
void SanitizeFilename(CString &str);
#endif
#endif // MPT_WITH_MFC
#endif // MODPLUG_TRACKER

View file

@ -34,16 +34,16 @@ static T log2(T x)
}
static MPT_CONSTEXPR11_FUN int lower_bound_entropy_bits(unsigned int x)
static MPT_CONSTEXPR14_FUN int lower_bound_entropy_bits(unsigned int x)
{
return detail::lower_bound_entropy_bits(x);
}
template <typename T>
static inline bool is_mask(T x)
static MPT_CONSTEXPR14_FUN bool is_mask(T x)
{
STATIC_ASSERT(std::numeric_limits<T>::is_integer);
static_assert(std::numeric_limits<T>::is_integer);
typedef typename std::make_unsigned<T>::type unsigned_T;
unsigned_T ux = static_cast<unsigned_T>(x);
unsigned_T mask = 0;
@ -86,7 +86,7 @@ static T generate_timeseed()
{
uint64be time;
time = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock().now().time_since_epoch()).count();
mpt::byte bytes[sizeof(time)];
std::byte bytes[sizeof(time)];
std::memcpy(bytes, &time, sizeof(time));
hash(std::begin(bytes), std::end(bytes));
}
@ -94,7 +94,7 @@ static T generate_timeseed()
{
uint64be time;
time = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock().now().time_since_epoch()).count();
mpt::byte bytes[sizeof(time)];
std::byte bytes[sizeof(time)];
std::memcpy(bytes, &time, sizeof(time));
hash(std::begin(bytes), std::end(bytes));
}
@ -126,8 +126,19 @@ crand::result_type crand::operator()()
#endif // MODPLUG_TRACKER
sane_random_device::sane_random_device()
: rd_reliable(rd.entropy() > 0.0)
: rd_reliable(false)
{
try
{
prd = std::make_unique<std::random_device>();
rd_reliable = ((*prd).entropy() > 0.0);
} MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)
{
MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e);
} catch(const std::exception &)
{
rd_reliable = false;
}
if(!rd_reliable)
{
init_fallback();
@ -136,9 +147,19 @@ sane_random_device::sane_random_device()
sane_random_device::sane_random_device(const std::string & token_)
: token(token_)
, rd(token)
, rd_reliable(rd.entropy() > 0.0)
, rd_reliable(false)
{
try
{
prd = std::make_unique<std::random_device>(token);
rd_reliable = ((*prd).entropy() > 0.0);
} MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e)
{
MPT_EXCEPTION_RETHROW_OUT_OF_MEMORY(e);
} catch(const std::exception &)
{
rd_reliable = false;
}
if(!rd_reliable)
{
init_fallback();
@ -160,7 +181,7 @@ void sane_random_device::init_fallback()
seeds.push_back(static_cast<unsigned int>(static_cast<unsigned char>(token[i])));
}
std::seed_seq seed(seeds.begin(), seeds.end());
rd_fallback = mpt::make_unique<std::mt19937>(seed);
rd_fallback = std::make_unique<std::mt19937>(seed);
} else
{
uint64 seed_val = mpt::generate_timeseed<uint64>();
@ -168,53 +189,59 @@ void sane_random_device::init_fallback()
seeds[0] = static_cast<uint32>(seed_val >> 32);
seeds[1] = static_cast<uint32>(seed_val >> 0);
std::seed_seq seed(seeds + 0, seeds + 2);
rd_fallback = mpt::make_unique<std::mt19937>(seed);
rd_fallback = std::make_unique<std::mt19937>(seed);
}
}
}
sane_random_device::result_type sane_random_device::operator()()
{
MPT_LOCK_GUARD<mpt::mutex> l(m);
mpt::lock_guard<mpt::mutex> l(m);
result_type result = 0;
try
if(prd)
{
if(rd.min() != 0 || !mpt::is_mask(rd.max()))
{ // insane std::random_device
// This implementation is not exactly uniformly distributed but good enough
// for OpenMPT.
double rd_min = static_cast<double>(rd.min());
double rd_max = static_cast<double>(rd.max());
double rd_range = rd_max - rd_min;
double rd_size = rd_range + 1.0;
double rd_entropy = mpt::log2(rd_size);
int iterations = static_cast<int>(std::ceil(result_bits() / rd_entropy));
double tmp = 0.0;
for(int i = 0; i < iterations; ++i)
{
tmp = (tmp * rd_size) + (static_cast<double>(rd()) - rd_min);
}
double result_01 = std::floor(tmp / std::pow(rd_size, iterations));
result = static_cast<result_type>(std::floor(result_01 * (static_cast<double>(max() - min()) + 1.0))) + min();
} else
{ // sane std::random_device
result = 0;
std::size_t rd_bits = mpt::lower_bound_entropy_bits(rd.max());
for(std::size_t entropy = 0; entropy < (sizeof(result_type) * 8); entropy += rd_bits)
{
if(rd_bits < (sizeof(result_type) * 8))
try
{
if constexpr(std::random_device::min() != 0 || !mpt::is_mask(std::random_device::max()))
{ // insane std::random_device
// This implementation is not exactly uniformly distributed but good enough
// for OpenMPT.
double rd_min = static_cast<double>(std::random_device::min());
double rd_max = static_cast<double>(std::random_device::max());
double rd_range = rd_max - rd_min;
double rd_size = rd_range + 1.0;
double rd_entropy = mpt::log2(rd_size);
int iterations = static_cast<int>(std::ceil(result_bits() / rd_entropy));
double tmp = 0.0;
for(int i = 0; i < iterations; ++i)
{
result = (result << rd_bits) | static_cast<result_type>(rd());
} else
tmp = (tmp * rd_size) + (static_cast<double>((*prd)()) - rd_min);
}
double result_01 = std::floor(tmp / std::pow(rd_size, iterations));
result = static_cast<result_type>(std::floor(result_01 * (static_cast<double>(max() - min()) + 1.0))) + min();
} else
{ // sane std::random_device
result = 0;
std::size_t rd_bits = mpt::lower_bound_entropy_bits(std::random_device::max());
for(std::size_t entropy = 0; entropy < (sizeof(result_type) * 8); entropy += rd_bits)
{
result = result | static_cast<result_type>(rd());
if(rd_bits < (sizeof(result_type) * 8))
{
result = (result << rd_bits) | static_cast<result_type>((*prd)());
} else
{
result = result | static_cast<result_type>((*prd)());
}
}
}
} catch(const std::exception &)
{
rd_reliable = false;
init_fallback();
}
} catch(const std::exception &)
} else
{
rd_reliable = false;
init_fallback();
}
if(!rd_reliable)
{ // std::random_device is unreliable

View file

@ -44,50 +44,113 @@ namespace mpt
#ifdef MPT_BUILD_FUZZER
static const uint32 FUZZER_RNG_SEED = 3141592653u; // pi
static constexpr uint32 FUZZER_RNG_SEED = 3141592653u; // pi
#endif // MPT_BUILD_FUZZER
namespace detail
{
MPT_CONSTEXPR11_FUN int lower_bound_entropy_bits(unsigned int x)
MPT_CONSTEXPR14_FUN int lower_bound_entropy_bits(unsigned int x)
{
// easy to compile-time evaluate even for stupid compilers
return
x >= 0xffffffffu ? 32 :
x >= 0x7fffffffu ? 31 :
x >= 0x3fffffffu ? 30 :
x >= 0x1fffffffu ? 29 :
x >= 0x0fffffffu ? 28 :
x >= 0x07ffffffu ? 27 :
x >= 0x03ffffffu ? 26 :
x >= 0x01ffffffu ? 25 :
x >= 0x00ffffffu ? 24 :
x >= 0x007fffffu ? 23 :
x >= 0x003fffffu ? 22 :
x >= 0x001fffffu ? 21 :
x >= 0x000fffffu ? 20 :
x >= 0x0007ffffu ? 19 :
x >= 0x0003ffffu ? 18 :
x >= 0x0001ffffu ? 17 :
x >= 0x0000ffffu ? 16 :
x >= 0x00007fffu ? 15 :
x >= 0x00003fffu ? 14 :
x >= 0x00001fffu ? 13 :
x >= 0x00000fffu ? 12 :
x >= 0x000007ffu ? 11 :
x >= 0x000003ffu ? 10 :
x >= 0x000001ffu ? 9 :
x >= 0x000000ffu ? 8 :
x >= 0x0000007fu ? 7 :
x >= 0x0000003fu ? 6 :
x >= 0x0000001fu ? 5 :
x >= 0x0000000fu ? 4 :
x >= 0x00000007u ? 3 :
x >= 0x00000003u ? 2 :
x >= 0x00000001u ? 1 :
0;
if(x >= 0xffffffffu)
{
return 32;
} else if(x >= 0x7fffffffu)
{
return 31;
} else if(x >= 0x3fffffffu)
{
return 30;
} else if(x >= 0x1fffffffu)
{
return 29;
} else if(x >= 0x0fffffffu)
{
return 28;
} else if(x >= 0x07ffffffu)
{
return 27;
} else if(x >= 0x03ffffffu)
{
return 26;
} else if(x >= 0x01ffffffu)
{
return 25;
} else if(x >= 0x00ffffffu)
{
return 24;
} else if(x >= 0x007fffffu)
{
return 23;
} else if(x >= 0x003fffffu)
{
return 22;
} else if(x >= 0x001fffffu)
{
return 21;
} else if(x >= 0x000fffffu)
{
return 20;
} else if(x >= 0x0007ffffu)
{
return 19;
} else if(x >= 0x0003ffffu)
{
return 18;
} else if(x >= 0x0001ffffu)
{
return 17;
} else if(x >= 0x0000ffffu)
{
return 16;
} else if(x >= 0x00007fffu)
{
return 15;
} else if(x >= 0x00003fffu)
{
return 14;
} else if(x >= 0x00001fffu)
{
return 13;
} else if(x >= 0x00000fffu)
{
return 12;
} else if(x >= 0x000007ffu)
{
return 11;
} else if(x >= 0x000003ffu)
{
return 10;
} else if(x >= 0x000001ffu)
{
return 9;
} else if(x >= 0x000000ffu)
{
return 8;
} else if(x >= 0x0000007fu)
{
return 7;
} else if(x >= 0x0000003fu)
{
return 6;
} else if(x >= 0x0000001fu)
{
return 5;
} else if(x >= 0x0000000fu)
{
return 4;
} else if(x >= 0x00000007u)
{
return 3;
} else if(x >= 0x00000003u)
{
return 2;
} else if(x >= 0x00000001u)
{
return 1;
}
return 0;
}
}
@ -111,15 +174,15 @@ template <typename Trng> struct engine_traits
template <typename T, typename Trng>
inline T random(Trng & rng)
{
STATIC_ASSERT(std::numeric_limits<T>::is_integer);
static_assert(std::numeric_limits<T>::is_integer);
typedef typename std::make_unsigned<T>::type unsigned_T;
const unsigned int rng_bits = mpt::engine_traits<Trng>::result_bits();
unsigned_T result = 0;
for(std::size_t entropy = 0; entropy < (sizeof(T) * 8); entropy += rng_bits)
{
MPT_CONSTANT_IF(rng_bits < (sizeof(T) * 8))
if constexpr(rng_bits < (sizeof(T) * 8))
{
MPT_CONSTEXPR11_VAR unsigned int shift_bits = rng_bits % (sizeof(T) * 8); // silence utterly stupid MSVC and GCC warnings about shifting by too big amount (in which case this branch is not even taken however)
constexpr unsigned int shift_bits = rng_bits % (sizeof(T) * 8); // silence utterly stupid MSVC and GCC warnings about shifting by too big amount (in which case this branch is not even taken however)
result = (result << shift_bits) ^ static_cast<unsigned_T>(rng());
} else
{
@ -132,22 +195,22 @@ inline T random(Trng & rng)
template <typename T, std::size_t required_entropy_bits, typename Trng>
inline T random(Trng & rng)
{
STATIC_ASSERT(std::numeric_limits<T>::is_integer);
static_assert(std::numeric_limits<T>::is_integer);
typedef typename std::make_unsigned<T>::type unsigned_T;
const unsigned int rng_bits = mpt::engine_traits<Trng>::result_bits();
unsigned_T result = 0;
for(std::size_t entropy = 0; entropy < std::min<std::size_t>(required_entropy_bits, sizeof(T) * 8); entropy += rng_bits)
for(std::size_t entropy = 0; entropy < std::min(required_entropy_bits, sizeof(T) * 8); entropy += rng_bits)
{
MPT_CONSTANT_IF(rng_bits < (sizeof(T) * 8))
if constexpr(rng_bits < (sizeof(T) * 8))
{
MPT_CONSTEXPR11_VAR unsigned int shift_bits = rng_bits % (sizeof(T) * 8); // silence utterly stupid MSVC and GCC warnings about shifting by too big amount (in which case this branch is not even taken however)
constexpr unsigned int shift_bits = rng_bits % (sizeof(T) * 8); // silence utterly stupid MSVC and GCC warnings about shifting by too big amount (in which case this branch is not even taken however)
result = (result << shift_bits) ^ static_cast<unsigned_T>(rng());
} else
{
result = static_cast<unsigned_T>(rng());
}
}
MPT_CONSTANT_IF(required_entropy_bits >= (sizeof(T) * 8))
if constexpr(required_entropy_bits >= (sizeof(T) * 8))
{
return static_cast<T>(result);
} else
@ -159,15 +222,15 @@ inline T random(Trng & rng)
template <typename T, typename Trng>
inline T random(Trng & rng, std::size_t required_entropy_bits)
{
STATIC_ASSERT(std::numeric_limits<T>::is_integer);
static_assert(std::numeric_limits<T>::is_integer);
typedef typename std::make_unsigned<T>::type unsigned_T;
const unsigned int rng_bits = mpt::engine_traits<Trng>::result_bits();
unsigned_T result = 0;
for(std::size_t entropy = 0; entropy < std::min<std::size_t>(required_entropy_bits, sizeof(T) * 8); entropy += rng_bits)
for(std::size_t entropy = 0; entropy < std::min(required_entropy_bits, sizeof(T) * 8); entropy += rng_bits)
{
MPT_CONSTANT_IF(rng_bits < (sizeof(T) * 8))
if constexpr(rng_bits < (sizeof(T) * 8))
{
MPT_CONSTEXPR11_VAR unsigned int shift_bits = rng_bits % (sizeof(T) * 8); // silence utterly stupid MSVC and GCC warnings about shifting by too big amount (in which case this branch is not even taken however)
constexpr unsigned int shift_bits = rng_bits % (sizeof(T) * 8); // silence utterly stupid MSVC and GCC warnings about shifting by too big amount (in which case this branch is not even taken however)
result = (result << shift_bits) ^ static_cast<unsigned_T>(rng());
} else
{
@ -183,20 +246,6 @@ inline T random(Trng & rng, std::size_t required_entropy_bits)
}
}
template <typename Tf> struct float_traits { };
template <> struct float_traits<float> {
typedef uint32 mantissa_uint_type;
enum : int { mantissa_bits = 24 };
};
template <> struct float_traits<double> {
typedef uint64 mantissa_uint_type;
enum : int { mantissa_bits = 53 };
};
template <> struct float_traits<long double> {
typedef uint64 mantissa_uint_type;
enum : int { mantissa_bits = 63 };
};
template <typename T>
struct uniform_real_distribution
{
@ -213,9 +262,8 @@ public:
template <typename Trng>
inline T operator()(Trng & rng) const
{
typedef typename float_traits<T>::mantissa_uint_type uint_type;
const int bits = float_traits<T>::mantissa_bits;
return ((b - a) * static_cast<T>(mpt::random<uint_type, bits>(rng)) / static_cast<T>((static_cast<uint_type>(1u) << bits))) + a;
const int mantissa_bits = std::numeric_limits<T>::digits;
return ((b - a) * static_cast<T>(mpt::random<uint64, mantissa_bits>(rng)) / static_cast<T>((static_cast<uint64>(1u) << mantissa_bits))) + a;
}
};
@ -223,7 +271,7 @@ public:
template <typename T, typename Trng>
inline T random(Trng & rng, T min, T max)
{
STATIC_ASSERT(!std::numeric_limits<T>::is_integer);
static_assert(!std::numeric_limits<T>::is_integer);
typedef mpt::uniform_real_distribution<T> dis_type;
dis_type dis(min, max);
return static_cast<T>(dis(rng));
@ -265,12 +313,12 @@ public:
}
static MPT_CONSTEXPR11_FUN result_type max()
{
STATIC_ASSERT(((result_mask >> result_shift) << result_shift) == result_mask);
static_assert(((result_mask >> result_shift) << result_shift) == result_mask);
return static_cast<result_type>(result_mask >> result_shift);
}
static MPT_CONSTEXPR11_FUN int result_bits()
{
STATIC_ASSERT(((static_cast<Tstate>(1) << result_bits_) - 1) == (result_mask >> result_shift));
static_assert(((static_cast<Tstate>(1) << result_bits_) - 1) == (result_mask >> result_shift));
return result_bits_;
}
inline result_type operator()()
@ -292,6 +340,59 @@ typedef lcg<uint32, uint16, 0u, 214013u, 2531011u, 0x7fff0000u, 16, 15> lcg_msvc
typedef lcg<uint32, uint16, 0x80000000u, 1103515245u, 12345u, 0x7fff0000u, 16, 15> lcg_c99;
typedef lcg<uint64, uint32, 0ull, 6364136223846793005ull, 1ull, 0xffffffff00000000ull, 32, 32> lcg_musl;
template <typename Tstate, typename Tvalue, Tstate x1, Tstate x2, Tstate x3, Tstate x4, int rol1, int rol2>
class modplug
{
public:
typedef Tstate state_type;
typedef Tvalue result_type;
private:
state_type state1;
state_type state2;
public:
template <typename Trng>
explicit inline modplug(Trng &rd)
: state1(mpt::random<state_type>(rd))
, state2(mpt::random<state_type>(rd))
{
}
explicit inline modplug(state_type seed1, state_type seed2)
: state1(seed1)
, state2(seed2)
{
}
public:
static MPT_CONSTEXPR11_FUN result_type min()
{
return static_cast<result_type>(0);
}
static MPT_CONSTEXPR11_FUN result_type max()
{
return std::numeric_limits<result_type>::max();
}
static MPT_CONSTEXPR11_FUN int result_bits()
{
static_assert(std::is_integral<result_type>::value);
static_assert(std::is_unsigned<result_type>::value);
return std::numeric_limits<result_type>::digits;
}
inline result_type operator()()
{
state_type a = state1;
state_type b = state2;
a = mpt::rotl(a, rol1);
a ^= x1;
a += x2 + (b * x3);
b += mpt::rotl(a, rol2) * x4;
state1 = a;
state2 = b;
result_type result = static_cast<result_type>(b);
return result;
}
};
typedef modplug<uint32, uint32, 0x10204080u, 0x78649E7Du, 4, 5, 1, 16> modplug_dither;
} // namespace rng
@ -325,7 +426,7 @@ public:
{
return RAND_MAX;
}
static MPT_CONSTEXPR11_FUN int result_bits()
static MPT_CONSTEXPR14_FUN int result_bits()
{
return detail::lower_bound_entropy_bits(RAND_MAX);
}
@ -348,7 +449,7 @@ class sane_random_device
private:
mpt::mutex m;
std::string token;
std::random_device rd;
std::unique_ptr<std::random_device> prd;
bool rd_reliable;
std::unique_ptr<std::mt19937> rd_fallback;
public:
@ -410,7 +511,7 @@ template <> struct engine_traits<std::mt19937> {
static MPT_CONSTEXPR11_FUN int result_bits() { return rng_type::word_size; }
template<typename Trd> static inline rng_type make(Trd & rd)
{
std::unique_ptr<mpt::seed_seq_values<seed_bits / sizeof(unsigned int)>> values = mpt::make_unique<mpt::seed_seq_values<seed_bits / sizeof(unsigned int)>>(rd);
std::unique_ptr<mpt::seed_seq_values<seed_bits / sizeof(unsigned int)>> values = std::make_unique<mpt::seed_seq_values<seed_bits / sizeof(unsigned int)>>(rd);
std::seed_seq seed(values->begin(), values->end());
return rng_type(seed);
}
@ -423,7 +524,7 @@ template <> struct engine_traits<std::mt19937_64> {
static MPT_CONSTEXPR11_FUN int result_bits() { return rng_type::word_size; }
template<typename Trd> static inline rng_type make(Trd & rd)
{
std::unique_ptr<mpt::seed_seq_values<seed_bits / sizeof(unsigned int)>> values = mpt::make_unique<mpt::seed_seq_values<seed_bits / sizeof(unsigned int)>>(rd);
std::unique_ptr<mpt::seed_seq_values<seed_bits / sizeof(unsigned int)>> values = std::make_unique<mpt::seed_seq_values<seed_bits / sizeof(unsigned int)>>(rd);
std::seed_seq seed(values->begin(), values->end());
return rng_type(seed);
}
@ -534,7 +635,7 @@ public:
}
result_type operator()()
{
MPT_LOCK_GUARD<mpt::mutex> l(m);
mpt::lock_guard<mpt::mutex> l(m);
return mpt::random<unsigned int>(rng);
}
};
@ -609,7 +710,7 @@ public:
public:
typename engine_traits<Trng>::result_type operator()()
{
MPT_LOCK_GUARD<mpt::mutex> l(m);
mpt::lock_guard<mpt::mutex> l(m);
return Trng::operator()();
}
};

View file

@ -1,7 +1,7 @@
/*
* mptSpan.h
* ---------
* Purpose: Various useful utility functions.
* Purpose: C++20 span.
* Notes : (currently none)
* Authors: OpenMPT Devs
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
@ -15,8 +15,14 @@
#include "mptBaseTypes.h"
#if MPT_CXX_AT_LEAST(20)
#include <array>
#include <span>
#else // !C++20
#include <array>
#include <iterator>
#include <type_traits>
#endif // C++20
@ -29,6 +35,12 @@ namespace mpt {
#if MPT_CXX_AT_LEAST(20)
using std::span;
#else // !C++20
// Simplified version of gsl::span.
// Non-owning read-only or read-write view into a contiguous block of T
// objects, i.e. equivalent to a (beg,end) or (data,size) tuple.
@ -40,18 +52,18 @@ class span
public:
typedef std::size_t size_type;
using element_type = T;
using value_type = typename std::remove_cv<T>::type;
using index_type = std::size_t;
using pointer = T *;
using const_pointer = const T *;
using reference = T &;
using const_reference = const T &;
typedef T value_type;
typedef T & reference;
typedef T * pointer;
typedef const T * const_pointer;
typedef const T & const_reference;
using iterator = pointer;
using const_iterator = const_pointer;
typedef pointer iterator;
typedef const_pointer const_iterator;
typedef typename std::iterator_traits<iterator>::difference_type difference_type;
using difference_type = typename std::iterator_traits<iterator>::difference_type;
private:
@ -60,22 +72,26 @@ private:
public:
span() : m_beg(nullptr), m_end(nullptr) { }
span() noexcept : m_beg(nullptr), m_end(nullptr) { }
span(pointer beg, pointer end) : m_beg(beg), m_end(end) { }
span(pointer data, size_type size) : m_beg(data), m_end(data + size) { }
span(pointer data, index_type size) : m_beg(data), m_end(data + size) { }
template <typename U, std::size_t N> span(U (&arr)[N]) : m_beg(arr), m_end(arr + N) { }
template <std::size_t N> span(element_type (&arr)[N]) : m_beg(arr), m_end(arr + N) { }
template <typename Cont> span(Cont &cont) : m_beg(cont.empty() ? nullptr : &(cont[0])), m_end(cont.empty() ? nullptr : &(cont[0]) + cont.size()) { }
template <std::size_t N> span(std::array<value_type, N> &arr) : m_beg(arr.data()), m_end(arr.data() + arr.size()) { }
template <std::size_t N> span(const std::array<value_type, N> &arr) : m_beg(arr.data()), m_end(arr.data() + arr.size()) { }
template <typename Cont> span(Cont &cont) : m_beg(std::data(cont)), m_end(std::data(cont) + std::size(cont)) { }
span(const span &other) : m_beg(other.begin()), m_end(other.end()) { }
template <typename U> span(const span<U> &other) : m_beg(other.begin()), m_end(other.end()) { }
span & operator = (span other) { m_beg = other.begin(); m_end = other.end(); return *this; }
span & operator = (const span & other) noexcept = default;
iterator begin() const { return iterator(m_beg); }
iterator end() const { return iterator(m_end); }
@ -84,24 +100,26 @@ public:
operator bool () const noexcept { return m_beg != nullptr; }
reference operator[](size_type index) { return at(index); }
const_reference operator[](size_type index) const { return at(index); }
reference operator[](index_type index) { return at(index); }
const_reference operator[](index_type index) const { return at(index); }
bool operator==(span const & other) const noexcept { return size() == other.size() && (m_beg == other.m_beg || std::equal(begin(), end(), other.begin())); }
bool operator!=(span const & other) const noexcept { return !(*this == other); }
reference at(size_type index) { return m_beg[index]; }
const_reference at(size_type index) const { return m_beg[index]; }
reference at(index_type index) { return m_beg[index]; }
const_reference at(index_type index) const { return m_beg[index]; }
pointer data() const noexcept { return m_beg; }
bool empty() const noexcept { return size() == 0; }
size_type size() const noexcept { return static_cast<size_type>(std::distance(m_beg, m_end)); }
size_type length() const noexcept { return size(); }
index_type size() const noexcept { return static_cast<index_type>(std::distance(m_beg, m_end)); }
index_type length() const noexcept { return size(); }
}; // class span
#endif // C++20
template <typename T> inline span<T> as_span(T * beg, T * end) { return span<T>(beg, end); }
template <typename T> inline span<T> as_span(T * data, std::size_t size) { return span<T>(data, size); }

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