diff --git a/README b/README index 9f40b3ae..15ee426e 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -FCEUX SDL 2.2.3 SDL README +FCEUX SDL 2.3.0 SDL README ========================== Originally By Lukas Sabota (sf: punkrockguy318) Updated By mjbudd77 diff --git a/SConstruct b/SConstruct deleted file mode 100644 index 5d97b46c..00000000 --- a/SConstruct +++ /dev/null @@ -1,256 +0,0 @@ -# -# SConstruct - build script for the SDL port of fceux -# -# You can adjust the BoolVariables below to include/exclude features -# at compile-time. You may also use arguments to specify the parameters. -# ie: scons RELEASE=1 GTK3=1 -# -# Use "scons" to compile and "scons install" to install. -# - -import os -import sys -import platform - -opts = Variables(None, ARGUMENTS) -opts.AddVariables( - BoolVariable('DEBUG', 'Build with debugging symbols', 1), - BoolVariable('RELEASE', 'Set to 1 to build for release', 0), - BoolVariable('FRAMESKIP', 'Enable frameskipping', 1), - BoolVariable('OPENGL', 'Enable OpenGL support', 1), - BoolVariable('LUA', 'Enable Lua support', 1), - BoolVariable('GTK', 'Enable GTK2 GUI (SDL only)', 0), - BoolVariable('GTK3', 'Enable GTK3 GUI (SDL only)', 1), - BoolVariable('NEWPPU', 'Enable new PPU core', 1), - BoolVariable('CREATE_AVI', 'Enable avi creation support (SDL only)', 1), - BoolVariable('LOGO', 'Enable a logoscreen when creating avis (SDL only)', 1), - BoolVariable('SYSTEM_LUA','Use system lua instead of static lua provided with fceux', 0), - BoolVariable('SYSTEM_MINIZIP', 'Use system minizip instead of static minizip provided with fceux', 0), - BoolVariable('LSB_FIRST', 'Least signficant byte first (non-PPC)', 1), - BoolVariable('CLANG', 'Compile with llvm-clang instead of gcc', 0), - BoolVariable('SDL2', 'Compile using SDL2 instead of SDL 1.2 (experimental/non-functional)', 1) -) -AddOption('--prefix', dest='prefix', type='string', nargs=1, action='store', metavar='DIR', help='installation prefix') - -prefix = GetOption('prefix') -env = Environment(options = opts) - -if env['RELEASE']: - env.Append(CPPDEFINES=["PUBLIC_RELEASE"]) - env['DEBUG'] = 0 - -# LSB_FIRST must be off for PPC to compile -if platform.system == "ppc": - env['LSB_FIRST'] = 0 - -# Default compiler flags: -env.Append(CCFLAGS = ['-Wall', '-Wno-write-strings', '-Wno-sign-compare', '-Wno-parentheses', '-Wno-unused-local-typedefs']) -env.Append(CXXFLAGS = ['-std=c++0x']) - -if 'PLATFORM' in os.environ: - env.Replace(PLATFORM = os.environ['PLATFORM']) -if 'CC' in os.environ: - env.Replace(CC = os.environ['CC']) -if 'CXX' in os.environ: - env.Replace(CXX = os.environ['CXX']) -if 'WINDRES' in os.environ: - env.Replace(WINDRES = os.environ['WINDRES']) -if 'CFLAGS' in os.environ: - env.Append(CCFLAGS = os.environ['CFLAGS'].split()) -if 'CXXFLAGS' in os.environ: - env.Append(CXXFLAGS = os.environ['CXXFLAGS'].split()) -if 'CPPFLAGS' in os.environ: - env.Append(CPPFLAGS = os.environ['CPPFLAGS'].split()) -if 'LDFLAGS' in os.environ: - env.Append(LINKFLAGS = os.environ['LDFLAGS'].split()) -if 'PKG_CONFIG_PATH' in os.environ: - env['ENV']['PKG_CONFIG_PATH'] = os.environ['PKG_CONFIG_PATH'] -if 'PKG_CONFIG_PATH' not in os.environ and env['PLATFORM'] == 'darwin': - env['ENV']['PKG_CONFIG_PATH'] = "/usr/local/lib/pkgconfig:/opt/X11/lib/pkgconfig" -if 'PKG_CONFIG_LIBDIR' in os.environ: - env['ENV']['PKG_CONFIG_LIBDIR'] = os.environ['PKG_CONFIG_LIBDIR'] - -print("platform: ", env['PLATFORM']) - -# compile with clang -if env['CLANG']: - env.Replace(CC='clang') - env.Replace(CXX='clang++') - -# special flags for cygwin -# we have to do this here so that the function and lib checks will go through mingw -if env['PLATFORM'] == 'cygwin': - env.Append(CCFLAGS = " -mno-cygwin") - env.Append(LINKFLAGS = " -mno-cygwin") - env['LIBS'] = ['wsock32']; - -if env['PLATFORM'] == 'win32': - env.Append(CPPPATH = [".", "drivers/win/", "drivers/common/", "drivers/", "drivers/win/zlib", "drivers/win/directx", "drivers/win/lua/include"]) - env.Append(CPPDEFINES = ["PSS_STYLE=2", "WIN32", "_USE_SHARED_MEMORY_", "NETWORK", "FCEUDEF_DEBUGGER", "NOMINMAX", "NEED_MINGW_HACKS", "_WIN32_IE=0x0600"]) - env.Append(LIBS = ["rpcrt4", "comctl32", "vfw32", "winmm", "ws2_32", "comdlg32", "ole32", "gdi32", "htmlhelp"]) -else: - conf = Configure(env) - # If libdw is available, compile in backward-cpp support - if conf.CheckLib('dw'): - conf.env.Append(CCFLAGS = "-DBACKWARD_HAS_DW=1") - conf.env.Append(LINKFLAGS = "-ldw") - if conf.CheckFunc('asprintf'): - conf.env.Append(CCFLAGS = "-DHAVE_ASPRINTF") - if env['SYSTEM_MINIZIP']: - assert env.ParseConfig('pkg-config minizip --cflags --libs'), "please install: libminizip" - assert env.ParseConfig('pkg-config zlib --cflags --libs'), "please install: zlib" - #assert conf.CheckLibWithHeader('z', 'zlib.h', 'c', 'inflate;', 1), "please install: zlib" - env.Append(CPPDEFINES=["_SYSTEM_MINIZIP"]) - else: - assert env.ParseConfig('pkg-config zlib --cflags --libs'), "please install: zlib" - #assert conf.CheckLibWithHeader('z', 'zlib.h', 'c', 'inflate;', 1), "please install: zlib" - if env['SDL2']: - assert env.ParseConfig('pkg-config sdl2 --cflags --libs'), "please install: sdl2" - env.Append(CPPDEFINES=["_SDL2"]) - #env.ParseConfig('pkg-config sdl2 --cflags --libs') - else: - if not conf.CheckLib('SDL'): - print('Did not find libSDL or SDL.lib, exiting!') - Exit(1) - env.ParseConfig('sdl-config --cflags --libs') - if env['GTK']: - if not conf.CheckLib('gtk-x11-2.0'): - print('Could not find libgtk-2.0, exiting!') - Exit(1) - # Add compiler and linker flags from pkg-config - config_string = 'pkg-config --cflags --libs gtk+-2.0' - env.ParseConfig(config_string) - env.Append(CPPDEFINES=["_GTK2"]) - env.Append(CCFLAGS = ["-D_GTK"]) - if env['GTK3']: - # Add compiler and linker flags from pkg-config - config_string = 'pkg-config --cflags --libs gtk+-3.0' - env.ParseConfig(config_string) - env.Append(CPPDEFINES=["_GTK3"]) - env.Append(CCFLAGS = ["-D_GTK"]) - - ### Just make every configuration use -ldl, it may be needed for some reason. - env.Append(LIBS = ["-ldl"]) - - ### Lua platform defines - ### Applies to all files even though only lua needs it, but should be ok - if env['LUA']: - env.Append(CPPDEFINES=["_S9XLUA_H"]) - if env['PLATFORM'] == 'darwin': - # Define LUA_USE_MACOSX otherwise we can't bind external libs from lua - env.Append(CCFLAGS = ["-DLUA_USE_MACOSX"]) - if env['PLATFORM'] == 'posix': - # If we're POSIX, we use LUA_USE_LINUX since that combines usual lua posix defines with dlfcn calls for dynamic library loading. - # Should work on any *nix - env.Append(CCFLAGS = ["-DLUA_USE_LINUX"]) - if env['SYSTEM_LUA']: - lua_link_flags = '' - lua_include_dir = '' - - if conf.CheckLib('luajit-5.1'): - lua_link_flags = "-lluajit-5.1" - lua_include_dir = "/usr/include/luajit-2.0" - elif conf.CheckLib('lua5.1'): - lua_link_flags = "-llua5.1" - lua_include_dir = "/usr/include/lua5.1" - elif conf.CheckLib('lua-5.1'): - lua_link_flags = "-llua-5.1" - lua_include_dir = "/usr/include/lua-5.1" - elif conf.CheckLib('lua'): - lua_link_flags = "-llua" - lua_include_dir = "/usr/include/lua" - - if 'LUA_LINKFLAGS' in os.environ: - lua_link_flags = os.environ['LUA_LINKFLAGS'] - if 'LUA_INCDIR' in os.environ: - lua_include_dir = os.environ['LUA_INCDIR'] - - if not lua_link_flags or not lua_include_dir: - print('Could not find liblua, exiting!') - Exit(1) - - env.Append(LINKFLAGS = lua_link_flags.split()) - env.Append(CCFLAGS = ["-I" + lua_include_dir]) - else: - env.Append(CCFLAGS = ["-Isrc/lua/src"]) - # "--as-needed" no longer available on OSX (probably BSD as well? TODO: test) - if env['PLATFORM'] != 'darwin': - env.Append(LINKFLAGS=['-Wl,--as-needed']) - - ### Search for gd if we're not in Windows - if (env['PLATFORM'] != 'win32' and env['PLATFORM'] != 'cygwin') and (env['CREATE_AVI'] or env['LOGO']): - gd = conf.CheckLib('gd', autoadd=1) - if gd == 0: - env['LOGO'] = 0 - print('Did not find libgd, you won\'t be able to create a logo screen for your avis.') - - if env['OPENGL'] and conf.CheckLibWithHeader('GL', 'GL/gl.h', 'c', autoadd=1): - conf.env.Append(CCFLAGS = "-DOPENGL") - conf.env.Append(CPPDEFINES = ['PSS_STYLE=1',"FCEUDEF_DEBUGGER"]) - - env = conf.Finish() - -if sys.byteorder == 'little' or env['PLATFORM'] == 'win32': - env.Append(CPPDEFINES = ['LSB_FIRST']) - -if env['FRAMESKIP']: - env.Append(CPPDEFINES = ['FRAMESKIP']) - -print("base CPPDEFINES:",env['CPPDEFINES']) -print("base CCFLAGS:",env['CCFLAGS']) - -if env['DEBUG']: - env.Append(CPPDEFINES=["_DEBUG"], CCFLAGS = ['-g', '-O0']) -else: - env.Append(CCFLAGS = ['-O2']) - -if env['PLATFORM'] != 'win32' and env['PLATFORM'] != 'cygwin' and env['CREATE_AVI']: - env.Append(CPPDEFINES=["CREATE_AVI"]) -else: - env['CREATE_AVI']=0; - -Export('env') -fceux = SConscript('src/SConscript') -env.Program(target="fceux-net-server", source=["fceux-server/server.cpp", "fceux-server/md5.cpp", "fceux-server/throttle.cpp"]) - -# Installation rules -if prefix == None: - prefix = "/usr/local" - -exe_suffix = '' -if env['PLATFORM'] == 'win32': - exe_suffix = '.exe' - -fceux_src = 'src/fceux' + exe_suffix -fceux_dst = 'bin/fceux' + exe_suffix - -fceux_net_server_src = 'fceux-net-server' + exe_suffix -fceux_net_server_dst = 'bin/fceux-net-server' + exe_suffix - -auxlib_src = 'src/auxlib.lua' -auxlib_dst = 'bin/auxlib.lua' - -fceux_h_src = 'output/fceux.chm' -fceux_h_dst = 'bin/fceux.chm' - -env.Command(fceux_h_dst, fceux_h_src, [Copy(fceux_h_dst, fceux_h_src)]) -env.Command(fceux_dst, fceux_src, [Copy(fceux_dst, fceux_src)]) -env.Command(fceux_net_server_dst, fceux_net_server_src, [Copy(fceux_net_server_dst, fceux_net_server_src)]) -env.Command(auxlib_dst, auxlib_src, [Copy(auxlib_dst, auxlib_src)]) - -man_src = 'documentation/fceux.6' -man_net_src = 'documentation/fceux-net-server.6' - -share_src = 'output/' - -image_src = 'fceux.png' - -desktop_src = 'fceux.desktop' - -env.Install(prefix + "/bin/", [fceux, fceux_net_server_src]) -env.InstallAs(prefix + '/share/fceux/', share_src) -env.Install(prefix + '/share/fceux/', auxlib_src) -env.Install(prefix + '/share/pixmaps/', image_src) -env.Install(prefix + '/share/applications/', desktop_src) -env.Install(prefix + "/share/man/man6/", [man_src, man_net_src]) -env.Alias('install', prefix) diff --git a/TODO-SDL b/TODO-SDL index 12d90a46..5d3a7dde 100644 --- a/TODO-SDL +++ b/TODO-SDL @@ -61,7 +61,7 @@ Network play (who actually uses this???) | NO | NO QT === * Clean out rest of old GTK comments and #ifdefs - * GUI Debug Tools TODO + * GUI Debug Tools Pretty Much Done * GUI should compile in windows as well.... but testing is not a priority since the windows gui already has a totally separate backend. BUGS diff --git a/_config.yml b/_config.yml index 4f848b1c..80eccb95 100644 --- a/_config.yml +++ b/_config.yml @@ -23,7 +23,6 @@ exclude: - NEWS - NewPPUtests.txt - README -- SConstruct - STYLE-GUIDELINES-SDL - TODO-SDL - _config.yml @@ -32,7 +31,6 @@ exclude: - azure-pipelines.yml - changelog.txt - configure.ac -- debian-crossbuild.sh - doxygen - fceux.desktop - readme.md diff --git a/configure.ac b/configure.ac deleted file mode 100644 index 83c74c8a..00000000 --- a/configure.ac +++ /dev/null @@ -1,159 +0,0 @@ -AC_INIT([fceux], [2.2.3]) -AC_CONFIG_SRCDIR([src/fceu.cpp]) -AM_INIT_AUTOMAKE - -AC_PROG_CC -AC_PROG_CPP -AC_PROG_CXX -AC_PROG_INSTALL -AC_CONFIG_MACRO_DIR([m4]) - -AC_CHECK_FUNC(asprintf, AC_DEFINE([HAVE_ASPRINTF])) - -## This is almost sure to not work -AC_ARG_WITH(nativewin32, - [AC_HELP_STRING([--with-nativewin32], - [use nativewin32])], - use_nativewin32=$withval, - use_nativewin32="no") - -AM_CONDITIONAL(WIN32, false) -AM_CONDITIONAL(UNIX, false) -AM_CONDITIONAL(NATIVEWIN32,false) -AM_CONDITIONAL(OPENGL, false) -AM_CONDITIONAL(GTK2, false) -AM_CONDITIONAL(GTK3, false) -AM_CONDITIONAL(LUA, false) -AM_CONDITIONAL(LUA_BUILTIN, false) -AM_CONDITIONAL(SYSTEM_MINIZIP, false) -AM_CONDITIONAL(GD, false) -AM_CONDITIONAL(FRAMESKIP, true) - -## Check for zlib -AC_CHECK_LIB([z], [zlibVersion],[], AC_MSG_ERROR([*** zlib not found!])) -LIBS="$LIBS -lz" -AC_CHECK_LIB([pthread], [pthread_create],[], AC_MSG_ERROR([*** pthread not found!])) -LIBS="$LIBS -lpthread" - -## Platform specific setup -if expr x"$target" : 'x.*beos' > /dev/null; then - CFLAGS="-no-fpic $CFLAGS" - CPPFLAGS="-no-fpic $CPPFLAGS" - AC_DEFINE([PSS_STYLE],[1]) -elif expr x"$target" : 'x.*mingw' > /dev/null; then - ## Probably doesn't work - AC_DEFINE([PSS_STYLE],[2]) - AC_DEFINE([WIN32]) - AM_CONDITIONAL(WIN32, true) - - if test x$use_nativewin32 = xyes; then - LIBS="$LIBS -mwindows -lddraw -ldinput -ldsound -lgdi32 -ldxguid -lwinmm -lshell32 -lwsock32 -lcomdlg32 -lole32" - AM_CONDITIONAL(NATIVEWIN32,true) - else - LIBS="$LIBS -ldsound -lwinmm" - fi -elif expr x"$target" : 'x.*darwin' > /dev/null; then - ## Probably doesn't work - AC_DEFINE([MACOSX]) -else - AM_CONDITIONAL(UNIX, true) - AC_DEFINE([UNIX]) - AC_DEFINE([PSS_STYLE],[1]) -fi -if test x$use_nativewin32 = xno; then - ## Check for SDL - SDL_VERSION=1.2.0 - AM_PATH_SDL($SDL_VERSION, [:], - AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])) - AC_DEFINE([SDL]) - - LIBS="$LIBS $SDL_LIBS" - CFLAGS="-Wall -fomit-frame-pointer $CFLAGS $SDL_CFLAGS" - CPPFLAGS="-Wall -fomit-frame-pointer $CPPFLAGS $SDL_CFLAGS" - - ## Check for OpenGL - AC_ARG_ENABLE([opengl], - AS_HELP_STRING([--enable-opengl], [Enable OpenGL support])) - AS_IF([test "x$enable_opengl" != "xno"], [ - AC_CHECK_HEADER([GL/gl.h],[AC_DEFINE([OPENGL]) AM_CONDITIONAL(OPENGL, true)], - [ - AC_CHECK_HEADER([OpenGL/gl.h],[AC_DEFINE([OPENGL]) AM_CONDITIONAL(OPENGL, true)],[]) - AC_DEFINE([APPLEOPENGL]) - ]) - LIBS="$LIBS -lGL -lGLU" - ]) - - ## Check for GTK2 - AC_ARG_ENABLE([gtk2], - AS_HELP_STRING([--enable-gtk2], [Enable GTK2 GUI])) - AS_IF([test "x$enable_gtk2" = "xyes"], [ - AM_PATH_GTK_2_0([2.24.0],AM_CONDITIONAL(GTK2, true),AC_MSG_ERROR([Gtk+ 2.24.0 or higher required.])) - AC_DEFINE([_GTK]) - AC_DEFINE([GTK2]) - ]) - - ## Check for GTK3 - AC_ARG_ENABLE([gtk3], - AS_HELP_STRING([--enable-gtk3], [Enable GTK3 GUI])) - AS_IF([test "x$enable_gtk2" = "xyes" -a "x$enable_gtk3" = "xyes"], [ - AC_MSG_ERROR([GTK2 and GTK3 cannot be simulatenously enabled.]) - ]) - AS_IF([test "x$enable_gtk3" = "xyes"], [ - AM_PATH_GTK_3_0([3.0.0],AM_CONDITIONAL(GTK3, true),AC_MSG_ERROR([Gtk+ 3.0.0 or higher required.])) - AC_DEFINE([_GTK]) - AC_DEFINE([GTK3]) - ]) -fi - -## Check for system lua -AC_ARG_ENABLE([lua], - AS_HELP_STRING([--enable-lua], [Use lua libraries found on this system])) -AS_IF([test "x$enable_lua" = "xyes"], [ - AC_SUBST(LUA, lua5.1) - AX_PROG_LUA([5.1],[5.2]) - PKG_CHECK_MODULES([lua51], [lua51]) - AX_LUA_LIBS([], AC_MSG_ERROR([Lua libs not found!])) - AC_DEFINE([_S9XLUA_H]) - AM_CONDITIONAL(LUA, true) - LIBS="$LIBS $LUA_LIB" -]) - -## Check for lua builtin -AC_ARG_ENABLE([lua-builtin], - AS_HELP_STRING([--enable-lua-builtin], [Use lua5.1 included with fceux])) -AS_IF([test "x$enable_lua-builtin" = "xyes"], [ - #AX_LUA_HEADERS([], AC_MSG_ERROR([Lua 5.1 headers not found!])) - AC_DEFINE([_S9XLUA_H]) - AM_CONDITIONAL(LUA_BUILTIN, true) -]) - -## Check for gd -AC_ARG_ENABLE([gd], - AS_HELP_STRING([--enable-gd], [Use libgd for AVI creation])) -AS_IF([test "x$enable_gd" = "xyes"], [ - #AX_LUA_HEADERS([], AC_MSG_ERROR([Lua 5.1 headers not found!])) - AX_CHECK_GD - LIBS="$LIBS $GD_LIBS" - AC_DEFINE([CREATE_AVI]) -]) - -## Check for system minizip -AC_ARG_ENABLE([system-minizip], - AS_HELP_STRING([--enable-system-minizip], [Use minizip from system instead of fceux distribution])) -AS_IF([test "x$enable_system_minizip" = "xyes"], [ - PKG_CHECK_MODULES([minizip], [minizip]) - AM_CONDITIONAL(SYSTEM_MINIZIP, true) - LIBS="$LIBS $minizip_LIBS" -]) - -AC_C_BIGENDIAN([], [AC_DEFINE([LSB_FIRST])]) - -## Check for frameskip disable -AC_ARG_ENABLE([frameskip], - AS_HELP_STRING([--disable-frameskip], [Disable frameskip feature])) - -AS_IF([test "x$disable_frameskip" != "xno"], [ - AC_DEFINE([FRAMESKIP]) -]) - -AC_OUTPUT([Makefile src/Makefile]) diff --git a/debian-crossbuild.sh b/debian-crossbuild.sh deleted file mode 100644 index f0623563..00000000 --- a/debian-crossbuild.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -if [ -f /usr/bin/i586-mingw32msvc-windres ]; then HOST=i586-mingw32msvc -else HOST=i586-mingw32 -fi -PLATFORM=win32 CC=${HOST}-gcc CXX=${HOST}-g++ WRC=${HOST}-windres WINDRES=${HOST}-windres scons $@ diff --git a/pipelines/debpkg.pl b/pipelines/debpkg.pl index ba27b62b..b2deb0cc 100755 --- a/pipelines/debpkg.pl +++ b/pipelines/debpkg.pl @@ -2,7 +2,7 @@ use strict; -my $VERSION="2.2.3"; +my $VERSION="2.3.0"; my $INSTALL_PREFIX="/tmp/fceux"; my $CTL_FILENAME="$INSTALL_PREFIX/DEBIAN/control"; my $ARCH="amd64"; diff --git a/pipelines/macOS_build.sh b/pipelines/macOS_build.sh index b6ac0807..0b48be4e 100755 --- a/pipelines/macOS_build.sh +++ b/pipelines/macOS_build.sh @@ -7,8 +7,8 @@ uname -a sw_vers FCEUX_VERSION_MAJOR=2 -FCEUX_VERSION_MINOR=2 -FCEUX_VERSION_PATCH=3 +FCEUX_VERSION_MINOR=3 +FCEUX_VERSION_PATCH=0 SCRIPT_DIR=$( cd $(dirname $BASH_SOURCE[0]); pwd ); diff --git a/readme.md b/readme.md index 5719756b..149e46f9 100644 --- a/readme.md +++ b/readme.md @@ -7,8 +7,8 @@ An open source NES Emulator for Windows and Unix that features solid emulation a Interim builds: * Win32: [fceux.zip](https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux.zip?branch=master&job=Windows%2032) * Win64: [fceux64.zip](https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux64.zip?branch=master&job=Windows%2064) -* Ubuntu: [fceux-2.2.3-amd64.deb](https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux-2.2.3-amd64.deb?branch=master&job=Ubuntu) -* MacOSX: [fceux-2.2.3-Darwin.dmg](https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux-2.2.3-Darwin.dmg?branch=master&job=MacOS) +* Ubuntu: [fceux-2.3.0-amd64.deb](https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux-2.3.0-amd64.deb?branch=master&job=Ubuntu) +* MacOSX: [fceux-2.3.0-Darwin.dmg](https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux-2.3.0-Darwin.dmg?branch=master&job=MacOS) * Status: [Appveyor](https://ci.appveyor.com/project/zeromus/fceux/) But you might like mesen more: https://github.com/SourMesen/Mesen diff --git a/src/SConscript b/src/SConscript deleted file mode 100644 index 20011465..00000000 --- a/src/SConscript +++ /dev/null @@ -1,42 +0,0 @@ -import glob -file_list = glob.glob('*.cpp') -file_list.remove('lua-engine.cpp') # use logic below for this - -subdirs = Split(""" -boards -drivers/common -fir -input -utils -""") -#palettes - -Import('env') -Export('env') - -if env['LUA']: - file_list.append('lua-engine.cpp') - if env['SYSTEM_LUA'] == 0: - subdirs.append('lua') - -if env['CREATE_AVI']: - subdirs.append('drivers/videolog') - - - -for dir in subdirs: - subdir_files = SConscript('%s/SConscript' % dir) - file_list.append(subdir_files) -if env['PLATFORM'] == 'win32': - platform_files = SConscript('drivers/win/SConscript') -else: - platform_files = SConscript('drivers/sdl/SConscript') -file_list.append(platform_files) - -print(env['LINKFLAGS']) - -if env['PLATFORM'] == 'win32': - fceux = env.Program('fceux.exe', file_list) -else: - fceux = env.Program('fceux', file_list) -Return('fceux') diff --git a/src/boards/SConscript b/src/boards/SConscript deleted file mode 100644 index f9afb2d5..00000000 --- a/src/boards/SConscript +++ /dev/null @@ -1,6 +0,0 @@ -import glob -source_list = glob.glob('*.cpp')+glob.glob('*.c') - -for x in range(len(source_list)): - source_list[x] = 'boards/' + source_list[x] -Return('source_list') diff --git a/src/drivers/Qt/AboutWindow.cpp b/src/drivers/Qt/AboutWindow.cpp index 170710ef..aab61613 100644 --- a/src/drivers/Qt/AboutWindow.cpp +++ b/src/drivers/Qt/AboutWindow.cpp @@ -119,7 +119,7 @@ AboutWindow::AboutWindow(QWidget *parent) mainLayout->addLayout( hbox1 ); hbox1 = new QHBoxLayout(); - lbl = new QLabel( tr("© 2016 FceuX Development Team") ); + lbl = new QLabel( tr("© 2020 FceuX Development Team") ); hbox1->addWidget( lbl ); hbox1->setAlignment( Qt::AlignCenter ); diff --git a/src/drivers/Qt/ConsoleDebugger.cpp b/src/drivers/Qt/ConsoleDebugger.cpp index b1cfd107..8489c40f 100644 --- a/src/drivers/Qt/ConsoleDebugger.cpp +++ b/src/drivers/Qt/ConsoleDebugger.cpp @@ -2071,7 +2071,6 @@ void QAsmView::updateAssemblyView(void) uint8 opcode[3]; char asmTxt[256]; dbg_asm_entry_t *a, *d; - //GtkTextIter iter, next_iter; char pc_found = 0; start_address_lp = starting_address = X.PC; @@ -2112,12 +2111,6 @@ void QAsmView::updateAssemblyView(void) } //asmText->clear(); - //gtk_text_buffer_get_start_iter( textbuf, &iter ); - - //textview_lines_allocated = gtk_text_buffer_get_line_count( textbuf ) - 1; - - //printf("Num Lines: %i\n", textview_lines_allocated ); - for (int i=0; i < 0xFFFF; i++) { line.clear(); diff --git a/src/drivers/Qt/config.cpp b/src/drivers/Qt/config.cpp index 125f017f..0fa39f9b 100644 --- a/src/drivers/Qt/config.cpp +++ b/src/drivers/Qt/config.cpp @@ -206,7 +206,6 @@ InitConfig() config->addOption('y', "yres", "SDL.YResolution", 0); config->addOption("SDL.LastXRes", 0); config->addOption("SDL.LastYRes", 0); - config->addOption('b', "bpp", "SDL.BitsPerPixel", 32); config->addOption("doublebuf", "SDL.DoubleBuffering", 1); config->addOption("autoscale", "SDL.AutoScale", 1); config->addOption("keepratio", "SDL.KeepRatio", 1); @@ -243,9 +242,6 @@ InitConfig() config->addOption("autoInputPreset", "SDL.AutoInputPreset", 0); - // allow for input configuration - //config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg); - // display input config->addOption("inputdisplay", "SDL.InputDisplay", 0); diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index dca3d868..7638ab90 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -387,7 +387,6 @@ static const char *DriverUsage = "Option Value Description\n" "--pal {0|1} Use PAL timing.\n" "--newppu {0|1} Enable the new PPU core. (WARNING: May break savestates)\n" -"--inputcfg d Configures input device d on startup.\n" "--input(1,2) d Set which input device to emulate for input 1 or 2.\n" " Devices: gamepad zapper powerpad.0 powerpad.1\n" " arkanoid\n" @@ -405,8 +404,6 @@ static const char *DriverUsage = "--(x/y)scale x Multiply width/height by x. \n" " (Real numbers >0 with OpenGL, otherwise integers >0).\n" "--(x/y)stretch {0|1} Stretch to fill surface on x/y axis (OpenGL only).\n" -"--bpp {8|16|32} Set bits per pixel.\n" -"--opengl {0|1} Enable OpenGL support.\n" "--fullscreen {0|1} Enable full screen mode.\n" "--noframe {0|1} Hide title bar and window decorations.\n" "--special {1-4} Use special video scaling filters\n" @@ -435,7 +432,6 @@ static const char *DriverUsage = "--players x Set the number of local players in a network play\n" " session.\n" "--rp2mic {0|1} Replace Port 2 Start with microphone (Famicom).\n" -"--nogui Don't load the GTK GUI\n" "--4buttonexit {0|1} exit the emulator when A+B+Select+Start is pressed\n" "--loadstate {0-9|>9} load from the given state when the game is loaded\n" "--savestate {0-9|>9} save to the given state when the game is closed\n" @@ -548,16 +544,7 @@ int fceuWrapperInit( int argc, char *argv[] ) g_config->save(); } - - //g_config->getOption("SDL.InputCfg", &s); - - //if (s.size() != 0) - //{ - // InitVideo(GameInfo); - // InputCfg(s); - //} - - // update the input devices + // update the input devices UpdateInput(g_config); // check for a .fcm file to convert to .fm2 diff --git a/src/drivers/Qt/input.cpp b/src/drivers/Qt/input.cpp index a4c6a3be..45193767 100644 --- a/src/drivers/Qt/input.cpp +++ b/src/drivers/Qt/input.cpp @@ -469,58 +469,6 @@ std::string GetFilename (const char *title, bool save, const char *filter) fname = GetOpenFileName (&ofn); #endif -//#ifdef _GTK -// int fullscreen = 0; -// g_config->getOption ("SDL.Fullscreen", &fullscreen); -// if (fullscreen) -// ToggleFS (); -// -// GtkWidget *fileChooser; -// -// GtkFileFilter *filterX; -// GtkFileFilter *filterAll; -// -// filterX = gtk_file_filter_new (); -// gtk_file_filter_add_pattern (filterX, filter); -// gtk_file_filter_set_name (filterX, filter); -// -// -// filterAll = gtk_file_filter_new (); -// gtk_file_filter_add_pattern (filterAll, "*"); -// gtk_file_filter_set_name (filterAll, "All Files"); -// -// if (save) -// fileChooser = gtk_file_chooser_dialog_new ("Save as", NULL, -// GTK_FILE_CHOOSER_ACTION_SAVE, -// "_Cancel", -// GTK_RESPONSE_CANCEL, -// "_Save", -// GTK_RESPONSE_ACCEPT, NULL); -// else -// fileChooser = gtk_file_chooser_dialog_new ("Open", NULL, -// GTK_FILE_CHOOSER_ACTION_OPEN, -// "_Cancel", -// GTK_RESPONSE_CANCEL, -// "_Open", -// GTK_RESPONSE_ACCEPT, NULL); -// -// // TODO: make file filters case insensitive -// //gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterX); -// gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fileChooser), filterAll); -// int response = gtk_dialog_run (GTK_DIALOG (fileChooser)); -// -// // flush gtk events -// while (gtk_events_pending ()) -// gtk_main_iteration_do (TRUE); -// -// if (response == GTK_RESPONSE_ACCEPT) -// fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser)); -// -// gtk_widget_destroy (fileChooser); -// -// while (gtk_events_pending ()) -// gtk_main_iteration_do (TRUE); -//#endif FCEUI_ToggleEmulationPause (); return fname; } @@ -530,71 +478,6 @@ std::string GetFilename (const char *title, bool save, const char *filter) */ std::string GetUserText (const char *title) { -#ifdef _GTK -/* prg318 - 10/13/11 - this is broken in recent build and causes - * segfaults/very weird behavior i'd rather remove it for now than it cause - * accidental segfaults - * TODO fix it -*/ -#if 0 -// -// GtkWidget* d; -// GtkWidget* entry; -// -// d = gtk_dialog_new_with_buttons(title, NULL, GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_OK); -// -// entry = gtk_entry_new(); -// -// GtkWidget* vbox = gtk_dialog_get_content_area(GTK_DIALOG(d)); -// -// gtk_container_add(GTK_CONTAINER(vbox), entry); -// -// gtk_widget_show_all(d); -// -// gtk_dialog_run(GTK_DIALOG(d)); -// -// // flush gtk events -// while(gtk_events_pending()) -// gtk_main_iteration_do(TRUE); -// -// std::string input = gtk_entry_get_text(GTK_ENTRY(entry)); -// -// if (FCEUI_EmulationPaused() == 0) -// FCEUI_ToggleEmulationPause(); // pause emulation -// -// int fullscreen = 0; -// g_config->getOption("SDL.Fullscreen", &fullscreen); -// if(fullscreen) -// ToggleFS(); // disable fullscreen emulation -// -// FILE *fpipe; -// std::string command = "zenity --entry --title=\""; -// command.append(title); -// command.append("\" --text=\""); -// command.append(title); -// command.append(":\""); -// -// if (!(fpipe = (FILE*)popen(command.c_str(),"r"))) // If fpipe is NULL -// FCEUD_PrintError("Pipe error on opening zenity"); -// int c; -// std::string input; -// while((c = fgetc(fpipe))) -// { -// if (c == EOF || c == '\n') -// break; -// input += c; -// } -// pclose(fpipe); -// gtk_widget_destroy(d); -// -// -// while(gtk_events_pending()) -// gtk_main_iteration_do(TRUE); -// -// FCEUI_ToggleEmulationPause(); // unpause emulation -// return input; -#endif // #if 0 -#endif return ""; } @@ -926,9 +809,6 @@ static void KeyboardCommands (void) { if ( Hotkeys[HK_SELECT_STATE_0 + i].getRisingEdge() ) { -#ifdef _GTK - setStateMenuItem(i); -#endif FCEUI_SelectState (i, 1); } } @@ -936,17 +816,11 @@ static void KeyboardCommands (void) if ( Hotkeys[HK_SELECT_STATE_NEXT].getRisingEdge() ) { FCEUI_SelectStateNext (1); -#ifdef _GTK - setStateMenuItem( CurrentState ); -#endif } if ( Hotkeys[HK_SELECT_STATE_PREV].getRisingEdge() ) { FCEUI_SelectStateNext (-1); -#ifdef _GTK - setStateMenuItem( CurrentState ); -#endif } if ( Hotkeys[HK_BIND_STATE].getRisingEdge() ) diff --git a/src/drivers/Qt/input.h b/src/drivers/Qt/input.h index 95a9f133..ba7ae199 100644 --- a/src/drivers/Qt/input.h +++ b/src/drivers/Qt/input.h @@ -74,7 +74,6 @@ int DTestButtonJoy(ButtConfig *bc); void FCEUD_UpdateInput(void); void UpdateInput(Config *config); -//void InputCfg(const std::string &); std::string GetUserText(const char* title); const char* ButtonName(const ButtConfig* bc); diff --git a/src/drivers/Qt/sdl-video.cpp b/src/drivers/Qt/sdl-video.cpp index bead8226..259a23ea 100644 --- a/src/drivers/Qt/sdl-video.cpp +++ b/src/drivers/Qt/sdl-video.cpp @@ -58,9 +58,6 @@ static int s_srendline, s_erendline; static int s_tlines; static int s_inited = 0; -//#ifdef OPENGL -//static int s_useOpenGL = 0; -//#endif static double s_exs = 1.0, s_eys = 1.0; static int s_eefx = 0; static int s_clipSides = 0; @@ -152,9 +149,6 @@ int InitVideo(FCEUGI *gi) // load the relevant configuration variables g_config->getOption("SDL.Fullscreen", &s_fullscreen); g_config->getOption("SDL.DoubleBuffering", &doublebuf); -//#ifdef OPENGL -// g_config->getOption("SDL.OpenGL", &s_useOpenGL); -//#endif g_config->getOption("SDL.SpecialFilter", &s_sponge); g_config->getOption("SDL.XStretch", &xstretch); g_config->getOption("SDL.YStretch", &ystretch); diff --git a/src/drivers/common/SConscript b/src/drivers/common/SConscript deleted file mode 100644 index 3d39b224..00000000 --- a/src/drivers/common/SConscript +++ /dev/null @@ -1,6 +0,0 @@ -import glob -source_list = glob.glob('*.cpp') + glob.glob('*.c') - -for x in range(len(source_list)): - source_list[x] = 'drivers/common/' + source_list[x] -Return('source_list') diff --git a/src/drivers/sdl/SConscript b/src/drivers/sdl/SConscript deleted file mode 100644 index 22fbb644..00000000 --- a/src/drivers/sdl/SConscript +++ /dev/null @@ -1,31 +0,0 @@ -# Fix compliation error about 'XKeysymToString' by linking X11 explicitly -# Thanks Antonio Ospite! -Import('env') -config_string = 'pkg-config --cflags --libs x11' -env.ParseConfig(config_string) -Export('env') - -source_list = Split( - """ - input.cpp - cheat.cpp - config.cpp - memview.cpp - ramwatch.cpp - debugger.cpp - glxwin.cpp - sdl.cpp - sdl-joystick.cpp - sdl-sound.cpp - sdl-throttle.cpp - sdl-video.cpp - unix-netplay.cpp - """) - -Import('env') - -if env['GTK'] or env['GTK3']: - source_list.append('gui.cpp') - -source_list = ['drivers/sdl/' + source for source in source_list] -Return('source_list') diff --git a/src/drivers/videolog/SConscript b/src/drivers/videolog/SConscript deleted file mode 100644 index b8554746..00000000 --- a/src/drivers/videolog/SConscript +++ /dev/null @@ -1,14 +0,0 @@ -my_list = Split(""" -nesvideos-piece.cpp -rgbtorgb.cpp -""") - -Import('env') - -if env['LOGO']: - env.Append(CCFLAGS = "-DHAVE_GD") - -for x in range(len(my_list)): - my_list[x] = 'drivers/videolog/' + my_list[x] -Return('my_list') - diff --git a/src/drivers/win/SConscript b/src/drivers/win/SConscript deleted file mode 100644 index a23de80d..00000000 --- a/src/drivers/win/SConscript +++ /dev/null @@ -1,62 +0,0 @@ -Import('env') - -my_list = Split(""" -archive.cpp -args.cpp -aviout.cpp -cdlogger.cpp -cheat.cpp -common.cpp -config.cpp -debugger.cpp -debuggersp.cpp -directories.cpp -gui.cpp -guiconfig.cpp -help.cpp -input.cpp -joystick.cpp -keyboard.cpp -log.cpp -main.cpp -mapinput.cpp -memview.cpp -memviewsp.cpp -memwatch.cpp -monitor.cpp -netplay.cpp -ntview.cpp -OutputDS.cpp -palette.cpp -ppuview.cpp -pref.cpp -replay.cpp -sound.cpp -state.cpp -tasedit.cpp -texthook.cpp -throttle.cpp -timing.cpp -tracer.cpp -video.cpp -wave.cpp -Win32InputBox.cpp -window.cpp -""") - -# TODO this is probably .obj if built on a Windows system... -my_list.append('res.o') -env.Command('res.o', 'res.rc', env['WINDRES'] + ' -Isrc/drivers/win -DLVS_OWNERDATA=0x1000 -o $TARGET $SOURCE') - -subdirs = Split(""" -directx -zlib""") - -for x in range(len(my_list)): - my_list[x] = 'drivers/win/' + my_list[x] - -for dir in subdirs: - subdir_files = SConscript('%s/SConscript' % dir) - my_list.append(subdir_files) - -Return('my_list') diff --git a/src/drivers/win/directx/SConscript b/src/drivers/win/directx/SConscript deleted file mode 100644 index 7635d53b..00000000 --- a/src/drivers/win/directx/SConscript +++ /dev/null @@ -1,10 +0,0 @@ -my_list = Split(""" -dsound.lib -dxguid.lib -ddraw.lib -dinput.lib -""") - -for x in range(len(my_list)): - my_list[x] = 'drivers/win/directx/' + my_list[x] -Return('my_list') diff --git a/src/drivers/win/zlib/SConscript b/src/drivers/win/zlib/SConscript deleted file mode 100644 index 122f7afd..00000000 --- a/src/drivers/win/zlib/SConscript +++ /dev/null @@ -1,20 +0,0 @@ -my_list = Split(""" -adler32.c -compress.c -crc32.c -deflate.c -gzio.c -infblock.c -infcodes.c -inffast.c -inflate.c -inftrees.c -infutil.c -trees.c -uncompr.c -zutil.c -""") - -for x in range(len(my_list)): - my_list[x] = 'drivers/win/zlib/' + my_list[x] -Return('my_list') diff --git a/src/fir/SConscript b/src/fir/SConscript deleted file mode 100644 index ef06e5d7..00000000 --- a/src/fir/SConscript +++ /dev/null @@ -1,6 +0,0 @@ -my_list = Split(""" -""") - -for x in range(len(my_list)): - my_list[x] = 'fir/' + my_list[x] -Return('my_list') diff --git a/src/input/SConscript b/src/input/SConscript deleted file mode 100644 index 2cb90e4e..00000000 --- a/src/input/SConscript +++ /dev/null @@ -1,6 +0,0 @@ -import glob -source_list = glob.glob('*.cpp') - -for x in range(len(source_list)): - source_list[x] = 'input/' + source_list[x] -Return('source_list') diff --git a/src/lua/SConscript b/src/lua/SConscript deleted file mode 100644 index 83a51b3d..00000000 --- a/src/lua/SConscript +++ /dev/null @@ -1,8 +0,0 @@ -import glob -source_list = glob.glob('src/*.c') -source_list.remove('src/lua.c') -source_list.remove('src/luac.c') - -for x in range(len(source_list)): - source_list[x] = 'lua/' + source_list[x] -Return('source_list') diff --git a/src/palettes/SConscript b/src/palettes/SConscript deleted file mode 100644 index 7e4aef54..00000000 --- a/src/palettes/SConscript +++ /dev/null @@ -1,6 +0,0 @@ -import glob -source_list = glob.glob('*.c') - -for x in range(len(source_list)): - source_list[x] = 'palettes/' + source_list[x] -Return('source_list') diff --git a/src/utils/SConscript b/src/utils/SConscript deleted file mode 100644 index bc9d9dab..00000000 --- a/src/utils/SConscript +++ /dev/null @@ -1,25 +0,0 @@ -import glob -#source_list = glob.glob('*.cpp') -source_list = Split( -""" -backward.cpp -ConvertUTF.c -xstring.cpp -crc32.cpp -endian.cpp -general.cpp -guid.cpp -md5.cpp -memory.cpp -""") - -Import('env') - - -if env['SYSTEM_MINIZIP'] == 0: - source_list.append('unzip.cpp') - source_list.append('ioapi.cpp') - -for x in range(len(source_list)): - source_list[x] = 'utils/' + source_list[x] -Return('source_list') diff --git a/src/version.h b/src/version.h index d0bca7d4..5cbfe854 100644 --- a/src/version.h +++ b/src/version.h @@ -61,7 +61,7 @@ #endif #define FCEU_VERSION_NUMERIC 22020 -#define FCEU_VERSION_STRING "2.2.3" FCEU_SUBVERSION_STRING FCEU_FEATURE_STRING FCEU_COMPILER +#define FCEU_VERSION_STRING "2.3.0" FCEU_SUBVERSION_STRING FCEU_FEATURE_STRING FCEU_COMPILER #define FCEU_NAME_AND_VERSION FCEU_NAME " " FCEU_VERSION_STRING #endif diff --git a/web/download.html b/web/download.html index d922f9a3..a39d59f7 100644 --- a/web/download.html +++ b/web/download.html @@ -77,8 +77,8 @@
Table of Contents:
+
+
+The Qt GUI can either use the standard system style/themes or custom stylesheets.
+The available standard styles that are installed on the system will be listed when running the executable command line help.
+To use a provided system style, use the --style command line argument.
+To use a custom Qt stylesheet file, set an environment variable named FCEUX_QT_STYLESHEET that contains
+the full path to the file. This will check for this at startup.
+If the variable is defined and the file is readable by the program,
+then the styling settings will be used by the GUI.
+
Bash Shell Setup Example:
+
+ export FCEUX_QT_STYLESHEET=/home/me/myFceux.qss ++ For information on Qt stylesheet syntax, see Qt online documentation
- NOTE:There is not a GUI available to remap these hotkeys for SDL. If you really - want to remap the hotkeys, you can edit the config file manually and replace the values - with SDL keysyms. Alternatively, you can use a tool like qjoypad - or joy2key and even map hotkeys to joystick buttons/axes. + NOTE: The GUI has a window to remap these hotkeys for SDL.
Key: | Action: |
---|
Key: | Button on Emulated Gamepad: | ||
---|---|---|---|
D | B |
Argument: | Value Type: | Default value: | Description: |
---|---|---|---|
Unknown | Original Author | ||
Lukas Sabota | FCEUX SDL documentation revival. | ||
mjbudd77 | +FCEUX Qt/SDL documentation upates. |
Table of Contents:
The most recent changes to fceuX are reflected immediately in the fceux - sourceforge subversion server. You can checkout the source code to build + github server. You can checkout the source code to build fceuX with the most recent sources by running the following command:
-svn co https://fceultra.svn.sourceforge.net/svnroot/fceultra/fceu fceux
-Instructions for compiling and installing fceuX can be found in the "README-SDL" file.
+git clone https://github.com/TASVideos/fceux.git
+Instructions for compiling and installing fceuX can be found in the "README" file.
-
If you have the GTK GUI compiled into fceuX, you can configure the gamepad by +
Using the Qt GUI, you can configure the gamepad by selecting "Options...Gamepad" in the menubar.
-You can allso configure the first gamepad by running fceux --inputcfg gamepad1
-When you configure a button you will be presented with a black window with a titlebar - indicating what button to map. FceuX will look for two - of the same keypress/joystick event in a row. If it doesn't find two of the same - keypresses in a row, it will allow you to map the button to two separate keys.
Try using different SDL audio drivers. You can set the SDL audio driver with @@ -58,11 +53,21 @@ you may want to try the latest version of fceuX to see if you are still having issues. FceuX 2.1.4 fixed the majority of the reported sound issues.
+The Qt/SDL version of fceux runs two threads. One for the GUI and one for the emulation. + The realtime OS scheduling and priority of both of these threads can be tuned via the GUI + timing config options window (accessible via the menu bar). For Mac OSX systems, fceux must + have root permission to increase process priority. For Linux systems, add the following + lines to the /etc/security/limits.conf file to ensure that fceux users have the proper system + resource permissions (requires reboot after editing for changes to take place): +
+* - priority 99 +* - rtprio 99 +* - nice -20 ++
You need to edit your ~/.fceux/fceux.cfg file. The SDL.Hotkeys.* values - are SDL keysyms, which can be found in SDL_keysym.h (probably - /usr/include/SDL/SDL_keysym.h on your system). At the time of writing, - hotkeys are not mappable from the GUI in sdl (although it is planned for the future). +
SDL hotkey bindings can be remapped using the Qt GUI. Selecting "Options...HotKeys" in the menubar.
If you want to map particular hotkeys (pause, save state, load state, etc) to buttons on @@ -77,6 +82,8 @@