diff --git a/Makefile b/Makefile index 33b0d422a..0bdb35aa6 100644 --- a/Makefile +++ b/Makefile @@ -71,7 +71,7 @@ datadir=$(datarootdir) exec_prefix=$(prefix) bindir=$(exec_prefix)/bin -DATA_PATH=$(datadir)/attract/ +DATA_PATH:=$(datadir)/attract/ EXE_BASE=attract EXE_EXT= OBJ_DIR=obj @@ -363,7 +363,7 @@ EXPATOBJS = \ $(EXPAT_OBJ_DIR)/xmlrole.o \ $(EXPAT_OBJ_DIR)/xmltok.o -$(OBJ_DIR)/libexpat.a: $(EXPATOBJS) | $(OBJ_DIR) +$(OBJ_DIR)/libexpat.a: $(EXPATOBJS) | $(EXPAT_OBJ_DIR) $(AR) $(ARFLAGS) $@ $(EXPATOBJS) $(EXPAT_OBJ_DIR)/%.o: $(EXTLIBS_DIR)/expat/%.c | $(EXPAT_OBJ_DIR) diff --git a/src/fe_input.cpp b/src/fe_input.cpp index 4b383851b..89e1b060a 100644 --- a/src/fe_input.cpp +++ b/src/fe_input.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -208,7 +209,7 @@ FeInputSource::FeInputSource( const sf::Event &e, const sf::IntRect &mc_rect, co break; case sf::Event::JoystickMoved: - if ( abs( e.joystickMove.position ) > joy_thresh ) + if ( std::abs( e.joystickMove.position ) > joy_thresh ) { m_type = (Type)(Joystick0 + e.joystickMove.joystickId); diff --git a/src/fe_overlay.cpp b/src/fe_overlay.cpp index 77b77fe52..e74471edf 100644 --- a/src/fe_overlay.cpp +++ b/src/fe_overlay.cpp @@ -28,6 +28,7 @@ #include #include #include +#include class FeConfigContextImp : public FeConfigContext { @@ -1024,7 +1025,7 @@ bool FeOverlay::event_loop( FeEventLoopCtx &ctx ) float pos = sf::Joystick::getAxisPosition( ctx.move_event.joystickMove.joystickId, ctx.move_event.joystickMove.axis ); - if ( abs( pos ) > m_feSettings.get_joy_thresh() ) + if ( std::abs( pos ) > m_feSettings.get_joy_thresh() ) cont=true; } break; diff --git a/src/main.cpp b/src/main.cpp index 0060f9265..1c6217ff1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,6 +31,7 @@ #include "fe_vm.hpp" #include #include +#include #include #ifndef NO_MOVIE @@ -809,7 +810,7 @@ int main(int argc, char *argv[]) float pos = sf::Joystick::getAxisPosition( move_event.joystickMove.joystickId, move_event.joystickMove.axis ); - if ( abs( pos ) > feSettings.get_joy_thresh() ) + if ( std::abs( pos ) > feSettings.get_joy_thresh() ) cont=true; } break; diff --git a/util/create-windows-pkg.sh b/util/create-windows-pkg.sh index 91a644654..0971d780f 100755 --- a/util/create-windows-pkg.sh +++ b/util/create-windows-pkg.sh @@ -32,12 +32,12 @@ fi cp -r *.md *.txt config/* stage/ cp -r ../extras/* stage/ +# output changelog +util/output-changelog-md.sh $1 > stage/Changelog.md + # Unix to Windows line endings # -sed -i 's/$/\r/' `find stage/ -name '*.*' | grep -e .md -e .txt -e .cfg -e .nut -e .nutr -e .msg -e .frag` - -# special case due to space in name -sed -i 's/$/\r/' "stage/layouts/particle animation/layout.nut" +find stage -type f -regextype posix-egrep -regex '.*\.(md|txt|cfg|nut|nutr|msg|frag)$' -print0 | xargs -0 sed -i 's/$/\r/' # Build and zip 32-bit windows version # diff --git a/util/osx/DS_Store b/util/osx/DS_Store new file mode 100644 index 000000000..661d8e67f Binary files /dev/null and b/util/osx/DS_Store differ diff --git a/util/osx/Info.plist b/util/osx/Info.plist new file mode 100644 index 000000000..7aeb61466 --- /dev/null +++ b/util/osx/Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIconFile + attract.icns + CFBundleExecutable + launch.sh + CFBundleIdentifier + org.attractmode.attract + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Attract + CFBundleDisplayName + AttradeMode + CFBundleSpokenName + Attract Mode + CFBundlePackageType + APPL + CFBundleShortVersionString + %%SHORTVERSION%% + CFBundleSignature + ???? + CFBundleVersion + %%BUNDLEVERSION%% + + diff --git a/util/osx/VolumeIcon.icns b/util/osx/VolumeIcon.icns new file mode 100644 index 000000000..4bb156ba6 Binary files /dev/null and b/util/osx/VolumeIcon.icns differ diff --git a/util/osx/attract.icns b/util/osx/attract.icns new file mode 100644 index 000000000..887fc1ff3 Binary files /dev/null and b/util/osx/attract.icns differ diff --git a/util/osx/background.png b/util/osx/background.png new file mode 100644 index 000000000..19157d8dc Binary files /dev/null and b/util/osx/background.png differ diff --git a/util/osx/bundlelibs.py b/util/osx/bundlelibs.py new file mode 100755 index 000000000..adbfe4867 --- /dev/null +++ b/util/osx/bundlelibs.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# coding: utf-8 + +# Recursively change dynamic library link paths for non-system libraries +# to be relative to the linked program and copy them to /../libs +# +# TODO: parse individual architectures (necessary?) +# modify temp lib instead of assuming path changes work +# +# Gist: https://gist.github.com/h0tw1r3/b12752f8e33f70422fbe +# Copyright: © 2015 Jeffrey Clark +# License: GPLv3 (http://www.gnu.org/licenses/gpl-3.0.html) + +import os, stat, sys, subprocess, re, shutil + +toolchain = os.getenv('TOOLCHAIN') +if toolchain == None: + toolchain = "" +else: + toolchain += "-" +otool = toolchain + "otool" +install_name_tool = toolchain + "install_name_tool" + +def runOtool(filename): + p = subprocess.Popen([otool, '-XL', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + return iter(p.stdout.readline, b'') + +def fixname(filename, old, new): + p = subprocess.Popen([install_name_tool, '-change', old, new, filename], stdout=subprocess.PIPE) + p.communicate() + return + +def fixid(filename, newid): + p = subprocess.Popen([install_name_tool, '-id', '@loader_path/../libs/' + newid, filename], stdout=subprocess.PIPE) + p.communicate() + return + +def cmd_exists(cmd): + return subprocess.call("type " + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0 + +def mainloop(filename): + for line in runOtool(filename): + m = re.search('\s+/((usr|opt)/local/.*) \(.*\)$', line) + if m and len(m.group(1)) != 0: + path = os.path.realpath( os.path.join(os.getenv('LIB_BASE_PATH','/'),m.group(1)) ) + linkname = os.path.basename( path ) + if os.path.isfile( '../libs/' + linkname ) is False: + try: + shutil.copy2(path, '../libs/') + os.chmod('../libs/' + linkname, stat.S_IRWXU | stat.S_IRGRP | stat.S_IROTH ) + fixid('../libs/' + linkname, linkname) + mainloop('../libs/' + linkname) + except IOError as e: + print e + continue + fixname( filename, '/' + m.group(1), '@loader_path/../libs/' + linkname ) + else: + m = re.search('\s+(@rpath(.*)) \(.*\)$', line) + if m and len(m.group(2)) != 0: + path = os.path.realpath(os.path.join(os.getenv('LIB_BASE_PATH','/'), 'usr/local/lib', m.group(2))) + print path + linkname = os.path.basename(path) + fixname(filename, m.group(1), '@loader_path/../libs/' + linkname) + +if (len(sys.argv) != 2): + print "Usage: " + os.path.basename(sys.argv[0]) + " executable" + sys.exit(1) +if (not cmd_exists(otool)): + raise ValueError('Unable to execute otool: ' + otool) +if (not cmd_exists(install_name_tool)): + raise ValueError('Unable to execute install_name_tool: ' + install_name_tool) +if (not os.path.isfile(sys.argv[1])): + raise ValueError('File does not exist: ' + sys.argv[1]) +if (not os.access(sys.argv[1], os.W_OK)): + raise ValueError('Unable to write to file: ' + sys.argv[1]) + +mainloop(sys.argv[1]) diff --git a/util/osx/create-pkg.sh b/util/osx/create-pkg.sh new file mode 100755 index 000000000..fed11b006 --- /dev/null +++ b/util/osx/create-pkg.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash +# +# Copyright: © 2015 Jeffrey Clark +# License: GPLv3 (http://www.gnu.org/licenses/gpl-3.0.html) + +### begin: init +set -o pipefail +set -o errtrace + +error() { + echo "ERROR in $0 : line $1 exit code $2" + exit $2 +} +trap 'error ${LINENO} ${?}' ERR + +SCRIPT_PATH="${BASH_SOURCE[0]}"; +if ([ -h "${SCRIPT_PATH}" ]) then + while([ -h "${SCRIPT_PATH}" ]) do SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done +fi +pushd . > /dev/null +cd `dirname ${SCRIPT_PATH}` > /dev/null +SCRIPT_PATH=`pwd`; +cd .. +### end: init + +LASTTAG=$(git describe --tag --abbrev=0) +VERSION=$(git describe --tag | sed 's/-[^-]*$//') +REVCOUNT=$(git rev-list HEAD --count) +BUNDLEVERSION=${VERSION//[v-]/.}; BUNDLEVERSION=${BUNDLEVERSION#"."} +SHORTVERSION=${LASTTAG//v/} + +### begin: make +PLATFORM=$(uname) +MAKEOPTS="" + +# osxcross auto-detect +if [[ "$PLATFORM" != "Darwin" ]]; then + ! [ -x "$(command -v hfsplus)" ] && echo "FATAL: 'hfsplus' not found" && exit 1 + ! [ -x "$(command -v mkfs.hfsplus)" ] && echo "FATAL: 'mkfs.hfs' not found" && exit 1 + ! [ -x "$(command -v dmg)" ] && echo "FATAL: 'dmg' not found" && exit 1 + + if [[ -z ${OSXCROSS_TARGET_DIR} || -z ${OSXCROSS_TARGET} ]]; then + echo "osxcross not initialized. add osxcross-conf and osxcross-env to the current environment" && exit 1 + fi + + [[ -z ${TOOLCHAIN} ]] && export TOOLCHAIN=x86_64-apple-${OSXCROSS_TARGET} + [[ -z ${LIB_BASE_PATH} ]] && export LIB_BASE_PATH="$(realpath ${OSXCROSS_TARGET_DIR}/macports/pkgs)" + + MAKEOPTS="$MAKEOPTS CROSS=1 TOOLCHAIN=${TOOLCHAIN} FE_MACOSX_COMPILE=1 EXTRA_CFLAGS=\"-arch i386 -arch x86_64\"" +fi + +NPROC=$(getconf _NPROCESSORS_ONLN) +LLIMIT=$(awk 'BEGIN{printf"%.1f",'${NPROC}'/2}') + +make -C .. clean +eval make -C .. -j${NPROC} -l${LLIMIT} ${MAKEOPTS} DATA_PATH=../config/ $@ +### end: make + +function finish { + if [[ ! -z $SCRATCH && -d $SCRATCH ]] ; then + rm -rf "${SCRATCH}" + fi +} +trap finish EXIT + +SCRATCH=$(mktemp -d -t package.XXXXXXXX) +APPCONTENT="${SCRATCH}"/disk/Attract.app/Contents + +# Create bundle folder structure +mkdir -p "${APPCONTENT}"/{MacOS,Resources,libs} + +cp -r ../config "${APPCONTENT}"/ +[[ -d ../../extras ]] && cp -r ../../extras/* "${APPCONTENT}"/config/ +cp -a ../attract "${APPCONTENT}"/MacOS/ +cp -a "${SCRIPT_PATH}"/attract.icns "${APPCONTENT}"/Resources/ +cp -a "${SCRIPT_PATH}"/launch.sh "${APPCONTENT}"/MacOS/ + +# Documentation +mkdir "${SCRATCH}/disk/Documentation" +cp -a ../License.txt ${SCRATCH}/disk/Documentation/ +cp ../*.md "${SCRATCH}"/disk/Documentation/ +./output-changelog-md.sh ${LASTTAG} > "${SCRATCH}"/disk/Documentation/Changelog.md + +# convert markdown to html if possible +find "${SCRATCH}"/disk/Documentation/ -name '*.md' | while read f +do + fp="${X%.md}" + if ! [ -x "$(command -v pandoc)" ]; then + mv "${f}" "${fp}.txt" + else + pandoc -f markdown_github -t html5 "${f}" -o "${fp}.html" && rm "${f}" + fi +done + +cat "${SCRIPT_PATH}"/Info.plist | sed 's/%%SHORTVERSION%%/'${SHORTVERSION}'/' | sed 's/%%BUNDLEVERSION%%/'${BUNDLEVERSION}'/' > "${APPCONTENT}"/Info.plist + +cp osx/DS_Store "${SCRATCH}/disk/.DS_Store" +cp osx/VolumeIcon.icns "${SCRATCH}/disk/.VolumeIcon.icns" +mkdir "${SCRATCH}/disk/.background" +cp osx/background.png "${SCRATCH}/disk/.background/background.png" + +# Copy extra libs to bundle and fix link path +pushd "${APPCONTENT}"/MacOS >/dev/null +${SCRIPT_PATH}/bundlelibs.py attract +popd >/dev/null + +if [[ "$PLATFORM" != "Darwin" ]]; then + WORKDMG="${SCRATCH}/uncompressed.dmg" + dd if=/dev/zero of="${WORKDMG}" bs=1M count=128 + mkfs.hfsplus -v "AttractMode" "${WORKDMG}" + hfsplus "${WORKDMG}" addall "${SCRATCH}/disk/" + hfsplus "${WORKDMG}" attr / C + hfsplus "${WORKDMG}" symlink " " /Applications + # TODO: genisoimage has drawbacks, but most people dont have libdmg-hfsplus built + # make conditional package based on best available tools. + # genisoimage -D -V "AttractMode ${VERSION#v}" -no-pad -r -apple -o ${SCRATCH}/uncompressed.dmg ${SCRATCH}/disk/ + dmg dmg "${WORKDMG}" ../attract-${VERSION#v}.dmg +else + # TODO: mount dmg and set file attributes (volume icon) and create Application symlink + hdiutil create -volname "AttractMode" -srcfolder ${SCRATCH}/disk/ -ov -format UDBZ ../attract-${VERSION#v}.dmg +fi diff --git a/util/osx/launch.sh b/util/osx/launch.sh new file mode 100755 index 000000000..5762a1a55 --- /dev/null +++ b/util/osx/launch.sh @@ -0,0 +1,3 @@ +#!/bin/bash +cd "${0%/*}" +./attract diff --git a/util/output-changelog-md.sh b/util/output-changelog-md.sh new file mode 100755 index 000000000..b98a4fe4f --- /dev/null +++ b/util/output-changelog-md.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# +# Generate markdown format changelog +# from tag (default HEAD) to previous tag +# grouped by author +# +# Copyright: © 2015 Jeffrey Clark +# License: GPLv3 (http://www.gnu.org/licenses/gpl-3.0.html) + +# set cwd +SCRIPT_PATH="${BASH_SOURCE[0]}"; +if ([ -h "${SCRIPT_PATH}" ]) then + while([ -h "${SCRIPT_PATH}" ]) do SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done +fi +pushd . > /dev/null +cd `dirname ${SCRIPT_PATH}` > /dev/null +SCRIPT_PATH=`pwd`; +cd ${SCRIPT_PATH}/.. + +if [ $# -eq 0 ] ; then + TAG=$(git describe --tag) +else + ## Just for attractmode + if [[ $1 =~ ^v ]]; then + TAG=$1 + else + TAG=v$1 + fi +fi +PRETAG=$(git describe --tag --abbrev=0 ${TAG}^) + +IFS=$'\r\n' + +echo -e "# Changelog #" + +RANGE="${TAG}..HEAD" +i=0 +for author in $(git --no-pager log --no-merges --pretty=format:"%an" ${RANGE} | sort | uniq -c) ; +do + [ $i -eq 0 ] && echo -e "\n## Commits made after ${TAG} ##" + name=$(echo $author | sed 's/^\ *\([0-9]*\)\ \(.*\)$/\2/') + count=$(echo $author | sed 's/^\ *\([0-9]*\)\ \(.*\)$/\1/') + echo -e "\n### $name ($count commits)\n" + git --no-pager log --author="$name" --date=short --no-merges --pretty=format:"* %s" ${RANGE} | grep -v "(nw)\| NW\| nw" + (( i++ )) +done + +RANGE="${PRETAG}..${TAG}" + +echo -e "\n## Commits from ${PRETAG} to ${TAG}" + +for author in $(git --no-pager log --no-merges --pretty=format:"%an" ${RANGE} | sort | uniq -c) ; +do + name=$(echo $author | sed 's/^\ *\([0-9]*\)\ \(.*\)$/\2/') + count=$(echo $author | sed 's/^\ *\([0-9]*\)\ \(.*\)$/\1/') + echo -e "\n### $name ($count commits)\n" + git --no-pager log --author="$name" --date=short --no-merges --pretty=format:"* %s" ${RANGE} | grep -v "(nw)\| NW\| nw" +done