diff --git a/README b/README index b25fcc9c3..b332e1ae0 100644 --- a/README +++ b/README @@ -1,15 +1,15 @@ -The Powder Toy - May 2013 +The Powder Toy - June 2014 -Get the latest version here: http://powdertoy.co.uk/Download.html +Get the latest version here: http://powdertoy.co.uk/Download.html To use online features such as saving, you need to register at: http://powdertoy.co.uk/Register.html Have you ever wanted to blow something up? Or maybe you always dreamt of operating an atomic power plant? Do you have a will to develop your own CPU? The Powder Toy lets you to do all of these, and even more! -The Powder Toy is a free physics sandbox game, which simulates air pressure and velocity, heat, gravity and a countless number of interactions between different substances! The game provides you with various building materials, liquids, gases and electronic components which can be used to construct complex machines, guns, bombs, realistic terrains and almost anything else. You can then mine them and watch cool explosions, add intricate wirings, play with little stickmen or operate your machine. You can browse and play thousands of different saves made by the community or upload your own � we welcome your creations! +The Powder Toy is a free physics sandbox game, which simulates air pressure and velocity, heat, gravity and a countless number of interactions between different substances! The game provides you with various building materials, liquids, gases and electronic components which can be used to construct complex machines, guns, bombs, realistic terrains and almost anything else. You can then mine them and watch cool explosions, add intricate wirings, play with little stickmen or operate your machine. You can browse and play thousands of different saves made by the community or upload your own - we welcome your creations! -There is a Lua API � you can automate your work or even make plugins for the game. The Powder Toy is free and the source code is distributed under the GNU General Public License, so you can modify the game yourself or help with development. Tpt is compiled using scons. +There is a Lua API - you can automate your work or even make plugins for the game. The Powder Toy is free and the source code is distributed under the GNU General Public License, so you can modify the game yourself or help with development. TPT is compiled using scons. Thanks: @@ -42,48 +42,51 @@ Controls: --------------------------------------------------------------------------- -TAB Switch between circle/square/triangle brush -Space Pause -Q Quit -Esc Quit -Z Zoom -S Save stamp (+ Ctrl when STK2 is out) -L Load last saved stamp -K Stamp library -1-9 Set view mode -P Save screenshot to .png -F Pause and go to next frame -G Increase grid size -Shift + G Decrease grid size -H Show/Hide HUD -Ctrl + H Show intro text -F1 Show intro text -D Debug mode (+ Ctrl when STK2 is out) -I Invert Pressure and Velocity map -W Toggle gravity modes (+ Ctrl when STK2 is out) -Y Toggle air modes -Ctrl + B Toggle decorations on/off -U Toggle ambient heat on/off -Ctrl + I Install powder toy, for loading saves/stamps by double clicking -~ Console -= Reset pressure and velocity map -Ctrl + = Reset Electricity -[ Decrease brush size -] Increase brush size -Alt + [ Decrease brush size by 1 -Alt + ] Increase brush size by 1 +TAB Switch between circle/square/triangle brush +Space Pause +Q Quit +Esc Quit +Z Zoom +S Save stamp (+ Ctrl when STK2 is out) +L Load last saved stamp +K Stamp library +1-9 Set view mode +P / F2 Save screenshot to .png +E Bring up element search +F Pause and go to next frame +G Increase grid size +Shift + G Decrease grid size +H Show/Hide HUD +Ctrl + H / F1 Show intro text +D / F3 Debug mode (+ Ctrl when STK2 is out) +I Invert Pressure and Velocity map +W Toggle gravity modes (+ Ctrl when STK2 is out) +Y Toggle air modes +B Enter decoration editor menu +Ctrl + B Toggle decorations on/off +N Toggle Newtonian Gravity on/off +U Toggle ambient heat on/off +Ctrl + I Install powder toy, for loading saves/stamps by double clicking +~ Console += Reset pressure and velocity map +Ctrl + = Reset Electricity +[ Decrease brush size +] Increase brush size +Alt + [ Decrease brush size by 1 +Alt + ] Increase brush size by 1 -Ctrl + C/V/X Copy/Paste/Cut -Ctrl + Z Undo -Ctrl + Cursor drag Rectangle -Shift + Cursor drag Line -Middle click Sample element -Alt + Left click Sample element -Mouse scroll Change brush size -Ctrl + Mouse scroll Change vertical brush size -Shift + Mouse scroll Change horizontal brush size -Shift + Ctrl + R Horizontal mirror for selected area -Ctrl + R Rotate selected area counterclockwise +Ctrl + C/V/X Copy/Paste/Cut +Ctrl + Z Undo +Ctrl + Cursor drag Rectangle +Shift + Cursor drag Line +Middle click Sample element +Alt + Left click Sample element +Mouse scroll Change brush size +Ctrl + Mouse scroll Change vertical brush size +Shift + Mouse scroll Change horizontal brush size +Shift + R Horizontal mirror for selected area when pasting stamps +Ctrl + Shift + R Vertical mirror for selected area when pasting stamps +R Rotate selected area counterclockwise when pasting stamps Only the left Ctrl, Shift, and Alt buttons are enabled to work, not the ones on the right @@ -91,11 +94,10 @@ Only the left Ctrl, Shift, and Alt buttons are enabled to work, not the ones on Command Line: --------------------------------------------------------------------------- -scale:1 Normal window resolution -scale:2 Doubled window resolution -kiosk Fullscreen mode -proxy:server[:port] Proxy server to use [Example: proxy:wwwcache.lancs.ac.uk:8080] -open Opens the file as a stamp or game save -ddir Directory used for saving stamps and preferences -ptsave:# (ex. ptsave:2198#Destroyable_city_5_wth_metro~dima-gord) - +scale:1 Normal window resolution +scale:2 Doubled window resolution +kiosk Fullscreen mode +proxy:server[:port] Proxy server to use [Example: proxy:wwwcache.lancs.ac.uk:8080] +open Opens the file as a stamp or game save +ddir Directory used for saving stamps and preferences +ptsave:#[name] [Example: ptsave:2198#Destroyable_city_5_wth_metro~dima-gord] diff --git a/SConscript b/SConscript old mode 100755 new mode 100644 index d6cfecff0..fd08935c2 --- a/SConscript +++ b/SConscript @@ -1,538 +1,533 @@ -# ============ -# SCons script -# ============ - -# the purpose of this script is to run a build of tpt from start to finish, including dependency checks. - -# .. contents :: Table of Contents - -# ============ -# requirements -# ============ - -# stdlib -# ====== - -import os -import sys -import subprocess -import time - -# 3rd party -# ========= - -# nothing besides scons. - -# ================= -# long commandlines -# ================= - -# .. : Fix for long command line - http://scons.org/wiki/LongCmdLinesOnWin32 - -# because of an implementation detail commandlines are limited to 10000 characters on windows using mingw. the following fix was copied from -# http://scons.org/wiki/LongCmdLinesOnWin32 and circumvents this issue. - -class ourSpawn: - def ourspawn(self, sh, escape, cmd, args, env): - newargs = ' '.join(args[1:]) - cmdline = cmd + " " + newargs - startupinfo = subprocess.STARTUPINFO() - startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW - proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env) - data, err = proc.communicate() - rv = proc.wait() - if rv: - print "=====" - print err - print "=====" - return rv - -def SetupSpawn( env ): - if sys.platform == 'win32': - buf = ourSpawn() - buf.ourenv = env - env['SPAWN'] = buf.ourspawn - -# =================== -# commandline options -# =================== - -# the following defines all optional commandlines - -AddOption('--opengl',dest="opengl",action='store_true',default=False,help="Build with OpenGL interface support.") -AddOption('--opengl-renderer',dest="opengl-renderer",action='store_true',default=False,help="Build with OpenGL renderer support. (requires --opengl)") -AddOption('--renderer',dest="renderer",action='store_true',default=False,help="Save renderer") -AddOption('--64bit',dest="_64bit",action='store_true',default=False,help="64-bit platform target") -AddOption('--static',dest="static",action="store_true",default=False,help="Static linking, reduces external library dependancies but increased file size") -AddOption('--pthreadw32-static',dest="ptw32-static",action="store_true",default=False,help="Use PTW32_STATIC_LIB for pthreadw32 headers") -AddOption('--python-ver',dest="pythonver",default=False,help="Python version to use for generator.py") -AddOption('--release',dest="release",action='store_true',default=False,help="Enable optimisations (Will slow down compiling)") -AddOption('--lua-dir',dest="lua-dir",default=False,help="Directory for lua includes") -AddOption('--sdl-dir',dest="sdl-dir",default=False,help="Directory for SDL includes") -AddOption('--tool',dest="toolprefix",default=False,help="Prefix") -AddOption('--sse',dest="sse",action='store_true',default=False,help="Enable SSE optimisations") -AddOption('--sse2',dest="sse2",action='store_true',default=False,help="Enable SSE2 optimisations") -AddOption('--sse3',dest="sse3",action='store_true',default=False,help="Enable SSE3 optimisations") -AddOption('--x86',dest="x86",action='store_true',default=True,help="Target Intel x86 platform") -AddOption('--nofft',dest="nofft", action='store_true',default=False,help="Do not use fftw3f for gravity.") -AddOption('--nolua',dest="nolua", action='store_true',default=False,help="Disable all lua scripting features.") - -AddOption('--warnings-as-errors', dest="warnings_as_errors", action="store_true", default=False, help="Treat all warnings as errors") -AddOption('--debugging', dest="debug", action="store_true", default=False, help="Enable debug options") -AddOption('--beta',dest="beta",action='store_true',default=False,help="Beta build.") -AddOption('--save-version',dest="save-version",default=False,help="Save version.") -AddOption('--minor-version',dest="minor-version",default=False,help="Minor version.") -AddOption('--build-number',dest="build-number",default=False,help="Build number.") -AddOption('--snapshot',dest="snapshot",action='store_true',default=False,help="Snapshot build.") -AddOption('--snapshot-id',dest="snapshot-id",default=False,help="Snapshot build ID.") -AddOption('--stable',dest="stable",default=True,help="Non snapshot build") -AddOption('--aao', dest="everythingAtOnce", action='store_true', default=False, help="Compile the whole game without generating intermediate objects (very slow), enable this when using compilers like clang or mscc that don't support -fkeep-inline-functions") - -AddOption('--fullclean',dest="justwork",action='store_true',default=False,help="for when nothing else works. Deletes all sconscript temporary files.") -AddOption('--copy-env',dest="copy_env",action='store_true',default=False,help="copy some common enviroment variables from the parent enviroment.") - -# using one of these commandline options is compulsory - -AddOption('--win',dest="win",action='store_true',default=False,help="Windows platform target.") -AddOption('--lin',dest="lin",action='store_true',default=False,help="Linux platform target") -AddOption('--macosx',dest="macosx",action='store_true',default=False,help="Mac OS X platform target") -AddOption('--rpi',dest="rpi",action='store_true',default=False,help="Raspbain platform target") - -# ============ -# main program -# ============ - -# the gist of the compiling rules are defined here - - -if(GetOption("justwork")): - import shutil - try: - shutil.rmtree("../.sconf_temp/") - except: - print "couldn't remove .sconf_temp" - try: - os.remove("../.sconsign.dblite") - except: - print "couldn't remove .sconsign.dblite" - -# platform selection -# ================== - -# generic platform settings -# +++++++++++++++++++++++++ - -# check if a platform is specified. -# .. : TODO: make it suggest commandline options if it isn't - -if((not GetOption('lin')) and (not GetOption('win')) and (not GetOption('rpi')) and (not GetOption('macosx'))): - print "You must specify a platform to target" - raise SystemExit(1) - -# windows specific platform settings -# ++++++++++++++++++++++++++++++++++ - -# if the platform is windows switch to a mingw toolset, use the default otherwise - -if(GetOption('win')): - env = Environment(tools = ['mingw'], ENV = os.environ) -else: - env = Environment(tools = ['default'], ENV = os.environ) - -if(GetOption("copy_env")): - lstvar=["CC","CXX","LD","CFLAGS","LIBPATH"] - print "WARNING: enviroment copying enabled. changes in the enviroment can easily break the build process." - for var in lstvar: - if var in os.environ: - env[var]=os.environ[var] - print "WARNING: copying enviroment variable {}={!r}".format(var,os.environ[var]) - -# macosx specific platform settings -# +++++++++++++++++++++++++++++++++ - -# if we're not on MACOSX check for headers etc - -if not GetOption("macosx"): - conf = Configure(env) - -# if sdl-dir is set check if we can find the sdl header there, if we can't just pass the header path to the compiler. - - if(GetOption("sdl-dir")): - if not conf.CheckCHeader(GetOption("sdl-dir") + '/SDL.h'): - print "sdl headers not found or not installed" - raise SystemExit(1) - else: - env.Append(CPPPATH=[GetOption("sdl-dir")]) - else: - -# otherwise try to parse the pkg config for sdl and grab the correct flags from there. - - try: - env.ParseConfig('sdl-config --cflags') - env.ParseConfig('sdl-config --libs') - except: - if not conf.CheckLib("SDL"): - print "libSDL not found or not installed" - raise SystemExit(1) - - -# if lua is enabled try to parse the lua pgk-config, or the lua-dir option if given - - if not GetOption("nolua"): - if(GetOption("lua-dir")): - if not conf.CheckCHeader(GetOption("lua-dir") + '/lua.h'): - print "lua5.1 headers not found or not installed" - raise SystemExit(1) - else: - env.Append(CPPPATH=[GetOption("lua-dir")]) - try: - env.ParseConfig('pkg-config --cflags lua5.1') - env.ParseConfig('pkg-config --libs lua5.1') - except: - #Check for Lua lib - if not conf.CheckLib('lua5.1') and not conf.CheckLib('lua-5.1') and not conf.CheckLib('lua51') and not conf.CheckLib('lua'): - print "liblua5.1 not found or not installed" - raise SystemExit(1) - -# if fft is enabled try to parse its config, fail otherwise. - - if not GetOption('nofft'): - # Check for FFT lib - if not conf.CheckLib('fftw3f') and not conf.CheckLib('fftw3f-3'): - print "libfftw3f not found or not installed" - raise SystemExit(1) - -# try to autodetect some libraries, fail otherwise - - #Check for Bzip lib - if not conf.CheckLib('bz2'): - print "libbz2 not found or not installed" - raise SystemExit(1) - - #Check for zlib - if not conf.CheckLib('z'): - print "libz not found or not installed" - raise SystemExit(1) - - if not conf.CheckCHeader("bzlib.h"): - print "bzip2 headers not found" - raise SystemExit(1) - -# finish the configuration - - env = conf.Finish(); -else: - -# if we ARE on macosx add the libraries to LIBS -# .. : seems like we're terrible at mac support? what gives? - - env.Append(LIBS=['z', 'bz2']) - if not GetOption('nofft'): - env.Append(LIBS=['fftw3f']) - -# enviroment setup -# ================ - -# add the correct compiler flags. - -# generic enviroment settings -# +++++++++++++++++++++++++++ - -# check if a tool prefix is set, and if it is select the propper tools for building. -# .. : TODO someone explain wtf this actually does - -if GetOption("toolprefix"): - env['CC'] = GetOption("toolprefix")+env['CC'] - env['CXX'] = GetOption("toolprefix")+env['CXX'] - if GetOption('win'): - env['RC'] = GetOption("toolprefix")+env['RC'] - -# make sure the compiler can find the source data and generated files. enable warnings, set C++ flavor, and keep inline functions - -env.Append(CPPPATH=['src/', 'data/', 'generated/']) -env.Append(CXXFLAGS=['-std=c++98']) -env.Append(LIBS=['pthread', 'm']) -env.Append(CPPDEFINES=["_GNU_SOURCE", "USE_STDINT", "_POSIX_C_SOURCE=200112L"]) - -# set the warnings we want, treat all warnings as errors, and ignore all "offsetof" warnings - -env.Append(CCFLAGS=['-Wno-invalid-offsetof']); -if GetOption('warnings_as_errors'): - env.Append(CCFLAGS=['-Werror']); - -# check all enabled libs, and add a define if they are enabled. - -if not GetOption('nofft'): - env.Append(CPPDEFINES=["GRAVFFT"]) -if not GetOption('nolua'): - env.Append(CPPDEFINES=["LUACONSOLE"]) - -# check if we need to use PTW32_STATIC_LIB for pthreadw32 headers, won't compile statically without this - -if GetOption("ptw32-static"): - env.Append(CPPDEFINES=['PTW32_STATIC_LIB']); - -# check if we need to do static linking. - -if(GetOption('static')): - env.Append(LINKFLAGS=['-static-libgcc']) - -# check if we need to compile the save renderer. add a define accordingly. compile the game by default. - -if(GetOption('renderer')): - env.Append(CPPDEFINES=['RENDERER']) -else: - env.Append(CPPDEFINES=["USE_SDL"]) - -# apply optimisations if it's a release build - -if(GetOption('release')): - if GetOption('macosx'): - env.Append(CCFLAGS=['-O3', '-ftree-vectorize', '-funsafe-math-optimizations', '-ffast-math', '-fomit-frame-pointer']) - else: - env.Append(CCFLAGS=['-O3', '-ftree-vectorize', '-funsafe-math-optimizations', '-ffast-math', '-fomit-frame-pointer', '-funsafe-loop-optimizations']) - -# rpi specific enviroment settings -# ++++++++++++++++++++++++++++++++ - -# check if we're compiling for raspberry pi, if we are include rpi specific libraries and defines. - -if(GetOption('rpi')): - if(GetOption('opengl')): - env.ParseConfig('pkg-config --libs glew gl glu') - openGLLibs = ['GL'] - env.Append(LIBS=['X11', 'rt']) - env.Append(CPPDEFINES=["LIN"]) - - -# windows specific enviroment settings -# ++++++++++++++++++++++++++++++++++++ - -# check if we're compiling for windows, if we are include windows specific libraries and defines. - -if(GetOption('win')): - openGLLibs = ['opengl32', 'glew32'] - env.Prepend(LIBS=['mingw32', 'ws2_32', 'SDLmain', 'SDL']) - env.Append(CCFLAGS=['-std=gnu++98']) - env.Append(LIBS=['winmm', 'gdi32']) - env.Append(CPPDEFINES=["WIN"]) - env.Append(LINKFLAGS=['-mwindows']) - if(GetOption('_64bit')): - env.Append(CPPDEFINES=['__CRT__NO_INLINE']) - env.Append(LINKFLAGS=['-Wl,--stack=16777216']) - -# linux specific enviroment settings -# ++++++++++++++++++++++++++++++++++++ - -# check if we're compiling for linux, if we are include linux specific libraries and defines. - -if(GetOption('lin')): - if(GetOption('opengl')): - env.ParseConfig('pkg-config --libs glew gl glu') - openGLLibs = ['GL'] - env.Append(LIBS=['X11', 'rt']) - env.Append(CPPDEFINES=["LIN"]) - if GetOption('_64bit'): - env.Append(LINKFLAGS=['-m64']) - env.Append(CCFLAGS=['-m64']) - else: - env.Append(LINKFLAGS=['-m32']) - env.Append(CCFLAGS=['-m32']) - -# macosx specific enviroment settings -# ++++++++++++++++++++++++++++++++++++ - -# check if we're compiling for macosx, if we are include macosx specific libraries and defines. - -if(GetOption('macosx')): - env.Append(CPPDEFINES=["MACOSX"]) - env.Append(CCFLAGS=['-I/Library/Frameworks/SDL.framework/Headers']) - env.Append(CCFLAGS=['-I/Library/Frameworks/Lua.framework/Headers']) - if not GetOption('nofft'): - env.Append(LINKFLAGS=['-lfftw3f']) - env.Append(LINKFLAGS=['-framework']) - env.Append(LINKFLAGS=['SDL']) - env.Append(LINKFLAGS=['-framework']) - env.Append(LINKFLAGS=['Lua']) - env.Append(LINKFLAGS=['-framework']); - env.Append(LINKFLAGS=['Cocoa']) - #env.Append(LINKFLAGS=['-framework SDL']) - #env.Append(LINKFLAGS=['-framework Lua']) - #env.Append(LINKFLAGS=['-framework Cocoa']) - if GetOption('_64bit'): - env.Append(LINKFLAGS=['-m64']) - env.Append(CCFLAGS=['-m64']) - else: - env.Append(LINKFLAGS=['-m32']) - env.Append(CCFLAGS=['-m32']) - -# defines -# ======= - -# A lot of commandline flags translate directly into defines. those flags follow: - -if GetOption('_64bit'): - env.Append(CPPDEFINES=["_64BIT"]) - -if(GetOption('beta')): - env.Append(CPPDEFINES='BETA') - -if(not GetOption('snapshot') and not GetOption('beta') and not GetOption('release') and not GetOption('stable')): - env.Append(CPPDEFINES='SNAPSHOT_ID=0') - env.Append(CPPDEFINES='SNAPSHOT') -elif(GetOption('snapshot') or GetOption('snapshot-id')): - if(GetOption('snapshot-id')): - env.Append(CPPDEFINES=['SNAPSHOT_ID=' + GetOption('snapshot-id')]) - else: - env.Append(CPPDEFINES=['SNAPSHOT_ID=' + str(int(time.time()))]) - env.Append(CPPDEFINES='SNAPSHOT') -elif(GetOption('stable')): - env.Append(CPPDEFINES='STABLE') - -if(GetOption('save-version')): - env.Append(CPPDEFINES=['SAVE_VERSION=' + GetOption('save-version')]) - -if(GetOption('minor-version')): - env.Append(CPPDEFINES=['MINOR_VERSION=' + GetOption('minor-version')]) - -if(GetOption('build-number')): - env.Append(CPPDEFINES=['BUILD_NUM=' + GetOption('build-number')]) - -if(GetOption('x86')): - env.Append(CPPDEFINES='X86') - -if(GetOption('debug')): - env.Append(CPPDEFINES='DEBUG') - env.Append(CCFLAGS='-g') - -if(GetOption('sse')): - env.Append(CCFLAGS='-msse') - env.Append(CPPDEFINES='X86_SSE') - -if(GetOption('sse2')): - env.Append(CCFLAGS='-msse2') - env.Append(CPPDEFINES='X86_SSE2') - -if(GetOption('sse3')): - env.Append(CCFLAGS='-msse3') - env.Append(CPPDEFINES='X86_SSE3') - -if(GetOption('opengl')): - env.Append(CPPDEFINES=["OGLI", "PIX32OGL"]) - env.Append(LIBS=openGLLibs) - -if(GetOption('opengl') and GetOption('opengl-renderer')): - env.Append(CPPDEFINES=["OGLR"]) -elif(GetOption('opengl-renderer')): - print "opengl-renderer requires opengl" - raise SystemExit(1) - -# compiling -# ========= - -# sources -# +++++++ - -# find all source files - -# generic sources -# --------------- -sources=Glob("src/*.cpp") - -sources+=Glob("src/*/*.cpp") -sources+=Glob("src/*/*/*.cpp") -if not GetOption('nolua'): - sources+=Glob("src/socket/*.c") - -# windows specific sources -# ------------------------ - -if(GetOption('win')): - sources += env.RES('resources/powder-res.rc') - sources = filter(lambda source: not 'src\\simulation\\Gravity.cpp' in str(source), sources) - sources = filter(lambda source: not 'src/simulation/Gravity.cpp' in str(source), sources) - -# macosx specific sources -# ----------------------- - -if(GetOption('macosx')): - sources +=["SDLMain.m"] - -# apply `long commandlines`_ fix -# ============================== - -# apply the commandline fix - -SetupSpawn(env) - -# find proper executable name -# =========================== - -# use some settings to detect what name to use for the executable - -programName = "powder" - -if(GetOption('renderer')): - programName = "render" - -if(GetOption('win')): - if(GetOption('renderer')): - programName = "Render" - else: - programName = "Powder" - -if(GetOption('_64bit')): - programName += "64" - -if(not (GetOption('sse2') or GetOption('sse3'))): - programName += "-legacy" - -if(GetOption('macosx')): - programName += "-x" - -if(GetOption('win')): - programName += ".exe" - - -# detect python executable name -# ============================= - -# detect the executable name for python so we can run some generator scripts - -if(GetOption('pythonver')): - pythonVer = GetOption('pythonver') -elif(GetOption('lin')): - pythonVer = "python2" -else: - pythonVer = "python" - -# Extra compiler flag to fix stack alignment -# When Windows creates the gravity calculation thread, it has 4 byte stack alignment -# But we need 16 byte alignment so that SSE instructions in FFTW work without crashing -if(GetOption('win')): - envCopy = env.Clone() - envCopy.Append(CCFLAGS=['-mstackrealign']) - #envCopy.Append(CCFLAGS=['-mincoming-stack-boundary=2']) - sources+=envCopy.Object('src/simulation/Gravity.cpp') - -# run generator commands -# ====================== - -env.Command(['generated/ElementClasses.cpp', 'generated/ElementClasses.h'], Glob('src/simulation/elements/*.cpp'), pythonVer + " generator.py elements $TARGETS $SOURCES") -sources+=Glob("generated/ElementClasses.cpp") - -env.Command(['generated/ToolClasses.cpp', 'generated/ToolClasses.h'], Glob('src/simulation/simtools/*.cpp'), pythonVer + " generator.py tools $TARGETS $SOURCES") -sources+=Glob("generated/ToolClasses.cpp") - -# final settings -# ============== - -# make a MD5 checksum decide wether or not a file changed. we had some problems with using the modification date for this purpose. - -env.Decider('MD5') - -# set a default target - -t=env.Program(target=programName, source=sources) -Default(t) + +import os +import subprocess +import sys +import platform +import atexit +import time +import SCons.Util + + +# because of an implementation detail commandlines are limited to 10000 characters on windows using mingw. the following fix was copied from +# http://scons.org/wiki/LongCmdLinesOnWin32 and circumvents this issue. +class ourSpawn: + def ourspawn(self, sh, escape, cmd, args, env): + newargs = ' '.join(args[1:]) + cmdline = cmd + " " + newargs + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env) + data, err = proc.communicate() + rv = proc.wait() + if rv: + print "=====" + print err + print "=====" + return rv +def SetupSpawn(env): + buf = ourSpawn() + buf.ourenv = env + env['SPAWN'] = buf.ourspawn + +def FatalError(message): + print(message) + raise SystemExit(1) + +#wrapper around SCons' AddOption +def AddSconsOption(name, default, hasArgs, help): + AddOption("--{0}".format(name), dest=name, action=("store" if hasArgs else "store_true"), default=default, help=help) + +AddSconsOption('win', False, False, "Target Windows.") +AddSconsOption('lin', False, False, "Target Linux.") +AddSconsOption('mac', False, False, "Target Mac OS X.") +AddSconsOption('msvc', False, False, "Use the Microsoft Visual Studio compiler.") +AddSconsOption("tool", False, True, "Tool prefix appended before gcc/g++.") + +AddSconsOption('beta', False, False, "Beta build.") +AddSconsOption('save-version', False, True, "Save version.") +AddSconsOption('minor-version', False, True, "Minor version.") +AddSconsOption('build-number', False, True, "Build number.") +AddSconsOption('snapshot', False, False, "Snapshot build.") +AddSconsOption('snapshot-id', False, True, "Snapshot build ID.") + +AddSconsOption('64bit', False, False, "Compile a 64 bit binary.") +AddSconsOption('32bit', False, False, "Compile a 32 bit binary.") +AddSconsOption("universal", False, False, "compile universal binaries on Mac OS X.") +AddSconsOption('no-sse', False, False, "Disable SSE optimizations.") +AddSconsOption('sse', True, False, "Enable SSE optimizations (default).") +AddSconsOption('sse2', True, False, "Enable SSE2 optimizations (default).") +AddSconsOption('sse3', False, False, "Enable SSE3 optimizations.") +AddSconsOption('native', False, False, "Enable optimizations specific to your cpu.") +AddSconsOption('release', True, False, "Enable loop / compiling optimizations (default).") + +AddSconsOption('debugging', False, False, "Compile with debug symbols.") +AddSconsOption('static', False, False, "Compile statically.") +AddSconsOption('opengl', False, False, "Build with OpenGL interface support.") +AddSconsOption('opengl-renderer', False, False, "Build with OpenGL renderer support (turns on --opengl).") #Note: this has nothing to do with --renderer, only tells the game to render particles with opengl +AddSconsOption('renderer', False, False, "Build the save renderer.") + +AddSconsOption('wall', False, False, "Error on all warnings.") +AddSconsOption('no-warnings', True, False, "Disable all compiler warnings (default).") +AddSconsOption('nolua', False, False, "Disable Lua.") +AddSconsOption('nofft', False, False, "Disable FFT.") +AddSconsOption("output", False, True, "Executable output name.") + + +#detect platform automatically, but it can be overrided +tool = GetOption('tool') +isX86 = platform.machine() in ["AMD64", "i386", "i686", "x86", "x86_64"] +platform = compilePlatform = platform.system() +if GetOption('win'): + platform = "Windows" +elif GetOption('lin'): + platform = "Linux" +elif GetOption('mac'): + platform = "Darwin" +elif compilePlatform not in ["Linux", "Windows", "Darwin"]: + FatalError("Unknown platform: {0}".format(platform)) + +msvc = GetOption('msvc') +if msvc and platform != "Windows": + FatalError("Error: --msvc only works on windows") + +#Create SCons Environment +if platform == "Windows" and not GetOption('msvc'): + env = Environment(tools = ['mingw'], ENV = {'PATH' : os.environ['PATH']}) +else: + env = Environment(tools = ['default'], ENV = {'PATH' : os.environ['PATH']}) + +#attempt to automatically find cross compiler +if not tool and compilePlatform == "Linux" and compilePlatform != platform: + if platform == "Darwin": + crossList = ["i686-apple-darwin9", "i686-apple-darwin10"] + elif not GetOption('64bit'): + crossList = ["mingw32", "i386-mingw32msvc", "i486-mingw32msvc", "i586-mingw32msvc", "i686-mingw32msvc"] + else: + crossList = ["x86_64-w64-mingw32", "i686-w64-mingw32", "amd64-mingw32msvc"] + for i in crossList: + if WhereIs("{0}-g++".format(i)): + env['ENV']['PATH'] = "/usr/{0}/bin:{1}".format(i, os.environ['PATH']) + tool = i+"-" + break + if not tool: + print("Could not automatically find cross compiler, use --tool to specify manually") + +#set tool prefix +#more things may to be set (http://clam-project.org/clam/trunk/CLAM/scons/sconstools/crossmingw.py), but this works for us +if tool: + env['CC'] = tool+env['CC'] + env['CXX'] = tool+env['CXX'] + if platform == "Windows": + env['RC'] = tool+env['RC'] + env['STRIP'] = tool+'strip' + +#copy environment variables because scons doesn't do this by default +for var in ["CC","CXX","LD","LIBPATH"]: + if var in os.environ: + env[var] = os.environ[var] + print "copying enviroment variable {0}={1!r}".format(var,os.environ[var]) +# variables containing several space separated things +for var in ["CFLAGS","CCFLAGS","CXXFLAGS","LINKFLAGS","CPPDEFINES","CPPPATH"]: + if var in os.environ: + if var in env: + env[var] += SCons.Util.CLVar(os.environ[var]) + else: + env[var] = SCons.Util.CLVar(os.environ[var]) + print "copying enviroment variable {0}={1!r}".format(var,os.environ[var]) + +#Used for intro text / executable name, actual bit flags are only set if the --64bit/--32bit command line args are given +def add32bitflags(env): + env["BIT"] = 32 +def add64bitflags(env): + if platform == "Windows": + env.Append(CPPDEFINES=['__CRT__NO_INLINE']) + env.Append(LINKFLAGS=['-Wl,--stack=16777216']) + env.Append(CPPDEFINES=['_64BIT']) + env["BIT"] = 64 +#add 32/64 bit defines before configuration +if GetOption('64bit'): + env.Append(LINKFLAGS=['-m64']) + env.Append(CCFLAGS=['-m64']) + add64bitflags(env) +elif GetOption('32bit'): + env.Append(LINKFLAGS=['-m32']) + env.Append(CCFLAGS=['-m32']) + add32bitflags(env) + +if GetOption('universal'): + if platform != "Darwin": + FatalError("Error: --universal only works on Mac OS X") + else: + env.Append(CCFLAGS=['-arch', 'i386', '-arch', 'x86_64']) + env.Append(LINKFLAGS=['-arch', 'i386', '-arch', 'x86_64']) + +env.Append(CPPPATH=['src/', 'data/', 'generated/']) +if GetOption("msvc"): + if GetOption("static"): + env.Append(LIBPATH=['StaticLibs/']) + else: + env.Append(LIBPATH=['Libraries/']) + +#Check 32/64 bit +def CheckBit(context): + context.Message('Checking if 64 bit... ') + program = """#include + #include + int main() { + printf("%d", (int)sizeof(size_t)); + return 0; + } + """ + ret = context.TryCompile(program, '.c') + if ret == 0: + return False + ret = context.TryRun(program, '.c') + if ret[1] == '': + return False + context.Result(int(ret[1]) == 8) + if int(ret[1]) == 8: + print("Adding 64 bit compile flags") + add64bitflags(context.env) + elif int(ret[1]) == 4: + print("Adding 32 bit compile flags") + add32bitflags(context.env) + return ret[1] + +#Custom function to check for Mac OS X frameworks +def CheckFramework(context, framework): + import SCons.Conftest + #Extreme hack, TODO: maybe think of a better one (like replicating CheckLib here) or at least just fix the message + ret = SCons.Conftest.CheckLib(context, ['m" -framework {0}"'.format(framework)], autoadd = 0) + context.did_show_result = 1 + if not ret: + context.env.Append(LINKFLAGS=["-framework", framework]) + if framework != "Cocoa": + env.Append(CPPPATH=['/Library/Frameworks/{0}.framework/Headers/'.format(framework)]) + return not ret + +#function that finds libraries and appends them to LIBS +def findLibs(env, conf): + #Windows specific libs + if platform == "Windows": + if msvc: + libChecks = ['shell32', 'wsock32', 'user32', 'Advapi32'] + if GetOption('static'): + libChecks += ['msvcrt', 'dxguid'] + for i in libChecks: + if not conf.CheckLib(i): + FatalError("Error: some windows libraries not found or not installed, make sure your compiler is set up correctly") + else: + if not conf.CheckLib('mingw32') or not conf.CheckLib('ws2_32'): + FatalError("Error: some windows libraries not found or not installed, make sure your compiler is set up correctly") + + if not conf.CheckLib('SDLmain'): + FatalError("libSDLmain not found or not installed") + + if platform == "Darwin": + if not conf.CheckFramework("SDL"): + FatalError("SDL framework not found or not installed") + elif not GetOption('renderer'): + if platform != "Darwin": + #Look for SDL + if not conf.CheckLib("SDL"): + FatalError("SDL development library not found or not installed") + if platform == "Linux" or compilePlatform == "Linux": + try: + env.ParseConfig('sdl-config --cflags') + env.ParseConfig('sdl-config --libs') + except: + pass + + #look for SDL.h + if not GetOption('renderer') and not conf.CheckCHeader('SDL.h'): + if conf.CheckCHeader('SDL/SDL.h'): + env.Append(CPPDEFINES=["SDL_INC"]) + else: + FatalError("SDL.h not found") + + if not GetOption('nolua') and not GetOption('renderer'): + #Look for Lua + luaver = "lua5.1" + if not conf.CheckLib(['lua5.1', 'lua-5.1', 'lua51', 'lua']): + if conf.CheckLib(['lua5.2', 'lua-5.2', 'lua52']): + env.Append(CPPDEFINES=["LUA_COMPAT_ALL"]) + luaver = "lua5.2" + elif platform != "Darwin" or not conf.CheckFramework("Lua"): + FatalError("lua5.1 development library not found or not installed") + if platform == "Linux": + try: + env.ParseConfig("pkg-config --cflags {0}".format(luaver)) + env.ParseConfig("pkg-config --libs {0}".format(luaver)) + except: + pass + + #Look for lua.h + if not conf.CheckCHeader('lua.h'): + if conf.CheckCHeader('lua5.1/lua.h'): + env.Append(CPPDEFINES=["LUA_INC"]) + else: + FatalError("lua.h not found") + + #Look for fftw + if not GetOption('nofft') and not conf.CheckLib(['fftw3f', 'fftw3f-3', 'libfftw3f-3']): + FatalError("fftw3f development library not found or not installed") + + #Look for bz2 + if not conf.CheckLib(['bz2', 'libbz2']): + FatalError("bz2 development library not found or not installed") + + #Check bz2 header too for some reason + if not conf.CheckCHeader('bzlib.h'): + FatalError("bzip2 headers not found") + + #Look for libz + if not conf.CheckLib('z'): + FatalError("libz not found or not installed") + + #Look for pthreads + if not conf.CheckLib(['pthread', 'pthreadVC2']): + FatalError("pthreads development library not found or not installed") + + if msvc: + if not conf.CheckHeader('dirent.h') or not conf.CheckHeader('fftw3.h') or not conf.CheckHeader('pthread.h') or not conf.CheckHeader('zlib.h'): + FatalError("Required headers not found") + else: + #Look for libm + if not conf.CheckLib('m'): + FatalError("libm not found or not installed") + + #Look for OpenGL libraries + if GetOption('opengl'): + if platform == "Linux": + if not conf.CheckLib('GL'): + FatalError("libGL not found or not installed") + try: + env.ParseConfig('pkg-config --libs glew gl glu') + except: + FatalError(sys.exc_info()[0]) + + elif platform == "Windows": + if not conf.CheckLib('opengl32'): + FatalError("opengl32 not found or not installed") + if not conf.CheckLib('glew32'): + FatalError("glew32 not found or not installed") + elif platform == "Darwin": + if not conf.CheckFramework("OpenGL"): + FatalError("OpenGL framework not found or not installed") + + if platform == "Linux": + if not conf.CheckLib('X11'): + FatalError("X11 development library not found or not installed") + + if not conf.CheckLib('rt'): + FatalError("librt not found or not installed") + elif platform == "Windows": + #These need to go last + if not conf.CheckLib('gdi32') or not conf.CheckLib('winmm') or (not msvc and not conf.CheckLib('dxguid')): + FatalError("Error: some windows libraries not found or not installed, make sure your compiler is set up correctly") + elif platform == "Darwin": + if not conf.CheckFramework("Cocoa"): + FatalError("Cocoa framework not found or not installed") + +if GetOption('clean'): + import shutil + try: + shutil.rmtree("generated/") + except: + print "couldn't remove build/generated/" +elif not GetOption('help'): + conf = Configure(env) + conf.AddTest('CheckFramework', CheckFramework) + conf.AddTest('CheckBit', CheckBit) + if not conf.CheckCC() or not conf.CheckCXX(): + FatalError("compiler not correctly configured") + if platform == compilePlatform and isX86 and not GetOption('32bit') and not GetOption('64bit'): + conf.CheckBit() + findLibs(env, conf) + env = conf.Finish() + +if not msvc: + if platform == "Windows": + env.Append(CCFLAGS=['-std=gnu++98']) + else: + env.Append(CXXFLAGS=['-std=c++98']) + env.Append(CXXFLAGS=['-Wno-invalid-offsetof']) + + +#Add platform specific flags and defines +if platform == "Windows": + env.Append(CPPDEFINES=["WIN", "_WIN32_WINNT=0x0501"]) + if msvc: + env.Append(CCFLAGS=['/Gm', '/Zi', '/EHsc']) #enable minimal rebuild, enable exceptions + env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS', '/OPT:REF', '/OPT:ICF']) + if GetOption('static'): + env.Append(CCFLAGS=['/GL']) #whole program optimization (linker may freeze indefinitely without this) + env.Append(LINKFLAGS=['/NODEFAULTLIB:LIBCMT.lib', '/LTCG']) + else: + env.Append(LINKFLAGS=['/NODEFAULTLIB:msvcrt.lib']) + else: + env.Append(LINKFLAGS=['-mwindows']) +elif platform == "Linux": + env.Append(CPPDEFINES=['LIN']) +elif platform == "Darwin": + env.Append(CPPDEFINES=['MACOSX']) + #env.Append(LINKFLAGS=['-headerpad_max_install_names']) #needed in some cross compiles + + +#Add architecture flags and defines +if isX86: + env.Append(CPPDEFINES='X86') +if not GetOption('no-sse'): + if GetOption('sse'): + if msvc: + env.Append(CCFLAGS=['/arch:SSE']) + else: + env.Append(CCFLAGS=['-msse']) + env.Append(CPPDEFINES=['X86_SSE']) + if GetOption('sse2'): + if msvc: + env.Append(CCFLAGS=['/arch:SSE2']) + else: + env.Append(CCFLAGS=['-msse2']) + env.Append(CPPDEFINES=['X86_SSE2']) + if GetOption('sse3'): + if msvc: + env.Append(CCFLAGS=['/arch:SSE3']) + else: + env.Append(CCFLAGS=['-msse3']) + env.Append(CPPDEFINES=['X86_SSE3']) +if GetOption('native') and not msvc: + env.Append(CCFLAGS=['-march=native']) + + +#Add optimization flags and defines +if GetOption('debugging'): + if msvc: + env.Append(CCFLAGS=['/Od']) + if GetOption('static'): + env.Append(CCFLAGS=['/MTd']) + else: + env.Append(CCFLAGS=['/MDd']) + else: + env.Append(CCFLAGS=['-Wall', '-g']) +elif GetOption('release'): + if msvc: + env.Append(CCFLAGS=['/O2', '/fp:fast']) + if GetOption('static'): + env.Append(CCFLAGS=['/MT']) + else: + env.Append(CCFLAGS=['/MD']) + else: + env.Append(CCFLAGS=['-O3', '-ftree-vectorize', '-funsafe-math-optimizations', '-ffast-math', '-fomit-frame-pointer']) + if platform != "Darwin": + env.Append(CCFLAGS=['-funsafe-loop-optimizations']) + +if GetOption('static'): + if not msvc: + env.Append(CCFLAGS=['-static-libgcc']) + env.Append(LINKFLAGS=['-static-libgcc']) + if platform == "Windows": + env.Append(CPPDEFINES=['PTW32_STATIC_LIB']) + if not msvc: + env.Append(LINKFLAGS=['-Wl,-Bstatic']) + + +#Add other flags and defines +if not GetOption('nofft'): + env.Append(CPPDEFINES=['GRAVFFT']) +if not GetOption('nolua') and not GetOption('renderer'): + env.Append(CPPDEFINES=['LUACONSOLE']) + +if GetOption('opengl') or GetOption('opengl-renderer'): + env.Append(CPPDEFINES=['OGLI', 'PIX32OGL']) + if GetOption('opengl-renderer'): + env.Append(CPPDEFINES=['OGLR']) + +if GetOption('renderer'): + env.Append(CPPDEFINES=['RENDERER']) +else: + env.Append(CPPDEFINES=['USE_SDL']) + +if GetOption("wall"): + if msvc: + env.Append(CCFLAGS=['/WX']) + else: + env.Append(CCFLAGS=['-Werror']) +elif GetOption("no-warnings"): + if msvc: + env.Append(CCFLAGS=['/W0']) + else: + env.Append(CCFLAGS=['-w']) + + +#Add version defines +if GetOption('save-version'): + env.Append(CPPDEFINES=["SAVE_VERSION={0}".format(GetOption('save-version'))]) + +if GetOption('minor-version'): + env.Append(CPPDEFINES=["MINOR_VERSION={0}".format(GetOption('minor-version'))]) + +if GetOption('build-number'): + env.Append(CPPDEFINES=["BUILD_NUM={0}".format(GetOption('build-number'))]) + +if GetOption('snapshot-id'): + env.Append(CPPDEFINES=["SNAPSHOT", "SNAPSHOT_ID={0}".format(GetOption('snapshot-id'))]) +elif GetOption('snapshot'): + env.Append(CPPDEFINES=["SNAPSHOT", "SNAPSHOT_ID={0}".format(str(int(time.time())))]) + +if GetOption('beta'): + env.Append(CPPDEFINES=['BETA']) + + +#Generate list of sources to compile +sources = Glob("src/*.cpp") + Glob("src/*/*.cpp") + Glob("src/*/*/*.cpp") + Glob("generated/*.cpp") +if not GetOption('nolua') and not GetOption('renderer'): + sources += Glob("src/lua/socket/*.c") + Glob("src/lua/LuaCompat.c") + +if platform == "Windows" and not msvc: + sources += env.RES('resources/powder-res.rc') + sources = filter(lambda source: not 'src\\simulation\\Gravity.cpp' in str(source), sources) + sources = filter(lambda source: not 'src/simulation/Gravity.cpp' in str(source), sources) + envCopy = env.Clone() + envCopy.Append(CCFLAGS='-mstackrealign') + sources += envCopy.Object('src/simulation/Gravity.cpp') +elif platform == "Darwin": + sources += ["src/SDLMain.m"] + + +#Program output name +if GetOption('output'): + programName = GetOption('output') +else: + programName = GetOption('renderer') and "render" or "powder" + if "BIT" in env and env["BIT"] == 64: + programName += "64" + if isX86 and GetOption('no-sse'): + programName += "-legacy" + if platform == "Windows": + programName = programName.capitalize() + programName += ".exe" + elif platform == "Darwin": + programName += "-x" + +#strip binary after compilation +def strip(): + global programName + global env + try: + os.system("{0} {1}/{2}".format(env['STRIP'] if 'STRIP' in env else "strip", GetOption('builddir'), programName)) + except: + print("Couldn't strip binary") +if not GetOption('debugging') and not GetOption('clean') and not GetOption('help') and not msvc: + atexit.register(strip) + +#Long command line fix for mingw on windows +if compilePlatform == "Windows" and not msvc: + SetupSpawn(env) + +#Once we get here, finally compile +env.Decider('MD5-timestamp') +SetOption('implicit_cache', 1) +t = env.Program(target=programName, source=sources) +Default(t) diff --git a/SConstruct b/SConstruct index 81456fde4..56255fbb8 100644 --- a/SConstruct +++ b/SConstruct @@ -1,2 +1,22 @@ +#run generator.py +if not GetOption('clean'): + execfile("generator.py") + AddOption('--builddir',dest="builddir",default="build",help="Directory to build to.") SConscript('SConscript', variant_dir=GetOption('builddir'), duplicate=0) +if GetOption('clean'): + import os, shutil + try: + shutil.rmtree(".sconf_temp/") + except: + print "couldn't remove .sconf_temp/" + + try: + shutil.rmtree("generated/") + except: + print "couldn't remove generated/" + + try: + os.remove(".sconsign.dblite") + except: + print "couldn't remove .sconsign.dblite" diff --git a/docs/.py.html b/docs/.py.html deleted file mode 100644 index e69de29bb..000000000 diff --git a/docs/SConscript.html b/docs/SConscript.html deleted file mode 100644 index 60b2372c8..000000000 --- a/docs/SConscript.html +++ /dev/null @@ -1,701 +0,0 @@ - - - - - - - - - - -
- - - -
-

requirements

-
-

stdlib

-
-import os
-import sys
-import subprocess
-import time
-
-
-
-

3rd party

-

nothing besides scons.

-
-
-
-

long commandlines

- -

because of an implementation detail commandlines are limited to 10000 characters on windows using mingw. the following fix was copied from -http://scons.org/wiki/LongCmdLinesOnWin32 and circumvents this issue.

-
-class ourSpawn:
-        def ourspawn(self, sh, escape, cmd, args, env):
-                newargs = ' '.join(args[1:])
-                cmdline = cmd + " " + newargs
-                startupinfo = subprocess.STARTUPINFO()
-                startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
-                proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
-                        stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env)
-                data, err = proc.communicate()
-                rv = proc.wait()
-                if rv:
-                        print "====="
-                        print err
-                        print "====="
-                return rv
-
-def SetupSpawn( env ):
-        if sys.platform == 'win32':
-                buf = ourSpawn()
-                buf.ourenv = env
-                env['SPAWN'] = buf.ourspawn
-
-
-
-

commandline options

-

the following defines all optional commandlines

-
-AddOption('--opengl',dest="opengl",action='store_true',default=False,help="Build with OpenGL interface support.")
-AddOption('--opengl-renderer',dest="opengl-renderer",action='store_true',default=False,help="Build with OpenGL renderer support. (requires --opengl)")
-AddOption('--renderer',dest="renderer",action='store_true',default=False,help="Save renderer")
-AddOption('--macosx',dest="macosx",action='store_true',default=False,help="Mac OS X platform target")
-AddOption('--rpi',dest="rpi",action='store_true',default=False,help="Raspbain platform target")
-AddOption('--64bit',dest="_64bit",action='store_true',default=False,help="64-bit platform target")
-AddOption('--static',dest="static",action="store_true",default=False,help="Static linking, reduces external library dependancies but increased file size")
-AddOption('--pthreadw32-static',dest="ptw32-static",action="store_true",default=False,help="Use PTW32_STATIC_LIB for pthreadw32 headers")
-AddOption('--python-ver',dest="pythonver",default=False,help="Python version to use for generator.py")
-AddOption('--release',dest="release",action='store_true',default=False,help="Enable optimisations (Will slow down compiling)")
-AddOption('--lua-dir',dest="lua-dir",default=False,help="Directory for lua includes")
-AddOption('--sdl-dir',dest="sdl-dir",default=False,help="Directory for SDL includes")
-AddOption('--tool',dest="toolprefix",default=False,help="Prefix")
-AddOption('--sse',dest="sse",action='store_true',default=False,help="Enable SSE optimisations")
-AddOption('--sse2',dest="sse2",action='store_true',default=False,help="Enable SSE2 optimisations")
-AddOption('--sse3',dest="sse3",action='store_true',default=False,help="Enable SSE3 optimisations")
-AddOption('--x86',dest="x86",action='store_true',default=True,help="Target Intel x86 platform")
-AddOption('--nofft',dest="nofft", action='store_true',default=False,help="Do not use fftw3f for gravity.")
-AddOption('--nolua',dest="nolua", action='store_true',default=False,help="Disable all lua scripting features.")
-
-AddOption('--debugging', dest="debug", action="store_true", default=False, help="Enable debug options")
-AddOption('--beta',dest="beta",action='store_true',default=False,help="Beta build.")
-AddOption('--save-version',dest="save-version",default=False,help="Save version.")
-AddOption('--minor-version',dest="minor-version",default=False,help="Minor version.")
-AddOption('--build-number',dest="build-number",default=False,help="Build number.")
-AddOption('--snapshot',dest="snapshot",action='store_true',default=False,help="Snapshot build.")
-AddOption('--snapshot-id',dest="snapshot-id",default=False,help="Snapshot build ID.")
-AddOption('--stable',dest="stable",default=True,help="Non snapshot build")
-AddOption('--aao', dest="everythingAtOnce", action='store_true', default=False, help="Compile the whole game without generating intermediate objects (very slow), enable this when using compilers like clang or mscc that don't support -fkeep-inline-functions")
-
-

using either of these commandline options is compulsory

-
-AddOption('--win',dest="win",action='store_true',default=False,help="Windows platform target.")
-AddOption('--lin',dest="lin",action='store_true',default=False,help="Linux platform target")
-
-
-
-

main program

-

the gist of the compiling rules are defined here

-
-

platform selection

-
-

generic platform settings

-

check if a platform is specified. -.. : TODO: make it suggest commandline options if it isn't

-
-if((not GetOption('lin')) and (not GetOption('win')) and (not GetOption('rpi')) and (not GetOption('macosx'))):
-        print "You must specify a platform to target"
-        raise SystemExit(1)
-
-

check if a tool prefix is set, and if it is select the propper tools for building. -.. : TODO someone explain wtf this actually does

-
-if GetOption("toolprefix"):
-        env['CC'] = GetOption("toolprefix")+env['CC']
-        env['CXX'] = GetOption("toolprefix")+env['CXX']
-        if GetOption('win'):
-                env['RC'] = GetOption("toolprefix")+env['RC']
-
-
-
-

windows specific platform settings

-

if the platform is windows switch to a mingw toolset, use the default otherwise

-
-if(GetOption('win')):
-        env = Environment(tools = ['mingw'], ENV = os.environ)
-else:
-        env = Environment(tools = ['default'], ENV = os.environ)
-
-
-
-

macosx specific platform settings

-

if we're not on MACOSX check for headers etc

-
-if not GetOption("macosx"):
-        conf = Configure(env)
-
-

if sdl-dir is set check if we can find the sdl header there, if we can't just pass the header path to the compiler.

-
-if(GetOption("sdl-dir")):
-        if not conf.CheckCHeader(GetOption("sdl-dir") + '/SDL.h'):
-                print "sdl headers not found or not installed"
-                raise SystemExit(1)
-        else:
-                env.Append(CPPPATH=[GetOption("sdl-dir")])
-else:
-
-

otherwise try to parse the pkg config for sdl and grab the correct flags from there.

-
-try:
-        env.ParseConfig('sdl-config --cflags')
-        env.ParseConfig('sdl-config --libs')
-except:
-        if not conf.CheckLib("SDL"):
-                print "libSDL not found or not installed"
-                raise SystemExit(1)
-
-

if lua is enabled try to parse the lua pgk-config, if that fails try the lua-dir option -.. : TODO: make this look the same as the SDL check, maybe make a function for it. keep it DRY.

-
-if not GetOption("nolua"):
-        try:
-                env.ParseConfig('pkg-config --cflags lua5.1')
-        except:
-                if(GetOption("lua-dir")):
-                        if not conf.CheckCHeader(GetOption("lua-dir") + '/lua.h'):
-                                print "lua5.1 headers not found or not installed"
-                                raise SystemExit(1)
-                        else:
-                                env.Append(CPPPATH=[GetOption("lua-dir")])
-
-

if fft is enabled try to parse its config, fail otherwise.

-
-if not GetOption('nofft'):
-        # Check for FFT lib
-        if not conf.CheckLib('fftw3f') and not conf.CheckLib('fftw3f-3'):
-                print "libfftw3f not found or not installed"
-                raise SystemExit(1)
-
-

try to autodetect some libraries, fail otherwise

-
-#Check for Bzip lib
-if not conf.CheckLib('bz2'):
-        print "libbz2 not found or not installed"
-        raise SystemExit(1)
-
-#Check for zlib
-if not conf.CheckLib('z'):
-        print "libz not found or not installed"
-        raise SystemExit(1)
-
-if not conf.CheckCHeader("bzlib.h"):
-        print "bzip2 headers not found"
-        raise SystemExit(1)
-
- -
-#Check for Lua lib
-if not GetOption("macosx") and not GetOption("nolua"):
-        if not conf.CheckLib('lua5.1') and not conf.CheckLib('lua-5.1') and not conf.CheckLib('lua51') and not conf.CheckLib('lua'):
-                print "liblua not found or not installed"
-                raise SystemExit(1)
-
-

finish the configuration

-
-        env = conf.Finish();
-else:
-
-

if we ARE on macosx add the libraries to LIBS -.. : seems like we're terrible at mac support? what gives?

-
-env.Append(LIBS=['z', 'bz2'])
-if not GetOption('nofft'):
-        env.Append(LIBS=['fftw3f'])
-
-
-
-
-

enviroment setup

-

add the correct compiler flags.

-
-

generic enviroment settings

-

make sure the compiler can find the source data and generated files. enable warnings, set C++ flavor, and keep inline functions

-
-env.Append(CPPPATH=['src/', 'data/', 'generated/'])
-env.Append(CCFLAGS=['-w', '-std=c++98', '-fkeep-inline-functions'])
-env.Append(LIBS=['pthread', 'm'])
-env.Append(CPPDEFINES=["_GNU_SOURCE", "USE_STDINT", "_POSIX_C_SOURCE=200112L"])
-
-

check all enabled libs, and add a define if they are enabled.

-
-if not GetOption('nofft'):
-        env.Append(CPPDEFINES=["GRAVFFT"])
-if not GetOption('nolua'):
-        env.Append(CPPDEFINES=["LUACONSOLE"])
-
-

check if we need to use PTW32_STATIC_LIB for pthreadw32 headers -.. : TODO: explain this so it actually means something :P

-
-if GetOption("ptw32-static"):
-        env.Append(CPPDEFINES=['PTW32_STATIC_LIB']);
-
-

check if we need to do static linking.

-
-if(GetOption('static')):
-        env.Append(LINKFLAGS=['-static-libgcc'])
-
-

check if we need to compile the save renderer. add a define accordingly. compile the game by default.

-
-if(GetOption('renderer')):
-        env.Append(CPPDEFINES=['RENDERER'])
-else:
-        env.Append(CPPDEFINES=["USE_SDL"])
-
-

apply optimisations if it's a release build

-
-if(GetOption('release')):
-        if GetOption('macosx'):
-                env.Append(CCFLAGS=['-O3', '-ftree-vectorize', '-funsafe-math-optimizations', '-ffast-math', '-fomit-frame-pointer'])
-        else:
-                env.Append(CCFLAGS=['-O3', '-ftree-vectorize', '-funsafe-math-optimizations', '-ffast-math', '-fomit-frame-pointer', '-funsafe-loop-optimizations', '-Wunsafe-loop-optimizations'])
-
-
-
-

rpi specific enviroment settings

-

check if we're compiling for rpi, if we are include rpi specific libraries and defines.

-
-if(GetOption('rpi')):
-        if(GetOption('opengl')):
-                env.ParseConfig('pkg-config --libs glew gl glu')
-        openGLLibs = ['GL']
-        env.Append(LIBS=['X11', 'rt'])
-        env.Append(CPPDEFINES=["LIN"])
-
-
-
-

windows specific enviroment settings

-

check if we're compiling for windows, if we are include windows specific libraries and defines.

-
-if(GetOption('win')):
-        openGLLibs = ['opengl32', 'glew32']
-        env.Prepend(LIBS=['mingw32', 'ws2_32', 'SDLmain', 'regex'])
-        env.Append(CCFLAGS=['-std=gnu++98'])
-        env.Append(LIBS=['winmm', 'gdi32'])
-        env.Append(CPPDEFINES=["WIN"])
-        env.Append(LINKFLAGS=['-mwindows'])
-        if(GetOption('_64bit')):
-                env.Append(CPPDEFINES=['__CRT__NO_INLINE'])
-                env.Append(LINKFLAGS=['-Wl,--stack=16777216'])
-
-
-
-

linux specific enviroment settings

-

check if we're compiling for linux, if we are include linux specific libraries and defines.

-
-if(GetOption('lin')):
-        if(GetOption('opengl')):
-                env.ParseConfig('pkg-config --libs glew gl glu')
-        openGLLibs = ['GL']
-        env.Append(LIBS=['X11', 'rt'])
-        env.Append(CPPDEFINES=["LIN"])
-        if GetOption('_64bit'):
-                env.Append(LINKFLAGS=['-m64'])
-                env.Append(CCFLAGS=['-m64'])
-        else:
-                env.Append(LINKFLAGS=['-m32'])
-                env.Append(CCFLAGS=['-m32'])
-
-
-
-

macosx specific enviroment settings

-

check if we're compiling for macosx, if we are include macosx specific libraries and defines.

-
-if(GetOption('macosx')):
-        env.Append(CPPDEFINES=["MACOSX"])
-        env.Append(CCFLAGS=['-I/Library/Frameworks/SDL.framework/Headers'])
-        env.Append(CCFLAGS=['-I/Library/Frameworks/Lua.framework/Headers'])
-        if not GetOption('nofft'):
-                env.Append(LINKFLAGS=['-lfftw3f'])
-        env.Append(LINKFLAGS=['-framework'])
-        env.Append(LINKFLAGS=['SDL'])
-        env.Append(LINKFLAGS=['-framework'])
-        env.Append(LINKFLAGS=['Lua'])
-        env.Append(LINKFLAGS=['-framework']);
-        env.Append(LINKFLAGS=['Cocoa'])
-        #env.Append(LINKFLAGS=['-framework SDL'])
-        #env.Append(LINKFLAGS=['-framework Lua'])
-        #env.Append(LINKFLAGS=['-framework Cocoa'])
-        if GetOption('_64bit'):
-                env.Append(LINKFLAGS=['-m64'])
-                env.Append(CCFLAGS=['-m64'])
-        else:
-                env.Append(LINKFLAGS=['-m32'])
-                env.Append(CCFLAGS=['-m32'])
-
-
-
-
-

defines

-

A lot of commandline flags translate directly into defines. those flags follow:

-
-if GetOption('_64bit'):
-        env.Append(CPPDEFINES=["_64BIT"])
-
-if(GetOption('beta')):
-        env.Append(CPPDEFINES='BETA')
-
-if(not GetOption('snapshot') and not GetOption('beta') and not GetOption('release') and not GetOption('stable')):
-        env.Append(CPPDEFINES='SNAPSHOT_ID=0')
-        env.Append(CPPDEFINES='SNAPSHOT')
-elif(GetOption('snapshot') or GetOption('snapshot-id')):
-        if(GetOption('snapshot-id')):
-                env.Append(CPPDEFINES=['SNAPSHOT_ID=' + GetOption('snapshot-id')])
-        else:
-                env.Append(CPPDEFINES=['SNAPSHOT_ID=' + str(int(time.time()))])
-        env.Append(CPPDEFINES='SNAPSHOT')
-elif(GetOption('stable')):
-        env.Append(CPPDEFINES='STABLE')
-
-if(GetOption('save-version')):
-        env.Append(CPPDEFINES=['SAVE_VERSION=' + GetOption('save-version')])
-
-if(GetOption('minor-version')):
-        env.Append(CPPDEFINES=['MINOR_VERSION=' + GetOption('minor-version')])
-
-if(GetOption('build-number')):
-        env.Append(CPPDEFINES=['BUILD_NUM=' + GetOption('build-number')])
-
-if(GetOption('x86')):
-        env.Append(CPPDEFINES='X86')
-
-if(GetOption('debug')):
-        env.Append(CPPDEFINES='DEBUG')
-        env.Append(CCFLAGS='-g')
-
-if(GetOption('sse')):
-        env.Append(CCFLAGS='-msse')
-        env.Append(CPPDEFINES='X86_SSE')
-
-if(GetOption('sse2')):
-        env.Append(CCFLAGS='-msse2')
-        env.Append(CPPDEFINES='X86_SSE2')
-
-if(GetOption('sse3')):
-        env.Append(CCFLAGS='-msse3')
-        env.Append(CPPDEFINES='X86_SSE3')
-
-if(GetOption('opengl')):
-        env.Append(CPPDEFINES=["OGLI", "PIX32OGL"])
-        env.Append(LIBS=openGLLibs)
-
-if(GetOption('opengl') and GetOption('opengl-renderer')):
-        env.Append(CPPDEFINES=["OGLR"])
-elif(GetOption('opengl-renderer')):
-        print "opengl-renderer requires opengl"
-        raise SystemExit(1)
-
-
-
-

compiling

-
-

sources

-

find all source files

-
-# generic sources
-# ---------------
-sources=Glob("src/*.cpp")
-
-sources+=Glob("src/*/*.cpp")
-sources+=Glob("src/gui/*/*.cpp")
-sources+=Glob("src/simulation/elements/*.cpp")
-sources+=Glob("src/simulation/tools/*.cpp")
-sources+=Glob("src/client/requestbroker/*.cpp")
-if not GetOption('nolua'):
-        sources+=Glob("src/socket/*.c")
-
-
-

windows specific sources

-
-if(GetOption('win')):
-    sources += env.RES('resources/powder-res.rc')
-        sources = filter(lambda source: not 'src\\simulation\\Gravity.cpp' in str(source), sources)
-        sources = filter(lambda source: not 'src/simulation/Gravity.cpp' in str(source), sources)
-
-
-
-

macosx specific sources

-
-if(GetOption('macosx')):
-        sources +=["SDLMain.m"]
-
-
-
-
-
-

apply long commandlines fix

-

apply the commandline fix

-
-SetupSpawn(env)
-
-
-
-

find proper executable name

-

use some settings to detect what name to use for the executable

-
-programName = "powder"
-
-if(GetOption('renderer')):
-        programName = "render"
-
-if(GetOption('win')):
-        if(GetOption('renderer')):
-                programName = "Render"
-        else:
-                programName = "Powder"
-
-if(GetOption('_64bit')):
-        programName += "64"
-
-if(not (GetOption('sse2') or GetOption('sse3'))):
-        programName += "-legacy"
-
-if(GetOption('macosx')):
-        programName += "-x"
-
-if(GetOption('win')):
-        programName += ".exe"
-
-
-
-

detect python executable name

-

detect the executable name for python so we can run some generator scripts

-
-if(GetOption('pythonver')):
-        pythonVer = GetOption('pythonver')
-elif(GetOption('lin')):
-        pythonVer = "python2"
-else:
-        pythonVer = "python"
-
- -
-
-

run generator commands

-
-env.Command(['generated/ElementClasses.cpp', 'generated/ElementClasses.h'], Glob('src/simulation/elements/*.cpp'), pythonVer + " generator.py elements $TARGETS $SOURCES")
-sources+=Glob("generated/ElementClasses.cpp")
-
-env.Command(['generated/ToolClasses.cpp', 'generated/ToolClasses.h'], Glob('src/simulation/tools/*.cpp'), pythonVer + " generator.py tools $TARGETS $SOURCES")
-sources+=Glob("generated/ToolClasses.cpp")
-
-
-
-

final settings

-

make a MD5 checksum decide wether or not a file changed. we had some problems with using the modification date for this purpose.

-
-env.Decider('MD5')
-
-

set a default target

-
-t=env.Program(target=programName, source=sources)
-Default(t)
-
-
-
-
- - diff --git a/docs/gendocs.sh.html b/docs/gendocs.sh.html deleted file mode 100644 index 6998e1525..000000000 --- a/docs/gendocs.sh.html +++ /dev/null @@ -1,217 +0,0 @@ - - - - - - - - - - -
- - - -
-

Documentation generator

-

the purpose of this script is to generate html documentation from the source code of specified files.

-
-
-

requirements

-

this script requires pylit to be installed and the rst2html command to be available

-
-
-

pre generation

-

make sure the script terminates on errors

-
-set -e
-
-

skip pregeneration if we get any commandline parameters

-
-if [ $# == 0 ]
-then
-
-

list of files to generate documentation for. the format is always:

-
-"$0 filename language"
-
-

the following languages are available: -- c -- c++ -- css -- python -- shell -- slang -- latex

-
-$0 SConscript python
-$0 gendocs.sh shell
-
-

exit program after running all the generation steps

-
-    exit
-fi
-
-
-
-

generation

-

inform the user of which file we're processing

-
-echo "--- generating docs for $1"
-
-

run pylit to convert source code to restructured text

-
-pylit $1 --language $2 $1.txt
-
-

run rst2html to convert restructured text to html

-
-rst2html.py $1.txt --stylesheet docs/style.css > docs/$1.html
-
-

clean up the restructured text file

-
-rm $1.txt
-
-
-
- - diff --git a/docs/style.css b/docs/style.css deleted file mode 100644 index 5e21628f1..000000000 --- a/docs/style.css +++ /dev/null @@ -1,137 +0,0 @@ -/* -:Authors: Ian Bicking, Michael Foord -:Contact: fuzzyman@voidspace.org.uk -:Date: 2005/08/26 -:Version: 0.1.0 -:Copyright: This stylesheet has been placed in the public domain. - -Stylesheet for Docutils. -Based on ``blue_box.css`` by Ian Bicking -and ``html4css1.css`` revision 1.46. -*/ - -@import url(file:///usr/local/lib/python2.7/dist-packages/docutils/writers/html4css1/html4css1.css); - -body { - font-family: Arial, sans-serif; -} - -em, i { - /* Typically serif fonts have much nicer italics */ - font-family: Times New Roman, Times, serif; -} - -a.target { - color: blue; -} - -a.target { - color: blue; -} - -a.toc-backref { - text-decoration: none; - color: black; -} - -a.toc-backref:hover { - background-color: inherit; -} - -a:hover { - background-color: #cccccc; -} - -div.attention, div.caution, div.danger, div.error, div.hint, -div.important, div.note, div.tip, div.warning { - background-color: #cccccc; - padding: 3px; - width: 80%; -} - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - text-align: center; - background-color: #999999; - display: block; - margin: 0; -} - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title { - color: #cc0000; - font-family: sans-serif; - text-align: center; - background-color: #999999; - display: block; - margin: 0; -} - -h1, h2, h3, h4, h5, h6 { - font-family: Helvetica, Arial, sans-serif; - border: thin solid black; - /* This makes the borders rounded on Mozilla, which pleases me */ - -moz-border-radius: 8px; - padding: 4px; -} - -h1 { - background-color: #444499; - color: #ffffff; - border: medium solid black; -} - -h1 a.toc-backref, h2 a.toc-backref { - color: #ffffff; -} - -h2 { - background-color: #666666; - color: #ffffff; - border: medium solid black; -} - -h3, h4, h5, h6 { - background-color: #cccccc; - color: #000000; -} - -h3 a.toc-backref, h4 a.toc-backref, h5 a.toc-backref, -h6 a.toc-backref { - color: #000000; -} - -h1.title { - text-align: center; - background-color: #444499; - color: #eeeeee; - border: thick solid black; - -moz-border-radius: 20px; -} - -table.footnote { - padding-left: 0.5ex; -} - -table.citation { - padding-left: 0.5ex -} - -pre.literal-block, pre.doctest-block { - border: thin black solid; - padding: 5px; -} - -.image img { border-style : solid; - border-width : 2px; -} - -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { - font-size: 100%; -} - -code, tt { - color: #000066; -} diff --git a/gendocs.sh b/gendocs.sh deleted file mode 100755 index 996596c32..000000000 --- a/gendocs.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash - -# Documentation generator -# ======================= - -# the purpose of this script is to generate html documentation from the source code of specified files. - -# requirements -# ============ - -# this script requires pylit to be installed and the rst2html command to be available - -# pre generation -# ============== - -# make sure the script terminates on errors - -set -e - -# skip pregeneration if we get any commandline parameters - -if [ $# == 0 ] -then - -# list of files to generate documentation for. the format is always:: - -# "$0 filename language" - -# the following languages are available: -# - c -# - c++ -# - css -# - python -# - shell -# - slang -# - latex - - $0 SConscript python - $0 gendocs.sh shell - -# exit program after running all the generation steps - - exit -fi - -# generation -# ========== - -# inform the user of which file we're processing - -echo "--- generating docs for $1" - -# run pylit to convert source code to restructured text - -pylit $1 --language $2 $1.txt - -# run rst2html to convert restructured text to html - -rst2html.py $1.txt --stylesheet docs/style.css > docs/$1.html - -# clean up the restructured text file - -rm $1.txt diff --git a/generator.py b/generator.py index db60a6be7..a5df4863e 100644 --- a/generator.py +++ b/generator.py @@ -223,11 +223,5 @@ std::vector GetTools() f.write(toolContent) f.close() -if(len(sys.argv) > 3): - if(sys.argv[1] == "elements"): - generateElements(sys.argv[4:], sys.argv[2], sys.argv[3]) - elif(sys.argv[1] == "tools"): - generateTools(sys.argv[4:], sys.argv[2], sys.argv[3]) -else: - generateElements(os.listdir("src/simulation/elements"), "generated/ElementClasses.cpp", "generated/ElementClasses.h") - generateTools(os.listdir("src/simulation/simtools"), "generated/ToolClasses.cpp", "generated/ToolClasses.h") +generateElements(os.listdir("src/simulation/elements"), "generated/ElementClasses.cpp", "generated/ElementClasses.h") +generateTools(os.listdir("src/simulation/simtools"), "generated/ToolClasses.cpp", "generated/ToolClasses.h") diff --git a/src/Config.h b/src/Config.h index 1346dc2ac..239d1be33 100644 --- a/src/Config.h +++ b/src/Config.h @@ -12,7 +12,7 @@ //VersionInfoStart #ifndef SAVE_VERSION -#define SAVE_VERSION 89 +#define SAVE_VERSION 90 #endif #ifndef MINOR_VERSION @@ -20,26 +20,17 @@ #endif #ifndef BUILD_NUM -#define BUILD_NUM 283 +#define BUILD_NUM 322 #endif #ifndef SNAPSHOT_ID #define SNAPSHOT_ID 0 #endif - -#ifndef STABLE -#ifndef BETA -#define BETA -#define SNAPSHOT -#endif -#endif //VersionInfoEnd //#define IGNORE_UPDATES //uncomment this for mods, to not get any update notifications -#if defined(DEBUG) || defined(RENDERER) || defined(X86_SSE2) #define HIGH_QUALITY_RESAMPLE //High quality image resampling, slower but much higher quality than my terribad linear interpolation -#endif #if defined(SNAPSHOT) #define IDENT_RELTYPE "S" @@ -130,6 +121,7 @@ #define CELL 4 #define ISTP (CELL/2) #define CFDS (4.0f/CELL) +#define SIM_MAXVELOCITY 1e4f //Air constants #define AIR_TSTEPP 0.3f @@ -181,6 +173,12 @@ #define TPT_INLINE inline #endif +#if defined(WIN) && defined(__GNUC__) +#define TH_ENTRY_POINT __attribute__((force_align_arg_pointer)) +#else +#define TH_ENTRY_POINT +#endif + #define SDEUT //#define REALHEAT diff --git a/src/PowderToySDL.cpp b/src/PowderToySDL.cpp index 88a680168..da28b10bf 100644 --- a/src/PowderToySDL.cpp +++ b/src/PowderToySDL.cpp @@ -3,10 +3,13 @@ #include #include #include +#ifdef SDL_INC +#include "SDL/SDL.h" +#else #include "SDL.h" +#endif #ifdef WIN #define _WIN32_WINNT 0x0501 //Necessary for some macros and functions, tells windows.h to include functions only available in Windows XP or later -#include "SDL_syswm.h" #include #endif #include @@ -49,9 +52,13 @@ extern "C" { using namespace std; -#if defined(USE_SDL) && defined(LIN) +#if defined(WIN) || defined(LIN) +#ifdef SDL_INC +#include +#else #include #endif +#endif #if defined(USE_SDL) && defined(LIN) && defined(SDL_VIDEO_DRIVER_X11) SDL_SysWMinfo sdl_wminfo; Atom XA_CLIPBOARD, XA_TARGETS, XA_UTF8_STRING; @@ -93,7 +100,7 @@ void ClipboardPush(std::string text) XFlush(sdl_wminfo.info.x11.display); sdl_wminfo.info.x11.unlock_func(); #else - printf("Not implemented: put text on clipboard \"%s\"\n", text); + printf("Not implemented: put text on clipboard \"%s\"\n", text.c_str()); #endif } diff --git a/SDLMain.h b/src/SDLMain.h similarity index 100% rename from SDLMain.h rename to src/SDLMain.h diff --git a/SDLMain.m b/src/SDLMain.m similarity index 93% rename from SDLMain.m rename to src/SDLMain.m index 50c4b890f..78ef1fe46 100644 --- a/SDLMain.m +++ b/src/SDLMain.m @@ -5,7 +5,11 @@ Feel free to customize this file to suit your needs */ +#ifdef SDL_INC +#include "SDL/SDL.h" +#else #include "SDL.h" +#endif #include "SDLMain.h" #include /* for MAXPATHLEN */ #include @@ -81,18 +85,20 @@ static NSString *getApplicationName(void) /* The main class of the application, the application's delegate */ @implementation SDLMain -/* Set the working directory to the .app's parent directory */ +/* Set the working directory to Application Support */ - (void) setupWorkingDirectory:(BOOL)shouldChdir { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); - if([paths count] < 1) return; - + if ([paths count] < 1) + return; + NSString *appSupportPath = [paths objectAtIndex:0]; BOOL isDir = NO; NSError *error = nil; NSString *appPath = [appSupportPath stringByAppendingPathComponent:@"The Powder Toy"]; - if (![[NSFileManager defaultManager] fileExistsAtPath:appPath isDirectory:&isDir] && isDir == NO) { - if(![[NSFileManager defaultManager] createDirectoryAtPath:appPath withIntermediateDirectories:YES attributes:nil error:&error]) + if (![[NSFileManager defaultManager] fileExistsAtPath:appPath isDirectory:&isDir] && isDir == NO) + { + if (![[NSFileManager defaultManager] createDirectoryAtPath:appPath withIntermediateDirectories:YES attributes:nil error:&error]) { NSLog(@"Could not set up working dir. Error: %@", error); return; @@ -297,9 +303,15 @@ static void CustomApplicationMain (int argc, char **argv) - (void) applicationDidFinishLaunching: (NSNotification *) note { int status; + SInt32 versionMajor = 0, versionMinor = 0; + Gestalt(gestaltSystemVersionMajor, &versionMajor); + Gestalt(gestaltSystemVersionMinor, &versionMinor); - /* Set the working directory to the .app's parent directory */ - [self setupWorkingDirectory:gFinderLaunch]; + /* using gFinderLaunch doesn't work in Mavericks and above, so always change it */ + if (versionMajor > 10 || versionMinor >= 9) + [self setupWorkingDirectory:TRUE]; + else + [self setupWorkingDirectory:gFinderLaunch]; #if SDL_USE_NIB_FILE /* Set the main menu to contain the real app name instead of "SDL App" */ @@ -355,7 +367,8 @@ static void CustomApplicationMain (int argc, char **argv) @end -char * readUserPreferences() { +char * readUserPreferences() +{ NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; NSString *prefDataNSString = [prefs stringForKey:@"powder.pref"]; @@ -367,12 +380,12 @@ char * readUserPreferences() { SDL_strlcpy(prefDataCopy, prefData, [prefDataNSString length]+1); [prefDataNSString release]; - [prefs release]; return prefDataCopy; } -void writeUserPreferences(const char * prefData) { +void writeUserPreferences(const char * prefData) +{ NSString *prefDataNSString = [NSString stringWithUTF8String:prefData]; NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; @@ -380,10 +393,10 @@ void writeUserPreferences(const char * prefData) { [prefs synchronize]; [prefDataNSString release]; - [prefs release]; } -char * readClipboard() { +char * readClipboard() +{ NSPasteboard *clipboard = [NSPasteboard generalPasteboard]; NSArray *classes = [[NSArray alloc] initWithObjects:[NSString class], nil]; @@ -403,7 +416,8 @@ char * readClipboard() { return clipboardDataCopy; } -void writeClipboard(const char * clipboardData) { +void writeClipboard(const char * clipboardData) +{ NSPasteboard *clipboard = [NSPasteboard generalPasteboard]; NSString *newString = [NSString stringWithUTF8String: clipboardData]; diff --git a/src/client/GameSave.cpp b/src/client/GameSave.cpp index f7ca37429..33ebfa299 100644 --- a/src/client/GameSave.cpp +++ b/src/client/GameSave.cpp @@ -1003,6 +1003,11 @@ void GameSave::readOPS(char * data, int dataLength) particles[newIndex].ctype = 0; } break; + case PT_PHOT: + if (savedVersion < 90) + { + particles[newIndex].flags |= FLAG_PHOTDECO; + } } //note: PSv was used in version 77.0 and every version before, add something in PSv too if the element is that old newIndex++; @@ -1550,6 +1555,10 @@ void GameSave::readPSv(char * data, int dataLength) // no more particle properties to load, so we can change type here without messing up loading if (i && i<=NPART) { + if (ver<90 && particles[i-1].type == PT_PHOT) + { + particles[i-1].flags |= FLAG_PHOTDECO; + } if (ver<79 && particles[i-1].type == PT_SPNG) { if (fabs(particles[i-1].vx)>0.0f || fabs(particles[i-1].vy)>0.0f) diff --git a/src/client/requestbroker/RequestBroker.cpp b/src/client/requestbroker/RequestBroker.cpp index 7f20c907e..98dac6e46 100644 --- a/src/client/requestbroker/RequestBroker.cpp +++ b/src/client/requestbroker/RequestBroker.cpp @@ -141,7 +141,7 @@ void RequestBroker::RetrieveImage(std::string imageUrl, int width, int height, R assureRunning(); } -void * RequestBroker::thumbnailQueueProcessHelper(void * ref) +TH_ENTRY_POINT void * RequestBroker::thumbnailQueueProcessHelper(void * ref) { ((RequestBroker*)ref)->thumbnailQueueProcessTH(); return NULL; diff --git a/src/client/requestbroker/RequestBroker.h b/src/client/requestbroker/RequestBroker.h index 58084f0ad..560a33f2b 100644 --- a/src/client/requestbroker/RequestBroker.h +++ b/src/client/requestbroker/RequestBroker.h @@ -7,6 +7,7 @@ #include #undef GetUserName //God dammit microsoft! +#include "Config.h" #include "Singleton.h" class GameSave; @@ -39,7 +40,7 @@ private: std::vector requestQueue; std::vector activeRequests; - static void * thumbnailQueueProcessHelper(void * ref); + TH_ENTRY_POINT static void * thumbnailQueueProcessHelper(void * ref); void thumbnailQueueProcessTH(); void assureRunning(); diff --git a/src/graphics/Graphics.cpp b/src/graphics/Graphics.cpp index c423baeaa..f365c7f0e 100644 --- a/src/graphics/Graphics.cpp +++ b/src/graphics/Graphics.cpp @@ -870,9 +870,15 @@ void Graphics::draw_icon(int x, int y, Icon icon, unsigned char alpha, bool inve break; case IconVoteUp: if(invert) - drawchar(x, y+1, 0xCB, 0, 100, 0, alpha); + { + drawchar(x-11, y+1, 0xCB, 0, 100, 0, alpha); + drawtext(x+2, y+1, "Vote", 0, 100, 0, alpha); + } else - drawchar(x, y+1, 0xCB, 0, 187, 18, alpha); + { + drawchar(x-11, y+1, 0xCB, 0, 187, 18, alpha); + drawtext(x+2, y+1, "Vote", 0, 187, 18, alpha); + } break; case IconVoteDown: if(invert) diff --git a/src/graphics/RasterDrawMethods.inl b/src/graphics/RasterDrawMethods.inl index 96dfb91d3..2b1d1397a 100644 --- a/src/graphics/RasterDrawMethods.inl +++ b/src/graphics/RasterDrawMethods.inl @@ -418,8 +418,30 @@ void PIXELMETHODS_CLASS::gradientrect(int x, int y, int width, int height, int r void PIXELMETHODS_CLASS::clearrect(int x, int y, int w, int h) { int i; - for (i=1; i VIDXRES) w = VIDXRES-x; + if (y+h > VIDYRES) h = VIDYRES-y; + if (x<0) + { + w += x; + x = 0; + } + if (y<0) + { + h += y; + y = 0; + } + if (w<0 || h<0) + return; + + for (i=0; i= 0 && parts[i].tmp < NPART && parts[i].tmp2 >= 0 && parts[i].tmp2 < NPART) draw_line(nx, ny, (int)(parts[parts[i].tmp].x+0.5f), (int)(parts[parts[i].tmp].y+0.5f), colr, colg, colb, cola); } } @@ -1956,6 +1956,23 @@ void Renderer::render_parts() fire_r[ny/CELL][nx/CELL] = firer; fire_g[ny/CELL][nx/CELL] = fireg; fire_b[ny/CELL][nx/CELL] = fireb; +#endif + } + if(firea && (pixel_mode & FIRE_SPARK)) + { +#ifdef OGLR + smokeV[csmokeV++] = nx; + smokeV[csmokeV++] = ny; + smokeC[csmokeC++] = ((float)firer)/255.0f; + smokeC[csmokeC++] = ((float)fireg)/255.0f; + smokeC[csmokeC++] = ((float)fireb)/255.0f; + smokeC[csmokeC++] = ((float)firea)/255.0f; + csmoke++; +#else + firea /= 4; + fire_r[ny/CELL][nx/CELL] = (firea*firer + (255-firea)*fire_r[ny/CELL][nx/CELL]) >> 8; + fire_g[ny/CELL][nx/CELL] = (firea*fireg + (255-firea)*fire_g[ny/CELL][nx/CELL]) >> 8; + fire_b[ny/CELL][nx/CELL] = (firea*fireb + (255-firea)*fire_b[ny/CELL][nx/CELL]) >> 8; #endif } } @@ -2441,6 +2458,7 @@ Renderer::Renderer(Graphics * g, Simulation * sim): SetColourMode(COLOUR_DEFAULT); AddRenderMode(RENDER_BASC); AddRenderMode(RENDER_FIRE); + AddRenderMode(RENDER_SPRK); //Render mode presets. Possibly load from config in future? renderModePresets = new RenderPreset[11]; @@ -2467,11 +2485,13 @@ Renderer::Renderer(Graphics * g, Simulation * sim): renderModePresets[4].Name = "Fire Display"; renderModePresets[4].RenderModes.push_back(RENDER_FIRE); + renderModePresets[4].RenderModes.push_back(RENDER_SPRK); renderModePresets[4].RenderModes.push_back(RENDER_EFFE); renderModePresets[4].RenderModes.push_back(RENDER_BASC); renderModePresets[5].Name = "Blob Display"; renderModePresets[5].RenderModes.push_back(RENDER_FIRE); + renderModePresets[5].RenderModes.push_back(RENDER_SPRK); renderModePresets[5].RenderModes.push_back(RENDER_EFFE); renderModePresets[5].RenderModes.push_back(RENDER_BLOB); @@ -2482,6 +2502,7 @@ Renderer::Renderer(Graphics * g, Simulation * sim): renderModePresets[7].Name = "Fancy Display"; renderModePresets[7].RenderModes.push_back(RENDER_FIRE); + renderModePresets[7].RenderModes.push_back(RENDER_SPRK); renderModePresets[7].RenderModes.push_back(RENDER_GLOW); renderModePresets[7].RenderModes.push_back(RENDER_BLUR); renderModePresets[7].RenderModes.push_back(RENDER_EFFE); diff --git a/src/gui/elementsearch/ElementSearchActivity.cpp b/src/gui/elementsearch/ElementSearchActivity.cpp index 92a5c72be..f36aee85e 100644 --- a/src/gui/elementsearch/ElementSearchActivity.cpp +++ b/src/gui/elementsearch/ElementSearchActivity.cpp @@ -25,7 +25,8 @@ ElementSearchActivity::ElementSearchActivity(GameController * gameController, st WindowActivity(ui::Point(-1, -1), ui::Point(236, 302)), gameController(gameController), tools(tools), - firstResult(NULL) + firstResult(NULL), + exit(false) { ui::Label * title = new ui::Label(ui::Point(4, 5), ui::Point(Size.X-8, 15), "Element Search"); title->SetTextColour(style::Colour::InformationTitle); @@ -56,7 +57,7 @@ ElementSearchActivity::ElementSearchActivity(GameController * gameController, st CloseAction(ElementSearchActivity * a) : a(a) { } void ActionCallback(ui::Button * sender_) { - a->Exit(); + a->exit = true; } }; @@ -167,7 +168,7 @@ void ElementSearchActivity::searchTools(std::string query) void ElementSearchActivity::SetActiveTool(int selectionState, Tool * tool) { gameController->SetActiveTool(selectionState, tool); - Exit(); + exit = true; } void ElementSearchActivity::OnDraw() @@ -179,17 +180,23 @@ void ElementSearchActivity::OnDraw() g->drawrect(Position.X+searchField->Position.X, Position.Y+searchField->Position.Y+searchField->Size.Y+8, searchField->Size.X, Size.Y-(searchField->Position.Y+searchField->Size.Y+8)-23, 255, 255, 255, 180); } +void ElementSearchActivity::OnTick(float dt) +{ + if (exit) + Exit(); +} + void ElementSearchActivity::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt) { if(key == KEY_ENTER || key == KEY_RETURN) { if(firstResult) gameController->SetActiveTool(0, firstResult); - Exit(); + exit = true; } if(key == KEY_ESCAPE) { - Exit(); + exit = true; } } diff --git a/src/gui/elementsearch/ElementSearchActivity.h b/src/gui/elementsearch/ElementSearchActivity.h index 74bb898d8..76f81ec60 100644 --- a/src/gui/elementsearch/ElementSearchActivity.h +++ b/src/gui/elementsearch/ElementSearchActivity.h @@ -21,11 +21,13 @@ class ElementSearchActivity: public WindowActivity { void searchTools(std::string query); public: class ToolAction; + bool exit; Tool * GetFirstResult() { return firstResult; } ElementSearchActivity(GameController * gameController, std::vector tools); void SetActiveTool(int selectionState, Tool * tool); virtual ~ElementSearchActivity(); virtual void OnDraw(); + virtual void OnTick(float dt); virtual void OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt); }; diff --git a/src/gui/filebrowser/FileBrowserActivity.cpp b/src/gui/filebrowser/FileBrowserActivity.cpp index 1b7276082..ab4fa8c88 100644 --- a/src/gui/filebrowser/FileBrowserActivity.cpp +++ b/src/gui/filebrowser/FileBrowserActivity.cpp @@ -134,6 +134,7 @@ FileBrowserActivity::FileBrowserActivity(std::string directory, FileSelectedCall textField->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; textField->SetActionCallback(new SearchAction(this)); AddComponent(textField); + FocusComponent(textField); itemList = new ui::ScrollPanel(ui::Point(4, 45), ui::Point(Size.X-8, Size.Y-53)); AddComponent(itemList); diff --git a/src/gui/game/GameController.cpp b/src/gui/game/GameController.cpp index 8a81bd538..43f039664 100644 --- a/src/gui/game/GameController.cpp +++ b/src/gui/game/GameController.cpp @@ -126,6 +126,7 @@ GameController::GameController(): options(NULL), activePreview(NULL), localBrowser(NULL), + foundSign(NULL), HasDone(false), firstTick(true) { @@ -350,6 +351,12 @@ void GameController::AdjustBrushSize(int direction, bool logarithmic, bool xAxis BrushChanged(gameModel->GetBrushID(), gameModel->GetBrush()->GetRadius().X, gameModel->GetBrush()->GetRadius().Y); } +void GameController::SetBrushSize(ui::Point newSize) +{ + gameModel->GetBrush()->SetRadius(newSize); + BrushChanged(gameModel->GetBrushID(), gameModel->GetBrush()->GetRadius().X, gameModel->GetBrush()->GetRadius().Y); +} + void GameController::AdjustZoomSize(int direction, bool logarithmic) { int newSize; @@ -554,34 +561,36 @@ bool GameController::BrushChanged(int brushType, int rx, int ry) bool GameController::MouseDown(int x, int y, unsigned button) { bool ret = commandInterface->OnMouseDown(x, y, button); - ui::Point point = PointTranslate(ui::Point(x, y)); - x = point.X; - y = point.Y; - if(ret && yGetActiveTool(0)->GetIdentifier() != "DEFAULT_UI_SIGN" || button != BUTTON_LEFT) //If it's not a sign tool or you are right/middle clicking + if (ret && yGetPlacingSave() && !gameView->GetPlacingZoom()) + { + ui::Point point = gameModel->AdjustZoomCoords(ui::Point(x, y)); + x = point.X; + y = point.Y; + if (gameModel->GetActiveTool(0) && gameModel->GetActiveTool(0)->GetIdentifier() != "DEFAULT_UI_SIGN" || button != BUTTON_LEFT) //If it's not a sign tool or you are right/middle clicking { - sign * foundSign = GetSignAt(x, y); + foundSign = GetSignAt(x, y); if(foundSign && splitsign(foundSign->text.c_str())) return false; } + } return ret; } bool GameController::MouseUp(int x, int y, unsigned button) { bool ret = commandInterface->OnMouseUp(x, y, button); - ui::Point point = PointTranslate(ui::Point(x, y)); - x = point.X; - y = point.Y; - if(ret && yGetPlacingSave()) { - if (gameModel->GetActiveTool(0)->GetIdentifier() != "DEFAULT_UI_SIGN" || button != BUTTON_LEFT) //If it's not a sign tool or you are right/middle clicking + ui::Point point = gameModel->AdjustZoomCoords(ui::Point(x, y)); + x = point.X; + y = point.Y; + if (gameModel->GetActiveTool(0) && gameModel->GetActiveTool(0)->GetIdentifier() != "DEFAULT_UI_SIGN" || button != BUTTON_LEFT) //If it's not a sign tool or you are right/middle clicking { sign * foundSign = GetSignAt(x, y); if(foundSign) { - const char* str=foundSign->text.c_str(); + const char* str = foundSign->text.c_str(); char type; - int pos=splitsign(str, &type); + int pos = splitsign(str, &type); if (pos) { ret = false; @@ -609,6 +618,7 @@ bool GameController::MouseUp(int x, int y, unsigned button) } } } + foundSign = NULL; return ret; } @@ -720,7 +730,7 @@ void GameController::Tick() #ifdef LUACONSOLE ((LuaScriptInterface*)commandInterface)->Init(); #endif -#ifndef MACOSX +#if !defined(MACOSX) && !defined(NO_INSTALL_CHECK) if(!Client::Ref().GetPrefBool("InstallCheck", false)) { Client::Ref().SetPref("InstallCheck", true); @@ -1401,8 +1411,7 @@ std::string GameController::ElementResolve(int type, int ctype) else if (type >= 0 && type < PT_NUM && gameModel->GetSimulation()->elements) return std::string(gameModel->GetSimulation()->elements[type].Name); } - else - return ""; + return ""; } bool GameController::IsValidElement(int type) diff --git a/src/gui/game/GameController.h b/src/gui/game/GameController.h index 9fe362458..a7cdfc94b 100644 --- a/src/gui/game/GameController.h +++ b/src/gui/game/GameController.h @@ -32,6 +32,8 @@ private: //Simulation * sim; bool firstTick; int screenshotIndex; + sign * foundSign; + PreviewController * activePreview; GameView * gameView; GameModel * gameModel; @@ -79,6 +81,7 @@ public: void SetZoomEnabled(bool zoomEnable); void SetZoomPosition(ui::Point position); void AdjustBrushSize(int direction, bool logarithmic = false, bool xAxis = false, bool yAxis = false); + void SetBrushSize(ui::Point newSize); void AdjustZoomSize(int direction, bool logarithmic = false); void ToolClick(int toolSelection, ui::Point point); void DrawPoints(int toolSelection, queue & pointQueue); diff --git a/src/gui/game/GameModel.cpp b/src/gui/game/GameModel.cpp index 19bebdcdc..13ae4dc4a 100644 --- a/src/gui/game/GameModel.cpp +++ b/src/gui/game/GameModel.cpp @@ -379,15 +379,21 @@ void GameModel::BuildMenus() Tool * GameModel::GetToolFromIdentifier(std::string identifier) { - for(std::vector::iterator iter = menuList.begin(), end = menuList.end(); iter != end; ++iter) + for (std::vector::iterator iter = menuList.begin(), end = menuList.end(); iter != end; ++iter) { std::vector menuTools = (*iter)->GetToolList(); - for(std::vector::iterator titer = menuTools.begin(), tend = menuTools.end(); titer != tend; ++titer) + for (std::vector::iterator titer = menuTools.begin(), tend = menuTools.end(); titer != tend; ++titer) { - if(identifier == (*titer)->GetIdentifier()) + if (identifier == (*titer)->GetIdentifier()) return *titer; } } + for (std::vector::iterator iter = extraElementTools.begin(), end = extraElementTools.end(); iter != end; ++iter) + { + if (identifier == (*iter)->GetIdentifier()) + return *iter; + } + return NULL; } @@ -957,6 +963,7 @@ void GameModel::Log(string message) if(consoleLog.size()>100) consoleLog.pop_back(); notifyLogChanged(message); + std::cout << message << std::endl; } deque GameModel::GetLog() diff --git a/src/gui/game/GameView.cpp b/src/gui/game/GameView.cpp index dd62eb412..0e372bc50 100644 --- a/src/gui/game/GameView.cpp +++ b/src/gui/game/GameView.cpp @@ -175,6 +175,7 @@ GameView::GameView(): isToolTipFadingIn(false), isButtonTipFadingIn(false), toolTipPosition(-1, -1), + saveSimulationButtonEnabled(false), shiftBehaviour(false), ctrlBehaviour(false), altBehaviour(false), @@ -283,11 +284,11 @@ GameView::GameView(): v->c->Vote(1); } }; - upVoteButton = new ui::Button(ui::Point(currentX, Size.Y-16), ui::Point(15, 15), "", "Like this save"); + upVoteButton = new ui::Button(ui::Point(currentX, Size.Y-16), ui::Point(39, 15), "", "Like this save"); upVoteButton->SetIcon(IconVoteUp); upVoteButton->Appearance.Margin.Top+=2; upVoteButton->Appearance.Margin.Left+=2; - currentX+=14; + currentX+=38; upVoteButton->SetActionCallback(new UpVoteAction(this)); AddComponent(upVoteButton); @@ -319,7 +320,7 @@ GameView::GameView(): v->c->OpenTags(); } }; - tagSimulationButton = new ui::Button(ui::Point(currentX, Size.Y-16), ui::Point(251, 15), "[no tags set]", "Add simulation tags"); + tagSimulationButton = new ui::Button(ui::Point(currentX, Size.Y-16), ui::Point(227, 15), "[no tags set]", "Add simulation tags"); tagSimulationButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; tagSimulationButton->SetIcon(IconTag); currentX+=252; @@ -618,6 +619,16 @@ ui::Point GameView::GetMousePosition() return currentMouse; } +bool GameView::GetPlacingSave() +{ + return selectMode != SelectNone; +} + +bool GameView::GetPlacingZoom() +{ + return zoomEnabled && !zoomCursorFixed; +} + void GameView::NotifyActiveToolsChanged(GameModel * sender) { for(int i = 0; i < toolButtons.size(); i++) @@ -2250,7 +2261,10 @@ void GameView::OnDraw() if(toolTipPresence && toolTipPosition.X!=-1 && toolTipPosition.Y!=-1 && toolTip.length()) { - g->drawtext(toolTipPosition.X, toolTipPosition.Y, (char*)toolTip.c_str(), 255, 255, 255, toolTipPresence>51?255:toolTipPresence*5); + if (toolTipPosition.Y == Size.Y-MENUSIZE-10) + g->drawtext_outline(toolTipPosition.X, toolTipPosition.Y, (char*)toolTip.c_str(), 255, 255, 255, toolTipPresence>51?255:toolTipPresence*5); + else + g->drawtext(toolTipPosition.X, toolTipPosition.Y, (char*)toolTip.c_str(), 255, 255, 255, toolTipPresence>51?255:toolTipPresence*5); } if(buttonTipShow > 0) diff --git a/src/gui/game/GameView.h b/src/gui/game/GameView.h index ab3b714b6..90fae7db2 100644 --- a/src/gui/game/GameView.h +++ b/src/gui/game/GameView.h @@ -136,6 +136,8 @@ public: bool GetHudEnable(); void SetDebugHUD(bool mode); bool GetDebugHUD(); + bool GetPlacingSave(); + bool GetPlacingZoom(); bool CtrlBehaviour(){ return ctrlBehaviour; } bool ShiftBehaviour(){ return shiftBehaviour; } bool AltBehaviour(){ return altBehaviour; } diff --git a/src/gui/interface/Keys.h b/src/gui/interface/Keys.h index 2707d4fdf..bb9219f27 100644 --- a/src/gui/interface/Keys.h +++ b/src/gui/interface/Keys.h @@ -1,6 +1,10 @@ #if defined(USE_SDL) +#ifdef SDL_INC +#include "SDL/SDL.h" +#else #include "SDL.h" +#endif #define KEY_UNKNOWN SDLK_UNKNOWN #define KEY_UP SDLK_UP #define KEY_NUM_UP SDLK_KP8 @@ -49,7 +53,11 @@ #define KEY_MOD_MODE KMOD_MODE #define KEY_MOD_RESERVED KMOD_RESERVED +#ifdef MACOSX +#define KEY_MOD_CONTROL (KEY_MOD_RCONTROL | KEY_MOD_LCONTROL | KEY_MOD_LMETA | KEY_MOD_RMETA) +#else #define KEY_MOD_CONTROL (KEY_MOD_RCONTROL | KEY_MOD_LCONTROL) +#endif #define KEY_MOD_ALT (KEY_MOD_RALT | KEY_MOD_LALT) #define KEY_MOD_SHIFT (KEY_MOD_RSHIFT | KEY_MOD_LSHIFT) diff --git a/src/gui/interface/Label.cpp b/src/gui/interface/Label.cpp index 24b8035b6..047fd50f6 100644 --- a/src/gui/interface/Label.cpp +++ b/src/gui/interface/Label.cpp @@ -346,8 +346,8 @@ void Label::updateSelection() void Label::SetDisplayText(std::string newText) { - displayText = newText; - tDisplayText = displayText; + ClearSelection(); + displayText = tDisplayText = newText; } void Label::Draw(const Point& screenPos) diff --git a/src/gui/interface/SaveButton.cpp b/src/gui/interface/SaveButton.cpp index 7e67e488e..6406d353c 100644 --- a/src/gui/interface/SaveButton.cpp +++ b/src/gui/interface/SaveButton.cpp @@ -180,19 +180,16 @@ void SaveButton::Draw(const Point& screenPos) g->fillrect(screenPos.X, screenPos.Y, Size.X, Size.Y, 100, 170, 255, 100); } + scaleFactor = (Size.Y-25)/((float)YRES); + thumbBoxSize = ui::Point(((float)XRES)*scaleFactor, ((float)YRES)*scaleFactor); if(thumbnail) { - thumbBoxSize = ui::Point(thumbnail->Width, thumbnail->Height); + //thumbBoxSize = ui::Point(thumbnail->Width, thumbnail->Height); if(save && save->id) g->draw_image(thumbnail, screenPos.X-3+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, 255); else g->draw_image(thumbnail, screenPos.X+(Size.X-thumbBoxSize.X)/2, screenPos.Y+(Size.Y-21-thumbBoxSize.Y)/2, 255); } - else - { - scaleFactor = (Size.Y-25)/((float)YRES); - thumbBoxSize = ui::Point(((float)XRES)*scaleFactor, ((float)YRES)*scaleFactor); - } if(save) { if(save->id) diff --git a/src/gui/options/OptionsView.cpp b/src/gui/options/OptionsView.cpp index 6459c3708..dd2bf5a32 100644 --- a/src/gui/options/OptionsView.cpp +++ b/src/gui/options/OptionsView.cpp @@ -1,11 +1,20 @@ +#include +#ifdef WIN + #include + #define getcwd _getcwd +#else + #include +#endif + #include "OptionsView.h" #include "gui/Style.h" #include "gui/interface/Button.h" #include "gui/interface/Label.h" #include "gui/interface/DropDown.h" +#include "gui/dialogues/ErrorMessage.h" OptionsView::OptionsView(): - ui::Window(ui::Point(-1, -1), ui::Point(300, 310)){ + ui::Window(ui::Point(-1, -1), ui::Point(300, 330)){ ui::Label * tempLabel = new ui::Label(ui::Point(4, 5), ui::Point(Size.X-8, 14), "Simulation Options"); tempLabel->SetTextColour(style::Colour::InformationTitle); @@ -150,7 +159,14 @@ OptionsView::OptionsView(): OptionsView * v; public: FullscreenAction(OptionsView * v_){ v = v_; } - virtual void ActionCallback(ui::Checkbox * sender){ v->c->SetFullscreen(sender->GetChecked()); } + virtual void ActionCallback(ui::Checkbox * sender) + { +#ifdef MACOSX + ErrorMessage::Blocking("Error", "fullscreen doesn't work on OS X"); +#else + v->c->SetFullscreen(sender->GetChecked()); +#endif + } }; fullscreen = new ui::Checkbox(ui::Point(8, 230), ui::Point(Size.X-6, 16), "Fullscreen", ""); @@ -191,6 +207,35 @@ OptionsView::OptionsView(): AddComponent(tempLabel); AddComponent(showAvatars); + class DataFolderAction: public ui::ButtonAction + { + public: + DataFolderAction() { } + void ActionCallback(ui::Button * sender) + { +//one of these should always be defined +#ifdef WIN + const char* openCommand = "start "; +#elif MACOSX + const char* openCommand = "open "; +//#elif LIN +#else + const char* openCommand = "xdg-open "; +#endif + char* workingDirectory = new char[FILENAME_MAX+strlen(openCommand)]; + sprintf(workingDirectory, "%s\"%s\"", openCommand, getcwd(NULL, 0)); + system(workingDirectory); + delete workingDirectory; + } + }; + ui::Button * dataFolderButton = new ui::Button(ui::Point(8, Size.Y-38), ui::Point(90, 16), "Open Data Folder"); + dataFolderButton->SetActionCallback(new DataFolderAction()); + AddComponent(dataFolderButton); + + tempLabel = new ui::Label(ui::Point(dataFolderButton->Position.X+dataFolderButton->Size.X+3, dataFolderButton->Position.Y), ui::Point(Size.X-28, 16), "\bg- Open the data and preferences folder"); + tempLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; tempLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; + AddComponent(tempLabel); + class CloseAction: public ui::ButtonAction { public: diff --git a/src/gui/render/RenderView.cpp b/src/gui/render/RenderView.cpp index f4a84d1ca..1f7b7c795 100644 --- a/src/gui/render/RenderView.cpp +++ b/src/gui/render/RenderView.cpp @@ -186,6 +186,14 @@ RenderView::RenderView(): tCheckbox->SetActionCallback(new RenderModeAction(this, RENDER_BASC)); AddComponent(tCheckbox); + checkboxOffset += cSpace; + + tCheckbox = new ui::Checkbox(ui::Point(checkboxOffset, YRES+4), ui::Point(30, 16), "Spark", "Glow effect on sparks"); + renderModes.push_back(tCheckbox); + tCheckbox->SetIcon(IconEffect); + tCheckbox->SetActionCallback(new RenderModeAction(this, RENDER_SPRK)); + AddComponent(tCheckbox); + checkboxOffset += sSpace; line1 = checkboxOffset-5; @@ -231,9 +239,9 @@ RenderView::RenderView(): AddComponent(tCheckbox); #ifdef OGLR - tCheckbox = new ui::Checkbox(ui::Point(checkboxOffset, YRES+4), ui::Point(30, 16), "Effect", "I don't know what this does..."); //I would remove the whole checkbox, but then there's a large empty space + tCheckbox = new ui::Checkbox(ui::Point(checkboxOffset, YRES+4), ui::Point(30, 16), "Effect", "Some type of OpenGL effect ... maybe"); //I would remove the whole checkbox, but then there's a large empty space #else - tCheckbox = new ui::Checkbox(ui::Point(checkboxOffset, YRES+4), ui::Point(30, 16), "Effect", "Does nothing"); + tCheckbox = new ui::Checkbox(ui::Point(checkboxOffset, YRES+4), ui::Point(30, 16), "Effect", "Enables moving solids, stickmen guns, and premium(tm) graphics"); #endif displayModes.push_back(tCheckbox); tCheckbox->SetIcon(IconEffect); @@ -379,9 +387,9 @@ void RenderView::OnTick(float dt) isToolTipFadingIn = false; if(toolTipPresence < 120) { - toolTipPresence += int(dt*2)>0?int(dt*2):1; + toolTipPresence += int(dt*2)>1?int(dt*2):2; if(toolTipPresence > 120) - toolTipPresence = 0; + toolTipPresence = 120; } } if(toolTipPresence>0) diff --git a/src/gui/save/ServerSaveActivity.cpp b/src/gui/save/ServerSaveActivity.cpp index c12979995..49adce737 100644 --- a/src/gui/save/ServerSaveActivity.cpp +++ b/src/gui/save/ServerSaveActivity.cpp @@ -114,6 +114,7 @@ ServerSaveActivity::ServerSaveActivity(SaveInfo save, ServerSaveActivity::SaveUp nameField->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; nameField->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; AddComponent(nameField); + FocusComponent(nameField); descriptionField = new ui::Textbox(ui::Point(8, 65), ui::Point((Size.X/2)-16, Size.Y-(65+16+4)), save.GetDescription(), "[save description]"); descriptionField->SetMultiline(true); diff --git a/src/gui/search/SearchController.cpp b/src/gui/search/SearchController.cpp index c65545893..15bc70f89 100644 --- a/src/gui/search/SearchController.cpp +++ b/src/gui/search/SearchController.cpp @@ -80,6 +80,7 @@ void SearchController::Update() void SearchController::Exit() { + InstantOpen(false); if(ui::Engine::Ref().GetWindow() == searchView) { ui::Engine::Ref().CloseWindow(); diff --git a/src/gui/search/SearchModel.cpp b/src/gui/search/SearchModel.cpp index f4de2d6c9..e0168fe7b 100644 --- a/src/gui/search/SearchModel.cpp +++ b/src/gui/search/SearchModel.cpp @@ -29,7 +29,7 @@ bool SearchModel::GetShowTags() return showTags; } -void * SearchModel::updateSaveListTHelper(void * obj) +TH_ENTRY_POINT void * SearchModel::updateSaveListTHelper(void * obj) { return ((SearchModel *)obj)->updateSaveListT(); } @@ -47,7 +47,7 @@ void * SearchModel::updateSaveListT() return saveList; } -void * SearchModel::updateTagListTHelper(void * obj) +TH_ENTRY_POINT void * SearchModel::updateTagListTHelper(void * obj) { return ((SearchModel *)obj)->updateTagListT(); } diff --git a/src/gui/search/SearchModel.h b/src/gui/search/SearchModel.h index 61f51d03e..4275a5012 100644 --- a/src/gui/search/SearchModel.h +++ b/src/gui/search/SearchModel.h @@ -42,13 +42,13 @@ private: bool updateSaveListWorking; volatile bool updateSaveListFinished; pthread_t updateSaveListThread; - static void * updateSaveListTHelper(void * obj); + TH_ENTRY_POINT static void * updateSaveListTHelper(void * obj); void * updateSaveListT(); bool updateTagListWorking; volatile bool updateTagListFinished; pthread_t updateTagListThread; - static void * updateTagListTHelper(void * obj); + TH_ENTRY_POINT static void * updateTagListTHelper(void * obj); void * updateTagListT(); public: SearchModel(); diff --git a/src/gui/search/SearchView.cpp b/src/gui/search/SearchView.cpp index e79e478bc..c1a649ed2 100644 --- a/src/gui/search/SearchView.cpp +++ b/src/gui/search/SearchView.cpp @@ -39,6 +39,7 @@ SearchView::SearchView(): searchField->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; searchField->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; searchField->SetActionCallback(new SearchAction(this)); + FocusComponent(searchField); class SortAction : public ui::ButtonAction diff --git a/src/lua/LegacyLuaAPI.cpp b/src/lua/LegacyLuaAPI.cpp index 8f2ed2e1d..ca67c8919 100644 --- a/src/lua/LegacyLuaAPI.cpp +++ b/src/lua/LegacyLuaAPI.cpp @@ -588,26 +588,14 @@ int luacon_mouseevent(int mx, int my, int mb, int event, int mouse_wheel) return mpcontinue; } -int luacon_step(int mx, int my, std::string selectl, std::string selectr, std::string selectalt, std::string selectreplace, int bsx, int bsy) +int luacon_step(int mx, int my) { int i, j, callret; lua_State* l=luacon_ci->l; - lua_pushinteger(l, bsy); - lua_pushinteger(l, bsx); - lua_pushstring(l, selectreplace.c_str()); - lua_pushstring(l, selectalt.c_str()); - lua_pushstring(l, selectr.c_str()); - lua_pushstring(l, selectl.c_str()); lua_pushinteger(l, my); lua_pushinteger(l, mx); lua_setfield(l, tptProperties, "mousex"); lua_setfield(l, tptProperties, "mousey"); - lua_setfield(l, tptProperties, "selectedl"); - lua_setfield(l, tptProperties, "selectedr"); - lua_setfield(l, tptProperties, "selecteda"); - lua_setfield(l, tptProperties, "selectedreplace"); - lua_setfield(l, tptProperties, "brushx"); - lua_setfield(l, tptProperties, "brushy"); lua_pushstring(l, "stepfunctions"); lua_rawget(l, LUA_REGISTRYINDEX); if(!lua_istable(l, -1)) @@ -1226,15 +1214,16 @@ int luatpt_set_property(lua_State* l) int luatpt_set_wallmap(lua_State* l) { int nx, ny, acount; - int x1, y1, width, height; - float value; + int x1, y1, width, height, wallType; acount = lua_gettop(l); x1 = abs(luaL_optint(l, 1, 0)); y1 = abs(luaL_optint(l, 2, 0)); width = abs(luaL_optint(l, 3, XRES/CELL)); height = abs(luaL_optint(l, 4, YRES/CELL)); - value = (float)luaL_optint(l, acount, 0); + wallType = luaL_optint(l, acount, 0); + if (wallType < 0 || wallType >= UI_WALLCOUNT) + return luaL_error(l, "Unrecognised wall number %d", wallType); if (acount == 5) //Draw rect { @@ -1249,7 +1238,7 @@ int luatpt_set_wallmap(lua_State* l) for (nx = x1; nxbmap[ny][nx] = value; + luacon_sim->bmap[ny][nx] = wallType; } } else //Set point @@ -1258,20 +1247,15 @@ int luatpt_set_wallmap(lua_State* l) x1 = (XRES/CELL); if(y1 > (YRES/CELL)) y1 = (YRES/CELL); - luacon_sim->bmap[y1][x1] = value; + luacon_sim->bmap[y1][x1] = wallType; } return 0; } int luatpt_get_wallmap(lua_State* l) { - int nx, ny, acount; - int x1, y1, width, height; - float value; - acount = lua_gettop(l); - - x1 = abs(luaL_optint(l, 1, 0)); - y1 = abs(luaL_optint(l, 2, 0)); + int x1 = abs(luaL_optint(l, 1, 0)); + int y1 = abs(luaL_optint(l, 2, 0)); if(x1 > (XRES/CELL) || y1 > (YRES/CELL)) return luaL_error(l, "Out of range"); @@ -1765,7 +1749,7 @@ int luatpt_next_getPartIndex(lua_State* l) getPartIndex_curIdx++; if (getPartIndex_curIdx >= NPART) { - getPartIndex_curIdx = 0; + getPartIndex_curIdx = -1; lua_pushboolean(l, 0); return 1; } @@ -1782,7 +1766,7 @@ int luatpt_getPartIndex(lua_State* l) { if(getPartIndex_curIdx < 0) { - lua_pushinteger(l, 0); + lua_pushinteger(l, -1); return 1; } lua_pushinteger(l, getPartIndex_curIdx); diff --git a/src/lua/LuaBit.cpp b/src/lua/LuaBit.cpp index f1479d05a..96fa00822 100644 --- a/src/lua/LuaBit.cpp +++ b/src/lua/LuaBit.cpp @@ -29,12 +29,7 @@ #define LUA_BITOP_VERSION "1.0.2" -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" -} +#include "LuaCompat.h" #ifdef _MSC_VER /* MSVC is stuck in the last century and doesn't have C99's stdint.h. */ @@ -183,11 +178,11 @@ int luaopen_bit(lua_State *L) msg = "arithmetic right-shift broken"; luaL_error(L, "bit library self-test failed (%s)", msg); } -#if LUA_VERSION_NUM < 502 +//#if LUA_VERSION_NUM < 502 luaL_register(L, "bit", bit_funcs); -#else - luaL_newlib(L, bit_funcs); -#endif +//#else +// luaL_newlib(L, bit_funcs); +//#endif return 1; } #endif diff --git a/src/lua/LuaButton.cpp b/src/lua/LuaButton.cpp index 1b55f895d..b4adf3b86 100644 --- a/src/lua/LuaButton.cpp +++ b/src/lua/LuaButton.cpp @@ -1,10 +1,4 @@ #ifdef LUACONSOLE -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" -} #include #include "LuaButton.h" diff --git a/src/lua/LuaButton.h b/src/lua/LuaButton.h index 69a77a4e7..6a7b965f6 100644 --- a/src/lua/LuaButton.h +++ b/src/lua/LuaButton.h @@ -1,11 +1,5 @@ #pragma once -extern "C" { - #include "lua.h" - #include "lauxlib.h" - #include "lualib.h" -} - #include "LuaLuna.h" #include "LuaComponent.h" diff --git a/src/lua/LuaCheckbox.cpp b/src/lua/LuaCheckbox.cpp index 55c39db68..24883e916 100644 --- a/src/lua/LuaCheckbox.cpp +++ b/src/lua/LuaCheckbox.cpp @@ -1,10 +1,4 @@ #ifdef LUACONSOLE -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" -} #include #include "LuaCheckbox.h" diff --git a/src/lua/LuaCheckbox.h b/src/lua/LuaCheckbox.h index 0f2e8ad2a..9dfc5a26a 100644 --- a/src/lua/LuaCheckbox.h +++ b/src/lua/LuaCheckbox.h @@ -1,11 +1,5 @@ #pragma once -extern "C" { - #include "lua.h" - #include "lauxlib.h" - #include "lualib.h" -} - #include "LuaLuna.h" #include "LuaComponent.h" diff --git a/src/lua/LuaCompat.c b/src/lua/LuaCompat.c new file mode 100644 index 000000000..0ecec2714 --- /dev/null +++ b/src/lua/LuaCompat.c @@ -0,0 +1,11 @@ +#include "LuaCompat.h" + +#if LUA_VERSION_NUM >= 502 +//implement missing luaL_typerror function +int luaL_typerror (lua_State *L, int narg, const char *tname) +{ + const char *msg = lua_pushfstring(L, "%s expected, got %s", tname, luaL_typename(L, narg)); + return luaL_argerror(L, narg, msg); +} + +#endif diff --git a/src/lua/LuaCompat.h b/src/lua/LuaCompat.h new file mode 100644 index 000000000..f7e843d9a --- /dev/null +++ b/src/lua/LuaCompat.h @@ -0,0 +1,30 @@ +#ifndef LUAINC_H +#define LUAINC_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef LUA_INC +#include "lua5.1/lua.h" +#include "lua5.1/lauxlib.h" +#include "lua5.1/lualib.h" +#else +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" +#endif + +#if LUA_VERSION_NUM >= 502 +#define luaL_getn(L,i) lua_rawlen(L, (i)) +#define LUA_GLOBALSINDEX LUA_RIDX_GLOBALS + +LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lua/LuaComponent.cpp b/src/lua/LuaComponent.cpp index 028dfb58c..f455732ea 100644 --- a/src/lua/LuaComponent.cpp +++ b/src/lua/LuaComponent.cpp @@ -1,10 +1,4 @@ #ifdef LUACONSOLE -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" -} #include #include "LuaComponent.h" diff --git a/src/lua/LuaComponent.h b/src/lua/LuaComponent.h index 8e408909d..6d0fad8b2 100644 --- a/src/lua/LuaComponent.h +++ b/src/lua/LuaComponent.h @@ -1,11 +1,5 @@ #pragma once -extern "C" { - #include "lua.h" - #include "lauxlib.h" - #include "lualib.h" -} - #include "LuaLuna.h" namespace ui diff --git a/src/lua/LuaLabel.cpp b/src/lua/LuaLabel.cpp index 4131918d0..07ad636ac 100644 --- a/src/lua/LuaLabel.cpp +++ b/src/lua/LuaLabel.cpp @@ -1,10 +1,4 @@ #ifdef LUACONSOLE -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" -} #include #include "LuaScriptInterface.h" diff --git a/src/lua/LuaLabel.h b/src/lua/LuaLabel.h index 2653d9c27..59c86b530 100644 --- a/src/lua/LuaLabel.h +++ b/src/lua/LuaLabel.h @@ -1,11 +1,5 @@ #pragma once -extern "C" { - #include "lua.h" - #include "lauxlib.h" - #include "lualib.h" -} - #include "LuaLuna.h" #include "LuaComponent.h" diff --git a/src/lua/LuaLuna.h b/src/lua/LuaLuna.h index 9fa4042e6..c5caa1877 100644 --- a/src/lua/LuaLuna.h +++ b/src/lua/LuaLuna.h @@ -1,10 +1,7 @@ #pragma once //http://lua-users.org/wiki/SimplerCppBinding -extern "C" { -#include "lua.h" -#include "lauxlib.h" -} +#include "LuaCompat.h" template class Luna { diff --git a/src/lua/LuaProgressBar.cpp b/src/lua/LuaProgressBar.cpp index 787cfcfad..cb6a9faaa 100644 --- a/src/lua/LuaProgressBar.cpp +++ b/src/lua/LuaProgressBar.cpp @@ -1,10 +1,4 @@ #ifdef LUACONSOLE -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" -} #include #include "LuaProgressBar.h" diff --git a/src/lua/LuaProgressBar.h b/src/lua/LuaProgressBar.h index a27ddee36..1c86b2fd2 100644 --- a/src/lua/LuaProgressBar.h +++ b/src/lua/LuaProgressBar.h @@ -1,11 +1,5 @@ #pragma once -extern "C" { - #include "lua.h" - #include "lauxlib.h" - #include "lualib.h" -} - #include "LuaLuna.h" #include "LuaComponent.h" diff --git a/src/lua/LuaScriptHelper.h b/src/lua/LuaScriptHelper.h index 6b8280337..b99082300 100644 --- a/src/lua/LuaScriptHelper.h +++ b/src/lua/LuaScriptHelper.h @@ -21,7 +21,7 @@ extern int tptElements; //Table for TPT element names extern int tptParts, tptPartsMeta, tptElementTransitions, tptPartsCData, tptPartMeta, tptPart, cIndex; void luacon_hook(lua_State *L, lua_Debug *ar); -int luacon_step(int mx, int my, std::string , std::string selectr, std::string selectedalt, std::string selectedreplace, int bsx, int bsy); +int luacon_step(int mx, int my); int luacon_mouseevent(int mx, int my, int mb, int event, int mouse_wheel); int luacon_keyevent(int key, int modifier, int event); int luacon_eval(const char *command); diff --git a/src/lua/LuaScriptInterface.cpp b/src/lua/LuaScriptInterface.cpp index be31049ba..bf54e65e7 100644 --- a/src/lua/LuaScriptInterface.cpp +++ b/src/lua/LuaScriptInterface.cpp @@ -73,6 +73,18 @@ int atPanic(lua_State *l) throw std::runtime_error("Unprotected lua panic: " + std::string(lua_tostring(l, -1))); } +int TptIndexClosure(lua_State *l) +{ + LuaScriptInterface *lsi = (LuaScriptInterface *)lua_touserdata(l, lua_upvalueindex(1)); + return lsi->tpt_index(l); +} + +int TptNewindexClosure(lua_State *l) +{ + LuaScriptInterface *lsi = (LuaScriptInterface *)lua_touserdata(l, lua_upvalueindex(1)); + return lsi->tpt_newIndex(l); +} + LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m): CommandInterface(c, m), currentCommand(false), @@ -127,7 +139,7 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m): int i = 0, j; char tmpname[12]; int currentElementMeta, currentElement; - const static struct luaL_reg tptluaapi [] = { + const static struct luaL_Reg tptluaapi [] = { {"test", &luatpt_test}, {"drawtext", &luatpt_drawtext}, {"create", &luatpt_create}, @@ -214,14 +226,6 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m): lua_setfield(l, tptProperties, "mousex"); lua_pushinteger(l, 0); lua_setfield(l, tptProperties, "mousey"); - lua_pushstring(l, "DEFAULT_PT_DUST"); - lua_setfield(l, tptProperties, "selectedl"); - lua_pushstring(l, "DEFAULT_PT_NONE"); - lua_setfield(l, tptProperties, "selectedr"); - lua_pushstring(l, "DEFAULT_PT_NONE"); - lua_setfield(l, tptProperties, "selecteda"); - lua_pushstring(l, "DEFAULT_PT_NONE"); - lua_setfield(l, tptProperties, "selectedreplace"); lua_newtable(l); tptPropertiesVersion = lua_gettop(l); @@ -332,6 +336,16 @@ tpt.partsdata = nil"); lua_gr_func[i] = 0; } + //make tpt.* a metatable + lua_newtable(l); + lua_pushlightuserdata(l, this); + lua_pushcclosure(l, TptIndexClosure, 1); + lua_setfield(l, -2, "__index"); + lua_pushlightuserdata(l, this); + lua_pushcclosure(l, TptNewindexClosure, 1); + lua_setfield(l, -2, "__newindex"); + lua_setmetatable(l, -2); + } void LuaScriptInterface::Init() @@ -351,11 +365,84 @@ void LuaScriptInterface::SetWindow(ui::Window * window) Window = window; } +int LuaScriptInterface::tpt_index(lua_State *l) +{ + std::string key = luaL_checkstring(l, 2); + if (!key.compare("selectedl")) + return lua_pushstring(l, luacon_selectedl.c_str()), 1; + if (!key.compare("selectedr")) + return lua_pushstring(l, luacon_selectedr.c_str()), 1; + if (!key.compare("selecteda")) + return lua_pushstring(l, luacon_selectedalt.c_str()), 1; + if (!key.compare("selectedreplace")) + return lua_pushstring(l, luacon_selectedreplace.c_str()), 1; + if (!key.compare("brushx")) + return lua_pushnumber(l, luacon_brushx), 1; + if (!key.compare("brushy")) + return lua_pushnumber(l, luacon_brushy), 1; + if (!key.compare("brushID")) + return lua_pushnumber(l, m->GetBrushID()), 1; + + //if not a special key, return the value in the table + return lua_rawget(l, 1), 1; +} + +int LuaScriptInterface::tpt_newIndex(lua_State *l) +{ + std::string key = luaL_checkstring(l, 2); + if (!key.compare("selectedl")) + { + Tool *t = m->GetToolFromIdentifier(luaL_checkstring(l, 3)); + if (t) + c->SetActiveTool(0, t); + else + luaL_error(l, "Invalid tool identifier: %s", lua_tostring(l, 3)); + } + else if (!key.compare("selectedr")) + { + Tool *t = m->GetToolFromIdentifier(luaL_checkstring(l, 3)); + if (t) + c->SetActiveTool(1, t); + else + luaL_error(l, "Invalid tool identifier: %s", lua_tostring(l, 3)); + } + else if (!key.compare("selecteda")) + { + Tool *t = m->GetToolFromIdentifier(luaL_checkstring(l, 3)); + if (t) + c->SetActiveTool(2, t); + else + luaL_error(l, "Invalid tool identifier: %s", lua_tostring(l, 3)); + } + else if (!key.compare("selectedreplace")) + { + Tool *t = m->GetToolFromIdentifier(luaL_checkstring(l, 3)); + if( t) + c->SetActiveTool(3, t); + else + luaL_error(l, "Invalid tool identifier: %s", lua_tostring(l, 3)); + } + else if (!key.compare("brushx")) + c->SetBrushSize(ui::Point(luaL_checkinteger(l, 3), luacon_brushy)); + else if (!key.compare("brushy")) + c->SetBrushSize(ui::Point(luacon_brushx, luaL_checkinteger(l, 3))); + else if (!key.compare("brushID")) + { + m->SetBrushID(luaL_checkinteger(l, 3)); + c->BrushChanged(m->GetBrushID(), luacon_brushx, luacon_brushy); + } + else + { + //if not a special key, set a value in the table + return lua_rawset(l, 1), 1; + } +} + //// Begin Interface API void LuaScriptInterface::initInterfaceAPI() { - struct luaL_reg interfaceAPIMethods [] = { + struct luaL_Reg interfaceAPIMethods [] = { {"showWindow", interface_showWindow}, {"closeWindow", interface_closeWindow}, {"addComponent", interface_addComponent}, @@ -448,7 +535,7 @@ int LuaScriptInterface::particlePropertiesCount; void LuaScriptInterface::initSimulationAPI() { //Methods - struct luaL_reg simulationAPIMethods [] = { + struct luaL_Reg simulationAPIMethods [] = { {"partNeighbours", simulation_partNeighbours}, {"partNeighbors", simulation_partNeighbours}, {"partChangeType", simulation_partChangeType}, @@ -1678,7 +1765,7 @@ int LuaScriptInterface::simulation_neighbours(lua_State * l) void LuaScriptInterface::initRendererAPI() { //Methods - struct luaL_reg rendererAPIMethods [] = { + struct luaL_Reg rendererAPIMethods [] = { {"renderModes", renderer_renderModes}, {"displayModes", renderer_displayModes}, {"colourMode", renderer_colourMode}, @@ -1870,7 +1957,7 @@ int LuaScriptInterface::renderer_debugHUD(lua_State * l) void LuaScriptInterface::initElementsAPI() { //Methods - struct luaL_reg elementsAPIMethods [] = { + struct luaL_Reg elementsAPIMethods [] = { {"allocate", elements_allocate}, {"element", elements_element}, {"property", elements_property}, @@ -1910,6 +1997,7 @@ void LuaScriptInterface::initElementsAPI() SETCONST(l, FLAG_STAGNANT); SETCONST(l, FLAG_SKIPMOVE); SETCONST(l, FLAG_MOVABLE); + SETCONST(l, FLAG_PHOTDECO); SETCONST(l, ST_NONE); SETCONST(l, ST_SOLID); SETCONST(l, ST_LIQUID); @@ -1999,7 +2087,7 @@ int LuaScriptInterface::elements_loadDefault(lua_State * l) luacon_model->BuildMenus(); luacon_sim->init_can_move(); std::fill(luacon_ren->graphicscache, luacon_ren->graphicscache+PT_NUM, gcache_item()); - + return 0; } int LuaScriptInterface::elements_allocate(lua_State * l) @@ -2296,6 +2384,7 @@ int LuaScriptInterface::elements_property(lua_State * l) } else return luaL_error(l, "Invalid element property"); + return 0; } else { @@ -2385,7 +2474,7 @@ int LuaScriptInterface::elements_free(lua_State * l) void LuaScriptInterface::initGraphicsAPI() { //Methods - struct luaL_reg graphicsAPIMethods [] = { + struct luaL_Reg graphicsAPIMethods [] = { {"textSize", graphics_textSize}, {"drawText", graphics_drawText}, {"drawLine", graphics_drawLine}, @@ -2393,6 +2482,8 @@ void LuaScriptInterface::initGraphicsAPI() {"fillRect", graphics_fillRect}, {"drawCircle", graphics_drawCircle}, {"fillCircle", graphics_fillCircle}, + {"getColors", graphics_getColors}, + {"getHexColor", graphics_getHexColor}, {NULL, NULL} }; luaL_register(l, "graphics", graphicsAPIMethods); @@ -2559,10 +2650,40 @@ int LuaScriptInterface::graphics_fillCircle(lua_State * l) return 0; } +int LuaScriptInterface::graphics_getColors(lua_State * l) +{ + unsigned int color = lua_tointeger(l, 1); + + int a = color >> 24; + int r = (color >> 16)&0xFF; + int g = (color >> 8)&0xFF; + int b = color&0xFF; + + lua_pushinteger(l, r); + lua_pushinteger(l, g); + lua_pushinteger(l, b); + lua_pushinteger(l, a); + return 4; +} + +int LuaScriptInterface::graphics_getHexColor(lua_State * l) +{ + int r = lua_tointeger(l, 1); + int g = lua_tointeger(l, 2); + int b = lua_tointeger(l, 3); + int a = 0; + if (lua_gettop(l) >= 4) + a = lua_tointeger(l, 4); + unsigned int color = (a<<24) + (r<<16) + (g<<8) + b; + + lua_pushinteger(l, color); + return 1; +} + void LuaScriptInterface::initFileSystemAPI() { //Methods - struct luaL_reg fileSystemAPIMethods [] = { + struct luaL_Reg fileSystemAPIMethods [] = { {"list", fileSystem_list}, {"exists", fileSystem_exists}, {"isFile", fileSystem_isFile}, @@ -2801,14 +2922,19 @@ bool LuaScriptInterface::OnBrushChanged(int brushType, int rx, int ry) bool LuaScriptInterface::OnActiveToolChanged(int toolSelection, Tool * tool) { + std::string identifier; + if (tool) + identifier = tool->GetIdentifier(); + else + identifier = ""; if (toolSelection == 0) - luacon_selectedl = tool->GetIdentifier(); + luacon_selectedl = identifier; else if (toolSelection == 1) - luacon_selectedr = tool->GetIdentifier(); + luacon_selectedr = identifier; else if (toolSelection == 2) - luacon_selectedalt = tool->GetIdentifier(); + luacon_selectedalt = identifier; else if (toolSelection == 3) - luacon_selectedreplace = tool->GetIdentifier(); + luacon_selectedreplace = identifier; return true; } @@ -2867,7 +2993,7 @@ void LuaScriptInterface::OnTick() ui::Engine::Ref().LastTick(gettime()); if(luacon_mousedown) luacon_mouseevent(luacon_mousex, luacon_mousey, luacon_mousebutton, LUACON_MPRESS, 0); - luacon_step(luacon_mousex, luacon_mousey, luacon_selectedl, luacon_selectedr, luacon_selectedalt, luacon_selectedreplace, luacon_brushx, luacon_brushy); + luacon_step(luacon_mousex, luacon_mousey); } int LuaScriptInterface::Command(std::string command) @@ -2934,6 +3060,223 @@ int LuaScriptInterface::Command(std::string command) } } +int strlcmp(const char* a, const char* b, int len) +{ + while(len) + { + if(!*b) + return 1; + if(*a>*b) + return -1; + if(*a<*b) + return 1; + a++; + b++; + len--; + } + if(!*b) + return 0; + return -1; +} + +std::string highlight(std::string command) +{ +#define CMP(X) (!strlcmp(wstart, X, len)) + std::stringstream result; + int pos = 0; + int len = command.length(); + const char *raw = command.c_str(); + char c; + while(c = raw[pos]) + { + if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_') + { + int len = 0; + char w; + const char* wstart = raw+pos; + while((w = wstart[len]) && ((w >= 'A' && w <= 'Z') || (w >= 'a' && w <= 'z') || (w >= '0' && w <= '9') || w == '_')) + len++; + if(CMP("and") || CMP("break") || CMP("do") || CMP("else") || CMP("elseif") || CMP("end") || CMP("for") || CMP("function") || CMP("if") || CMP("in") || CMP("local") || CMP("not") || CMP("or") || CMP("repeat") || CMP("return") || CMP("then") || CMP("until") || CMP("while")) + { + result << "\x0F\xB5\x89\x01"; + result.write(wstart, len); + result << "\bw"; + } + else if(CMP("false") || CMP("nil") || CMP("true")) + { + result << "\x0F\xCB\x4B\x16"; + result.write(wstart, len); + result << "\bw"; + } + else + { + result << "\x0F\x2A\xA1\x98"; + result.write(wstart, len); + result << "\bw"; + } + pos += len; + } + else if((c >= '0' && c <= '9') || (c == '.' && raw[pos + 1] >= '0' && raw[pos + 1] <= '9')) + { + if(c == '0' && raw[pos + 1] == 'x') + { + int len = 2; + char w; + const char *wstart = raw + pos; + while((w = wstart[len]) && ((w >= '0' && w <= '9') || (w >= 'A' && w <= 'F') || (w >= 'a' && w <= 'f'))) + len++; + result << "\x0F\xD3\x36\x82"; + result.write(wstart, len); + result << "\bw"; + pos += len; + } + else + { + int len = 0; + char w; + const char *wstart = raw+pos; + bool seendot = false; + while((w = wstart[len]) && ((w >= '0' && w <= '9') || w == '.')) + { + if(w == '.') + if(seendot) + break; + else + seendot = true; + len++; + } + if(w == 'e') + { + len++; + w = wstart[len]; + if(w == '+' || w == '-') + len++; + while((w = wstart[len]) && (w >= '0' && w <= '9')) + len++; + } + result << "\x0F\xD3\x36\x82"; + result.write(wstart, len); + result << "\bw"; + pos += len; + } + } + else if(c == '\'' || c == '"' || (c == '[' && (raw[pos + 1] == '[' || raw[pos + 1] == '='))) + { + if(c == '[') + { + int len = 1, eqs=0; + char w; + const char *wstart = raw + pos; + while((w = wstart[len]) && (w == '=')) + { + eqs++; + len++; + } + while((w = wstart[len])) + { + if(w == ']') + { + int nlen = 1; + const char *cstart = wstart + len; + while((w = cstart[nlen]) && (w == '=')) + nlen++; + if(w == ']' && nlen == eqs+1) + { + len += nlen+1; + break; + } + } + len++; + } + result << "\x0F\xDC\x32\x2F"; + result.write(wstart, len); + result << "\bw"; + pos += len; + } + else + { + int len = 1; + char w; + const char *wstart = raw+pos; + while((w = wstart[len]) && (w != c)) + { + if(w == '\\' && wstart[len + 1]) + len++; + len++; + } + if(w == c) + len++; + result << "\x0F\xDC\x32\x2F"; + result.write(wstart, len); + result << "\bw"; + pos += len; + } + } + else if(c == '-' && raw[pos + 1] == '-') + { + if(raw[pos + 2] == '[') + { + int len = 3, eqs = 0; + char w; + const char *wstart = raw + pos; + while((w = wstart[len]) && (w == '=')) + { + eqs++; + len++; + } + while((w = wstart[len])) + { + if(w == ']') + { + int nlen = 1; + const char *cstart = wstart + len; + while((w = cstart[nlen]) && (w == '=')) + nlen++; + if(w == ']' && nlen == eqs + 1) + { + len += nlen+1; + break; + } + } + len++; + } + result << "\x0F\x85\x99\x01"; + result.write(wstart, len); + result << "\bw"; + pos += len; + } + else + { + int len = 2; + char w; + const char *wstart = raw + pos; + while((w = wstart[len]) && (w != '\n')) + len++; + result << "\x0F\x85\x99\x01"; + result.write(wstart, len); + result << "\bw"; + pos += len; + } + } + else if(c == '{' || c == '}') + { + result << "\x0F\xCB\x4B\x16" << c; + pos++; + } + else if(c == '.' && raw[pos + 1] == '.' && raw[pos + 2] == '.') + { + result << "\x0F\x2A\xA1\x98..."; + pos += 3; + } + else + { + result << c; + pos++; + } + } + return result.str(); +} + std::string LuaScriptInterface::FormatCommand(std::string command) { if(command != "" && command[0] == '!') @@ -2941,7 +3284,7 @@ std::string LuaScriptInterface::FormatCommand(std::string command) return "!"+legacy->FormatCommand(command.substr(1)); } else - return command; + return highlight(command); } LuaScriptInterface::~LuaScriptInterface() { diff --git a/src/lua/LuaScriptInterface.h b/src/lua/LuaScriptInterface.h index edef9dfe2..65e770917 100644 --- a/src/lua/LuaScriptInterface.h +++ b/src/lua/LuaScriptInterface.h @@ -1,12 +1,7 @@ #ifndef LUASCRIPTINTERFACE_H_ #define LUASCRIPTINTERFACE_H_ -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" -} +#include "LuaCompat.h" #include "CommandInterface.h" #include "simulation/Simulation.h" @@ -136,6 +131,8 @@ class LuaScriptInterface: public CommandInterface static int graphics_fillRect(lua_State * l); static int graphics_drawCircle(lua_State * l); static int graphics_fillCircle(lua_State * l); + static int graphics_getColors(lua_State * l); + static int graphics_getHexColor(lua_State * l); void initFileSystemAPI(); static int fileSystem_list(lua_State * l); @@ -149,6 +146,9 @@ class LuaScriptInterface: public CommandInterface static int fileSystem_copy(lua_State * l); public: + int tpt_index(lua_State *l); + int tpt_newIndex(lua_State *l); + ui::Window * Window; lua_State *l; LuaScriptInterface(GameController * c, GameModel * m); diff --git a/src/lua/LuaSlider.cpp b/src/lua/LuaSlider.cpp index f8505d2e3..28b847bfa 100644 --- a/src/lua/LuaSlider.cpp +++ b/src/lua/LuaSlider.cpp @@ -1,10 +1,4 @@ #ifdef LUACONSOLE -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" -} #include #include "LuaSlider.h" diff --git a/src/lua/LuaSlider.h b/src/lua/LuaSlider.h index a1a97c45f..3fd919ed5 100644 --- a/src/lua/LuaSlider.h +++ b/src/lua/LuaSlider.h @@ -1,11 +1,5 @@ #pragma once -extern "C" { - #include "lua.h" - #include "lauxlib.h" - #include "lualib.h" -} - #include "LuaLuna.h" #include "LuaComponent.h" diff --git a/src/lua/LuaTextbox.cpp b/src/lua/LuaTextbox.cpp index 89191a65a..474c02d00 100644 --- a/src/lua/LuaTextbox.cpp +++ b/src/lua/LuaTextbox.cpp @@ -1,10 +1,4 @@ #ifdef LUACONSOLE -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" -} #include #include "LuaScriptInterface.h" diff --git a/src/lua/LuaTextbox.h b/src/lua/LuaTextbox.h index 9a45f618d..9f56740b7 100644 --- a/src/lua/LuaTextbox.h +++ b/src/lua/LuaTextbox.h @@ -1,11 +1,5 @@ #pragma once -extern "C" { - #include "lua.h" - #include "lauxlib.h" - #include "lualib.h" -} - #include "LuaLuna.h" #include "LuaComponent.h" diff --git a/src/lua/LuaWindow.cpp b/src/lua/LuaWindow.cpp index 46701f717..1c12583d8 100644 --- a/src/lua/LuaWindow.cpp +++ b/src/lua/LuaWindow.cpp @@ -1,10 +1,4 @@ #ifdef LUACONSOLE -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" -} #include #include "LuaScriptInterface.h" diff --git a/src/lua/LuaWindow.h b/src/lua/LuaWindow.h index 187b3ddd8..69123cc22 100644 --- a/src/lua/LuaWindow.h +++ b/src/lua/LuaWindow.h @@ -1,11 +1,5 @@ #pragma once -extern "C" { - #include "lua.h" - #include "lauxlib.h" - #include "lualib.h" -} - #include "LuaLuna.h" #include "gui/interface/Platform.h" diff --git a/src/lua/TPTSTypes.cpp b/src/lua/TPTSTypes.cpp index 466a7eeca..0779e02f5 100644 --- a/src/lua/TPTSTypes.cpp +++ b/src/lua/TPTSTypes.cpp @@ -26,10 +26,22 @@ AnyType::AnyType(const AnyType & v): AnyType::operator NumberType() { - if(type != TypeNumber) - throw InvalidConversionException(type, TypeNumber); - else + if (type == TypeNumber) return NumberType(value.num); + else if (type == TypeFloat) + return NumberType(value.numf); + else + throw InvalidConversionException(type, TypeNumber); +} + +AnyType::operator FloatType() +{ + if (type == TypeNumber) + return FloatType(value.num); + else if (type == TypeFloat) + return FloatType(value.numf); + else + throw InvalidConversionException(type, TypeFloat); } AnyType::operator StringType() @@ -96,6 +108,18 @@ int NumberType::Value() return value.num; } +//Float Type + +FloatType::FloatType(float number): AnyType(TypeFloat, ValueValue()) +{ + value.numf = number; +} + +float FloatType::Value() +{ + return value.numf; +} + //String type StringType::StringType(std::string string): AnyType(TypeString, ValueValue()) diff --git a/src/lua/TPTSTypes.h b/src/lua/TPTSTypes.h index 00dfbb695..1f58e56ad 100644 --- a/src/lua/TPTSTypes.h +++ b/src/lua/TPTSTypes.h @@ -5,8 +5,8 @@ #include #include "gui/interface/Point.h" -enum ValueType { TypeNumber, TypePoint, TypeString, TypeNull, TypeFunction }; -typedef union { int num; std::string* str; ui::Point* pt; } ValueValue; +enum ValueType { TypeNumber, TypeFloat, TypePoint, TypeString, TypeNull, TypeFunction }; +typedef union { int num; float numf; std::string* str; ui::Point* pt; } ValueValue; class GeneralException { @@ -23,6 +23,7 @@ public: class NumberType; +class FloatType; class StringType; class PointType; @@ -35,6 +36,7 @@ public: AnyType(ValueType type_, ValueValue value_); AnyType(const AnyType & v); operator NumberType(); + operator FloatType(); operator StringType(); operator PointType(); ValueType GetType(); @@ -44,6 +46,8 @@ public: { case TypeNumber: return "Number"; + case TypeFloat: + return "Float"; case TypePoint: return "Point"; case TypeString: @@ -62,6 +66,8 @@ public: { case TypeNumber: return "Number"; + case TypeFloat: + return "Float"; case TypePoint: return "Point"; case TypeString: @@ -95,6 +101,13 @@ public: int Value(); }; +class FloatType: public AnyType +{ +public: + FloatType(float number); + float Value(); +}; + class StringType: public AnyType { public: diff --git a/src/lua/TPTScriptInterface.cpp b/src/lua/TPTScriptInterface.cpp index 5c8454117..edcca0f34 100644 --- a/src/lua/TPTScriptInterface.cpp +++ b/src/lua/TPTScriptInterface.cpp @@ -84,11 +84,13 @@ ValueType TPTScriptInterface::testType(std::string word) parseNumber: for(i = 0; i < word.length(); i++) { - if(!(rawWord[i] >= '0' && rawWord[i] <= '9') && rawWord[i] != '.' && !(rawWord[i] == '-' && !i)) + if (!(rawWord[i] >= '0' && rawWord[i] <= '9') && !(rawWord[i] == '-' && !i)) { - if(rawWord[i] == ',' && rawWord[i+1] >= '0' && rawWord[i+1] <= '9') + if (rawWord[i] == '.' && rawWord[i+1]) + goto parseFloat; + else if (rawWord[i] == ',' && rawWord[i+1] >= '0' && rawWord[i+1] <= '9') goto parsePoint; - else if((rawWord[i] == '#' || rawWord[i] == 'x') && + else if ((rawWord[i] == '#' || (i && rawWord[i-1] == '0' && rawWord[i] == 'x')) && ((rawWord[i+1] >= '0' && rawWord[i+1] <= '9') || (rawWord[i+1] >= 'a' && rawWord[i+1] <= 'f') || (rawWord[i+1] >= 'A' && rawWord[i+1] <= 'F'))) @@ -97,17 +99,23 @@ ValueType TPTScriptInterface::testType(std::string word) goto parseString; } } + return TypeNumber; + parseFloat: + for (i++; i < word.length(); i++) + if(!((rawWord[i] >= '0' && rawWord[i] <= '9') || (rawWord[i] >= 'a' && rawWord[i] <= 'f') || (rawWord[i] >= 'A' && rawWord[i] <= 'F'))) + { + goto parseString; + } + return TypeFloat; parseNumberHex: - i++; - for(; i < word.length(); i++) + for (i++; i < word.length(); i++) if(!((rawWord[i] >= '0' && rawWord[i] <= '9') || (rawWord[i] >= 'a' && rawWord[i] <= 'f') || (rawWord[i] >= 'A' && rawWord[i] <= 'F'))) { goto parseString; } return TypeNumber; parsePoint: - i++; - for(; i < word.length(); i++) + for (i++; i < word.length(); i++) if(!(rawWord[i] >= '0' && rawWord[i] <= '9')) { goto parseString; @@ -117,22 +125,22 @@ ValueType TPTScriptInterface::testType(std::string word) return TypeString; } -int TPTScriptInterface::parseNumber(char * stringData) +float TPTScriptInterface::parseNumber(char * stringData) { char cc; int base = 10; int currentNumber = 0; - if(stringData[0] == '#') + if (stringData[0] == '#') { stringData++; base = 16; } - else if(stringData[0] == '0' && stringData[1] == 'x') + else if (stringData[0] == '0' && stringData[1] == 'x') { stringData+=2; base = 16; } - if(base == 16) + if (base == 16) { while(cc = *(stringData++)) { @@ -149,7 +157,7 @@ int TPTScriptInterface::parseNumber(char * stringData) } else { - return atof(stringData); + return atoi(stringData); } return currentNumber; } @@ -181,6 +189,8 @@ AnyType TPTScriptInterface::eval(std::deque * words) break; case TypeNumber: return NumberType(parseNumber(rawWord)); + case TypeFloat: + return FloatType(atof(rawWord)); case TypePoint: { int pointX, pointY; @@ -190,6 +200,7 @@ AnyType TPTScriptInterface::eval(std::deque * words) case TypeString: return StringType(word); } + return StringType(word); } std::string TPTScriptInterface::FormatCommand(std::string command) @@ -257,9 +268,14 @@ AnyType TPTScriptInterface::tptS_set(std::deque * words) //Selector int newValue; - if(value.GetType() == TypeNumber) + float newValuef; + if (value.GetType() == TypeNumber) { - newValue = ((NumberType)value).Value(); + newValue = newValuef = ((NumberType)value).Value(); + } + else if (value.GetType() == TypeFloat) + { + newValue = newValuef = ((FloatType)value).Value(); } else if(value.GetType() == TypeString) { @@ -267,9 +283,11 @@ AnyType TPTScriptInterface::tptS_set(std::deque * words) { std::string newString = ((StringType)value).Value(); if (newString.at(newString.length()-1) == 'C') - newValue = atoi(newString.substr(0, newString.length()-1).c_str())+273; + newValuef = atof(newString.substr(0, newString.length()-1).c_str())+273.15; else if (newString.at(newString.length()-1) == 'F') - newValue = (int)((atoi(newString.substr(0, newString.length()-1).c_str())-32.0f)*5/9+273.15f); + newValuef = (atof(newString.substr(0, newString.length()-1).c_str())-32.0f)*5/9+273.15f; + else + throw GeneralException("Invalid value for assignment"); } else { @@ -285,7 +303,7 @@ AnyType TPTScriptInterface::tptS_set(std::deque * words) } else throw GeneralException("Invalid value for assignment"); - if (property.Value() == "type" && (newValue < 0 || newValue >= PT_NUM)) + if (property.Value() == "type" && (newValue < 0 || newValue >= PT_NUM || !sim->elements[newValue].Enabled)) throw GeneralException("Invalid element"); if(selector.GetType() == TypePoint || selector.GetType() == TypeNumber) @@ -309,7 +327,7 @@ AnyType TPTScriptInterface::tptS_set(std::deque * words) *((int*)(partsBlock+(partIndex*sizeof(Particle))+propertyOffset)) = newValue; break; case FormatFloat: - *((float*)(partsBlock+(partIndex*sizeof(Particle))+propertyOffset)) = newValue; + *((float*)(partsBlock+(partIndex*sizeof(Particle))+propertyOffset)) = newValuef; break; } returnValue = 1; @@ -334,7 +352,7 @@ AnyType TPTScriptInterface::tptS_set(std::deque * words) if(sim->parts[j].type) { returnValue++; - *((float*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue; + *((float*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValuef; } } break; @@ -371,7 +389,7 @@ AnyType TPTScriptInterface::tptS_set(std::deque * words) if(sim->parts[j].type == type) { returnValue++; - *((float*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue; + *((float*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValuef; } } break; diff --git a/src/lua/TPTScriptInterface.h b/src/lua/TPTScriptInterface.h index dea284e73..d0144075d 100644 --- a/src/lua/TPTScriptInterface.h +++ b/src/lua/TPTScriptInterface.h @@ -7,7 +7,7 @@ class TPTScriptInterface: public CommandInterface { protected: AnyType eval(std::deque * words); - int parseNumber(char * stringData); + float parseNumber(char * stringData); AnyType tptS_set(std::deque * words); AnyType tptS_create(std::deque * words); AnyType tptS_delete(std::deque * words); diff --git a/src/socket/auxiliar.c b/src/lua/socket/auxiliar.c similarity index 99% rename from src/socket/auxiliar.c rename to src/lua/socket/auxiliar.c index 951497011..cb00e7b43 100644 --- a/src/socket/auxiliar.c +++ b/src/lua/socket/auxiliar.c @@ -24,7 +24,7 @@ int auxiliar_open(lua_State *L) { * Creates a new class with given methods * Methods whose names start with __ are passed directly to the metatable. \*-------------------------------------------------------------------------*/ -void auxiliar_newclass(lua_State *L, const char *classname, luaL_reg *func) { +void auxiliar_newclass(lua_State *L, const char *classname, luaL_Reg *func) { luaL_newmetatable(L, classname); /* mt */ /* create __index table to place methods */ lua_pushstring(L, "__index"); /* mt,"__index" */ diff --git a/src/socket/auxiliar.h b/src/lua/socket/auxiliar.h similarity index 97% rename from src/socket/auxiliar.h rename to src/lua/socket/auxiliar.h index 18b849554..be704142b 100644 --- a/src/socket/auxiliar.h +++ b/src/lua/socket/auxiliar.h @@ -31,11 +31,10 @@ * RCS ID: $Id: auxiliar.h,v 1.9 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ -#include "lua.h" -#include "lauxlib.h" +#include "../LuaCompat.h" int auxiliar_open(lua_State *L); -void auxiliar_newclass(lua_State *L, const char *classname, luaL_reg *func); +void auxiliar_newclass(lua_State *L, const char *classname, luaL_Reg *func); void auxiliar_add2group(lua_State *L, const char *classname, const char *group); void auxiliar_setclass(lua_State *L, const char *classname, int objidx); void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx); diff --git a/src/socket/buffer.c b/src/lua/socket/buffer.c similarity index 98% rename from src/socket/buffer.c rename to src/lua/socket/buffer.c index 73f4ffa85..11a9e5f0e 100644 --- a/src/socket/buffer.c +++ b/src/lua/socket/buffer.c @@ -4,9 +4,6 @@ * * RCS ID: $Id: buffer.c,v 1.28 2007/06/11 23:44:54 diego Exp $ \*=========================================================================*/ -#include "lua.h" -#include "lauxlib.h" - #include "buffer.h" /*=========================================================================*\ @@ -225,7 +222,7 @@ static int recvline(p_buffer buf, luaL_Buffer *b) { pos = 0; while (pos < count && data[pos] != '\n') { /* we ignore all \r's */ - if (data[pos] != '\r') luaL_putchar(b, data[pos]); + if (data[pos] != '\r') luaL_addchar(b, data[pos]); pos++; } if (pos < count) { /* found '\n' */ diff --git a/src/socket/buffer.h b/src/lua/socket/buffer.h similarity index 98% rename from src/socket/buffer.h rename to src/lua/socket/buffer.h index baf93caa0..3cbba6b20 100644 --- a/src/socket/buffer.h +++ b/src/lua/socket/buffer.h @@ -17,7 +17,7 @@ * * RCS ID: $Id: buffer.h,v 1.12 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ -#include "lua.h" +#include "../LuaCompat.h" #include "io.h" #include "timeout.h" diff --git a/src/socket/except.c b/src/lua/socket/except.c similarity index 97% rename from src/socket/except.c rename to src/lua/socket/except.c index 5faa5be00..74ec666e9 100644 --- a/src/socket/except.c +++ b/src/lua/socket/except.c @@ -6,9 +6,6 @@ \*=========================================================================*/ #include -#include "lua.h" -#include "lauxlib.h" - #include "except.h" /*=========================================================================*\ @@ -21,7 +18,7 @@ static int finalize(lua_State *L); static int do_nothing(lua_State *L); /* except functions */ -static luaL_reg func[] = { +static luaL_Reg func[] = { {"newtry", global_newtry}, {"protect", global_protect}, {NULL, NULL} diff --git a/src/socket/except.h b/src/lua/socket/except.h similarity index 98% rename from src/socket/except.h rename to src/lua/socket/except.h index 81efb29be..5d5a18293 100644 --- a/src/socket/except.h +++ b/src/lua/socket/except.h @@ -28,7 +28,7 @@ * RCS ID: $Id: except.h,v 1.2 2005/09/29 06:11:41 diego Exp $ \*=========================================================================*/ -#include "lua.h" +#include "../LuaCompat.h" int except_open(lua_State *L); diff --git a/src/socket/inet.c b/src/lua/socket/inet.c similarity index 99% rename from src/socket/inet.c rename to src/lua/socket/inet.c index f2cddeeab..4506cefbb 100644 --- a/src/socket/inet.c +++ b/src/lua/socket/inet.c @@ -7,9 +7,6 @@ #include #include -#include "lua.h" -#include "lauxlib.h" - #include "inet.h" /*=========================================================================*\ @@ -21,7 +18,7 @@ static void inet_pushresolved(lua_State *L, struct hostent *hp); static int inet_global_gethostname(lua_State *L); /* DNS functions */ -static luaL_reg func[] = { +static luaL_Reg func[] = { { "toip", inet_global_toip }, { "tohostname", inet_global_tohostname }, { "gethostname", inet_global_gethostname}, diff --git a/src/socket/inet.h b/src/lua/socket/inet.h similarity index 98% rename from src/socket/inet.h rename to src/lua/socket/inet.h index 766226611..b1a081cc7 100644 --- a/src/socket/inet.h +++ b/src/lua/socket/inet.h @@ -16,7 +16,7 @@ * * RCS ID: $Id: inet.h,v 1.16 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ -#include "lua.h" +#include "../LuaCompat.h" #include "socket.h" #include "timeout.h" diff --git a/src/socket/io.c b/src/lua/socket/io.c similarity index 100% rename from src/socket/io.c rename to src/lua/socket/io.c diff --git a/src/socket/io.h b/src/lua/socket/io.h similarity index 98% rename from src/socket/io.h rename to src/lua/socket/io.h index cce3aaf55..810a3b977 100644 --- a/src/socket/io.h +++ b/src/lua/socket/io.h @@ -15,7 +15,7 @@ * RCS ID: $Id: io.h,v 1.11 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ #include -#include "lua.h" +#include "../LuaCompat.h" #include "timeout.h" diff --git a/src/socket/luasocket.c b/src/lua/socket/luasocket.c similarity index 90% rename from src/socket/luasocket.c rename to src/lua/socket/luasocket.c index 11ffee94c..e44e37bfe 100644 --- a/src/socket/luasocket.c +++ b/src/lua/socket/luasocket.c @@ -14,16 +14,6 @@ * RCS ID: $Id: luasocket.c,v 1.53 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ -/*=========================================================================*\ -* Standard include files -\*=========================================================================*/ -#include "lua.h" -#include "lauxlib.h" - -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include "compat-5.1.h" -#endif - /*=========================================================================*\ * LuaSocket includes \*=========================================================================*/ @@ -47,7 +37,7 @@ static int base_open(lua_State *L); /*-------------------------------------------------------------------------*\ * Modules and functions \*-------------------------------------------------------------------------*/ -static const luaL_reg mod[] = { +static const luaL_Reg mod[] = { {"auxiliar", auxiliar_open}, {"except", except_open}, {"timeout", timeout_open}, @@ -59,7 +49,7 @@ static const luaL_reg mod[] = { {NULL, NULL} }; -static luaL_reg func[] = { +static luaL_Reg func[] = { {"skip", global_skip}, {"__unload", global_unload}, {NULL, NULL} diff --git a/src/socket/luasocket.h b/src/lua/socket/luasocket.h similarity index 97% rename from src/socket/luasocket.h rename to src/lua/socket/luasocket.h index 67270abb9..4b22bfe30 100644 --- a/src/socket/luasocket.h +++ b/src/lua/socket/luasocket.h @@ -8,7 +8,7 @@ * * RCS ID: $Id: luasocket.h,v 1.25 2007/06/11 23:44:54 diego Exp $ \*=========================================================================*/ -#include "lua.h" +#include "../LuaCompat.h" /*-------------------------------------------------------------------------*\ * Current socket library version diff --git a/src/socket/options.c b/src/lua/socket/options.c similarity index 99% rename from src/socket/options.c rename to src/lua/socket/options.c index 5da3c518c..a51850501 100644 --- a/src/socket/options.c +++ b/src/lua/socket/options.c @@ -6,8 +6,6 @@ \*=========================================================================*/ #include -#include "lauxlib.h" - #include "auxiliar.h" #include "options.h" #include "inet.h" diff --git a/src/socket/options.h b/src/lua/socket/options.h similarity index 97% rename from src/socket/options.h rename to src/lua/socket/options.h index 4981cf2a0..ac65047a4 100644 --- a/src/socket/options.h +++ b/src/lua/socket/options.h @@ -10,7 +10,7 @@ * RCS ID: $Id: options.h,v 1.4 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ -#include "lua.h" +#include "../LuaCompat.h" #include "socket.h" /* option registry */ diff --git a/src/socket/select.c b/src/lua/socket/select.c similarity index 98% rename from src/socket/select.c rename to src/lua/socket/select.c index d70f66271..9c295dd90 100644 --- a/src/socket/select.c +++ b/src/lua/socket/select.c @@ -6,9 +6,6 @@ \*=========================================================================*/ #include -#include "lua.h" -#include "lauxlib.h" - #include "socket.h" #include "timeout.h" #include "select.h" @@ -27,7 +24,7 @@ static void make_assoc(lua_State *L, int tab); static int global_select(lua_State *L); /* functions in library namespace */ -static luaL_reg func[] = { +static luaL_Reg func[] = { {"select", global_select}, {NULL, NULL} }; diff --git a/src/socket/select.h b/src/lua/socket/select.h similarity index 100% rename from src/socket/select.h rename to src/lua/socket/select.h diff --git a/src/socket/socket.h b/src/lua/socket/socket.h similarity index 100% rename from src/socket/socket.h rename to src/lua/socket/socket.h diff --git a/src/socket/socket.lua b/src/lua/socket/socket.lua similarity index 100% rename from src/socket/socket.lua rename to src/lua/socket/socket.lua diff --git a/src/socket/socket.lua.cpp b/src/lua/socket/socket.lua.cpp similarity index 98% rename from src/socket/socket.lua.cpp rename to src/lua/socket/socket.lua.cpp index 4952cce62..ca5e61b1d 100644 --- a/src/socket/socket.lua.cpp +++ b/src/lua/socket/socket.lua.cpp @@ -1,10 +1,6 @@ #ifdef LUACONSOLE // socket.lua from luasocket compiled into a cpp file -extern "C" { - #include "lua.h" - #include "lauxlib.h" - #include "lualib.h" -} +#include "../LuaCompat.h" void luaopen_socket(lua_State *l){ int socket_luac_sz=4061; const char* socket_luac="-----------------------------------------------------------------------------\012-- LuaSocket helper module\012-- Author: Diego Nehab\012-- RCS ID: $Id: socket.lua,v 1.22 2005/11/22 08:33:29 diego Exp $\012-----------------------------------------------------------------------------\012\012-----------------------------------------------------------------------------\012-- Declare module and import dependencies\012-----------------------------------------------------------------------------\012local base = _G\012local string = require(\042string\042)\012local math = require(\042math\042)\012local socket = require(\042socket.core\042)\012module(\042socket\042)\012\012-----------------------------------------------------------------------------\012-- Exported auxiliar functions\012-----------------------------------------------------------------------------\012function connect(address, port, laddress, lport)\012 local sock, err = socket.tcp()\012 if not sock then return nil, err end\012 if laddress then\012 local res, err = sock:bind(laddress, lport, -1)\012 if not res then return nil, err end\012 end\012 local res, err = sock:connect(address, port)\012 if not res then return nil, err end\012 return sock\012end\012\012function bind(host, port, backlog)\012 local sock, err = socket.tcp()\012 if not sock then return nil, err end\012 sock:setoption(\042reuseaddr\042, true)\012 local res, err = sock:bind(host, port)\012 if not res then return nil, err end\012 res, err = sock:listen(backlog)\012 if not res then return nil, err end\012 return sock\012end\012\012try = newtry()\012\012function choose(table)\012 return function(name, opt1, opt2)\012 if base.type(name) ~= \042string\042 then\012 name, opt1, opt2 = \042default\042, name, opt1\012 end\012 local f = table[name or \042nil\042]\012 if not f then base.error(\042unknown key (\042.. base.tostring(name) ..\042)\042, 3)\012 else return f(opt1, opt2) end\012 end\012end\012\012-----------------------------------------------------------------------------\012-- Socket sources and sinks, conforming to LTN12\012-----------------------------------------------------------------------------\012-- create namespaces inside LuaSocket namespace\012sourcet = {}\012sinkt = {}\012\012BLOCKSIZE = 2048\012\012sinkt[\042close-when-done\042] = function(sock)\012 return base.setmetatable({\012 getfd = function() return sock:getfd() end,\012 dirty = function() return sock:dirty() end\012 }, {\012 __call = function(self, chunk, err)\012 if not chunk then\012 sock:close()\012 return 1\012 else return sock:send(chunk) end\012 end\012 })\012end\012\012sinkt[\042keep-open\042] = function(sock)\012 return base.setmetatable({\012 getfd = function() return sock:getfd() end,\012 dirty = function() return sock:dirty() end\012 }, {\012 __call = function(self, chunk, err)\012 if chunk then return sock:send(chunk)\012 else return 1 end\012 end\012 })\012end\012\012sinkt[\042default\042] = sinkt[\042keep-open\042]\012\012sink = choose(sinkt)\012\012sourcet[\042by-length\042] = function(sock, length)\012 return base.setmetatable({\012 getfd = function() return sock:getfd() end,\012 dirty = function() return sock:dirty() end\012 }, {\012 __call = function()\012 if length <= 0 then return nil end\012 local size = math.min(socket.BLOCKSIZE, length)\012 local chunk, err = sock:receive(size)\012 if err then return nil, err end\012 length = length - string.len(chunk)\012 return chunk\012 end\012 })\012end\012\012sourcet[\042until-closed\042] = function(sock)\012 local done\012 return base.setmetatable({\012 getfd = function() return sock:getfd() end,\012 dirty = function() return sock:dirty() end\012 }, {\012 __call = function()\012 if done then return nil end\012 local chunk, err, partial = sock:receive(socket.BLOCKSIZE)\012 if not err then return chunk\012 elseif err == \042closed\042 then\012 sock:close()\012 done = 1\012 return partial\012 else return nil, err end\012 end\012 })\012end\012\012\012sourcet[\042default\042] = sourcet[\042until-closed\042]\012\012source = choose(sourcet)\012\012"; diff --git a/src/socket/socket.lua.h b/src/lua/socket/socket.lua.h similarity index 57% rename from src/socket/socket.lua.h rename to src/lua/socket/socket.lua.h index 2e527c859..9bc789240 100644 --- a/src/socket/socket.lua.h +++ b/src/lua/socket/socket.lua.h @@ -1,2 +1,2 @@ -#include "lua.h" +#include "../LuaCompat.h" void luaopen_socket(lua_State *l); diff --git a/src/socket/tcp.c b/src/lua/socket/tcp.c similarity index 99% rename from src/socket/tcp.c rename to src/lua/socket/tcp.c index 6b8a79b4b..2b06ed2b7 100644 --- a/src/socket/tcp.c +++ b/src/lua/socket/tcp.c @@ -6,9 +6,6 @@ \*=========================================================================*/ #include -#include "lua.h" -#include "lauxlib.h" - #include "auxiliar.h" #include "socket.h" #include "inet.h" @@ -38,7 +35,7 @@ static int meth_setfd(lua_State *L); static int meth_dirty(lua_State *L); /* tcp object methods */ -static luaL_reg tcp[] = { +static luaL_Reg tcp[] = { {"__gc", meth_close}, {"__tostring", auxiliar_tostring}, {"accept", meth_accept}, @@ -73,7 +70,7 @@ static t_opt opt[] = { }; /* functions in library namespace */ -static luaL_reg func[] = { +static luaL_Reg func[] = { {"tcp", global_create}, {NULL, NULL} }; diff --git a/src/socket/tcp.h b/src/lua/socket/tcp.h similarity index 97% rename from src/socket/tcp.h rename to src/lua/socket/tcp.h index 511357f37..6bd59317a 100644 --- a/src/socket/tcp.h +++ b/src/lua/socket/tcp.h @@ -16,7 +16,7 @@ * * RCS ID: $Id: tcp.h,v 1.7 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ -#include "lua.h" +#include "../LuaCompat.h" #include "buffer.h" #include "timeout.h" diff --git a/src/socket/timeout.c b/src/lua/socket/timeout.c similarity index 99% rename from src/socket/timeout.c rename to src/lua/socket/timeout.c index c1df10218..e686d6347 100644 --- a/src/socket/timeout.c +++ b/src/lua/socket/timeout.c @@ -6,9 +6,6 @@ \*=========================================================================*/ #include -#include "lua.h" -#include "lauxlib.h" - #include "auxiliar.h" #include "timeout.h" @@ -33,7 +30,7 @@ static int timeout_lua_gettime(lua_State *L); static int timeout_lua_sleep(lua_State *L); -static luaL_reg func[] = { +static luaL_Reg func[] = { { "gettime", timeout_lua_gettime }, { "sleep", timeout_lua_sleep }, { NULL, NULL } diff --git a/src/socket/timeout.h b/src/lua/socket/timeout.h similarity index 97% rename from src/socket/timeout.h rename to src/lua/socket/timeout.h index d2d896410..5584ab10d 100644 --- a/src/socket/timeout.h +++ b/src/lua/socket/timeout.h @@ -6,7 +6,7 @@ * * RCS ID: $Id: timeout.h,v 1.14 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ -#include "lua.h" +#include "../LuaCompat.h" /* timeout control structure */ typedef struct t_timeout_ { diff --git a/src/socket/udp.c b/src/lua/socket/udp.c similarity index 99% rename from src/socket/udp.c rename to src/lua/socket/udp.c index fc25aa027..d863b549a 100644 --- a/src/socket/udp.c +++ b/src/lua/socket/udp.c @@ -6,9 +6,6 @@ \*=========================================================================*/ #include -#include "lua.h" -#include "lauxlib.h" - #include "auxiliar.h" #include "socket.h" #include "inet.h" @@ -43,7 +40,7 @@ static int meth_setfd(lua_State *L); static int meth_dirty(lua_State *L); /* udp object methods */ -static luaL_reg udp[] = { +static luaL_Reg udp[] = { {"__gc", meth_close}, {"__tostring", auxiliar_tostring}, {"close", meth_close}, @@ -76,7 +73,7 @@ static t_opt opt[] = { }; /* functions in library namespace */ -static luaL_reg func[] = { +static luaL_Reg func[] = { {"udp", global_create}, {NULL, NULL} }; diff --git a/src/socket/udp.h b/src/lua/socket/udp.h similarity index 97% rename from src/socket/udp.h rename to src/lua/socket/udp.h index 280171217..e2383e56d 100644 --- a/src/socket/udp.h +++ b/src/lua/socket/udp.h @@ -14,7 +14,7 @@ * * RCS ID: $Id: udp.h,v 1.10 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ -#include "lua.h" +#include "../LuaCompat.h" #include "timeout.h" #include "socket.h" diff --git a/src/socket/unix.c b/src/lua/socket/unix.c similarity index 99% rename from src/socket/unix.c rename to src/lua/socket/unix.c index 048630f19..086d34e09 100644 --- a/src/socket/unix.c +++ b/src/lua/socket/unix.c @@ -7,9 +7,6 @@ \*=========================================================================*/ #include -#include "lua.h" -#include "lauxlib.h" - #include "auxiliar.h" #include "socket.h" #include "options.h" @@ -40,7 +37,7 @@ static const char *unix_tryconnect(p_unix un, const char *path); static const char *unix_trybind(p_unix un, const char *path); /* unix object methods */ -static luaL_reg un[] = { +static luaL_Reg un[] = { {"__gc", meth_close}, {"__tostring", auxiliar_tostring}, {"accept", meth_accept}, @@ -72,7 +69,7 @@ static t_opt opt[] = { }; /* our socket creation function */ -static luaL_reg func[] = { +static luaL_Reg func[] = { {"unix", global_create}, {NULL, NULL} }; diff --git a/src/socket/unix.h b/src/lua/socket/unix.h similarity index 96% rename from src/socket/unix.h rename to src/lua/socket/unix.h index f3b543e06..491b6466c 100644 --- a/src/socket/unix.h +++ b/src/lua/socket/unix.h @@ -10,7 +10,7 @@ * * RCS ID: $Id: unix.h,v 1.9 2006/03/13 07:16:39 diego Exp $ \*=========================================================================*/ -#include "lua.h" +#include "../LuaCompat.h" #include "buffer.h" #include "timeout.h" diff --git a/src/socket/usocket.c b/src/lua/socket/usocket.c similarity index 100% rename from src/socket/usocket.c rename to src/lua/socket/usocket.c diff --git a/src/socket/usocket.h b/src/lua/socket/usocket.h similarity index 100% rename from src/socket/usocket.h rename to src/lua/socket/usocket.h diff --git a/src/socket/wsocket.c b/src/lua/socket/wsocket.c similarity index 100% rename from src/socket/wsocket.c rename to src/lua/socket/wsocket.c diff --git a/src/socket/wsocket.h b/src/lua/socket/wsocket.h similarity index 100% rename from src/socket/wsocket.h rename to src/lua/socket/wsocket.h diff --git a/src/simulation/CoordStack.h b/src/simulation/CoordStack.h new file mode 100644 index 000000000..32625a24f --- /dev/null +++ b/src/simulation/CoordStack.h @@ -0,0 +1,74 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef Simulation_CoordStack_h +#define Simulation_CoordStack_h + +#include "Config.h" // for XRES and YRES +#include + +class CoordStackOverflowException: public std::exception +{ +public: + CoordStackOverflowException() { } + virtual const char* what() const throw() + { + return "Maximum number of entries in the coordinate stack was exceeded"; + } + ~CoordStackOverflowException() throw() {}; +}; + +class CoordStack +{ +private: + unsigned short (*stack)[2]; + int stack_size; + const static int stack_limit = XRES*YRES; +public: + CoordStack() : + stack(NULL), + stack_size(0) + { + stack = (unsigned short(*)[2])(malloc(sizeof(unsigned short)*2*stack_limit)); + } + ~CoordStack() + { + if (stack) free(stack); + } + void push(int x, int y) + { + if (stack_size>=stack_limit) + throw CoordStackOverflowException(); + stack[stack_size][0] = x; + stack[stack_size][1] = y; + stack_size++; + } + void pop(int& x, int& y) + { + stack_size--; + x = stack[stack_size][0]; + y = stack[stack_size][1]; + } + int getSize() const + { + return stack_size; + } + void clear() + { + stack_size = 0; + } +}; + +#endif diff --git a/src/simulation/ElementGraphics.h b/src/simulation/ElementGraphics.h index d1c816739..1069d8d1d 100644 --- a/src/simulation/ElementGraphics.h +++ b/src/simulation/ElementGraphics.h @@ -21,6 +21,7 @@ #define FIREMODE 0x00FF0000 #define FIRE_ADD 0x00010000 #define FIRE_BLEND 0x00020000 +#define FIRE_SPARK 0x00040000 #define EFFECT 0xFF000000 #define EFFECT_GRAVIN 0x01000000 @@ -29,7 +30,8 @@ #define EFFECT_DBGLINES 0x08000000 #define RENDER_EFFE OPTIONS | PSPEC_STICKMAN | EFFECT | PMODE_SPARK | PMODE_FLARE | PMODE_LFLARE -#define RENDER_FIRE OPTIONS | PSPEC_STICKMAN | /*PMODE_FLAT |*/ PMODE_ADD | PMODE_BLEND | FIREMODE +#define RENDER_FIRE OPTIONS | PSPEC_STICKMAN | /*PMODE_FLAT |*/ PMODE_ADD | PMODE_BLEND | FIRE_ADD | FIRE_BLEND +#define RENDER_SPRK OPTIONS | PSPEC_STICKMAN | PMODE_ADD | PMODE_BLEND | FIRE_SPARK #define RENDER_GLOW OPTIONS | PSPEC_STICKMAN | /*PMODE_FLAT |*/ PMODE_GLOW | PMODE_ADD | PMODE_BLEND #define RENDER_BLUR OPTIONS | PSPEC_STICKMAN | /*PMODE_FLAT |*/ PMODE_BLUR | PMODE_ADD | PMODE_BLEND #define RENDER_BLOB OPTIONS | PSPEC_STICKMAN | /*PMODE_FLAT |*/ PMODE_BLOB | PMODE_ADD | PMODE_BLEND diff --git a/src/simulation/Elements.h b/src/simulation/Elements.h index 54f5483aa..f00a3a6c3 100644 --- a/src/simulation/Elements.h +++ b/src/simulation/Elements.h @@ -35,7 +35,9 @@ #define FLAG_STAGNANT 0x1 #define FLAG_SKIPMOVE 0x2 // skip movement for one frame, only implemented for PHOT #define FLAG_WATEREQUAL 0x4 //if a liquid was already checked during equalization -#define FLAG_MOVABLE 0x8 // if can move +#define FLAG_MOVABLE 0x8 // compatibility with old saves (moving SPNG), only applies to SPNG +#define FLAG_PHOTDECO 0x8 // compatibility with old saves (decorated photons), only applies to PHOT. Having the same value as FLAG_MOVABLE is fine because they apply to different elements, and this saves space for future flags, + #define ST_NONE 0 #define ST_SOLID 1 diff --git a/src/simulation/Gravity.cpp b/src/simulation/Gravity.cpp index a2670de00..d76fda5e8 100755 --- a/src/simulation/Gravity.cpp +++ b/src/simulation/Gravity.cpp @@ -74,6 +74,7 @@ void Gravity::gravity_cleanup() free(gravx); free(gravp); free(gravmask); + free(obmap); } void Gravity::gravity_update_async() @@ -126,7 +127,7 @@ void Gravity::gravity_update_async() } } -void *Gravity::update_grav_async_helper(void * context) +TH_ENTRY_POINT void *Gravity::update_grav_async_helper(void * context) { ((Gravity *)context)->update_grav_async(); return NULL; @@ -144,6 +145,10 @@ void Gravity::update_grav_async() //memset(th_gravy, 0, XRES*YRES*sizeof(float)); //memset(th_gravx, 0, XRES*YRES*sizeof(float)); //memset(th_gravp, 0, XRES*YRES*sizeof(float)); +#ifdef GRAVFFT + if (!grav_fft_status) + grav_fft_init(); +#endif while(!thread_done){ if(!done){ update_grav(); @@ -301,7 +306,6 @@ void Gravity::update_grav() if(changed) { th_gravchanged = 1; - if (!grav_fft_status) grav_fft_init(); //copy gravmap into padded gravmap array for (y=0; y=CELL) - { - if (!FloodFillPmapCheck(x1-1, y, parttype) || bitmap[(y*XRES)+x1-1]) - { - break; - } - x1--; - } - while (x2>8])+propoffset)) = propvalue.Float; - break; - - case StructProperty::ParticleType: - case StructProperty::Integer: - *((int*)(((char*)&parts[i>>8])+propoffset)) = propvalue.Integer; - break; - - case StructProperty::UInteger: - *((unsigned int*)(((char*)&parts[i>>8])+propoffset)) = propvalue.UInteger; - break; - - default: - break; - } - bitmap[(y*XRES)+x] = 1; - } - if (y>=CELL+dy) - for (x=x1; x<=x2; x++) - if (FloodFillPmapCheck(x, y-dy, parttype) && !bitmap[((y-dy)*XRES)+x]) - if (!flood_prop_2(x, y-dy, propoffset, propvalue, proptype, parttype, bitmap)) - return 0; - if (y=CELL) + { + if (!FloodFillPmapCheck(x1-1, y, parttype) || bitmap[(y*XRES)+x1-1]) + break; + x1--; + } + while (x2>8])+propoffset)) = propvalue.Float; + break; + + case StructProperty::ParticleType: + case StructProperty::Integer: + *((int*)(((char*)&parts[i>>8])+propoffset)) = propvalue.Integer; + break; + + case StructProperty::UInteger: + *((unsigned int*)(((char*)&parts[i>>8])+propoffset)) = propvalue.UInteger; + break; + + default: + break; + } + bitmap[(y*XRES)+x] = 1; + did_something = 1; + } + if (y>=CELL+dy) + for (x=x1; x<=x2; x++) + if (FloodFillPmapCheck(x, y-dy, parttype) && !bitmap[((y-dy)*XRES)+x]) + cs.push(x, y-dy); + if (y0); + } + catch (std::exception& e) + { + std::cerr << e.what() << std::endl; + free(bitmap); + return -1; + } free(bitmap); - return 0; + return did_something; } SimulationSample Simulation::GetSample(int x, int y) @@ -1439,21 +1447,23 @@ int Simulation::FloodParts(int x, int y, int fullc, int cm, int flags) if (cm==-1) { //if initial flood point is out of bounds, do nothing - if (c != 0 && (x < CELL || x >= XRES-CELL || y < CELL || y >= YRES-CELL)) + if (c != 0 && (x < CELL || x >= XRES-CELL || y < CELL || y >= YRES-CELL || c == PT_SPRK)) return 1; else if (x < 0 || x >= XRES || y < 0 || y >= YRES) return 1; - if (c==0) + if (c == 0) { cm = pmap[y][x]&0xFF; - if (!cm) - cm = photons[y][x]&0xFF; if (!cm) { - if (bmap[y/CELL][x/CELL]) - return FloodWalls(x, y, WL_ERASE, -1); - else - return -1; + cm = photons[y][x]&0xFF; + if (!cm) + { + if (bmap[y/CELL][x/CELL]) + return FloodWalls(x, y, WL_ERASE, -1); + else + return -1; + } } } else @@ -2043,8 +2053,11 @@ void Simulation::init_can_move() || destinationType == PT_ISOZ || destinationType == PT_ISZS || destinationType == PT_QRTZ || destinationType == PT_PQRT || destinationType == PT_H2) can_move[PT_PHOT][destinationType] = 2; - if (destinationType != PT_DMND && destinationType != PT_INSL && destinationType != PT_VOID && destinationType != PT_PVOD && destinationType != PT_VIBR) + if (destinationType != PT_DMND && destinationType != PT_INSL && destinationType != PT_VOID && destinationType != PT_PVOD && destinationType != PT_VIBR && destinationType != PT_PRTI && destinationType != PT_PRTO) + { can_move[PT_PROT][destinationType] = 2; + can_move[PT_GRVT][destinationType] = 2; + } } //other special cases that weren't covered above @@ -2578,24 +2591,6 @@ int Simulation::get_normal_interp(int pt, float x0, float y0, float dx, float dy return get_normal(pt, x, y, dx, dy, nx, ny); } -//For soap only -void Simulation::detach(int i) -{ - if ((parts[i].ctype&2) == 2) - { - if ((parts[parts[i].tmp].ctype&4) == 4) - parts[parts[i].tmp].ctype ^= 4; - } - - if ((parts[i].ctype&4) == 4) - { - if ((parts[parts[i].tmp2].ctype&2) == 2) - parts[parts[i].tmp2].ctype ^= 2; - } - - parts[i].ctype = 0; -} - void Simulation::kill_part(int i)//kills particle number i { int x = (int)(parts[i].x+0.5f); @@ -2627,7 +2622,7 @@ void Simulation::kill_part(int i)//kills particle number i } else if (parts[i].type == PT_SOAP) { - detach(i); + Element_SOAP::detach(this, i); } parts[i].type = PT_NONE; @@ -2657,7 +2652,7 @@ void Simulation::part_change_type(int i, int x, int y, int t)//changes the type fighcount--; } else if (parts[i].type == PT_SOAP) - detach(i); + Element_SOAP::detach(this, i); parts[i].type = t; if (elements[t].Properties & TYPE_ENERGY) @@ -2772,13 +2767,18 @@ int Simulation::create_part(int p, int x, int y, int tv) if (t == PT_LIFE && v < NGOL && drawOn != PT_STOR) parts[pmap[y][x]>>8].tmp = v; } - else if ((drawOn == PT_DTEC || (drawOn == PT_PSTN && t != PT_FRME)) && drawOn != t) + else if ((drawOn == PT_DTEC || (drawOn == PT_PSTN && t != PT_FRME) || drawOn == PT_DRAY) && drawOn != t) { parts[pmap[y][x]>>8].ctype = t; - if (drawOn == PT_DTEC && t==PT_LIFE && v>8].tmp = v; + if (t == PT_LIFE && v >= 0 && v < NGOL) + { + if (drawOn == PT_DTEC) + parts[pmap[y][x]>>8].tmp = v; + else if (drawOn == PT_DRAY) + parts[pmap[y][x]>>8].ctype |= v<<8; + } } - else if (drawOn == PT_CRAY && drawOn != t && drawOn != PT_PSCN && drawOn != PT_INST && drawOn != PT_METL) + else if (drawOn == PT_CRAY && drawOn != t && t != PT_PSCN && t != PT_INST && t != PT_METL) { parts[pmap[y][x]>>8].ctype = t; if (t==PT_LIFE && v>8], parts[i].ctype); break; } case PT_ELEC: @@ -3054,6 +3056,15 @@ int Simulation::create_part(int p, int x, int y, int tv) parts[i].vy = 2.0f*sinf(a); break; } + case PT_GRVT: + { + float a = (rand()%360)*3.14159f/180.0f; + parts[i].life = 250 + rand()%200; + parts[i].vx = 2.0f*cosf(a); + parts[i].vy = 2.0f*sinf(a); + parts[i].tmp = 7; + break; + } case PT_TRON: { int randhue = rand()%360; @@ -4199,6 +4210,12 @@ killed: } else { + if (mv > SIM_MAXVELOCITY) + { + parts[i].vx *= SIM_MAXVELOCITY/mv; + parts[i].vy *= SIM_MAXVELOCITY/mv; + mv = SIM_MAXVELOCITY; + } // interpolate to see if there is anything in the way dx = parts[i].vx*ISTP/mv; dy = parts[i].vy*ISTP/mv; @@ -4224,7 +4241,7 @@ killed: clear_y = (int)(clear_yf+0.5f); break; } - if (fin_x=XRES-CELL || fin_y>=YRES-CELL || pmap[fin_y][fin_x] || (bmap[fin_y/CELL][fin_x/CELL] && (bmap[fin_y/CELL][fin_x/CELL]==WL_DESTROYALL || !eval_move(t,fin_x,fin_y,NULL)))) + if (!eval_move(t, fin_x, fin_y, NULL) || (t == PT_PHOT && pmap[fin_y][fin_x])) { // found an obstacle clear_xf = fin_xf-dx; @@ -4284,7 +4301,8 @@ killed: } r = get_wavelength_bin(&parts[i].ctype); - if (r == -1) { + if (r == -1 || !(parts[i].ctype&0x3FFFFFFF)) + { kill_part(i); continue; } @@ -4434,7 +4452,7 @@ killed: else { s = 1; - r = (rand()%2)*2-1; + r = (rand()%2)*2-1;// position search direction (left/right first) if ((clear_x!=x || clear_y!=y || nt || surround_space) && (fabsf(parts[i].vx)>0.01f || fabsf(parts[i].vy)>0.01f)) { @@ -4522,10 +4540,15 @@ killed: rt = 30;//slight less water lag, although it changes how it moves a lot else rt = 10; + // clear_xf, clear_yf is the last known position that the particle should almost certainly be able to move to nxf = clear_xf; nyf = clear_yf; + nx = clear_x; + ny = clear_y; + // Look for spaces to move horizontally (perpendicular to gravity direction), keep going until a space is found or the number of positions examined = rt for (j=0;jfabsf(pGravX)) mv = fabsf(pGravY); else @@ -4551,8 +4575,13 @@ killed: if (mv<0.0001f) break; pGravX /= mv; pGravY /= mv; + // Move 1 pixel perpendicularly to gravity + // r is +1/-1, to try moving left or right at random if (j) { + // Not quite the gravity direction + // Gravity direction + last change in gravity direction + // This makes liquid movement a bit less frothy, particularly for balls of liquid in radial gravity. With radial gravity, instead of just moving along a tangent, the attempted movement will follow the curvature a bit better. nxf += r*(pGravY*2.0f-prev_pGravY); nyf += -r*(pGravX*2.0f-prev_pGravX); } @@ -4563,6 +4592,7 @@ killed: } prev_pGravX = pGravX; prev_pGravY = pGravY; + // Check whether movement is allowed nx = (int)(nxf+0.5f); ny = (int)(nyf+0.5f); if (nx<0 || ny<0 || nx>=XRES || ny >=YRES) @@ -4572,20 +4602,25 @@ killed: s = do_move(i, x, y, nxf, nyf); if (s) { + // Movement was successful nx = (int)(parts[i].x+0.5f); ny = (int)(parts[i].y+0.5f); break; } + // A particle of a different type, or a wall, was found. Stop trying to move any further horizontally unless the wall should be completely invisible to particles. if (bmap[ny/CELL][nx/CELL]!=WL_STREAM) break; } } if (s==1) { + // The particle managed to move horizontally, now try to move vertically (parallel to gravity direction) + // Keep going until the particle is blocked (by something that isn't the same element) or the number of positions examined = rt clear_x = nx; clear_y = ny; for (j=0;jfabsf(pGravX)) mv = fabsf(pGravY); else @@ -4611,22 +4647,24 @@ killed: if (mv<0.0001f) break; pGravX /= mv; pGravY /= mv; + // Move 1 pixel in the direction of gravity nxf += pGravX; nyf += pGravY; nx = (int)(nxf+0.5f); ny = (int)(nyf+0.5f); if (nx<0 || ny<0 || nx>=XRES || ny>=YRES) break; + // If the space is anything except the same element (a wall, empty space, or occupied by a particle of a different element), try to move into it if ((pmap[ny][nx]&0xFF)!=t || bmap[ny/CELL][nx/CELL]) { s = do_move(i, clear_x, clear_y, nxf, nyf); if (s || bmap[ny/CELL][nx/CELL]!=WL_STREAM) - break; + break; // found the edge of the liquid and movement into it succeeded, so stop moving down } } } else if (s==-1) {} // particle is out of bounds - else if ((clear_x!=x||clear_y!=y) && do_move(i, x, y, clear_xf, clear_yf)) {} + else if ((clear_x!=x||clear_y!=y) && do_move(i, x, y, clear_xf, clear_yf)) {} // try moving to the last clear position else parts[i].flags |= FLAG_STAGNANT; parts[i].vx *= elements[t].Collision; parts[i].vy *= elements[t].Collision; @@ -4760,8 +4798,8 @@ void Simulation::update_particles()//doesn't update the particles themselves, bu { if (emap[y][x]) emap[y][x] --; - air->bmap_blockair[y][x] = (bmap[y][x]==WL_WALL || bmap[y][x]==WL_WALLELEC || (bmap[y][x]==WL_EWALL && !emap[y][x])); - air->bmap_blockairh[y][x] = (bmap[y][x]==WL_WALL || bmap[y][x]==WL_WALLELEC || bmap[y][x]==WL_GRAV || (bmap[y][x]==WL_EWALL && !emap[y][x])) ? 0x8:0; + air->bmap_blockair[y][x] = (bmap[y][x]==WL_WALL || bmap[y][x]==WL_WALLELEC || bmap[y][x]==WL_BLOCKAIR || (bmap[y][x]==WL_EWALL && !emap[y][x])); + air->bmap_blockairh[y][x] = (bmap[y][x]==WL_WALL || bmap[y][x]==WL_WALLELEC || bmap[y][x]==WL_BLOCKAIR || bmap[y][x]==WL_GRAV || (bmap[y][x]==WL_EWALL && !emap[y][x])) ? 0x8:0; } } } diff --git a/src/simulation/Simulation.h b/src/simulation/Simulation.h index 5933619a5..93d92a63b 100644 --- a/src/simulation/Simulation.h +++ b/src/simulation/Simulation.h @@ -135,7 +135,6 @@ public: void kill_part(int i); bool FloodFillPmapCheck(int x, int y, int type); int flood_prop(int x, int y, size_t propoffset, PropertyValue propvalue, StructProperty::PropertyType proptype); - int flood_prop_2(int x, int y, size_t propoffset, PropertyValue propvalue, StructProperty::PropertyType proptype, int parttype, char * bitmap); int flood_water(int x, int y, int i, int originaly, int check); int FloodINST(int x, int y, int fullc, int cm); void detach(int i); diff --git a/src/simulation/SimulationData.cpp b/src/simulation/SimulationData.cpp index d3c74fec3..9ddd03128 100644 --- a/src/simulation/SimulationData.cpp +++ b/src/simulation/SimulationData.cpp @@ -130,6 +130,7 @@ wall_type * LoadWalls(int & wallCount) {PIXPACK(0x579777), PIXPACK(0x000000), 1, Renderer::WallIcon, "GAS WALL", "Allows gases, blocks all other particles."}, {PIXPACK(0xFFEE00), PIXPACK(0xAA9900), 4, Renderer::WallIcon, "GRAVITY WALL", "Gravity wall. Newtonian Gravity has no effect inside a box drawn with this."}, {PIXPACK(0xFFAA00), PIXPACK(0xAA5500), 4, Renderer::WallIcon, "ENERGY WALL", "Allows energy particles, blocks all other particles."}, + {PIXPACK(0xDCDCDC), PIXPACK(0x000000), 1, Renderer::WallIcon, "AIRBLOCK WALL", "Allows all particles, but blocks air."}, }; wallCount = UI_WALLCOUNT; wall_type * wtypesT = (wall_type*)malloc(UI_WALLCOUNT*sizeof(wall_type)); diff --git a/src/simulation/SimulationData.h b/src/simulation/SimulationData.h index 2dc275f2d..00c693646 100644 --- a/src/simulation/SimulationData.h +++ b/src/simulation/SimulationData.h @@ -54,9 +54,10 @@ #define WL_ALLOWGAS 13 #define WL_GRAV 14 #define WL_ALLOWENERGY 15 +#define WL_BLOCKAIR 16 #define WL_FLOODHELPER 255 -#define UI_WALLCOUNT 16 +#define UI_WALLCOUNT 17 #define OLD_SPC_AIR 236 #define SPC_AIR 256 diff --git a/src/simulation/elements/ARAY.cpp b/src/simulation/elements/ARAY.cpp index 16bff2d4e..baa4a1262 100644 --- a/src/simulation/elements/ARAY.cpp +++ b/src/simulation/elements/ARAY.cpp @@ -59,6 +59,7 @@ int Element_ARAY::update(UPDATE_FUNC_ARGS) if (!r) continue; if ((r&0xFF)==PT_SPRK && parts[r>>8].life==3) { + bool isBlackDeco = false; int destroy = (parts[r>>8].ctype==PT_PSCN)?1:0; int nostop = (parts[r>>8].ctype==PT_INST)?1:0; int colored = 0; @@ -76,6 +77,8 @@ int Element_ARAY::update(UPDATE_FUNC_ARGS) } else parts[nr].ctype = colored; parts[nr].temp = parts[i].temp; + if (isBlackDeco) + parts[nr].dcolour = 0xFF000000; } } else if (!destroy) { if ((r&0xFF)==PT_BRAY) { @@ -97,9 +100,18 @@ int Element_ARAY::update(UPDATE_FUNC_ARGS) //docontinue = 1; break; } + if (isBlackDeco) + parts[r>>8].dcolour = 0xFF000000; } else if ((r&0xFF)==PT_FILT) {//get color if passed through FILT - colored = Element_FILT::interactWavelengths(&parts[r>>8], colored); - //this if prevents BRAY from stopping on certain materials + if (parts[r>>8].tmp != 6) + { + colored = Element_FILT::interactWavelengths(&parts[r>>8], colored); + if (!colored) + break; + } + isBlackDeco = (parts[r>>8].dcolour==0xFF000000); + parts[r>>8].life = 4; + //this if prevents BRAY from stopping on certain materials } else if ((r&0xFF)!=PT_STOR && (r&0xFF)!=PT_INWR && ((r&0xFF)!=PT_SPRK || parts[r>>8].ctype!=PT_INWR) && (r&0xFF)!=PT_ARAY && (r&0xFF)!=PT_WIFI && !((r&0xFF)==PT_SWCH && parts[r>>8].life>=10)) { if (nyy!=0 || nxx!=0) { sim->create_part(-1, x+nxi+nxx, y+nyi+nyy, PT_SPRK); @@ -136,15 +148,23 @@ int Element_ARAY::update(UPDATE_FUNC_ARGS) } } else if (destroy) { if ((r&0xFF)==PT_BRAY) { + parts[r>>8].tmp = 2; parts[r>>8].life = 1; docontinue = 1; - //this if prevents red BRAY from stopping on certain materials + if (isBlackDeco) + parts[r>>8].dcolour = 0xFF000000; + //this if prevents red BRAY from stopping on certain materials } else if ((r&0xFF)==PT_STOR || (r&0xFF)==PT_INWR || ((r&0xFF)==PT_SPRK && parts[r>>8].ctype==PT_INWR) || (r&0xFF)==PT_ARAY || (r&0xFF)==PT_WIFI || (r&0xFF)==PT_FILT || ((r&0xFF)==PT_SWCH && parts[r>>8].life>=10)) { if((r&0xFF)==PT_STOR) { parts[r>>8].tmp = 0; parts[r>>8].life = 0; } + else if ((r&0xFF)==PT_FILT) + { + isBlackDeco = (parts[r>>8].dcolour==0xFF000000); + parts[r>>8].life = 2; + } docontinue = 1; } else { docontinue = 0; diff --git a/src/simulation/elements/BRAY.cpp b/src/simulation/elements/BRAY.cpp index 285c06585..ed521bd9c 100644 --- a/src/simulation/elements/BRAY.cpp +++ b/src/simulation/elements/BRAY.cpp @@ -55,7 +55,7 @@ int Element_BRAY::graphics(GRAPHICS_FUNC_ARGS) { trans = cpart->life * 7; if (trans>255) trans = 255; - if (cpart->ctype) { + if (cpart->ctype&0x3FFFFFFF) { *colg = 0; *colb = 0; *colr = 0; @@ -75,7 +75,7 @@ int Element_BRAY::graphics(GRAPHICS_FUNC_ARGS) { trans = cpart->life/4; if (trans>255) trans = 255; - if (cpart->ctype) { + if (cpart->ctype&0x3FFFFFFF) { *colg = 0; *colb = 0; *colr = 0; diff --git a/src/simulation/elements/CRAY.cpp b/src/simulation/elements/CRAY.cpp index 1cdb66ea9..742eca31a 100644 --- a/src/simulation/elements/CRAY.cpp +++ b/src/simulation/elements/CRAY.cpp @@ -78,6 +78,7 @@ int Element_CRAY::update(UPDATE_FUNC_ARGS) continue; if ((r&0xFF)==PT_SPRK && parts[r>>8].life==3) { //spark found, start creating unsigned int colored = 0; + bool isBlackDeco = false; bool destroy = parts[r>>8].ctype==PT_PSCN; bool nostop = parts[r>>8].ctype==PT_INST; bool createSpark = (parts[r>>8].ctype==PT_INWR); @@ -103,10 +104,15 @@ int Element_CRAY::update(UPDATE_FUNC_ARGS) docontinue = 0; } } else if ((r&0xFF)==PT_FILT) { // get color if passed through FILT - if (parts[r>>8].tmp==0) + if (parts[r>>8].dcolour == 0xFF000000) + colored = 0xFF000000; + else if (parts[r>>8].tmp==0) { colored = wavelengthToDecoColour(Element_FILT::getWavelengths(&parts[r>>8])); } + else if (colored==0xFF000000) + colored = 0; + parts[r>>8].life = 4; } else if ((r&0xFF) == PT_CRAY || nostop) { docontinue = 1; } else if(destroy && r && ((r&0xFF) != PT_DMND)) { diff --git a/src/simulation/elements/DRAY.cpp b/src/simulation/elements/DRAY.cpp new file mode 100644 index 000000000..96d8d8a8c --- /dev/null +++ b/src/simulation/elements/DRAY.cpp @@ -0,0 +1,122 @@ +#include "simulation/Elements.h" +//#TPT-Directive ElementClass Element_DRAY PT_DRAY 178 +Element_DRAY::Element_DRAY() +{ + Identifier = "DEFAULT_PT_DRAY"; + Name = "DRAY"; + Colour = PIXPACK(0xFFAA22); + MenuVisible = 1; + MenuSection = SC_ELEC; + Enabled = 1; + + Advection = 0.0f; + AirDrag = 0.00f * CFDS; + AirLoss = 0.90f; + Loss = 0.00f; + Collision = 0.0f; + Gravity = 0.0f; + Diffusion = 0.00f; + HotAir = 0.000f * CFDS; + Falldown = 0; + + Flammable = 0; + Explosive = 0; + Meltable = 0; + Hardness = 1; + + Weight = 100; + + Temperature = R_TEMP + 273.15f; + HeatConduct = 0; + Description = "Duplicator ray. Replicates a line of particles in front of it."; + + State = ST_SOLID; + Properties = TYPE_SOLID|PROP_LIFE_DEC; + + LowPressure = IPL; + LowPressureTransition = NT; + HighPressure = IPH; + HighPressureTransition = NT; + LowTemperature = ITL; + LowTemperatureTransition = NT; + HighTemperature = ITH; + HighTemperatureTransition = NT; + + Update = &Element_DRAY::update; + Graphics = NULL; +} + +//should probably be in Simulation.h +bool InBounds(int x, int y) +{ + return (x>=0 && y>=0 && x>8, copyLength = parts[i].tmp, copySpaces = parts[i].tmp2; + if (copySpaces <= 0) + copySpaces = 0; + if (copyLength <= 0) + copyLength = 0; + else + copySpaces++; //strange hack + if (!parts[i].life) // only fire when life is 0, but nothing sets the life right now + { + for (int rx = -1; rx <= 1; rx++) + for (int ry = -1; ry <= 1; ry++) + if (BOUNDS_CHECK && (rx || ry)) + { + int r = pmap[y+ry][x+rx]; + if ((r&0xFF) == PT_SPRK && parts[r>>8].life == 3) //spark found, start creating + { + bool overwrite = parts[r>>8].ctype == PT_PSCN; + int partsRemaining = copyLength, xCopyTo, yCopyTo; //positions where the line will start being copied at + + if (parts[r>>8].ctype == PT_INWR && rx && ry) // INWR doesn't spark from diagonals + continue; + + //figure out where the copying will start/end + for (int xStep = rx*-1, yStep = ry*-1, xCurrent = x+xStep, yCurrent = y+yStep; ; xCurrent+=xStep, yCurrent+=yStep) + { + int rr = pmap[yCurrent][xCurrent]; + if ((!copyLength && (rr&0xFF) == ctype && (ctype != PT_LIFE || parts[rr>>8].ctype == ctypeExtra)) + || !(--partsRemaining && InBounds(xCurrent+xStep, yCurrent+yStep))) + { + copyLength -= partsRemaining; + xCopyTo = xCurrent + xStep*copySpaces; + yCopyTo = yCurrent + yStep*copySpaces; + break; + } + } + + //now, actually copy the particles + partsRemaining = copyLength + 1; + for (int xStep = rx*-1, yStep = ry*-1, xCurrent = x+xStep, yCurrent = y+yStep; InBounds(xCopyTo, yCopyTo) && --partsRemaining; xCurrent+=xStep, yCurrent+=yStep, xCopyTo+=xStep, yCopyTo+=yStep) + { + int type = pmap[yCurrent][xCurrent]&0xFF, p; + if (overwrite) + sim->delete_part(xCopyTo, yCopyTo); + if (type == PT_SPRK) //hack + p = sim->create_part(-1, xCopyTo, yCopyTo, PT_METL); + else if (type) + p = sim->create_part(-1, xCopyTo, yCopyTo, type); + else + continue; + if (p >= 0) + { + if (type == PT_SPRK) + sim->part_change_type(p, xCopyTo, yCopyTo, PT_SPRK); + parts[p] = parts[pmap[yCurrent][xCurrent]>>8]; + parts[p].x = xCopyTo; + parts[p].y = yCopyTo; + } + } + } + } + } + return 0; +} + +Element_DRAY::~Element_DRAY() {} diff --git a/src/simulation/elements/DTEC.cpp b/src/simulation/elements/DTEC.cpp index ed894a2ca..259dd2fd5 100644 --- a/src/simulation/elements/DTEC.cpp +++ b/src/simulation/elements/DTEC.cpp @@ -73,6 +73,7 @@ int Element_DTEC::update(UPDATE_FUNC_ARGS) } } } + bool setFilt = false; int photonWl = 0; for (rx=-rd; rxphotons[y+ry][x+rx]; if(!r) continue; - if (parts[r>>8].type == parts[i].ctype && (parts[i].ctype != PT_LIFE || parts[i].tmp == parts[r>>8].ctype || !parts[i].tmp)) + if ((r&0xFF) == parts[i].ctype && (parts[i].ctype != PT_LIFE || parts[i].tmp == parts[r>>8].ctype || !parts[i].tmp)) parts[i].life = 1; - if (parts[r>>8].type == PT_PHOT) + if ((r&0xFF) == PT_PHOT || ((r&0xFF) == PT_BRAY && parts[r>>8].tmp!=2)) + { + setFilt = true; photonWl = parts[r>>8].ctype; + } } - if (photonWl) + if (setFilt) { int nx, ny; for (rx=-1; rx<2; rx++) diff --git a/src/simulation/elements/EXOT.cpp b/src/simulation/elements/EXOT.cpp index e2f6e4125..6b3af102f 100644 --- a/src/simulation/elements/EXOT.cpp +++ b/src/simulation/elements/EXOT.cpp @@ -94,7 +94,7 @@ int Element_EXOT::update(UPDATE_FUNC_ARGS) } } } - if (parts[i].tmp > 245 && parts[i].life > 1000) + if (parts[i].tmp > 245 && parts[i].life > 1337) if (rt!=PT_EXOT && rt!=PT_BREC && rt!=PT_DMND && rt!=PT_CLNE && rt!=PT_PRTI && rt!=PT_PRTO && rt!=PT_PCLN && rt!=PT_VOID && rt!=PT_NBHL && rt!=PT_WARP) { sim->create_part(i, x, y, rt); diff --git a/src/simulation/elements/FILT.cpp b/src/simulation/elements/FILT.cpp index 7e8ae996f..be0672845 100644 --- a/src/simulation/elements/FILT.cpp +++ b/src/simulation/elements/FILT.cpp @@ -31,7 +31,7 @@ Element_FILT::Element_FILT() Description = "Filter for photons, changes the color."; State = ST_SOLID; - Properties = TYPE_SOLID | PROP_NOAMBHEAT; + Properties = TYPE_SOLID | PROP_NOAMBHEAT | PROP_LIFE_DEC; LowPressure = IPL; LowPressureTransition = NT; @@ -60,7 +60,10 @@ int Element_FILT::graphics(GRAPHICS_FUNC_ARGS) for (x=0; x<12; x++) *colg += (wl >> (x+9)) & 1; x = 624/(*colr+*colg+*colb+1); - *cola = 127; + if (cpart->life>0 && cpart->life<=4) + *cola = 127+cpart->life*30; + else + *cola = 127; *colr *= x; *colg *= x; *colb *= x; diff --git a/src/simulation/elements/GVRT.cpp b/src/simulation/elements/GVRT.cpp new file mode 100644 index 000000000..16bd475e5 --- /dev/null +++ b/src/simulation/elements/GVRT.cpp @@ -0,0 +1,74 @@ +#include "simulation/Elements.h" +//#TPT-Directive ElementClass Element_GRVT PT_GRVT 177 +Element_GRVT::Element_GRVT() +{ + Identifier = "DEFAULT_PT_GRVT"; + Name = "GRVT"; + Colour = PIXPACK(0x00EE76); + MenuVisible = 1; + MenuSection = SC_NUCLEAR; + Enabled = 1; + + Advection = 0.0f; + AirDrag = 0.00f * CFDS; + AirLoss = 1.00f; + Loss = 1.00f; + Collision = -.99f; + Gravity = 0.0f; + Diffusion = 0.00f; + HotAir = 0.000f * CFDS; + Falldown = 0; + + Flammable = 40; + Explosive = 0; + Meltable = 0; + Hardness = 1; + + Weight = -1; + + Temperature = R_TEMP+273.15f; + HeatConduct = 61; + Description = "Gravitons. Create Newtonian Gravity."; + + State = ST_GAS; + Properties = TYPE_ENERGY|PROP_LIFE_DEC|PROP_LIFE_KILL_DEC; + + LowPressure = IPL; + LowPressureTransition = NT; + HighPressure = IPH; + HighPressureTransition = NT; + LowTemperature = ITL; + LowTemperatureTransition = NT; + HighTemperature = ITH; + HighTemperatureTransition = NT; + + Update = &Element_GRVT::update; + Graphics = &Element_GRVT::graphics; +} + +//#TPT-Directive ElementHeader Element_GRVT static int update(UPDATE_FUNC_ARGS) +int Element_GRVT::update(UPDATE_FUNC_ARGS) +{ + //at higher tmps they just go completely insane + if (parts[i].tmp >= 100) + parts[i].tmp = 100; + if (parts[i].tmp <= -100) + parts[i].tmp = -100; + + sim->gravmap[(y/CELL)*(XRES/CELL)+(x/CELL)] = 0.2f*parts[i].tmp; + return 0; +} + +//#TPT-Directive ElementHeader Element_GRVT static int graphics(GRAPHICS_FUNC_ARGS) +int Element_GRVT::graphics(GRAPHICS_FUNC_ARGS) +{ + *firea = 5; + *firer = 0; + *fireg = 250; + *fireb = 170; + + *pixel_mode |= FIRE_BLEND; + return 1; +} + +Element_GRVT::~Element_GRVT() {} diff --git a/src/simulation/elements/H2.cpp b/src/simulation/elements/H2.cpp index 6bcbb2e9a..4610fd8cb 100644 --- a/src/simulation/elements/H2.cpp +++ b/src/simulation/elements/H2.cpp @@ -96,6 +96,7 @@ int Element_H2::update(UPDATE_FUNC_ARGS) int j; float temp = parts[i].temp; sim->create_part(i,x,y,PT_NBLE); + parts[i].tmp = 0x1; j = sim->create_part(-3,x+rand()%3-1,y+rand()%3-1,PT_NEUT); if (j>-1) diff --git a/src/simulation/elements/NBLE.cpp b/src/simulation/elements/NBLE.cpp index 02e2953ef..5c689f593 100644 --- a/src/simulation/elements/NBLE.cpp +++ b/src/simulation/elements/NBLE.cpp @@ -51,7 +51,7 @@ int Element_NBLE::update(UPDATE_FUNC_ARGS) { if (parts[i].temp > 5273.15 && sim->pv[y/CELL][x/CELL] > 100.0f) { - parts[i].tmp = 1; + parts[i].tmp |= 0x1; if (!(rand()%5)) { int j; diff --git a/src/simulation/elements/PHOT.cpp b/src/simulation/elements/PHOT.cpp index 3c9435156..e792aaf6f 100644 --- a/src/simulation/elements/PHOT.cpp +++ b/src/simulation/elements/PHOT.cpp @@ -120,7 +120,11 @@ int Element_PHOT::graphics(GRAPHICS_FUNC_ARGS) *fireb = *colb; *pixel_mode &= ~PMODE_FLAT; - *pixel_mode |= FIRE_ADD | PMODE_ADD; + *pixel_mode |= FIRE_ADD | PMODE_ADD | NO_DECO; + if (cpart->flags & FLAG_PHOTDECO) + { + *pixel_mode &= ~NO_DECO; + } return 0; } diff --git a/src/simulation/elements/PIPE.cpp b/src/simulation/elements/PIPE.cpp index ee1a21ab1..daf354b17 100644 --- a/src/simulation/elements/PIPE.cpp +++ b/src/simulation/elements/PIPE.cpp @@ -201,7 +201,7 @@ int Element_PIPE::update(UPDATE_FUNC_ARGS) else if ((parts[i].tmp&0xFF) == 0 && (sim->elements[r&0xFF].Properties & (TYPE_PART | TYPE_LIQUID | TYPE_GAS | TYPE_ENERGY))) { if ((r&0xFF)==PT_SOAP) - sim->detach(r>>8); + Element_SOAP::detach(sim, r>>8); transfer_part_to_pipe(parts+(r>>8), parts+i); sim->kill_part(r>>8); } diff --git a/src/simulation/elements/PROT.cpp b/src/simulation/elements/PROT.cpp index 32b6907e9..45580570a 100644 --- a/src/simulation/elements/PROT.cpp +++ b/src/simulation/elements/PROT.cpp @@ -91,7 +91,8 @@ int Element_PROT::update(UPDATE_FUNC_ARGS) //make temp of other things closer to it's own temperature. This will change temp of things that don't conduct, and won't change the PROT's temperature if (under) { - if ((under&0xFF) == PT_WIFI || (under&0xFF) == PT_PRTI || (under&0xFF) == PT_PRTO) + //now changed so that PROT goes through portal, so only the WIFI part applies + if ((under&0xFF) == PT_WIFI/* || (under&0xFF) == PT_PRTI || (under&0xFF) == PT_PRTO*/) { float change; if (parts[i].temp<173.15f) change = -1000.0f; diff --git a/src/simulation/elements/PRTI.cpp b/src/simulation/elements/PRTI.cpp index aaddb4d78..658f738c8 100644 --- a/src/simulation/elements/PRTI.cpp +++ b/src/simulation/elements/PRTI.cpp @@ -82,7 +82,7 @@ int Element_PRTI::update(UPDATE_FUNC_ARGS) continue;// Handling these is a bit more complicated, and is done in STKM_interact() if ((r&0xFF) == PT_SOAP) - sim->detach(r>>8); + Element_SOAP::detach(sim, r>>8); for ( nnx=0; nnx<80; nnx++) if (!sim->portalp[parts[i].tmp][count][nnx].type) diff --git a/src/simulation/elements/QRTZ.cpp b/src/simulation/elements/QRTZ.cpp index b3996627f..9bbc264c2 100644 --- a/src/simulation/elements/QRTZ.cpp +++ b/src/simulation/elements/QRTZ.cpp @@ -57,8 +57,11 @@ int Element_QRTZ::update(UPDATE_FUNC_ARGS) if (parts[i].pavg[1]-parts[i].pavg[0] > 0.05*(parts[i].temp/3) || parts[i].pavg[1]-parts[i].pavg[0] < -0.05*(parts[i].temp/3)) { sim->part_change_type(i,x,y,PT_PQRT); + parts[i].life = 5; //timer before it can grow or diffuse again } } + if (parts[i].life>5) + parts[i].life = 5; // absorb SLTW if (parts[i].tmp != -1) for (rx=-1; rx<2; rx++) @@ -75,7 +78,7 @@ int Element_QRTZ::update(UPDATE_FUNC_ARGS) } } // grow and diffuse - if (parts[i].tmp > 0) + if (parts[i].tmp > 0 && (parts[i].vx*parts[i].vx + parts[i].vy*parts[i].vy)<0.2f && parts[i].life<=0) { bool stopgrow = false; int rnd, sry, srx; @@ -96,8 +99,14 @@ int Element_QRTZ::update(UPDATE_FUNC_ARGS) np = sim->create_part(-1,x+srx,y+sry,PT_QRTZ); if (np>-1) { + parts[np].temp = parts[i].temp; parts[np].tmp2 = parts[i].tmp2; parts[i].tmp--; + if (t == PT_PQRT) + { + // If PQRT is stationary and has started growing particles of QRTZ, the PQRT is basically part of a new QRTZ crystal. So turn it back into QRTZ so that it behaves more like part of the crystal. + sim->part_change_type(i,x,y,PT_QRTZ); + } if (rand()%2) { parts[np].tmp=-1;//dead qrtz diff --git a/src/simulation/elements/REPL.cpp b/src/simulation/elements/RPEL.cpp similarity index 76% rename from src/simulation/elements/REPL.cpp rename to src/simulation/elements/RPEL.cpp index e0823ecf7..70e38830e 100644 --- a/src/simulation/elements/REPL.cpp +++ b/src/simulation/elements/RPEL.cpp @@ -1,8 +1,8 @@ #include "simulation/Elements.h" -//#TPT-Directive ElementClass Element_REPL PT_REPL 160 -Element_REPL::Element_REPL() +//#TPT-Directive ElementClass Element_RPEL PT_RPEL 160 +Element_RPEL::Element_RPEL() { - Identifier = "DEFAULT_PT_REPL"; + Identifier = "DEFAULT_PT_RPEL"; Name = "RPEL"; Colour = PIXPACK(0x99CC00); MenuVisible = 1; @@ -42,19 +42,19 @@ Element_REPL::Element_REPL() HighTemperature = ITH; HighTemperatureTransition = NT; - Update = &Element_REPL::update; + Update = &Element_RPEL::update; } -//#TPT-Directive ElementHeader Element_REPL static int update(UPDATE_FUNC_ARGS) -int Element_REPL::update(UPDATE_FUNC_ARGS) +//#TPT-Directive ElementHeader Element_RPEL static int update(UPDATE_FUNC_ARGS) +int Element_RPEL::update(UPDATE_FUNC_ARGS) { int r, rx, ry, ri; for(ri = 0; ri <= 10; ri++) { rx = (rand()%21)-10; ry = (rand()%21)-10; - if (BOUNDS_CHECK && (rx || ry)) + if (x+rx >= 0 && x+rx < XRES && y+ry >= 0 && y+ry < YRES && (rx || ry)) { r = pmap[y+ry][x+rx]; if (!r) @@ -70,4 +70,4 @@ int Element_REPL::update(UPDATE_FUNC_ARGS) } -Element_REPL::~Element_REPL() {} +Element_RPEL::~Element_RPEL() {} diff --git a/src/simulation/elements/SOAP.cpp b/src/simulation/elements/SOAP.cpp index 2e721d169..c88314302 100644 --- a/src/simulation/elements/SOAP.cpp +++ b/src/simulation/elements/SOAP.cpp @@ -47,6 +47,24 @@ Element_SOAP::Element_SOAP() } +//#TPT-Directive ElementHeader Element_SOAP static void detach(Simulation * sim, int i) +void Element_SOAP::detach(Simulation * sim, int i) +{ + if ((sim->parts[i].ctype&2) == 2 && sim->parts[sim->parts[i].tmp].type == PT_SOAP) + { + if ((sim->parts[sim->parts[i].tmp].ctype&4) == 4) + sim->parts[sim->parts[i].tmp].ctype ^= 4; + } + + if ((sim->parts[i].ctype&4) == 4 && sim->parts[sim->parts[i].tmp2].type == PT_SOAP) + { + if ((sim->parts[sim->parts[i].tmp2].ctype&2) == 2) + sim->parts[sim->parts[i].tmp2].ctype ^= 2; + } + + sim->parts[i].ctype = 0; +} + //#TPT-Directive ElementHeader Element_SOAP static void attach(Particle * parts, int i1, int i2) void Element_SOAP::attach(Particle * parts, int i1, int i2) { @@ -86,30 +104,36 @@ int Element_SOAP::update(UPDATE_FUNC_ARGS) { if (parts[i].temp>FREEZING) { + if (parts[i].tmp < 0 || parts[i].tmp >= NPART || parts[i].tmp2 < 0 || parts[i].tmp2 >= NPART) + { + parts[i].tmp = parts[i].tmp2 = parts[i].ctype = 0; + return 0; + } if (parts[i].life<=0) { + //if only connected on one side if ((parts[i].ctype&6) != 6 && (parts[i].ctype&6)) { - int target; - target = i; - while((parts[target].ctype&6) != 6 && (parts[target].ctype&6)) + int target = i; + //break entire bubble in a loop + while((parts[target].ctype&6) != 6 && (parts[target].ctype&6) && parts[target].type == PT_SOAP) { if (parts[target].ctype&2) { target = parts[target].tmp; - sim->detach(target); + detach(sim, target); } if (parts[target].ctype&4) { target = parts[target].tmp2; - sim->detach(target); + detach(sim, target); } } } if ((parts[i].ctype&6) != 6) parts[i].ctype = 0; if ((parts[i].ctype&6) == 6 && (parts[parts[i].tmp].ctype&6) == 6 && parts[parts[i].tmp].tmp == i) - sim->detach(i); + detach(sim, i); } parts[i].vy = (parts[i].vy-0.1f)*0.5f; parts[i].vx *= 0.5f; @@ -143,7 +167,7 @@ int Element_SOAP::update(UPDATE_FUNC_ARGS) || (r && sim->elements[r&0xFF].State != ST_GAS && (r&0xFF) != PT_SOAP && (r&0xFF) != PT_GLAS)) { - sim->detach(i); + detach(sim, i); continue; } } @@ -151,18 +175,21 @@ int Element_SOAP::update(UPDATE_FUNC_ARGS) { if (parts[r>>8].ctype == 1) { - int buf; - buf = parts[i].tmp; + int buf = parts[i].tmp; + parts[i].tmp = r>>8; - parts[buf].tmp2 = r>>8; + if (parts[buf].type == PT_SOAP) + parts[buf].tmp2 = r>>8; parts[r>>8].tmp2 = i; parts[r>>8].tmp = buf; parts[r>>8].ctype = 7; } else if (parts[r>>8].ctype == 7 && parts[i].tmp != r>>8 && parts[i].tmp2 != r>>8) { - parts[parts[i].tmp].tmp2 = parts[r>>8].tmp2; - parts[parts[r>>8].tmp2].tmp = parts[i].tmp; + if (parts[parts[i].tmp].type == PT_SOAP) + parts[parts[i].tmp].tmp2 = parts[r>>8].tmp2; + if (parts[parts[r>>8].tmp2].type == PT_SOAP) + parts[parts[r>>8].tmp2].tmp = parts[i].tmp; parts[r>>8].tmp2 = i; parts[i].tmp = r>>8; } diff --git a/src/simulation/elements/SPRK.cpp b/src/simulation/elements/SPRK.cpp index 6dfde7833..35a384215 100644 --- a/src/simulation/elements/SPRK.cpp +++ b/src/simulation/elements/SPRK.cpp @@ -48,8 +48,8 @@ Element_SPRK::Element_SPRK() //#TPT-Directive ElementHeader Element_SPRK static int update(UPDATE_FUNC_ARGS) int Element_SPRK::update(UPDATE_FUNC_ARGS) - { - int r, rx, ry, rt, conduct_sprk, nearp, pavg, ct = parts[i].ctype, sender, receiver; +{ + int r, rx, ry, nearp, pavg, ct = parts[i].ctype, sender, receiver; Element_FIRE::update(UPDATE_FUNC_SUBCALL_ARGS); if (parts[i].life<=0) @@ -96,13 +96,13 @@ int Element_SPRK::update(UPDATE_FUNC_ARGS) } break; case PT_NBLE: - if (parts[i].life<=1 && parts[i].temp<5273.15f) + if (parts[i].life<=1 && !(parts[i].tmp&0x1)) { parts[i].life = rand()%150+50; sim->part_change_type(i,x,y,PT_PLSM); parts[i].ctype = PT_NBLE; if (parts[i].temp > 5273.15) - parts[i].tmp |= 4; + parts[i].tmp |= 0x4; parts[i].temp = 3500; sim->pv[y/CELL][x/CELL] += 1; } @@ -302,7 +302,7 @@ int Element_SPRK::update(UPDATE_FUNC_ARGS) goto conduct; continue; case PT_NBLE: - if (parts[i].temp < 5273.15f) + if (!(parts[i].tmp&0x1)) goto conduct; continue; case PT_PSCN: @@ -355,11 +355,11 @@ int Element_SPRK::update(UPDATE_FUNC_ARGS) int Element_SPRK::graphics(GRAPHICS_FUNC_ARGS) { - *firea = 80; - *firer = 170; - *fireg = 200; - *fireb = 220; - *pixel_mode |= FIRE_ADD; + *firea = 60; + *firer = *colr/2; + *fireg = *colg/2; + *fireb = *colb/2; + *pixel_mode |= FIRE_SPARK; return 1; } diff --git a/src/simulation/elements/STOR.cpp b/src/simulation/elements/STOR.cpp index ce26767ec..348297c28 100644 --- a/src/simulation/elements/STOR.cpp +++ b/src/simulation/elements/STOR.cpp @@ -61,7 +61,8 @@ int Element_STOR::update(UPDATE_FUNC_ARGS) continue; if (!parts[i].tmp && !parts[i].life && (r&0xFF)!=PT_STOR && !(sim->elements[(r&0xFF)].Properties&TYPE_SOLID) && (!parts[i].ctype || (r&0xFF)==parts[i].ctype)) { - if ((r&0xFF) == PT_SOAP) sim->detach(r>>8); + if ((r&0xFF) == PT_SOAP) + Element_SOAP::detach(sim, r>>8); parts[i].tmp = parts[r>>8].type; parts[i].temp = parts[r>>8].temp; parts[i].tmp2 = parts[r>>8].life; diff --git a/src/simulation/elements/URAN.cpp b/src/simulation/elements/URAN.cpp index 61d5add82..24ad11cf7 100644 --- a/src/simulation/elements/URAN.cpp +++ b/src/simulation/elements/URAN.cpp @@ -51,8 +51,15 @@ int Element_URAN::update(UPDATE_FUNC_ARGS) { if (!sim->legacy_enable && sim->pv[y/CELL][x/CELL]>0.0f) { - float atemp = parts[i].temp + (-MIN_TEMP); - parts[i].temp = restrict_flt((atemp*(1+(sim->pv[y/CELL][x/CELL]/2000)))+MIN_TEMP, MIN_TEMP, MAX_TEMP); + if (parts[i].temp == MIN_TEMP) + { + parts[i].temp += .01f; + } + else + { + float atemp = parts[i].temp + (-MIN_TEMP); + parts[i].temp = restrict_flt((atemp*(1+(sim->pv[y/CELL][x/CELL]/2000)))+MIN_TEMP, MIN_TEMP, MAX_TEMP); + } } return 0; } diff --git a/src/tasks/Task.cpp b/src/tasks/Task.cpp index 133d76484..8cc71d01a 100644 --- a/src/tasks/Task.cpp +++ b/src/tasks/Task.cpp @@ -1,3 +1,4 @@ +#include "Config.h" #include "Task.h" #include "TaskListener.h" @@ -122,7 +123,7 @@ void Task::after() } -void * Task::doWork_helper(void * ref) +TH_ENTRY_POINT void * Task::doWork_helper(void * ref) { bool newSuccess = ((Task*)ref)->doWork(); pthread_mutex_lock(&((Task*)ref)->taskMutex); diff --git a/src/tasks/Task.h b/src/tasks/Task.h index a7bf1c756..d562f77fc 100644 --- a/src/tasks/Task.h +++ b/src/tasks/Task.h @@ -41,7 +41,7 @@ protected: virtual void before(); virtual void after(); virtual bool doWork(); - static void * doWork_helper(void * ref); + TH_ENTRY_POINT static void * doWork_helper(void * ref); virtual void notifyProgress(int progress); virtual void notifyError(std::string error);