diff --git a/.appveyor.yml b/.appveyor.yml
new file mode 100644
index 0000000..259b7ed
--- /dev/null
+++ b/.appveyor.yml
@@ -0,0 +1,42 @@
+image: Visual Studio 2019
+
+environment:
+ matrix:
+ - { PYTHON: "C:\\Python27", APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015" }
+ - { PYTHON: "C:\\Python35", APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015" }
+ - PYTHON: "C:\\Python36"
+ - PYTHON: "C:\\Python37"
+ - PYTHON: "C:\\Python38"
+ - { PYTHON: "C:\\Python27-x64", APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015" }
+ - { PYTHON: "C:\\Python35-x64", APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015" }
+ - PYTHON: "C:\\Python36-x64"
+ - PYTHON: "C:\\Python37-x64"
+ - PYTHON: "C:\\Python38-x64"
+
+install:
+ - "%PYTHON%\\python.exe -m pip install wheel"
+
+build: off
+
+before_test:
+ - "%PYTHON%\\python.exe setup.py bdist_wheel"
+ - "cd dist"
+ - "%PYTHON%\\python.exe -m pip install --find-links=. atari-py"
+ - "%PYTHON%\\python.exe -m pip install gym"
+
+test_script:
+ - "%PYTHON%\\python.exe -c \"import gym; env = gym.make('Enduro-v0'); env.reset(); [env.step(env.action_space.sample()) for i in range(1000)]\""
+
+artifacts:
+ - path: dist\*.whl
+ name: Releases
+
+deploy:
+ provider: GitHub
+ auth_token:
+ secure: "Weh3LepGE4k174U43zSHYAiM1pUCUSlQ+wjwpmUI2X3SsZqTpdRKzDUwkLnHjp23"
+ artifact: /.*\.whl/
+ draft: false
+ prerelease: false
+ on:
+ appveyor_repo_tag: true
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..cbed0de
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,42 @@
+language: sh
+script: ./build.sh
+os:
+ - linux
+ - windows
+ - osx
+env:
+ - PY_VER=3.6
+ - PY_VER=3.7
+ - PY_VER=3.5
+osx_image: xcode8.3
+matrix:
+ exclude:
+ os: windows
+ env: PY_VER=3.5
+deploy:
+ provider: s3
+ access_key_id: AKIAIR7X3BP26ZWUNFPA
+ skip_cleanup: true
+ secret_access_key:
+ secure: wUNE0AxIZ3rQVO6pUXQyfOVI4UN/4bgTb+y8566pFYQ68mzZEW3XNl96n8HtkHGYuJGnNGWGbGKcp2a1MCoiyePR+NnmoUxCledUffU+s88Sxg9Qj7DW8JOLImocNXG+8y2OeC+QjmrkB109inM0c2T+ESeLZi9yALaLSxVEKToXB1EBDtOohjelNcA8xoP9yb4H6yoT01XLNkno2o9fmKc+ZXtLi9xZVpMX1aH0Hs2pchm0WmE7d93XVD0K9ZM/2q1yT8ojJngKAbpJeJQSSSJStNpFBIp7hc+2slFP9/QOCPJQZQuIjJkHj2iXEMgIrerbFgl/n5konQiZFHwDZbmubQR8cfVOmr/+By8n9h13rzL7OpqCx84f4QuaRifRY6vMnu0nqbo7M7vkW0fEzcMOEpn1fcL0ulOOFc9Oedyvn08flK2M3DX10rglncK+MkGdWjH23K/1PLNOCIdNO8kWO+yvuCbdx1oJzMcpr5w52Sh+pWt4xXk1TQvXtzPVxLxf+mGumHvU1wSFW2IbBcLIv3C/BeqeNbyRNIrXT2rfaOzDj8LEXOq3IIdfgKmHx2a4Iz3V3S2a5vJiXeBtr9G4LtH/k9eRRyr6CKN+HqSZSRnwL0W8i3u7QvcP6wSF91lJCpAJpsuu5faE3RKfW/hUd/gsmo1f1tcJZEaCkzo=
+ bucket: games-wheels
+ local-dir: wheelhouse
+ upload-dir: atari-py/$TRAVIS_TAG
+ acl: public_read
+ on:
+ repo: openai/atari-py
+ tags: true
+
+jobs:
+ # this extra stage is due to Travis bug that prevets deploying to pypi from windows or usage of
+ # secret env variables on windows. Instead of doing either, we are deploying to s3 first, and
+ # then using a separate stage to download files from s3 and deploy them to pypi.
+ include:
+ - stage: "Deploy to PyPI"
+ script: ./deploy_to_pypi.sh
+ env:
+ - TWINE_USERNAME=peterz-openai
+ - AWS_ACCESS_KEY_ID=AKIAIR7X3BP26ZWUNFPA
+ - AWS_DEFAULT_REGION=us-west-2
+ - secure: "i0qbR3wG2OvJWVBKnAVkgtNIPPxoNQz8KBn+c9RBAWZw0XDsjkUwsDZMTXzll1Do24xLb9FVti2iq7GsNvHcCzltSGOLv6UDm2ywJc4Bz/Fyho27A0kYGe6W/FwtEt+VTkx4z0+7tNOb4KVhs26OmIGdKMJwNibnU86rRtzf05Iq7xS+8Mi/9j09oC9ZXACzOFTmbQe98Gq93ROo+7wfpCVJip9QigJTSZhE7axBEtpXlZ5//T2Eo2bxbJs5f9tNiMrLRy8NMYq1B/he9HevpxlqE15+wJs9exaDClWLtsb7trFKSnmrqtUeXI3aUIQwLgQfaYJlvvmSBUtJxxyk5QHLn3+0u6TCA9ZbHaEElXSLrcexjSEp37+HXH0Z69JzTYn0pVX4IvrmuLhgg4X3z7Ys3SyIe8Tq39QubQ8TWM8bzBN5H0VYObY35BmLl68k2AF61Rq0obJS48ekguzf88DwI9UzxYm8LnlsgpyeX1iLJ6Sy9xdP3S/5onP1+bzaDZ7JNMabNmJ22ZjqPyBp+mUyBjfab9ouDS07CNAPmyQV6VWSL8EaD9QawWB0khgKoen+NNFGeivEIgCRanP9Rg7mpw7Px9elwbl2hXGco7EGdZFPV89uHWEhL2nHUmxVjaRUNlSXjDrwI6f8vlMfbHU5PskxlrG047F/is3gQ00="
+ - secure: "NZRMo04bBX2X7phT29rQKDklPFVbnqMoUAhrVFjTLxvAqsQdericyalMjXsE79IA02uZEsHfS45P9YXzgHC4uCZI6694kOZfhmBtQ0FxeJ5M3Zx6IRyMhf92rk7F/DRcRBe78JIBkgTXDJCyQoEX1/RIYIz723BSzRGosOJa1xUub8MQ7Rl3TF54j9JAshBNBTpIw1tORWo3K1A8FucQNgI3N7DucWhg+C3D7cxZok5xwz7FoXHt+Xv7wFvCETaNIsmu/3EI15K9Y43XXQ2rBc46g41SDX7f1rwVNl0D8kStjyDdhdQODDdKPMe3dl6Lckz0qMTaoTUnWL91L+qBAFHsC2imWJVNGL+/4iyTRQAsq/hl7GYNcesfm7kCXNcCjSeyx3ZkOOgZ0okFKWZK51RuKjlCcKgDOMSInCW8vR2rRK699wAfePr38t5TO5E2uQ+hF52NMbzDKw9C6azX4UaWuKPio8oxseOWfLKSYZTCVirBikLM8m4LABCZyKiMlTR1SdzxQmrLAxgnWaD+QYY4SoN4fButDjONOARFKF5e3njzVQo2nHmXb1EATOmnQ4pjKcJezSccIcmYeWpPskXWSmJbWi81zwHz/AyqH6fEnAWmVj0RKjrBfyCZCtEGBikQ9KTJuVHupwNT17CyZKUxtxBpYOpFnk+mLLom3Ak="
diff --git a/ChangeLog b/ChangeLog
deleted file mode 100644
index 0ede910..0000000
--- a/ChangeLog
+++ /dev/null
@@ -1,56 +0,0 @@
-June 22nd, 2015. ALE 0.5.0.
- * Added action_repeat_stochasticity.
- * Added sound playback, visualization.
- * Added screen/sound recording ability.
- * CMake now available.
- * Incorporated Benjamin Goodrich's Python interface.
- * Some game fixes.
- * Added examples for shared library, Python, fifo, RL-Glue interfaces.
- * Incorporated Java agent into main repository.
- * Removed internal controller, now superseded by shared library interface.
- * Better ALEInterface.
- * Many other changes.
-
-February 15th, 2015. ALE 0.5dev.
- * Removed the following command-line flags: 'output_file', 'system_reset_steps', 'use_environment_distribution', 'backward_compatible_save', internal agent flags
- * The flag 'use_starting_actions' was removed and internally its value is always 'true'.
- * The flag 'disable_color_averaging' was renamed to 'color_averaging' and FALSE is its default value.
-
-April 28th, 2014. ALE 0.4.4.
- * Fixed a memory issue in ALEScreen.
-
-April 26th, 2014. Bug fix (Mayank Daswani).
- * Fixed issues with frame numbers not being correctly updated.
- * Fixed a bug where total reward was not properly reported under frame skipping.
-
-January 7th, 2013. ALE 0.4.3.
- * Fixed a bug with ALEState's m_frame_number.
-
-June 12th, 2013. ALE 0.4.2.
- * Modified StellaEnvironment save/load interface to provide additional flexibility.
- * Series of bug fixes from Matthew Hausknecht and community.
-
-May 24th, 2013. Bug fix to ALE 0.4.1.
- * Fixed RL-Glue syntax from OBSERVATION to OBSERVATIONS. Thanks to Angus MacIsaac for picking this bug up.
-
-May 22nd, 2013. ALE 0.4.1.
- * Added frame skipping support directly in StellaEnvironment.
- * Reverted default number of episodes to 10.
-
-April 22nd, 2013. ALE 0.4.0.
- * RL-Glue support
- * Shared library interface
- * Simpler direct environment interfacing
- * Improved environment handling
- * Improved environment customization
- * Better documentation
-
-October 3rd, 2012. Moving to GITHub.
-
-August 7th, 2012. ALE 0.3.1.
- * Fixed frames per episode cap for FIFO agents, added functionality to
- limit the total number of frames per run for FIFO agents.
-
-July 22nd, 2012. ALE 0.3.
- * Initial ALE release.
-
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 5fd410b..0000000
--- a/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-.PHONY: build clean
-
-build:
- make -C atari_py/ale_interface build
-
-clean:
- rm -rf dist atari_py.egg-info
- make -C atari_py/ale_interface clean
-
-package_data:
- ( echo "ale_interface/build/*.so" && echo "ale_interface/build/ale" && cd atari_py && git ls-files |grep -v \\.py$ ) > atari_py/package_data.txt
-
-upload:
- make clean
- rm -rf dist
- python setup.py sdist
- twine upload dist/*
diff --git a/README-ale.md b/README-ale.md
index 6031d27..edee571 100644
--- a/README-ale.md
+++ b/README-ale.md
@@ -1,23 +1,119 @@
-(Contents from [https://github.com/bbitmaster/ale_python_interface](https://github.com/bbitmaster/ale_python_interface))
+[](https://travis-ci.org/mgbellemare/Arcade-Learning-Environment)
-# Arcade-Learning-Environment
+# The Arcade Learning Environment
-The Arcade Learning Environment (ALE) -- a platform for AI research.
+The Arcade Learning Environment (ALE) is a simple object-oriented framework that allows researchers and hobbyists to develop AI agents for Atari 2600 games. It is built on top of the Atari 2600 emulator [Stella](https://stella-emu.github.io/) and separates the details of emulation from agent design. This [video](https://www.youtube.com/watch?v=nzUiEkasXZI) depicts over 50 games currently supported in the ALE.
-For more details and installation instructions, see the [website](http://www.arcadelearningenvironment.org) and [manual](doc/manual/manual.pdf). To ask questions and discuss, please join the [ALE-users group](https://groups.google.com/forum/#!forum/arcade-learning-environment).
+For an overview of our goals for the ALE read [The Arcade Learning Environment: An Evaluation Platform for General Agents](http://www.jair.org/papers/paper3912.html). If you use ALE in your research, we ask that you please cite this paper in reference to the environment (BibTeX entry at the end of this document). Also, if you have any questions or comments about the ALE, please contact us through our [mailing list](https://groups.google.com/forum/#!forum/arcade-learning-environment).
-## Citing ALE
-If ALE helps in your research, please cite the following:
+Feedback and suggestions are welcome and may be addressed to any active member of the ALE team.
- @article{bellemare13arcade,
- author = {{Bellemare}, M.~G. and {Naddaf}, Y. and {Veness}, J. and {Bowling}, M.},
- title = {The Arcade Learning Environment: An Evaluation Platform for General Agents},
- journal = {Journal of Artificial Intelligence Research},
- year = "2013",
- month = "jun",
- volume = "47",
- pages = "253--279",
- }
+### Features
+- Object-oriented framework with support to add agents and games.
+- Emulation core uncoupled from rendering and sound generation modules for fast emulation with minimal library dependencies.
+- Automatic extraction of game score and end-of-game signal for more than 50 Atari 2600 games.
+- Multi-platform code (compiled and tested under OS X and several Linux distributions, with Cygwin support).
+- Communication between agents and emulation core can be accomplished through pipes, allowing for cross-language development (sample Java code included).
+- Python development is supported through ctypes.
+- Agents programmed in C++ have access to all features in the ALE.
+- Visualization tools.
+
+## Quick start
+
+
+Install main dependences:
+```
+sudo apt-get install libsdl1.2-dev libsdl-gfx1.2-dev libsdl-image1.2-dev cmake
+```
+
+Compilation:
+
+```
+$ mkdir build && cd build
+$ cmake -DUSE_SDL=ON -DUSE_RLGLUE=OFF -DBUILD_EXAMPLES=ON ..
+$ make -j 4
+```
+
+To install python module:
+
+```
+$ pip install .
+or
+$ pip install --user .
+```
+
+Getting the ALE to work on Visual Studio requires a bit of extra wrangling. You may wish to use IslandMan93's [Visual Studio port of the ALE.](https://github.com/Islandman93/Arcade-Learning-Environment)
+
+For more details and installation instructions, see the [manual](doc/manual/manual.pdf). To ask questions and discuss, please join the [ALE-users group](https://groups.google.com/forum/#!forum/arcade-learning-environment).
+
+## ALE releases
+
+Releases before v.0.5 are available for download in our previous [website](http://www.arcadelearningenvironment.org/). For the latest releases, please check our releases [page](https://github.com/mgbellemare/Arcade-Learning-Environment/releases).
+
+## List of command-line parameters
+
+Execute ./ale -help for more details; alternatively, see documentation
+available at http://www.arcadelearningenvironment.org.
+
+```
+-random_seed [n] -- sets the random seed; defaults to the current time
+
+-game_controller [fifo|fifo_named] -- specifies how agents interact
+ with the ALE; see Java agent documentation for details
+
+-config [file] -- specifies a configuration file, from which additional
+ parameters are read
+
+-run_length_encoding [false|true] -- determine whether run-length encoding is
+ used to send data over pipes; irrelevant when an internal agent is
+ being used
+
+-max_num_frames_per_episode [n] -- sets the maximum number of frames per
+ episode. Once this number is reached, a new episode will start. Currently
+ implemented for all agents when using pipes (fifo/fifo_named)
+
+-max_num_frames [n] -- sets the maximum number of frames (independent of how
+ many episodes are played)
+```
+
+
+## Citing The Arcade Learning Environment
+
+
+If you use the ALE in your research, we ask that you please cite the following.
+
+*M. G. Bellemare, Y. Naddaf, J. Veness and M. Bowling. The Arcade Learning Environment: An Evaluation Platform for General Agents, Journal of Artificial Intelligence Research, Volume 47, pages 253-279, 2013.*
+
+In BibTeX format:
+
+```
+@Article{bellemare13arcade,
+ author = {{Bellemare}, M.~G. and {Naddaf}, Y. and {Veness}, J. and {Bowling}, M.},
+ title = {The Arcade Learning Environment: An Evaluation Platform for General Agents},
+ journal = {Journal of Artificial Intelligence Research},
+ year = "2013",
+ month = "jun",
+ volume = "47",
+ pages = "253--279",
+}
+```
+
+
+If you use the ALE with sticky actions (flag `repeat_action_probability`), or if you use the different game flavours (mode and difficulty switches), we ask you that you also cite the following:
+
+*M. C. Machado, M. G. Bellemare, E. Talvitie, J. Veness, M. J. Hausknecht, M. Bowling. Revisiting the Arcade Learning Environment: Evaluation Protocols and Open Problems for General Agents, CoRR abs/1709.06009, 2017.*
+
+In BibTex format:
+
+```
+@Article{machado17arcade,
+ author = {Marlos C. Machado and Marc G. Bellemare and Erik Talvitie and Joel Veness and Matthew J. Hausknecht and Michael Bowling},
+ title = {Revisiting the Arcade Learning Environment: Evaluation Protocols and Open Problems for General Agents},
+ journal = {CoRR},
+ volume = {abs/1709.06009},
+ year = {2017}
+}
+```
diff --git a/README.md b/README.md
index 76ae5f4..6a7c463 100644
--- a/README.md
+++ b/README.md
@@ -1,23 +1,13 @@
# atari_py
-A packaged and slightly-modified version of [https://github.com/bbitmaster/ale_python_interface](https://github.com/bbitmaster/ale_python_interface).
+An `openai/atari-py` fork with Windows support and removed zlib/libpng dependencies.
## Installation
-To install via pip, run:
+To simply install [`atari-py` wheels (binaries)](https://github.com/Kojoley/atari-py/releases) use this command:
-```pip install atari-py```
+```pip install -f https://github.com/Kojoley/atari-py/releases atari_py```
-Alternatively, you can install using setuptools using
+If you have any `distutils` supported compiler you can install from sources:
-```python setup.py install```
-
-You can also trigger a build of the C++ code via `make`, and then add
-this repo to your `PYTHONPATH`:
-
-```export PYTHONPATH=/path/to/atari-py:$PYTHONPATH```
-
-### Common issues
-
-- Make sure you have `cmake` installed. On OSX, you probably want
- `brew install cmake`.
+```pip install git+https://github.com/Kojoley/atari-py.git```
diff --git a/atari_py/__init__.py b/atari_py/__init__.py
index 6dd7b48..e09a7bd 100644
--- a/atari_py/__init__.py
+++ b/atari_py/__init__.py
@@ -1,4 +1,4 @@
-from ale_python_interface import *
+from .ale_python_interface import *
import os
def _game_dir():
@@ -9,4 +9,7 @@ def get_game_path(game_name):
def list_games():
files = os.listdir(_game_dir())
- return [os.path.basename(f).split(".")[0] for f in files]
\ No newline at end of file
+ return [os.path.basename(f).split(".")[0] for f in files]
+
+# default to only logging errors
+ALEInterface.setLoggerMode(ALEInterface.Logger.Error)
diff --git a/atari_py/ale_c_wrapper.cpp b/atari_py/ale_c_wrapper.cpp
index 2ddd746..30f6073 100644
--- a/atari_py/ale_c_wrapper.cpp
+++ b/atari_py/ale_c_wrapper.cpp
@@ -1,3 +1,25 @@
-//all code is currently in the .h file
#include "ale_c_wrapper.h"
+#include
+#include
+#include
+
+void encodeState(ALEState *state, char *buf, int buf_len) {
+ std::string str = state->serialize();
+
+ if (buf_len < int(str.length())) {
+ throw new std::runtime_error("Buffer is not big enough to hold serialized ALEState. Please use encodeStateLen to determine the correct buffer size");
+ }
+
+ memcpy(buf, str.data(), str.length());
+}
+
+int encodeStateLen(ALEState *state) {
+ return state->serialize().length();
+}
+
+ALEState *decodeState(const char *serialized, int len) {
+ std::string str(serialized, len);
+
+ return new ALEState(str);
+}
\ No newline at end of file
diff --git a/atari_py/ale_c_wrapper.h b/atari_py/ale_c_wrapper.h
index 1666591..21eac34 100644
--- a/atari_py/ale_c_wrapper.h
+++ b/atari_py/ale_c_wrapper.h
@@ -3,104 +3,131 @@
#include
+#ifdef _WIN32
+# define SYMBOL_EXPORT __declspec(dllexport)
+#endif
+#ifndef SYMBOL_EXPORT
+# define SYMBOL_EXPORT
+#endif
+
extern "C" {
// Declares int rgb_palette[256]
#include "atari_ntsc_rgb_palette.h"
- ALEInterface *ALE_new() {return new ALEInterface();}
- void ALE_del(ALEInterface *ale){delete ale;}
- const char *getString(ALEInterface *ale, const char *key){return ale->getString(key).c_str();}
- int getInt(ALEInterface *ale,const char *key) {return ale->getInt(key);}
- bool getBool(ALEInterface *ale,const char *key){return ale->getBool(key);}
- float getFloat(ALEInterface *ale,const char *key){return ale->getFloat(key);}
- void setString(ALEInterface *ale,const char *key,const char *value){ale->setString(key,value);}
- void setInt(ALEInterface *ale,const char *key,int value){ale->setInt(key,value);}
- void setBool(ALEInterface *ale,const char *key,bool value){ale->setBool(key,value);}
- void setFloat(ALEInterface *ale,const char *key,float value){ale->setFloat(key,value);}
- void loadROM(ALEInterface *ale,const char *rom_file){ale->loadROM(rom_file);}
- int act(ALEInterface *ale,int action){return ale->act((Action)action);}
- bool game_over(ALEInterface *ale){return ale->game_over();}
- void reset_game(ALEInterface *ale){ale->reset_game();}
- void getLegalActionSet(ALEInterface *ale,int *actions){
+ SYMBOL_EXPORT ALEInterface *ALE_new() {return new ALEInterface();}
+ SYMBOL_EXPORT void ALE_del(ALEInterface *ale){delete ale;}
+ SYMBOL_EXPORT const char *getString(ALEInterface *ale, const char *key){return ale->getString(key).c_str();}
+ SYMBOL_EXPORT int getInt(ALEInterface *ale,const char *key) {return ale->getInt(key);}
+ SYMBOL_EXPORT bool getBool(ALEInterface *ale,const char *key){return ale->getBool(key);}
+ SYMBOL_EXPORT float getFloat(ALEInterface *ale,const char *key){return ale->getFloat(key);}
+ SYMBOL_EXPORT void setString(ALEInterface *ale,const char *key,const char *value){ale->setString(key,value);}
+ SYMBOL_EXPORT void setInt(ALEInterface *ale,const char *key,int value){ale->setInt(key,value);}
+ SYMBOL_EXPORT void setBool(ALEInterface *ale,const char *key,bool value){ale->setBool(key,value);}
+ SYMBOL_EXPORT void setFloat(ALEInterface *ale,const char *key,float value){ale->setFloat(key,value);}
+ SYMBOL_EXPORT bool loadROM(ALEInterface *ale,const char *rom,size_t size,const char *name){return ale->loadROM(std::string(rom, size), name);}
+ SYMBOL_EXPORT int act(ALEInterface *ale,int action){return ale->act((Action)action);}
+ SYMBOL_EXPORT bool game_over(ALEInterface *ale){return ale->game_over();}
+ SYMBOL_EXPORT void reset_game(ALEInterface *ale){ale->reset_game();}
+ SYMBOL_EXPORT void getAvailableModes(ALEInterface *ale,int *availableModes) {
+ ModeVect modes_vect = ale->getAvailableModes();
+ for(unsigned int i = 0; i < ale->getAvailableModes().size(); i++){
+ availableModes[i] = modes_vect[i];
+ }
+ }
+ SYMBOL_EXPORT int getAvailableModesSize(ALEInterface *ale) {return ale->getAvailableModes().size();}
+ SYMBOL_EXPORT void setMode(ALEInterface *ale, int mode) {ale->setMode(mode);}
+ SYMBOL_EXPORT void getAvailableDifficulties(ALEInterface *ale,int *availableDifficulties) {
+ DifficultyVect difficulties_vect = ale->getAvailableDifficulties();
+ for(unsigned int i = 0; i < ale->getAvailableDifficulties().size(); i++){
+ availableDifficulties[i] = difficulties_vect[i];
+ }
+ }
+ SYMBOL_EXPORT int getAvailableDifficultiesSize(ALEInterface *ale) {return ale->getAvailableDifficulties().size();}
+ SYMBOL_EXPORT void setDifficulty(ALEInterface *ale, int difficulty) {ale->setDifficulty(difficulty);}
+ SYMBOL_EXPORT void getLegalActionSet(ALEInterface *ale,int *actions){
ActionVect action_vect = ale->getLegalActionSet();
- for(unsigned int i = 0;i < ale->getLegalActionSet().size();i++){
+ for(unsigned int i = 0; i < ale->getLegalActionSet().size(); i++){
actions[i] = action_vect[i];
}
}
- int getLegalActionSize(ALEInterface *ale){return ale->getLegalActionSet().size();}
- void getMinimalActionSet(ALEInterface *ale,int *actions){
+ SYMBOL_EXPORT int getLegalActionSize(ALEInterface *ale){return ale->getLegalActionSet().size();}
+ SYMBOL_EXPORT void getMinimalActionSet(ALEInterface *ale,int *actions){
ActionVect action_vect = ale->getMinimalActionSet();
for(unsigned int i = 0;i < ale->getMinimalActionSet().size();i++){
actions[i] = action_vect[i];
}
}
- int getMinimalActionSize(ALEInterface *ale){return ale->getMinimalActionSet().size();}
- int getFrameNumber(ALEInterface *ale){return ale->getFrameNumber();}
- int lives(ALEInterface *ale){return ale->lives();}
- int getEpisodeFrameNumber(ALEInterface *ale){return ale->getEpisodeFrameNumber();}
- void getScreen(ALEInterface *ale,unsigned char *screen_data){
+ SYMBOL_EXPORT int getMinimalActionSize(ALEInterface *ale){return ale->getMinimalActionSet().size();}
+ SYMBOL_EXPORT int getFrameNumber(ALEInterface *ale){return ale->getFrameNumber();}
+ SYMBOL_EXPORT int lives(ALEInterface *ale){return ale->lives();}
+ SYMBOL_EXPORT int getEpisodeFrameNumber(ALEInterface *ale){return ale->getEpisodeFrameNumber();}
+ SYMBOL_EXPORT void getScreen(ALEInterface *ale,unsigned char *screen_data){
int w = ale->getScreen().width();
int h = ale->getScreen().height();
pixel_t *ale_screen_data = (pixel_t *)ale->getScreen().getArray();
memcpy(screen_data,ale_screen_data,w*h*sizeof(pixel_t));
}
- void getRAM(ALEInterface *ale,unsigned char *ram){
+ SYMBOL_EXPORT void getRAM(ALEInterface *ale,unsigned char *ram){
unsigned char *ale_ram = ale->getRAM().array();
int size = ale->getRAM().size();
memcpy(ram,ale_ram,size*sizeof(unsigned char));
}
- int getRAMSize(ALEInterface *ale){return ale->getRAM().size();}
- int getScreenWidth(ALEInterface *ale){return ale->getScreen().width();}
- int getScreenHeight(ALEInterface *ale){return ale->getScreen().height();}
+ SYMBOL_EXPORT int getRAMSize(ALEInterface *ale){return ale->getRAM().size();}
+ SYMBOL_EXPORT int getScreenWidth(ALEInterface *ale){return ale->getScreen().width();}
+ SYMBOL_EXPORT int getScreenHeight(ALEInterface *ale){return ale->getScreen().height();}
- void getScreenRGB(ALEInterface *ale, int *output_buffer){
+ SYMBOL_EXPORT void getScreenRGB(ALEInterface *ale, unsigned char *output_buffer){
size_t w = ale->getScreen().width();
size_t h = ale->getScreen().height();
size_t screen_size = w*h;
pixel_t *ale_screen_data = ale->getScreen().getArray();
- for(int i = 0;i < w*h;i++){
- output_buffer[i] = rgb_palette[ale_screen_data[i]];
- }
-
+ ale->theOSystem->colourPalette().applyPaletteRGB(output_buffer, ale_screen_data, screen_size );
}
- void getScreenGrayscale(ALEInterface *ale, unsigned char *output_buffer){
+
+ SYMBOL_EXPORT void getScreenRGB2(ALEInterface *ale, unsigned char *output_buffer){
size_t w = ale->getScreen().width();
size_t h = ale->getScreen().height();
size_t screen_size = w*h;
pixel_t *ale_screen_data = ale->getScreen().getArray();
- ale->theOSystem->colourPalette().applyPaletteGrayscale(output_buffer, ale_screen_data, screen_size);
- }
-
- void saveState(ALEInterface *ale){ale->saveState();}
- void loadState(ALEInterface *ale){ale->loadState();}
- void saveScreenPNG(ALEInterface *ale,const char *filename){ale->saveScreenPNG(filename);}
-
- ALEState* cloneState(ALEInterface *ale) {
- return new ALEState(ale->cloneState());
- }
-
- void ALEState_del(ALEState* state) {
- delete state;
- }
-
- void restoreState(ALEInterface *ale, ALEState* state) {
- ale->restoreState(*state);
+ int j = 0;
+ for(int i = 0;i < screen_size;i++){
+ unsigned int zrgb = rgb_palette[ale_screen_data[i]];
+ output_buffer[j++] = (zrgb>>16)&0xff;
+ output_buffer[j++] = (zrgb>>8)&0xff;
+ output_buffer[j++] = (zrgb>>0)&0xff;
+ }
}
- int ALEState_getFrameNumber(ALEState* state) {
- return state->getFrameNumber();
- }
- int ALEState_getEpisodeFrameNumber(ALEState* state) {
- return state->getEpisodeFrameNumber();
- }
+ SYMBOL_EXPORT void getScreenGrayscale(ALEInterface *ale, unsigned char *output_buffer){
+ size_t w = ale->getScreen().width();
+ size_t h = ale->getScreen().height();
+ size_t screen_size = w*h;
+ pixel_t *ale_screen_data = ale->getScreen().getArray();
- bool ALEState_equals(ALEState* a, ALEState *b) {
- return a->equals(*b);
+ ale->theOSystem->colourPalette().applyPaletteGrayscale(output_buffer, ale_screen_data, screen_size);
}
+ SYMBOL_EXPORT void saveState(ALEInterface *ale){ale->saveState();}
+ SYMBOL_EXPORT void loadState(ALEInterface *ale){ale->loadState();}
+ SYMBOL_EXPORT ALEState* cloneState(ALEInterface *ale){return new ALEState(ale->cloneState());}
+ SYMBOL_EXPORT void restoreState(ALEInterface *ale, ALEState* state){ale->restoreState(*state);}
+ SYMBOL_EXPORT ALEState* cloneSystemState(ALEInterface *ale){return new ALEState(ale->cloneSystemState());}
+ SYMBOL_EXPORT void restoreSystemState(ALEInterface *ale, ALEState* state){ale->restoreSystemState(*state);}
+ SYMBOL_EXPORT void deleteState(ALEState* state){delete state;}
+ //Kojoley SYMBOL_EXPORT void saveScreenPNG(ALEInterface *ale,const char *filename){ale->saveScreenPNG(filename);}
+
+ // Encodes the state as a raw bytestream. This may have multiple '\0' characters
+ // and thus should not be treated as a C string. Use encodeStateLen to find the length
+ // of the buffer to pass in, or it will be overrun as this simply memcpys bytes into the buffer.
+ SYMBOL_EXPORT void encodeState(ALEState *state, char *buf, int buf_len);
+ SYMBOL_EXPORT int encodeStateLen(ALEState *state);
+ SYMBOL_EXPORT ALEState *decodeState(const char *serialized, int len);
+
+ // 0: Info, 1: Warning, 2: Error
+ SYMBOL_EXPORT void setLoggerMode(int mode) { ale::Logger::setMode(ale::Logger::mode(mode)); }
}
#endif
diff --git a/atari_py/ale_interface/CMakeLists.txt b/atari_py/ale_interface/CMakeLists.txt
index 140ef1b..ec9c6af 100644
--- a/atari_py/ale_interface/CMakeLists.txt
+++ b/atari_py/ale_interface/CMakeLists.txt
@@ -1,13 +1,20 @@
cmake_minimum_required (VERSION 2.6)
project(ale)
+set(ALEVERSION "0.6")
+
option(USE_SDL "Use SDL" OFF)
option(USE_RLGLUE "Use RL-Glue" OFF)
option(BUILD_EXAMPLES "Build Example Agents" OFF)
+option(BUILD_CPP_LIB "Build C++ Shared Library" OFF)
+option(BUILD_CLI "Build ALE Command Line Interface" OFF)
+option(BUILD_C_LIB "Build ALE C Library (needed for Python interface)" ON)
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wunused -fPIC -O3 -fomit-frame-pointer -D__STDC_CONSTANT_MACROS")
-add_definitions(-DHAVE_INTTYPES)
-set(LINK_LIBS z)
+find_package(ZLIB REQUIRED)
+if(ZLIB_FOUND)
+ include_directories(${ZLIB_INCLUDE_DIRS})
+ set(LINK_LIBS ${ZLIB_LIBRARIES})
+endif()
if(USE_RLGLUE)
add_definitions(-D__USE_RLGLUE)
@@ -23,8 +30,9 @@ if(USE_SDL)
list(APPEND LINK_LIBS ${SDL_LIBRARY} ${SDL_MAIN_LIBRARY})
else()
MESSAGE("SDL 1.2 not found: You may need to manually edit CMakeLists.txt or run \"cmake -i\" to specify your SDL path.")
- # Uncomment below to specify the path to your SDL library. Run "locate libSDL" if unsure.
+ # Uncomment below to specify the path to your SDL library and header file. Run "locate libSDL" and "locate SDL.h" if unsure.
# link_directories(path_to_your_SDL)
+ # include_directories(path_to_your_SDL_header)
if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -framework Cocoa")
list(APPEND LINK_LIBS sdl sdlmain)
@@ -46,18 +54,71 @@ endforeach(module ${MODULES})
# OS-dependent specifics
if(APPLE)
+ add_definitions(-DBSPF_MAC_OSX)
include_directories(/System/Library/Frameworks/vecLib.framework/Versions/Current/Headers)
set(CMAKE_SHARED_LIBRARY_SUFFIX ".so")
endif()
-if(WINDOWS OR MINGW)
+if(WIN32 OR MINGW)
+ add_definitions(-DBSPF_WIN32)
list(APPEND SOURCES ${SOURCE_DIR}/os_dependent/SettingsWin32.cxx ${SOURCE_DIR}/os_dependent/OSystemWin32.cxx ${SOURCE_DIR}/os_dependent/FSNodeWin32.cxx)
else()
+ add_definitions(-DBSPF_UNIX)
list(APPEND SOURCES ${SOURCE_DIR}/os_dependent/SettingsUNIX.cxx ${SOURCE_DIR}/os_dependent/OSystemUNIX.cxx ${SOURCE_DIR}/os_dependent/FSNodePOSIX.cxx)
+ SET(BIN_INSTALL_DIR "bin")
+ SET(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" )
+ SET(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE STRING "Library directory name")
+ SET(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE STRING "Headers directory name")
+ SET(PKGCONFIG_INSTALL_DIR "${LIB_INSTALL_DIR}/pkgconfig/" CACHE STRING "Base directory for pkgconfig files")
+
endif()
+# List and set the install targets for the headers, generate and install the pkgconfig file
+if(UNIX)
+
+ INSTALL(FILES ${SOURCE_DIR}/os_dependent/SettingsUNIX.hxx ${SOURCE_DIR}/os_dependent/SettingsWin32.hxx ${SOURCE_DIR}/os_dependent/OSystemUNIX.hxx ${SOURCE_DIR}/os_dependent/OSystemWin32.hxx DESTINATION ${INCLUDE_INSTALL_DIR}/${PROJECT_NAME}/os_dependent)
+ file(GLOB module_headers ${SOURCE_DIR}/*.h?[xp])
+ foreach(header ${module_headers})
+ INSTALL(FILES ${header} DESTINATION ${INCLUDE_INSTALL_DIR}/${PROJECT_NAME})
+ endforeach(header ${HEADERS})
+
+ foreach(module ${MODULES})
+ file(GLOB module_headers ${SOURCE_DIR}/${module}/*.h)
+ foreach(header ${module_headers})
+ INSTALL(FILES ${header} DESTINATION ${INCLUDE_INSTALL_DIR}/${PROJECT_NAME}/${module}/)
+ endforeach(header ${HEADERS})
+
+ file(GLOB module_headers ${SOURCE_DIR}/${module}/*.h?[xp])
+ foreach(header ${module_headers})
+ INSTALL(FILES ${header} DESTINATION ${INCLUDE_INSTALL_DIR}/${PROJECT_NAME}/${module}/)
+ endforeach(header ${HEADERS})
+ endforeach(module ${MODULES})
+
+ ###################################
+ # Pkg-config stuff
+ ###################################
+
+ FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
+"
+Name: ${PROJECT_NAME}
+Description: The Arcade Learning Environment (ALE) - a platform for AI research.
+URL: http://www.arcadelearningenvironment.org/
+Version: ${ALEVERSION}
+Requires:
+Libs: -L${LIB_INSTALL_DIR} -lale
+Cflags: -I${INCLUDE_INSTALL_DIR}
+"
+)
+
+
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
+ DESTINATION ${PKGCONFIG_INSTALL_DIR})
+
+endif(UNIX)
+
include_directories(
${SOURCE_DIR}
+ ${SOURCE_DIR}/zlib
${SOURCE_DIR}/common
${SOURCE_DIR}/controllers
${SOURCE_DIR}/emucore
@@ -71,31 +132,77 @@ include_directories(
${SOURCE_DIR}/external/TinyMT
)
-add_library(ale-lib SHARED ${SOURCE_DIR}/ale_interface.cpp ${SOURCES})
-set_target_properties(ale-lib PROPERTIES OUTPUT_NAME ale)
-set_target_properties(ale-lib PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
-add_executable(ale-bin ${SOURCE_DIR}/main.cpp ${SOURCE_DIR}/ale_interface.cpp ${SOURCES})
-set_target_properties(ale-bin PROPERTIES OUTPUT_NAME ale)
-set_target_properties(ale-bin PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
-add_library(ale-c-lib SHARED ${CMAKE_CURRENT_SOURCE_DIR}/../ale_c_wrapper.cpp ${SOURCE_DIR}/ale_interface.cpp ${SOURCES})
-set_target_properties(ale-c-lib PROPERTIES OUTPUT_NAME ale_c)
-set_target_properties(ale-c-lib PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
+if(NOT BUILD_CPP_LIB AND BUILD_EXAMPLES)
+ set(BUILD_CPP_LIB ON)
+ MESSAGE("Enabling C++ library to support examples.")
+endif()
+
+if(BUILD_CPP_LIB)
+ add_library(ale-lib SHARED ${SOURCE_DIR}/ale_interface.cpp ${SOURCES})
+ set_target_properties(ale-lib PROPERTIES OUTPUT_NAME ale)
+ set_target_properties(ale-lib PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+ if(UNIX)
+ install(TARGETS ale-lib
+ DESTINATION ${LIB_INSTALL_DIR})
+ endif()
+ target_link_libraries(ale-lib ${LINK_LIBS})
+endif()
+
+if(BUILD_CLI)
+ add_executable(ale-bin ${SOURCE_DIR}/main.cpp ${SOURCE_DIR}/ale_interface.cpp ${SOURCES})
+ set_target_properties(ale-bin PROPERTIES OUTPUT_NAME ale)
+ set_target_properties(ale-bin PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+ if(UNIX)
+ install(TARGETS ale-bin
+ DESTINATION ${BIN_INSTALL_DIR})
+ endif()
+ target_link_libraries(ale-bin ${LINK_LIBS})
+endif()
-target_link_libraries(ale-lib ${LINK_LIBS})
-target_link_libraries(ale-bin ${LINK_LIBS})
-target_link_libraries(ale-c-lib ${LINK_LIBS})
+if(BUILD_C_LIB)
+ add_library(ale-c-lib SHARED ${CMAKE_CURRENT_SOURCE_DIR}/../ale_c_wrapper.cpp ${SOURCE_DIR}/ale_interface.cpp ${SOURCES})
+ set_target_properties(ale-c-lib PROPERTIES OUTPUT_NAME ale_c)
+ set_target_properties(ale-c-lib PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+ if(UNIX)
+ install(TARGETS ale-c-lib
+ DESTINATION ${LIB_INSTALL_DIR})
+ endif()
+ target_link_libraries(ale-c-lib ${LINK_LIBS})
+endif()
if(BUILD_EXAMPLES)
+ # Shared library example.
link_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_executable(sharedLibraryInterfaceExample ${CMAKE_CURRENT_SOURCE_DIR}/doc/examples/sharedLibraryInterfaceExample.cpp)
set_target_properties(sharedLibraryInterfaceExample PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc/examples)
+ set_target_properties(sharedLibraryInterfaceExample PROPERTIES OUTPUT_NAME ${PROJECT_NAME}-sharedLibraryInterfaceExample)
+
target_link_libraries(sharedLibraryInterfaceExample ale)
target_link_libraries(sharedLibraryInterfaceExample ${LINK_LIBS})
add_dependencies(sharedLibraryInterfaceExample ale-lib)
-
+
+ # Fifo interface example.
+ link_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+ add_executable(fifoInterfaceExample ${CMAKE_CURRENT_SOURCE_DIR}/doc/examples/fifoInterfaceExample.cpp)
+ set_target_properties(fifoInterfaceExample PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc/examples)
+ set_target_properties(fifoInterfaceExample PROPERTIES OUTPUT_NAME ${PROJECT_NAME}-fifoInterfaceExample)
+ target_link_libraries(fifoInterfaceExample ale)
+ target_link_libraries(fifoInterfaceExample ${LINK_LIBS})
+ add_dependencies(fifoInterfaceExample ale-lib)
+
+ add_executable(sharedLibraryInterfaceWithModesExample ${CMAKE_CURRENT_SOURCE_DIR}/doc/examples/sharedLibraryInterfaceWithModesExample.cpp)
+ set_target_properties(sharedLibraryInterfaceWithModesExample PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc/examples)
+ set_target_properties(sharedLibraryInterfaceWithModesExample PROPERTIES OUTPUT_NAME ${PROJECT_NAME}-sharedLibraryInterfaceWithModesExample)
+ target_link_libraries(sharedLibraryInterfaceWithModesExample ale)
+ target_link_libraries(sharedLibraryInterfaceWithModesExample ${LINK_LIBS})
+ add_dependencies(sharedLibraryInterfaceWithModesExample ale-lib)
+
+ # Example showing how to record an Atari 2600 video.
if (USE_SDL)
add_executable(videoRecordingExample ${CMAKE_CURRENT_SOURCE_DIR}/doc/examples/videoRecordingExample.cpp)
set_target_properties(videoRecordingExample PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc/examples)
+ set_target_properties(videoRecordingExample PROPERTIES OUTPUT_NAME ${PROJECT_NAME}-videoRecordingExample)
target_link_libraries(videoRecordingExample ale)
target_link_libraries(videoRecordingExample ${LINK_LIBS})
add_dependencies(videoRecordingExample ale-lib)
@@ -105,12 +212,49 @@ endif()
if(USE_RLGLUE)
add_executable(RLGlueAgent ${CMAKE_CURRENT_SOURCE_DIR}/doc/examples/RLGlueAgent.c)
set_target_properties(RLGlueAgent PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc/examples)
+ set_target_properties(RLGlueAgent PROPERTIES OUTPUT_NAME ${PROJECT_NAME}-RLGlueAgent)
target_link_libraries(RLGlueAgent rlutils)
target_link_libraries(RLGlueAgent rlagent)
target_link_libraries(RLGlueAgent rlgluenetdev)
+
add_executable(RLGlueExperiment ${CMAKE_CURRENT_SOURCE_DIR}/doc/examples/RLGlueExperiment.c)
set_target_properties(RLGlueExperiment PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc/examples)
+ set_target_properties(RLGlueExperiment PROPERTIES OUTPUT_NAME ${PROJECT_NAME}-RLGlueExperiment)
target_link_libraries(RLGlueExperiment rlutils)
target_link_libraries(RLGlueExperiment rlexperiment)
target_link_libraries(RLGlueExperiment rlgluenetdev)
+
endif()
+
+
+########### Add uninstall target ###############
+ FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
+"
+IF(NOT EXISTS \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\")
+ MESSAGE(FATAL_ERROR \"Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\")
+ENDIF(NOT EXISTS \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\")
+
+FILE(READ \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\" files)
+STRING(REGEX REPLACE \"\\n\" \";\" files \"\${files}\")
+FOREACH(file \${files})
+ MESSAGE(STATUS \"Uninstalling \"\$ENV{DESTDIR}\${file}\"\")
+ IF(EXISTS \"\$ENV{DESTDIR}\${file}\")
+ EXEC_PROGRAM(
+ \"@CMAKE_COMMAND@\" ARGS \"-E remove \"\$ENV{DESTDIR}\${file}\"\"
+ OUTPUT_VARIABLE rm_out
+ RETURN_VALUE rm_retval
+ )
+ IF(NOT \"\${rm_retval}\" STREQUAL 0)
+ MESSAGE(FATAL_ERROR \"Problem when removing \"\$ENV{DESTDIR}\${file}\"\")
+ ENDIF(NOT \"\${rm_retval}\" STREQUAL 0)
+ ELSE(EXISTS \"\$ENV{DESTDIR}\${file}\")
+ MESSAGE(STATUS \"File \"\$ENV{DESTDIR}\${file}\" does not exist.\")
+ ENDIF(EXISTS \"\$ENV{DESTDIR}\${file}\")
+ENDFOREACH(file)
+")
+
+ADD_CUSTOM_TARGET(uninstall
+ "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+ COMMAND rm -rf ${INCLUDE_INSTALL_DIR}/ale)
+
+
diff --git a/atari_py/ale_interface/Makefile b/atari_py/ale_interface/Makefile
deleted file mode 100644
index e77c530..0000000
--- a/atari_py/ale_interface/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-.PHONY: build clean
-
-build:
- mkdir -p build && cd build && cmake .. && make -j4
-
-clean:
- rm -rf build
diff --git a/atari_py/ale_interface/common.rules b/atari_py/ale_interface/common.rules
deleted file mode 100644
index 285cd64..0000000
--- a/atari_py/ale_interface/common.rules
+++ /dev/null
@@ -1,31 +0,0 @@
-# Common build rules, used by the sub modules and their module.mk files
-
-# Copy the list of objects to a new variable. The name of the new variable
-# contains the module name, a trick we use so we can keep multiple different
-# module object lists, one for each module.
-MODULE_OBJS-$(MODULE) := $(MODULE_OBJS)
-
-MODULE_LIB-$(MODULE) := $(MODULE)/lib$(notdir $(MODULE)).a
-
-# If not building as a plugin, add the object files to the main OBJS list
-#OBJS += $(MODULE_LIB-$(MODULE))
-OBJS += $(MODULE_OBJS)
-
-# Convenience library target
-#$(MODULE_LIB-$(MODULE)): $(MODULE_OBJS)
-# -$(RM) $@
-# $(AR) $@ $+
-# $(RANLIB) $@
-
-# Pseudo target for comfort, allows for "make common", "make gui" etc.
-#$(MODULE): $(MODULE_LIB-$(MODULE))
-
-
-# Clean target, removes all object files. This looks a bit hackish, as we have to
-# copy the content of MODULE_OBJS to another unique variable (the next module.mk
-# will overwrite it after all). The same for the libMODULE.a library file.
-clean: clean-$(MODULE)
-clean-$(MODULE): clean-% :
- -$(RM) $(MODULE_OBJS-$*) $(MODULE_LIB-$*) $(PLUGIN-$*)
-
-.PHONY: clean-$(MODULE) $(MODULE)
diff --git a/atari_py/ale_interface/makefile.mac b/atari_py/ale_interface/makefile.mac
deleted file mode 100644
index 3f2f179..0000000
--- a/atari_py/ale_interface/makefile.mac
+++ /dev/null
@@ -1,248 +0,0 @@
-##============================================================================
-# makefile for the A.L.E: Atari Learing Environment (Powered by Stella)
-##============================================================================
-
-srcdir ?= .
-# Set this to 1 to enable SDL and display_screen
-USE_SDL := 0
-# Set this to 1 to enable the RLGlue interface
-USE_RLGLUE := 0
-DEFINES := -DRLGENV_NOMAINLOOP
-LDFLAGS :=
-# /opt/local/include for MacPorts; /usr/local/include for RL-Glue
-INCLUDES := -Isrc/controllers -Isrc/os_dependent -I/usr/include -I/opt/local/include -I/usr/local/include -Isrc/environment -Isrc/external
-LIBS_SDL := -lSDL -lSDLmain
-LIBS_RLGLUE := -lrlutils -lrlgluenetdev
-LIBS := -L/opt/local/lib
-OBJS :=
-PROF :=
-MODULES :=
-MODULE_DIRS :=
-DISTNAME := atari_learning_environment
-DEBUG := 0
-
-# -------- Generated by configure -----------
-CXX := g++
-CXXFLAGS :=
-LD := g++
-# LIBS += -lz -lX11
-# For the Mac
-LIBS += -lz -framework Cocoa
-RANLIB := ranlib
-INSTALL := install
-AR := ar cru
-MKDIR := mkdir -p
-ECHO := printf
-CAT := cat
-RM := rm -f
-RM_REC := rm -f -r
-ZIP := zip -q
-CP := cp
-
-
-# MODULES += src/unix
-MODULE_DIRS +=
-EXEEXT :=
-NASM := /usr/bin/nasm
-NASMFLAGS := -f elf
-
-PREFIX := /usr/local
-BINDIR := /usr/local/bin
-DOCDIR := /usr/local/share/doc/stella
-DATADIR := /usr/local/share
-PROFILE :=
-
-HAVE_GCC3 = 1
-HAVE_NASM = 1
-
-INCLUDES += -Isrc/games -Isrc/emucore -Isrc/emucore/m6502/src -Isrc/emucore/m6502/src/bspf/src -Isrc/common -Isrc/controllers -Isrc/environment
-OBJS +=
-DEFINES += -DUNIX -DHAS_ALTIVEC -DUSE_NASM -DBSPF_UNIX -DHAVE_INTTYPES -DWINDOWED_SUPPORT -DHAVE_GETTIMEOFDAY -DSNAPSHOT_SUPPORT
-LDFLAGS +=
-
-ifeq ("$(USE_SDL)", "1")
- CXXFLAGS+=$(shell sdl-config --cflags)
- LDFLAGS+=$(shell sdl-config --libs)
- DEFINES += -D__USE_SDL -DSOUND_SUPPORT
-endif
-
-ifeq ("$(USE_RLGLUE)", "1")
- DEFINES += -D__USE_RLGLUE
- LIBS += $(LIBS_RLGLUE)
-endif
-
-# Uncomment this for stricter compile time code verification
-# CXXFLAGS+= -Werror
-
-CXXFLAGS += -Wall -Wunused -fPIC
-
-ifeq ("$(DEBUG)", "1")
- CXXFLAGS += -g -O0
-else
- CXXFLAGS += -O3
-endif
-
-ifdef PROFILE
- PROF:= -g -pg -fprofile-arcs -ftest-coverage
- CXXFLAGS+= $(PROF)
-else
- CXXFLAGS+= -fomit-frame-pointer
-endif
-
-# Even more warnings...
-#CXXFLAGS+= -pedantic -Wpointer-arith -Wcast-qual -Wconversion
-#CXXFLAGS+= -Wshadow -Wimplicit -Wundef -Wnon-virtual-dtor
-#CXXFLAGS+= -Wno-reorder -Wwrite-strings -fcheck-new -Wctor-dtor-privacy
-
-#######################################################################
-# Misc stuff - you should never have to edit this #
-#######################################################################
-
-EXECUTABLE := ale$(EXEEXT)
-LIBRARY := libale.so
-
-all: tags $(EXECUTABLE) $(LIBRARY)
-
-
-######################################################################
-# Various minor settings
-######################################################################
-
-# The name for the directory used for dependency tracking
-DEPDIR := .deps
-
-
-######################################################################
-# Module settings
-######################################################################
-
-MODULES := $(MODULES)
-
-# After the game specific modules follow the shared modules
-MODULES += \
- src \
- src/emucore \
- src/emucore/m6502 \
- src/common \
- src/controllers \
- src/os_dependent \
- src/games \
- src/environment \
- src/external
-
-
-######################################################################
-# The build rules follow - normally you should have no need to
-# touch whatever comes after here.
-######################################################################
-
-# Concat DEFINES and INCLUDES to form the CPPFLAGS
-CPPFLAGS:= $(DEFINES) $(INCLUDES)
-
-# Include the build instructions for all modules
--include $(addprefix $(srcdir)/, $(addsuffix /module.mk,$(MODULES)))
-
-# Depdir information
-DEPDIRS = $(addsuffix /$(DEPDIR),$(MODULE_DIRS))
-DEPFILES =
-
-# The build rule for the Stella executable
-$(EXECUTABLE): $(OBJS)
- $(LD) $(LDFLAGS) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) $(PROF) -o $@
-
-$(LIBRARY): $(OBJS)
- $(LD) $(LDFLAGS) -shared -o $(LIBRARY) $(OBJS) $(LIBS)
-
-distclean: clean
- $(RM_REC) $(DEPDIRS)
- $(RM) build.rules config.h config.mak config.log
-
-clean:
- $(RM) $(OBJS) $(EXECUTABLE) $(LIBRARY)
-
-
-
-
-.PHONY: all clean dist distclean
-
-.SUFFIXES: .cxx
-ifndef HAVE_GCC3
-# If you use GCC, disable the above and enable this for intelligent
-# dependency tracking.
-.cxx.o:
- $(MKDIR) $(*D)/$(DEPDIR)
- $(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d2" $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
- $(ECHO) "$(*D)/" > $(*D)/$(DEPDIR)/$(*F).d
- $(CAT) "$(*D)/$(DEPDIR)/$(*F).d2" >> "$(*D)/$(DEPDIR)/$(*F).d"
- $(RM) "$(*D)/$(DEPDIR)/$(*F).d2"
-
-.c.o:
- $(MKDIR) $(*D)/$(DEPDIR)
- $(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d2" $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
- $(ECHO) "$(*D)/" > $(*D)/$(DEPDIR)/$(*F).d
- $(CAT) "$(*D)/$(DEPDIR)/$(*F).d2" >> "$(*D)/$(DEPDIR)/$(*F).d"
- $(RM) "$(*D)/$(DEPDIR)/$(*F).d2"
-else
-# If you even have GCC 3.x, you can use this build rule, which is safer; the above
-# rule can get you into a bad state if you Ctrl-C at the wrong moment.
-# Also, with this GCC inserts additional dummy rules for the involved headers,
-# which ensures a smooth compilation even if said headers become obsolete.
-.cxx.o:
- $(MKDIR) $(*D)/$(DEPDIR)
- $(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
-
-.c.o:
- $(MKDIR) $(*D)/$(DEPDIR)
- $(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
-endif
-
-ifdef HAVE_NASM
-.SUFFIXES: .asm
-.asm.o:
- $(NASM) -O1 $(NASMFLAGS) -g -o $*.o $(<)
-endif
-
-# Include the dependency tracking files. We add /dev/null at the end
-# of the list to avoid a warning/error if no .d file exist
--include $(wildcard $(addsuffix /*.d,$(DEPDIRS))) /dev/null
-
-# check if configure has been run or has been changed since last run
-config.mak: $(srcdir)/configure
- @echo "You need to run ./configure before you can run make"
- @echo "Either you haven't run it before or it has changed."
- @exit 1
-
-install: all
- $(INSTALL) -d "$(DESTDIR)$(BINDIR)"
- $(INSTALL) -c -s -m 755 "$(srcdir)/stella$(EXEEXT)" "$(DESTDIR)$(BINDIR)/stella$(EXEEXT)"
- $(INSTALL) -d "$(DESTDIR)$(DOCDIR)"
- $(INSTALL) -c -m 644 "$(srcdir)/Announce.txt" "$(srcdir)/Changes.txt" "$(srcdir)/Copyright.txt" "$(srcdir)/License.txt" "$(srcdir)/README-SDL.txt" "$(srcdir)/Readme.txt" "$(srcdir)/Todo.txt" "$(srcdir)/docs/index.html" "$(srcdir)/docs/debugger.html" "$(DESTDIR)$(DOCDIR)/"
- $(INSTALL) -d "$(DESTDIR)$(DOCDIR)/graphics"
- $(INSTALL) -c -m 644 $(wildcard $(srcdir)/docs/graphics/*.png) "$(DESTDIR)$(DOCDIR)/graphics"
- $(INSTALL) -d "$(DESTDIR)$(DATADIR)/applications"
- $(INSTALL) -c -m 644 "$(srcdir)/src/unix/stella.desktop" "$(DESTDIR)$(DATADIR)/applications"
- $(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons"
- $(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/mini"
- $(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/large"
- $(INSTALL) -c -m 644 "$(srcdir)/src/common/stella.png" "$(DESTDIR)$(DATADIR)/icons"
- $(INSTALL) -c -m 644 "$(srcdir)/src/common/stella.png" "$(DESTDIR)$(DATADIR)/icons/mini"
- $(INSTALL) -c -m 644 "$(srcdir)/src/common/stella.png" "$(DESTDIR)$(DATADIR)/icons/large"
-
-install-strip: install
- strip stella$(EXEEXT)
-
-uninstall:
- rm -f "$(DESTDIR)$(BINDIR)/stella$(EXEEXT)"
- rm -rf "$(DESTDIR)$(DOCDIR)/"
- rm -f "$(DESTDIR)$(DATADIR)/applications/stella.desktop"
- rm -f "$(DESTDIR)$(DATADIR)/icons/stella.png"
- rm -f "$(DESTDIR)$(DATADIR)/icons/mini/stella.png"
- rm -f "$(DESTDIR)$(DATADIR)/icons/large/stella.png"
-
-
-# Use Exuberant ctags (the one from Slackware's vim package, for instance),
-# not the one from emacs!
-tags:
- ctags `find . -name '*.[ch]xx' -o -name '*.c' -o -name '*.y'` || true
-
-
diff --git a/atari_py/ale_interface/makefile.unix b/atari_py/ale_interface/makefile.unix
deleted file mode 100644
index 1367ba7..0000000
--- a/atari_py/ale_interface/makefile.unix
+++ /dev/null
@@ -1,246 +0,0 @@
-##============================================================================
-# makefile for the A.L.E: Atari Learing Environment (Powered by Stella)
-##============================================================================
-
-srcdir ?= .
-# Set this to 1 to enable SDL, display_screen, and sound support
-USE_SDL := 0
-# Set this to 1 to enable the RLGlue interface
-USE_RLGLUE := 0
-DEFINES := -DRLGENV_NOMAINLOOP
-LDFLAGS :=
-# /usr/local/include for RL-Glue
-INCLUDES := -Isrc/controllers -Isrc/os_dependent -I/usr/include -I/usr/local/include -Isrc/environment -Isrc/external
-LIBS_RLGLUE := -lrlutils -lrlgluenetdev
-LIBS :=
-OBJS :=
-PROF :=
-MODULES :=
-MODULE_DIRS :=
-DISTNAME := atari_learning_environment
-DEBUG := 0
-
-# -------- Generated by configure -----------
-CXX := g++
-CXXFLAGS :=
-LD := g++
-LIBS += -lz
-RANLIB := ranlib
-INSTALL := install
-AR := ar cru
-MKDIR := mkdir -p
-ECHO := printf
-CAT := cat
-RM := rm -f
-RM_REC := rm -f -r
-ZIP := zip -q
-CP := cp
-
-
-# MODULES += src/unix
-MODULE_DIRS +=
-EXEEXT :=
-NASM := /usr/bin/nasm
-NASMFLAGS := -f elf
-
-PREFIX := /usr/local
-BINDIR := /usr/local/bin
-DOCDIR := /usr/local/share/doc/stella
-DATADIR := /usr/local/share
-PROFILE :=
-
-HAVE_GCC3 = 1
-HAVE_NASM = 1
-
-INCLUDES += -Isrc/games -Isrc/emucore -Isrc/emucore/m6502/src -Isrc/emucore/m6502/src/bspf/src -Isrc/common -Isrc/controllers -Isrc/environment
-OBJS +=
-DEFINES += -DUNIX -DHAS_ALTIVEC -DUSE_NASM -DBSPF_UNIX -DHAVE_INTTYPES -DWINDOWED_SUPPORT -DHAVE_GETTIMEOFDAY -DSNAPSHOT_SUPPORT
-LDFLAGS +=
-
-ifeq ($(strip $(USE_SDL)), 1)
- CXXFLAGS+=$(shell sdl-config --cflags)
- LIBS+=$(shell sdl-config --libs)
- DEFINES += -D__USE_SDL -DSOUND_SUPPORT
-endif
-
-ifeq ($(strip $(USE_RLGLUE)), 1)
- DEFINES += -D__USE_RLGLUE
- LIBS += $(LIBS_RLGLUE)
-endif
-
-
-# Uncomment this for stricter compile time code verification
-# CXXFLAGS+= -Werror
-
-CXXFLAGS += -Wall -Wunused -fPIC
-
-ifeq ($(strip $(DEBUG)), 1)
- CXXFLAGS += -g -O0
-else
- CXXFLAGS += -O3
-endif
-
-ifdef PROFILE
- PROF:= -g -pg -fprofile-arcs -ftest-coverage
- CXXFLAGS+= $(PROF)
-else
- CXXFLAGS+= -fomit-frame-pointer
-endif
-
-# Even more warnings...
-#CXXFLAGS+= -pedantic -Wpointer-arith -Wcast-qual -Wconversion
-#CXXFLAGS+= -Wshadow -Wimplicit -Wundef -Wnon-virtual-dtor
-#CXXFLAGS+= -Wno-reorder -Wwrite-strings -fcheck-new -Wctor-dtor-privacy
-
-#######################################################################
-# Misc stuff - you should never have to edit this #
-#######################################################################
-
-EXECUTABLE := ale$(EXEEXT)
-LIBRARY := libale.so
-
-all: tags $(EXECUTABLE) $(LIBRARY)
-
-
-######################################################################
-# Various minor settings
-######################################################################
-
-# The name for the directory used for dependency tracking
-DEPDIR := .deps
-
-
-######################################################################
-# Module settings
-######################################################################
-
-MODULES := $(MODULES)
-
-# After the game specific modules follow the shared modules
-MODULES += \
- src \
- src/emucore \
- src/emucore/m6502 \
- src/common \
- src/controllers \
- src/os_dependent \
- src/games \
- src/environment \
- src/external
-
-
-######################################################################
-# The build rules follow - normally you should have no need to
-# touch whatever comes after here.
-######################################################################
-
-# Concat DEFINES and INCLUDES to form the CPPFLAGS
-CPPFLAGS:= $(DEFINES) $(INCLUDES)
-
-# Include the build instructions for all modules
--include $(addprefix $(srcdir)/, $(addsuffix /module.mk,$(MODULES)))
-
-# Depdir information
-DEPDIRS = $(addsuffix /$(DEPDIR),$(MODULE_DIRS))
-DEPFILES =
-
-# The build rule for the Stella executable
-$(EXECUTABLE): $(OBJS)
- $(LD) $(LDFLAGS) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) $(PROF) -o $@
-
-$(LIBRARY): $(OBJS)
- $(LD) $(LDFLAGS) -shared -o $(LIBRARY) $(OBJS) $(LIBS)
-
-distclean: clean
- $(RM_REC) $(DEPDIRS)
- $(RM) build.rules config.h config.mak config.log
-
-clean:
- $(RM) $(OBJS) $(EXECUTABLE) $(LIBRARY)
-
-
-
-
-.PHONY: all clean dist distclean
-
-.SUFFIXES: .cxx
-ifndef HAVE_GCC3
-# If you use GCC, disable the above and enable this for intelligent
-# dependency tracking.
-.cxx.o:
- $(MKDIR) $(*D)/$(DEPDIR)
- $(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d2" $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
- $(ECHO) "$(*D)/" > $(*D)/$(DEPDIR)/$(*F).d
- $(CAT) "$(*D)/$(DEPDIR)/$(*F).d2" >> "$(*D)/$(DEPDIR)/$(*F).d"
- $(RM) "$(*D)/$(DEPDIR)/$(*F).d2"
-
-.c.o:
- $(MKDIR) $(*D)/$(DEPDIR)
- $(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d2" $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
- $(ECHO) "$(*D)/" > $(*D)/$(DEPDIR)/$(*F).d
- $(CAT) "$(*D)/$(DEPDIR)/$(*F).d2" >> "$(*D)/$(DEPDIR)/$(*F).d"
- $(RM) "$(*D)/$(DEPDIR)/$(*F).d2"
-else
-# If you even have GCC 3.x, you can use this build rule, which is safer; the above
-# rule can get you into a bad state if you Ctrl-C at the wrong moment.
-# Also, with this GCC inserts additional dummy rules for the involved headers,
-# which ensures a smooth compilation even if said headers become obsolete.
-.cxx.o:
- $(MKDIR) $(*D)/$(DEPDIR)
- $(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
-
-.c.o:
- $(MKDIR) $(*D)/$(DEPDIR)
- $(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
-endif
-
-ifdef HAVE_NASM
-.SUFFIXES: .asm
-.asm.o:
- $(NASM) -O1 $(NASMFLAGS) -g -o $*.o $(<)
-endif
-
-# Include the dependency tracking files. We add /dev/null at the end
-# of the list to avoid a warning/error if no .d file exist
--include $(wildcard $(addsuffix /*.d,$(DEPDIRS))) /dev/null
-
-# check if configure has been run or has been changed since last run
-config.mak: $(srcdir)/configure
- @echo "You need to run ./configure before you can run make"
- @echo "Either you haven't run it before or it has changed."
- @exit 1
-
-install: all
- $(INSTALL) -d "$(DESTDIR)$(BINDIR)"
- $(INSTALL) -c -s -m 755 "$(srcdir)/stella$(EXEEXT)" "$(DESTDIR)$(BINDIR)/stella$(EXEEXT)"
- $(INSTALL) -d "$(DESTDIR)$(DOCDIR)"
- $(INSTALL) -c -m 644 "$(srcdir)/Announce.txt" "$(srcdir)/Changes.txt" "$(srcdir)/Copyright.txt" "$(srcdir)/License.txt" "$(srcdir)/README-SDL.txt" "$(srcdir)/Readme.txt" "$(srcdir)/Todo.txt" "$(srcdir)/docs/index.html" "$(srcdir)/docs/debugger.html" "$(DESTDIR)$(DOCDIR)/"
- $(INSTALL) -d "$(DESTDIR)$(DOCDIR)/graphics"
- $(INSTALL) -c -m 644 $(wildcard $(srcdir)/docs/graphics/*.png) "$(DESTDIR)$(DOCDIR)/graphics"
- $(INSTALL) -d "$(DESTDIR)$(DATADIR)/applications"
- $(INSTALL) -c -m 644 "$(srcdir)/src/unix/stella.desktop" "$(DESTDIR)$(DATADIR)/applications"
- $(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons"
- $(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/mini"
- $(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/large"
- $(INSTALL) -c -m 644 "$(srcdir)/src/common/stella.png" "$(DESTDIR)$(DATADIR)/icons"
- $(INSTALL) -c -m 644 "$(srcdir)/src/common/stella.png" "$(DESTDIR)$(DATADIR)/icons/mini"
- $(INSTALL) -c -m 644 "$(srcdir)/src/common/stella.png" "$(DESTDIR)$(DATADIR)/icons/large"
-
-install-strip: install
- strip stella$(EXEEXT)
-
-uninstall:
- rm -f "$(DESTDIR)$(BINDIR)/stella$(EXEEXT)"
- rm -rf "$(DESTDIR)$(DOCDIR)/"
- rm -f "$(DESTDIR)$(DATADIR)/applications/stella.desktop"
- rm -f "$(DESTDIR)$(DATADIR)/icons/stella.png"
- rm -f "$(DESTDIR)$(DATADIR)/icons/mini/stella.png"
- rm -f "$(DESTDIR)$(DATADIR)/icons/large/stella.png"
-
-
-# Use Exuberant ctags (the one from Slackware's vim package, for instance),
-# not the one from emacs!
-tags:
- ctags `find . -name '*.[ch]xx' -o -name '*.c' -o -name '*.y'` || true
-
-
diff --git a/atari_py/ale_interface/setup.sh b/atari_py/ale_interface/setup.sh
deleted file mode 100755
index 2d66814..0000000
--- a/atari_py/ale_interface/setup.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-set -e
-mkdir -p build && cd build && cmake .. && make -j4
diff --git a/atari_py/ale_interface/src/ale_interface.cpp b/atari_py/ale_interface/src/ale_interface.cpp
index f8c81b1..15310af 100644
--- a/atari_py/ale_interface/src/ale_interface.cpp
+++ b/atari_py/ale_interface/src/ale_interface.cpp
@@ -27,34 +27,50 @@
*
* The shared library interface.
**************************************************************************** */
+
#include "ale_interface.hpp"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#include
-#include
+#include
+
+#include "common/ColourPalette.hpp"
+#include "common/Constants.h"
+#include "emucore/Console.hxx"
+#include "emucore/Props.hxx"
+#include "environment/ale_screen.hpp"
+#include "games/RomSettings.hpp"
-using namespace std;
using namespace ale;
+
// Display ALE welcome message
std::string ALEInterface::welcomeMessage() {
std::ostringstream oss;
- oss << "A.L.E: Arcade Learning Environment (version "
- << Version << ")\n"
- << "[Powered by Stella]\n"
- << "Use -help for help screen.";
+ oss << "A.L.E: Arcade Learning Environment (version " << Version << ")\n"
+ << "[Powered by Stella]\n" << "Use -help for help screen.";
return oss.str();
}
void ALEInterface::disableBufferedIO() {
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stdin, NULL, _IONBF, 0);
- cin.rdbuf()->pubsetbuf(0,0);
- cout.rdbuf()->pubsetbuf(0,0);
- cin.sync_with_stdio();
- cout.sync_with_stdio();
+ std::cin.rdbuf()->pubsetbuf(0, 0);
+ std::cout.rdbuf()->pubsetbuf(0, 0);
+ std::cin.sync_with_stdio();
+ std::cout.sync_with_stdio();
}
-void ALEInterface::createOSystem(std::auto_ptr &theOSystem,
- std::auto_ptr &theSettings) {
-#if (defined(WIN32) || defined(__MINGW32__))
+void ALEInterface::createOSystem(scoped_ptr& theOSystem,
+ scoped_ptr& theSettings) {
+#if (defined(_WIN32) || defined(__MINGW32__))
theOSystem.reset(new OSystemWin32());
theSettings.reset(new SettingsWin32(theOSystem.get()));
#else
@@ -62,48 +78,67 @@ void ALEInterface::createOSystem(std::auto_ptr &theOSystem,
theSettings.reset(new SettingsUNIX(theOSystem.get()));
#endif
- setDefaultSettings(theOSystem->settings());
-
theOSystem->settings().loadConfig();
}
-void ALEInterface::loadSettings(const string& romfile,
- std::auto_ptr &theOSystem) {
+void ALEInterface::checkForUnsupportedRom(OSystem& theOSystem) {
+ const Properties properties = theOSystem.console().properties();
+ const std::string md5 = properties.get(Cartridge_MD5);
+ bool found = false;
+ std::ifstream ss("md5.txt");
+ std::string item;
+ while (!found && std::getline(ss, item)) {
+ if (!item.compare(0, md5.size(), md5)) {
+ const std::string rom_candidate = item.substr(md5.size() + 1);
+ found = true;
+ }
+ }
+ if (!found) {
+ // If the md5 doesn't match our master list, warn the user.
+ Logger::Warning << std::endl;
+ Logger::Warning << "WARNING: Possibly unsupported ROM: mismatched MD5." << std::endl;
+ Logger::Warning << "Cartridge_MD5: " << md5 << std::endl;
+ const std::string name = properties.get(Cartridge_Name);
+ Logger::Warning << "Cartridge_name: " << name << std::endl;
+ Logger::Warning << std::endl;
+ }
+}
+
+void ALEInterface::loadSettings(const std::string& rom, const std::string& name,
+ OSystem& theOSystem) {
// Load the configuration from a config file (passed on the command
// line), if provided
- string configFile = theOSystem->settings().getString("config", false);
+ std::string configFile = theOSystem.settings().getString("config", false);
- if (!configFile.empty())
- theOSystem->settings().loadConfig(configFile.c_str());
+ if (!configFile.empty()) {
+ theOSystem.settings().loadConfig(configFile.c_str());
+ }
- theOSystem->settings().validate();
- theOSystem->create();
+ theOSystem.settings().validate();
+ theOSystem.create();
// Attempt to load the ROM
- if (romfile == "" || !FilesystemNode::fileExists(romfile)) {
- Logger::Error << "No ROM File specified or the ROM file was not found."
+ if (rom.empty()) {
+ Logger::Error << "Empty ROM File specified"
<< std::endl;
exit(1);
- } else if (theOSystem->createConsole(romfile)) {
- Logger::Info << "Running ROM file..." << std::endl;
- theOSystem->settings().setString("rom_file", romfile);
+ } else if (theOSystem.createConsole(rom, name)) {
+ checkForUnsupportedRom(theOSystem);
+ Logger::Info << "Running ROM " << name << "..." << std::endl;
+ theOSystem.settings().setString("rom_name", name);
} else {
+ Logger::Error << "Unable to create console for " << name << std::endl;
exit(1);
}
- // Seed random number generator
- if (theOSystem->settings().getString("random_seed") == "time") {
- Logger::Info << "Random Seed: Time" << endl;
- Random::seed((uInt32)time(NULL));
- } else {
- int seed = theOSystem->settings().getInt("random_seed");
- assert(seed >= 0);
- Logger::Info << "Random Seed: " << seed << endl;
- Random::seed((uInt32)seed);
- }
+// Must force the resetting of the OSystem's random seed, which is set before we change
+// choose our random seed.
+ Logger::Info << "Random seed is "
+ << theOSystem.settings().getInt("random_seed") << std::endl;
+ theOSystem.resetRNGSeed();
- string currentDisplayFormat = theOSystem->console().getFormat();
- theOSystem->colourPalette().setPalette("standard", currentDisplayFormat);
+ std::string currentDisplayFormat = theOSystem.console().getFormat();
+ theOSystem.colourPalette().setPalette("standard", currentDisplayFormat);
}
ALEInterface::ALEInterface() {
@@ -119,30 +154,34 @@ ALEInterface::ALEInterface(bool display_screen) {
this->setBool("display_screen", display_screen);
}
-ALEInterface::~ALEInterface() {}
+ALEInterface::~ALEInterface() {
+}
// Loads and initializes a game. After this call the game should be
// ready to play. Resets the OSystem/Console/Environment/etc. This is
// necessary after changing a setting. Optionally specify a new rom to
// load.
-void ALEInterface::loadROM(string rom_file = "") {
+bool ALEInterface::loadROM(std::string rom_file, std::string name) {
assert(theOSystem.get());
- if (rom_file.empty()) {
- rom_file = theOSystem->romFile();
- }
- loadSettings(rom_file, theOSystem);
- romSettings.reset(buildRomRLWrapper(rom_file));
+ loadSettings(rom_file, name, *theOSystem);
+ romSettings.reset(buildRomRLWrapper(name));
+ if (romSettings.get() == NULL) return false;
environment.reset(new StellaEnvironment(theOSystem.get(), romSettings.get()));
max_num_frames = theOSystem->settings().getInt("max_num_frames_per_episode");
environment->reset();
#ifndef __USE_SDL
if (theOSystem->p_display_screen != NULL) {
- Logger::Error << "Screen display requires directive __USE_SDL to be defined." << endl;
- Logger::Error << "Please recompile this code with flag '-D__USE_SDL'." << endl;
- Logger::Error << "Also ensure ALE has been compiled with USE_SDL active (see ALE makefile)." << endl;
+ Logger::Error
+ << "Screen display requires directive __USE_SDL to be defined." << std::endl;
+ Logger::Error << "Please recompile this code with flag '-D__USE_SDL'."
+ << std::endl;
+ Logger::Error
+ << "Also ensure ALE has been compiled with USE_SDL active (see ALE makefile)."
+ << std::endl;
exit(1);
}
#endif
+ return true;
}
// Get the value of a setting.
@@ -164,46 +203,44 @@ float ALEInterface::getFloat(const std::string& key) {
}
// Set the value of a setting.
-void ALEInterface::setString(const string& key, const string& value) {
+void ALEInterface::setString(const std::string& key, const std::string& value) {
assert(theSettings.get());
assert(theOSystem.get());
theSettings->setString(key, value);
theSettings->validate();
}
-void ALEInterface::setInt(const string& key, const int value) {
+void ALEInterface::setInt(const std::string& key, const int value) {
assert(theSettings.get());
assert(theOSystem.get());
theSettings->setInt(key, value);
theSettings->validate();
}
-void ALEInterface::setBool(const string& key, const bool value) {
+void ALEInterface::setBool(const std::string& key, const bool value) {
assert(theSettings.get());
assert(theOSystem.get());
theSettings->setBool(key, value);
theSettings->validate();
}
-void ALEInterface::setFloat(const string& key, const float value) {
+void ALEInterface::setFloat(const std::string& key, const float value) {
assert(theSettings.get());
assert(theOSystem.get());
theSettings->setFloat(key, value);
theSettings->validate();
}
-
// Resets the game, but not the full system.
void ALEInterface::reset_game() {
environment->reset();
}
// Indicates if the game has ended.
-bool ALEInterface::game_over() {
- return (environment->isTerminal() ||
- (max_num_frames > 0 && getEpisodeFrameNumber() >= max_num_frames));
+bool ALEInterface::game_over() const {
+ return environment->isTerminal();
}
// The remaining number of lives.
-const int ALEInterface::lives() {
- if (!romSettings.get()){
+int ALEInterface::lives() {
+ if (!romSettings.get()) {
throw std::runtime_error("ROM not set");
}
return romSettings->lives();
@@ -226,10 +263,47 @@ reward_t ALEInterface::act(Action action) {
return reward;
}
+// Returns the vector of modes available for the current game.
+// This should be called only after the rom is loaded.
+ModeVect ALEInterface::getAvailableModes() {
+ return romSettings->getAvailableModes();
+}
+
+// Sets the mode of the game.
+// The mode must be an available mode.
+// This should be called only after the rom is loaded.
+void ALEInterface::setMode(game_mode_t m) {
+ //We first need to make sure m is an available mode
+ ModeVect available = romSettings->getAvailableModes();
+ if(find(available.begin(), available.end(), m) != available.end()) {
+ environment->setMode(m);
+ } else {
+ throw std::runtime_error("Invalid game mode requested");
+ }
+}
+
+//Returns the vector of difficulties available for the current game.
+//This should be called only after the rom is loaded.
+DifficultyVect ALEInterface::getAvailableDifficulties() {
+ return romSettings->getAvailableDifficulties();
+}
+
+// Sets the difficulty of the game.
+// The difficulty must be an available mode.
+// This should be called only after the rom is loaded.
+void ALEInterface::setDifficulty(difficulty_t m) {
+ DifficultyVect available = romSettings->getAvailableDifficulties();
+ if(find(available.begin(), available.end(), m) != available.end()) {
+ environment->setDifficulty(m);
+ } else {
+ throw std::runtime_error("Invalid difficulty requested");
+ }
+}
+
// Returns the vector of legal actions. This should be called only
// after the rom is loaded.
ActionVect ALEInterface::getLegalActionSet() {
- if (!romSettings.get()){
+ if (!romSettings.get()) {
throw std::runtime_error("ROM not set");
}
return romSettings->getAllActions();
@@ -238,7 +312,7 @@ ActionVect ALEInterface::getLegalActionSet() {
// Returns the vector of the minimal set of actions needed to play
// the game.
ActionVect ALEInterface::getMinimalActionSet() {
- if (!romSettings.get()){
+ if (!romSettings.get()) {
throw std::runtime_error("ROM not set");
}
return romSettings->getMinimalActionSet();
@@ -250,7 +324,7 @@ int ALEInterface::getFrameNumber() {
}
// Returns the frame number since the start of the current episode
-int ALEInterface::getEpisodeFrameNumber() {
+int ALEInterface::getEpisodeFrameNumber() const {
return environment->getEpisodeFrameNumber();
}
@@ -259,6 +333,32 @@ const ALEScreen& ALEInterface::getScreen() {
return environment->getScreen();
}
+//This method should receive an empty vector to fill it with
+//the grayscale colours
+void ALEInterface::getScreenGrayscale(
+ std::vector& grayscale_output_buffer) {
+ size_t w = environment->getScreen().width();
+ size_t h = environment->getScreen().height();
+ size_t screen_size = w * h;
+
+ pixel_t *ale_screen_data = environment->getScreen().getArray();
+ theOSystem->colourPalette().applyPaletteGrayscale(grayscale_output_buffer,
+ ale_screen_data, screen_size);
+}
+
+//This method should receive a vector to fill it with
+//the RGB colours. The first positions contain the red colours,
+//followed by the green colours and then the blue colours
+void ALEInterface::getScreenRGB(std::vector& output_rgb_buffer) {
+ size_t w = environment->getScreen().width();
+ size_t h = environment->getScreen().height();
+ size_t screen_size = w * h;
+
+ pixel_t *ale_screen_data = environment->getScreen().getArray();
+
+ theOSystem->colourPalette().applyPaletteRGB(output_rgb_buffer, ale_screen_data, screen_size);
+}
+
// Returns the current RAM content
const ALERAM& ALEInterface::getRAM() {
return environment->getRAM();
@@ -282,12 +382,22 @@ void ALEInterface::restoreState(const ALEState& state) {
return environment->restoreState(state);
}
-void ALEInterface::saveScreenPNG(const string& filename) {
-
+ALEState ALEInterface::cloneSystemState() {
+ return environment->cloneSystemState();
+}
+
+void ALEInterface::restoreSystemState(const ALEState& state) {
+ return environment->restoreSystemState(state);
+}
+
+/* Kojoley
+void ALEInterface::saveScreenPNG(const std::string& filename) {
ScreenExporter exporter(theOSystem->colourPalette());
exporter.save(environment->getScreen(), filename);
}
-ScreenExporter *ALEInterface::createScreenExporter(const std::string &filename) const {
- return new ScreenExporter(theOSystem->colourPalette(), filename);
+ScreenExporter *ALEInterface::createScreenExporter(
+ const std::string &filename) const {
+ return new ScreenExporter(theOSystem->colourPalette(), filename);
}
+Kojoley */
diff --git a/atari_py/ale_interface/src/ale_interface.hpp b/atari_py/ale_interface/src/ale_interface.hpp
index 47a5f7a..9d03f7d 100644
--- a/atari_py/ale_interface/src/ale_interface.hpp
+++ b/atari_py/ale_interface/src/ale_interface.hpp
@@ -32,21 +32,23 @@
#include "emucore/FSNode.hxx"
#include "emucore/OSystem.hxx"
-#include "os_dependent/SettingsWin32.hxx"
-#include "os_dependent/OSystemWin32.hxx"
-#include "os_dependent/SettingsUNIX.hxx"
-#include "os_dependent/OSystemUNIX.hxx"
+#if (defined(_WIN32) || defined(__MINGW32__))
+# include "os_dependent/SettingsWin32.hxx"
+# include "os_dependent/OSystemWin32.hxx"
+#else
+# include "os_dependent/SettingsUNIX.hxx"
+# include "os_dependent/OSystemUNIX.hxx"
+#endif
#include "games/Roms.hpp"
-#include "common/Defaults.hpp"
#include "common/display_screen.h"
#include "environment/stella_environment.hpp"
-#include "common/ScreenExporter.hpp"
+//Kojoley #include "common/ScreenExporter.hpp"
#include "common/Log.hpp"
#include
-#include
+#include "common/scoped_ptr.hpp"
-static const std::string Version = "0.5.0";
+static const std::string Version = "0.6.0";
/**
This class interfaces ALE with external code for controlling agents.
@@ -74,7 +76,7 @@ class ALEInterface {
// Resets the Atari and loads a game. After this call the game
// should be ready to play. This is necessary after changing a
// setting for the setting to take effect.
- void loadROM(std::string rom_file);
+ bool loadROM(std::string rom = "", std::string name = "");
// Applies an action to the game and returns the reward. It is the
// user's responsibility to check if the game has ended and reset
@@ -83,11 +85,38 @@ class ALEInterface {
reward_t act(Action action);
// Indicates if the game has ended.
- bool game_over();
+ bool game_over() const;
// Resets the game, but not the full system.
void reset_game();
+ // Returns the vector of modes available for the current game.
+ // This should be called only after the rom is loaded.
+ ModeVect getAvailableModes();
+
+ // Sets the mode of the game.
+ // The mode must be an available mode (otherwise it throws an exception).
+ // This should be called only after the rom is loaded.
+ void setMode(game_mode_t m);
+
+ //Returns the vector of difficulties available for the current game.
+ //This should be called only after the rom is loaded. Notice
+ // that there are 2 levers, the right and left switches. They
+ // are not tied to any specific player. In Venture, for example,
+ // we have the following interpretation for the difficulties:
+ // Skill Switch
+ // Level Setting
+ // 1 left B/right B
+ // 2 left B/right A
+ // 3 left A/right B
+ // 4 left A/right A
+ DifficultyVect getAvailableDifficulties();
+
+ // Sets the difficulty of the game.
+ // The difficulty must be an available mode (otherwise it throws an exception).
+ // This should be called only after the rom is loaded.
+ void setDifficulty(difficulty_t m);
+
// Returns the vector of legal actions. This should be called only
// after the rom is loaded.
ActionVect getLegalActionSet();
@@ -100,14 +129,23 @@ class ALEInterface {
int getFrameNumber();
// The remaining number of lives.
- const int lives();
+ int lives();
// Returns the frame number since the start of the current episode
- int getEpisodeFrameNumber();
+ int getEpisodeFrameNumber() const;
// Returns the current game screen
const ALEScreen &getScreen();
+ //This method should receive an empty vector to fill it with
+ //the grayscale colours
+ void getScreenGrayscale(std::vector& grayscale_output_buffer);
+
+ //This method should receive a vector to fill it with
+ //the RGB colours. The first positions contain the red colours,
+ //followed by the green colours and then the blue colours
+ void getScreenRGB(std::vector& output_rgb_buffer);
+
// Returns the current RAM content
const ALERAM &getRAM();
@@ -117,33 +155,49 @@ class ALEInterface {
// Loads the state of the system
void loadState();
+ // This makes a copy of the environment state. This copy does *not* include pseudorandomness,
+ // making it suitable for planning purposes. By contrast, see cloneSystemState.
ALEState cloneState();
+ // Reverse operation of cloneState(). This does not restore pseudorandomness, so that repeated
+ // calls to restoreState() in the stochastic controls setting will not lead to the same outcomes.
+ // By contrast, see restoreSystemState.
void restoreState(const ALEState& state);
+ // This makes a copy of the system & environment state, suitable for serialization. This includes
+ // pseudorandomness and so is *not* suitable for planning purposes.
+ ALEState cloneSystemState();
+
+ // Reverse operation of cloneSystemState.
+ void restoreSystemState(const ALEState& state);
+
// Save the current screen as a png file
- void saveScreenPNG(const std::string& filename);
+ //Kojoley void saveScreenPNG(const std::string& filename);
// Creates a ScreenExporter object which can be used to save a sequence of frames. Ownership
// said object is passed to the caller. Frames are saved in the directory 'path', which needs
// to exists.
- ScreenExporter *createScreenExporter(const std::string &path) const;
+ //Kojoley ScreenExporter *createScreenExporter(const std::string &path) const;
public:
- std::auto_ptr theOSystem;
- std::auto_ptr theSettings;
- std::auto_ptr romSettings;
- std::auto_ptr environment;
+ scoped_ptr theOSystem;
+ scoped_ptr theSettings;
+ scoped_ptr romSettings;
+ scoped_ptr environment;
int max_num_frames; // Maximum number of frames for each episode
public:
// Display ALE welcome message
static std::string welcomeMessage();
static void disableBufferedIO();
- static void createOSystem(std::auto_ptr &theOSystem,
- std::auto_ptr &theSettings);
+ static void createOSystem(scoped_ptr& theOSystem,
+ scoped_ptr& theSettings);
static void loadSettings(const std::string& romfile,
- std::auto_ptr &theOSystem);
+ const std::string& name,
+ OSystem& theOSystem);
+
+ private:
+ static void checkForUnsupportedRom(OSystem& theOSystem);
};
#endif
diff --git a/atari_py/ale_interface/src/common/ColourPalette.cpp b/atari_py/ale_interface/src/common/ColourPalette.cpp
index 1244c52..fde02a0 100644
--- a/atari_py/ale_interface/src/common/ColourPalette.cpp
+++ b/atari_py/ale_interface/src/common/ColourPalette.cpp
@@ -34,7 +34,10 @@ inline uInt32 convertGrayscale(uInt32 packedRGBValue)
double g = (packedRGBValue >> 8) & 0xff;
double b = (packedRGBValue >> 0) & 0xff;
- uInt8 lum = (uInt8) round(r * 0.2989 + g * 0.5870 + b * 0.1140 );
+ // `round` is the part of c++11, but we have to support c++98
+ // because of python2. As we have unsigend values here it is safe
+ // to replace `round` call with +0.5 which is equal in this case.
+ uInt8 lum = (uInt8) (r * 0.2989 + g * 0.5870 + b * 0.1140 + 0.5);
return packRGB(lum, lum, lum);
}
@@ -45,8 +48,10 @@ ColourPalette::ColourPalette(): m_palette(NULL) {
void ColourPalette::getRGB(int val, int &r, int &g, int &b) const
{
- assert (m_palette != NULL);
+ assert(m_palette != NULL);
assert(val >= 0 && val <= 0xFF);
+ // Make sure we are reading from RGB, not grayscale.
+ assert((val & 0x01) == 0);
// Set the RGB components accordingly
r = (m_palette[val] >> 16) & 0xFF;
@@ -56,9 +61,10 @@ void ColourPalette::getRGB(int val, int &r, int &g, int &b) const
uInt8 ColourPalette::getGrayscale(int val) const
{
- assert (m_palette != NULL);
+ assert(m_palette != NULL);
assert(val >= 0 && val < 0xFF);
-
+ assert((val & 0x01) == 1);
+
// Set the RGB components accordingly
return (m_palette[val+1] >> 0) & 0xFF;
}
@@ -81,6 +87,21 @@ void ColourPalette::applyPaletteRGB(uInt8* dst_buffer, uInt8 *src_buffer, size_t
}
}
+void ColourPalette::applyPaletteRGB(std::vector& dst_buffer, uInt8 *src_buffer, size_t src_size)
+{
+ dst_buffer.resize(3 * src_size);
+ assert(dst_buffer.size() == 3 * src_size);
+
+ uInt8 *p = src_buffer;
+
+ for(size_t i = 0; i < src_size * 3; i += 3, p++){
+ int rgb = m_palette[*p];
+ dst_buffer[i+0] = (unsigned char) ((rgb >> 16)); // r
+ dst_buffer[i+1] = (unsigned char) ((rgb >> 8)); // g
+ dst_buffer[i+2] = (unsigned char) ((rgb >> 0)); // b
+ }
+}
+
void ColourPalette::applyPaletteGrayscale(uInt8* dst_buffer, uInt8 *src_buffer, size_t src_size)
{
uInt8 *p = src_buffer;
@@ -91,6 +112,18 @@ void ColourPalette::applyPaletteGrayscale(uInt8* dst_buffer, uInt8 *src_buffer,
}
}
+void ColourPalette::applyPaletteGrayscale(std::vector& dst_buffer, uInt8 *src_buffer, size_t src_size)
+{
+ dst_buffer.resize(src_size);
+ assert(dst_buffer.size() == src_size);
+
+ uInt8 *p = src_buffer;
+
+ for(size_t i = 0; i < src_size; i++, p++){
+ dst_buffer[i] = (unsigned char) (m_palette[*p+1] & 0xFF);
+ }
+}
+
void ColourPalette::setPalette(const string& type,
const string& displayFormat)
{
diff --git a/atari_py/ale_interface/src/common/ColourPalette.hpp b/atari_py/ale_interface/src/common/ColourPalette.hpp
index b9e4587..f769955 100644
--- a/atari_py/ale_interface/src/common/ColourPalette.hpp
+++ b/atari_py/ale_interface/src/common/ColourPalette.hpp
@@ -16,6 +16,7 @@
#ifndef __COLOUR_PALETTE_HPP__
#define __COLOUR_PALETTE_HPP__
+#include
#include
// Include obscure header file for uInt32 definition
#include "../emucore/m6502/src/bspf/src/bspf.hxx"
@@ -41,6 +42,7 @@ class ColourPalette {
8 bits => 24 bits
*/
void applyPaletteRGB(uInt8* dst_buffer, uInt8 *src_buffer, size_t src_size);
+ void applyPaletteRGB(std::vector& dst_buffer, uInt8 *src_buffer, size_t src_size);
/**
Applies the current grayscale palette to the src_buffer and returns the results in dst_buffer
@@ -48,6 +50,7 @@ class ColourPalette {
8 bits => 8 bits
*/
void applyPaletteGrayscale(uInt8* dst_buffer, uInt8 *src_buffer, size_t src_size);
+ void applyPaletteGrayscale(std::vector& dst_buffer, uInt8 *src_buffer, size_t src_size);
/**
Loads all defined palettes with PAL color-loss data depending
diff --git a/atari_py/ale_interface/src/common/Constants.h b/atari_py/ale_interface/src/common/Constants.h
index 0918c2a..3a37fa3 100644
--- a/atari_py/ale_interface/src/common/Constants.h
+++ b/atari_py/ale_interface/src/common/Constants.h
@@ -79,6 +79,14 @@ std::string action_to_string(Action a);
// Define datatypes
typedef std::vector ActionVect;
+// mode type
+typedef unsigned game_mode_t;
+typedef std::vector ModeVect;
+
+// difficulty type
+typedef unsigned difficulty_t;
+typedef std::vector DifficultyVect;
+
// reward type for RL interface
typedef int reward_t;
diff --git a/atari_py/ale_interface/src/common/Defaults.cpp b/atari_py/ale_interface/src/common/Defaults.cpp
deleted file mode 100644
index ff506fc..0000000
--- a/atari_py/ale_interface/src/common/Defaults.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/* *****************************************************************************
- * A.L.E (Arcade Learning Environment)
- * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and
- * the Reinforcement Learning and Artificial Intelligence Laboratory
- * Released under the GNU General Public License; see License.txt for details.
- *
- * Based on: Stella -- "An Atari 2600 VCS Emulator"
- * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team
- *
- * *****************************************************************************
- * Defaults.cpp
- *
- * Defines methods for setting default parameters.
- *
- **************************************************************************** */
-#include "Defaults.hpp"
-
-void setDefaultSettings(Settings &settings) {
- // Controller settings
- settings.setInt("max_num_frames", 0);
- settings.setInt("max_num_frames_per_episode", 0);
-
- // FIFO controller settings
- settings.setBool("run_length_encoding", true);
-
- // Environment customization settings
- settings.setBool("restricted_action_set", false);
- settings.setString("random_seed", "time");
- settings.setBool("color_averaging", false);
- settings.setBool("send_rgb", false);
- settings.setInt("frame_skip", 1);
- settings.setFloat("repeat_action_probability", 0.25);
-
- // Display Settings
- settings.setBool("display_screen", false);
-
- // Record settings
- settings.setString("record_sound_filename", "");
-}
diff --git a/atari_py/ale_interface/src/common/Defaults.hpp b/atari_py/ale_interface/src/common/Defaults.hpp
deleted file mode 100644
index c9bca20..0000000
--- a/atari_py/ale_interface/src/common/Defaults.hpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/* *****************************************************************************
- * A.L.E (Arcade Learning Environment)
- * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and
- * the Reinforcement Learning and Artificial Intelligence Laboratory
- * Released under the GNU General Public License; see License.txt for details.
- *
- * Based on: Stella -- "An Atari 2600 VCS Emulator"
- * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team
- *
- * *****************************************************************************
- * Defaults.hpp
- *
- * Defines methods for setting default parameters.
- *
- **************************************************************************** */
-
-#ifndef __DEFAULTS_HPP__
-#define __DEFAULTS_HPP__
-
-#include "../emucore/Settings.hxx"
-
-/** Sets all of the ALE-specific default settings */
-void setDefaultSettings(Settings &settings);
-
-#endif // __DEFAULTS_HPP__
diff --git a/atari_py/ale_interface/src/common/Log.cpp b/atari_py/ale_interface/src/common/Log.cpp
index 901f0f5..64ef888 100644
--- a/atari_py/ale_interface/src/common/Log.cpp
+++ b/atari_py/ale_interface/src/common/Log.cpp
@@ -2,7 +2,7 @@
#include
using namespace ale;
-Logger::mode Logger::current_mode = Warning;
+Logger::mode Logger::current_mode = Info;
void Logger::setMode(Logger::mode m){
current_mode = m;
diff --git a/atari_py/ale_interface/src/common/ScreenExporter.cpp b/atari_py/ale_interface/src/common/ScreenExporter.cpp
deleted file mode 100644
index c2fb30a..0000000
--- a/atari_py/ale_interface/src/common/ScreenExporter.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/* *****************************************************************************
- * A.L.E (Arcade Learning Environment)
- * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and
- * the Reinforcement Learning and Artificial Intelligence Laboratory
- * Released under the GNU General Public License; see License.txt for details.
- *
- * Based on: Stella -- "An Atari 2600 VCS Emulator"
- * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team
- *
- * *****************************************************************************
- * ScreenExporter.hpp
- *
- * A class for exporting Atari 2600 frames as PNGs.
- *
- **************************************************************************** */
-
-#include "ScreenExporter.hpp"
-#include
-#include
-#include
-#include "Log.hpp"
-
-// MGB: These methods originally belonged to ExportScreen. Possibly these should be returned to
-// their own class, rather than be static methods. They are here to avoid exposing the gritty
-// details of PNG generation.
-static void writePNGChunk(std::ofstream& out, const char* type, uInt8* data, int size) {
-
- // Stuff the length/type into the buffer
- uInt8 temp[8];
- temp[0] = size >> 24;
- temp[1] = size >> 16;
- temp[2] = size >> 8;
- temp[3] = size;
- temp[4] = type[0];
- temp[5] = type[1];
- temp[6] = type[2];
- temp[7] = type[3];
-
- // Write the header
- out.write((const char*)temp, 8);
-
- // Append the actual data
- uInt32 crc = crc32(0, temp + 4, 4);
- if(size > 0)
- {
- out.write((const char*)data, size);
- crc = crc32(crc, data, size);
- }
-
- // Write the CRC
- temp[0] = crc >> 24;
- temp[1] = crc >> 16;
- temp[2] = crc >> 8;
- temp[3] = crc;
- out.write((const char*)temp, 4);
-}
-
-
-static void writePNGHeader(std::ofstream& out, const ALEScreen &screen, bool doubleWidth = true) {
-
- int width = doubleWidth ? screen.width() * 2: screen.width();
- int height = screen.height();
- // PNG file header
- uInt8 header[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
- out.write((const char*)header, sizeof(header));
-
- // PNG IHDR
- uInt8 ihdr[13];
- ihdr[0] = (width >> 24) & 0xFF; // width
- ihdr[1] = (width >> 16) & 0xFF;
- ihdr[2] = (width >> 8) & 0xFF;
- ihdr[3] = (width >> 0) & 0xFF;
- ihdr[4] = (height >> 24) & 0xFF; // height
- ihdr[5] = (height >> 16) & 0xFF;
- ihdr[6] = (height >> 8) & 0xFF;
- ihdr[7] = (height >> 0) & 0xFF;
- ihdr[8] = 8; // 8 bits per sample (24 bits per pixel)
- ihdr[9] = 2; // PNG_COLOR_TYPE_RGB
- ihdr[10] = 0; // PNG_COMPRESSION_TYPE_DEFAULT
- ihdr[11] = 0; // PNG_FILTER_TYPE_DEFAULT
- ihdr[12] = 0; // PNG_INTERLACE_NONE
- writePNGChunk(out, "IHDR", ihdr, sizeof(ihdr));
-}
-
-
-static void writePNGData(std::ofstream &out, const ALEScreen &screen, const ColourPalette &palette, bool doubleWidth = true) {
-
- int dataWidth = screen.width();
- int width = doubleWidth ? dataWidth * 2 : dataWidth;
- int height = screen.height();
-
- // If so desired, double the width
-
- // Fill the buffer with scanline data
- int rowbytes = width * 3;
-
- std::vector buffer((rowbytes + 1) * height, 0);
- uInt8* buf_ptr = &buffer[0];
-
- for(int i = 0; i < height; i++) {
- *buf_ptr++ = 0; // first byte of row is filter type
- for(int j = 0; j < dataWidth; j++) {
- int r, g, b;
-
- palette.getRGB(screen.getArray()[i * dataWidth + j], r, g, b);
- // Double the pixel width, if so desired
- int jj = doubleWidth ? 2 * j : j;
-
- buf_ptr[jj * 3 + 0] = r;
- buf_ptr[jj * 3 + 1] = g;
- buf_ptr[jj * 3 + 2] = b;
-
- if (doubleWidth) {
-
- jj = jj + 1;
-
- buf_ptr[jj * 3 + 0] = r;
- buf_ptr[jj * 3 + 1] = g;
- buf_ptr[jj * 3 + 2] = b;
- }
- }
- buf_ptr += rowbytes; // add pitch
- }
-
- // Compress the data with zlib
- uLongf compmemsize = (uLongf)((height * (width + 1) * 3 + 1) + 12);
- std::vector compmem(compmemsize, 0);
-
- if((compress(&compmem[0], &compmemsize, &buffer[0], height * (width * 3 + 1)) != Z_OK)) {
-
- // @todo -- throw a proper exception
- ale::Logger::Error << "Error: Couldn't compress PNG" << std::endl;
- return;
- }
-
- // Write the compressed framebuffer data
- writePNGChunk(out, "IDAT", &compmem[0], compmemsize);
-}
-
-
-static void writePNGEnd(std::ofstream &out) {
-
- // Finish up
- writePNGChunk(out, "IEND", 0, 0);
-}
-
-ScreenExporter::ScreenExporter(ColourPalette &palette):
- m_palette(palette),
- m_frame_number(0),
- m_frame_field_width(6) {
-}
-
-
-ScreenExporter::ScreenExporter(ColourPalette &palette, const std::string &path):
- m_palette(palette),
- m_frame_number(0),
- m_frame_field_width(6),
- m_path(path) {
-}
-
-
-void ScreenExporter::save(const ALEScreen &screen, const std::string &filename) const {
-
- // Open file for writing
- std::ofstream out(filename.c_str(), std::ios_base::binary);
- if (!out.good()) {
-
- // @todo exception
- ale::Logger::Error << "Could not open " << filename << " for writing" << std::endl;
- return;
- }
-
- // Now write the PNG proper
- writePNGHeader(out, screen, true);
- writePNGData(out, screen, m_palette, true);
- writePNGEnd(out);
-
- out.close();
-}
-
-void ScreenExporter::saveNext(const ALEScreen &screen) {
-
- // Must have specified a directory.
- assert(m_path.size() > 0);
-
- // MGB: It would be nice here to automagically create paths, but the only way I know of
- // doing this cleanly is via boost, which we don't include.
-
- // Construct the filename from basepath & current frame number
- std::ostringstream oss;
- oss << m_path << "/" <<
- std::setw(m_frame_field_width) << std::setfill('0') << m_frame_number << ".png";
-
- // Save the png
- save(screen, oss.str());
-
- m_frame_number++;
-}
-
-
diff --git a/atari_py/ale_interface/src/common/ScreenExporter.hpp b/atari_py/ale_interface/src/common/ScreenExporter.hpp
deleted file mode 100644
index 91f0d0c..0000000
--- a/atari_py/ale_interface/src/common/ScreenExporter.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/* *****************************************************************************
- * A.L.E (Arcade Learning Environment)
- * Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and
- * the Reinforcement Learning and Artificial Intelligence Laboratory
- * Released under the GNU General Public License; see License.txt for details.
- *
- * Based on: Stella -- "An Atari 2600 VCS Emulator"
- * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team
- *
- * *****************************************************************************
- * ScreenExporter.hpp
- *
- * A class for exporting Atari 2600 frames as PNGs.
- *
- **************************************************************************** */
-
-#ifndef __SCREEN_EXPORTER_HPP__
-#define __SCREEN_EXPORTER_HPP__
-
-#include
-#include "display_screen.h"
-#include "../environment/ale_screen.hpp"
-
-class ScreenExporter {
-
- public:
-
- /** Creates a new ScreenExporter which can be used to save screens using save(filename). */
- ScreenExporter(ColourPalette &palette);
-
- /** Creates a new ScreenExporter which will save frames successively in the directory provided.
- Frames are sequentially named with 6 digits, starting at 000000. */
- ScreenExporter(ColourPalette &palette, const std::string &path);
-
- /** Save the given screen to the given filename. No paths are created. */
- void save(const ALEScreen &screen, const std::string &filename) const;
-
- /** Save the given screen according to our own internal numbering. */
- void saveNext(const ALEScreen &screen);
-
- private:
-
- ColourPalette &m_palette;
-
- /** The next frame number. */
- int m_frame_number;
-
- /** The width of the frame number when constructing filenames (set to 6). */
- int m_frame_field_width;
-
- /** The directory where we save successive frames. */
- std::string m_path;
-};
-
-#endif // __SCREEN_EXPORTER_HPP__
-
-
-
diff --git a/atari_py/ale_interface/src/common/SoundNull.hxx b/atari_py/ale_interface/src/common/SoundNull.hxx
index ecb6d88..adc964b 100644
--- a/atari_py/ale_interface/src/common/SoundNull.hxx
+++ b/atari_py/ale_interface/src/common/SoundNull.hxx
@@ -41,7 +41,7 @@ class SoundNull : public Sound
using the object.
*/
SoundNull(OSystem* osystem);
-
+
/**
Destructor
*/
@@ -54,7 +54,7 @@ class SoundNull : public Sound
@param enable Either true or false, to enable or disable the sound system
@return Whether the sound system was enabled or disabled
*/
- void setEnabled(bool enable) { }
+ void setEnabled(bool) { }
/**
The system cycle counter is being adjusting by the specified amount. Any
@@ -62,14 +62,14 @@ class SoundNull : public Sound
@param amount The amount the cycle counter is being adjusted by
*/
- void adjustCycleCounter(Int32 amount) { }
+ void adjustCycleCounter(Int32) { }
/**
Sets the number of channels (mono or stereo sound).
@param channels The number of channels
*/
- void setChannels(uInt32 channels) { }
+ void setChannels(uInt32) { }
/**
Sets the display framerate. Sound generation for NTSC and PAL games
@@ -77,7 +77,7 @@ class SoundNull : public Sound
@param framerate The base framerate depending on NTSC or PAL ROM
*/
- void setFrameRate(uInt32 framerate) { }
+ void setFrameRate(uInt32) { }
/**
Initializes the sound device. This must be called before any
@@ -103,7 +103,7 @@ class SoundNull : public Sound
@param state Mutes sound if true, unmute if false
*/
- void mute(bool state) { }
+ void mute(bool) { }
/**
Reset the sound device.
@@ -117,7 +117,7 @@ class SoundNull : public Sound
@param value The value to save into the register
@param cycle The system cycle at which the register is being updated
*/
- void set(uInt16 addr, uInt8 value, Int32 cycle) { }
+ void set(uInt16, uInt8, Int32) { }
/**
Sets the volume of the sound device to the specified level. The
@@ -126,7 +126,7 @@ class SoundNull : public Sound
@param percent The new volume percentage level for the sound device
*/
- void setVolume(Int32 percent) { }
+ void setVolume(Int32) { }
/**
Adjusts the volume of the sound device based on the given direction.
@@ -134,7 +134,7 @@ class SoundNull : public Sound
@param direction Increase or decrease the current volume by a predefined
amount based on the direction (1 = increase, -1 =decrease)
*/
- void adjustVolume(Int8 direction) { }
+ void adjustVolume(Int8) { }
/**
* Tells the sound engine to record one frame's worth of sound.
diff --git a/atari_py/ale_interface/src/common/display_screen.h b/atari_py/ale_interface/src/common/display_screen.h
index ffe4abd..60910de 100644
--- a/atari_py/ale_interface/src/common/display_screen.h
+++ b/atari_py/ale_interface/src/common/display_screen.h
@@ -68,7 +68,7 @@ class DisplayScreen {
/** A dummy class that simply ignores display events. */
class DisplayScreen {
public:
- DisplayScreen(MediaSource* mediaSource, Sound* sound, ColourPalette &palette) {}
+ DisplayScreen(MediaSource*, Sound*, ColourPalette &) {}
void display_screen() {}
bool manual_control_engaged() { return false; }
Action getUserAction() { return UNDEFINED; }
diff --git a/atari_py/ale_interface/src/common/misc_tools.h b/atari_py/ale_interface/src/common/misc_tools.h
index fe1ddb8..8e34d5a 100644
--- a/atari_py/ale_interface/src/common/misc_tools.h
+++ b/atari_py/ale_interface/src/common/misc_tools.h
@@ -17,7 +17,7 @@
#include "Constants.h"
-#if (defined(WIN32) || defined(__MINGW32__))
+#if (defined(_WIN32) || defined(__MINGW32__))
#include
#endif
@@ -54,7 +54,7 @@ inline void bound(int& x, int lower_bound, int upper_bound) {
/* *****************************************************************************
Return time in milliseconds.
**************************************************************************** */
-#if (defined(WIN32) || defined(__MINGW32__))
+#if (defined(_WIN32) || defined(__MINGW32__))
#include
inline long timeMillis() {
diff --git a/atari_py/ale_interface/src/common/module.mk b/atari_py/ale_interface/src/common/module.mk
index 336f4fe..7e977a4 100644
--- a/atari_py/ale_interface/src/common/module.mk
+++ b/atari_py/ale_interface/src/common/module.mk
@@ -3,12 +3,11 @@ MODULE := src/common
MODULE_OBJS := \
src/common/SoundNull.o \
src/common/SoundSDL.o \
- src/common/SoundExporter.o\
+ src/common/SoundExporter.o \
src/common/display_screen.o \
src/common/ColourPalette.o \
src/common/ScreenExporter.o \
src/common/Constants.o \
- src/common/Defaults.o \
src/common/Log.o
MODULE_DIRS += \
diff --git a/atari_py/ale_interface/src/common/mt19937.hpp b/atari_py/ale_interface/src/common/mt19937.hpp
new file mode 100644
index 0000000..9ff4eda
--- /dev/null
+++ b/atari_py/ale_interface/src/common/mt19937.hpp
@@ -0,0 +1,117 @@
+/* Copyright (C) 2019 by Nikita Kniazev
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef NK_MT19937
+#define NK_MT19937
+
+#include
+
+#if defined(_MSC_VER) && (_MSC_VER < 1600)
+typedef unsigned __int32 uint32_t;
+#else
+# include
+# include
+#endif
+
+class mt19937
+{
+public:
+ typedef uint32_t result_type;
+
+ static const size_t word_size = 32;
+ static const size_t state_size = 624;
+ static const size_t shift_size = 397;
+ static const size_t mask_bits = 31;
+ static const uint32_t xor_mask = 0x9908b0df;
+ static const size_t tempering_u = 11;
+ static const uint32_t tempering_d = 0xffffffff;
+ static const size_t tempering_s = 7;
+ static const uint32_t tempering_b = 0x9d2c5680;
+ static const size_t tempering_t = 15;
+ static const uint32_t tempering_c = 0xefc60000;
+ static const size_t tempering_l = 18;
+ static const uint32_t initialization_multiplier = 1812433253;
+ static const uint32_t default_seed = 5489u;
+
+
+ explicit mt19937(uint32_t value = default_seed) { seed(value); }
+
+ void seed(uint32_t value = default_seed)
+ {
+ state[0] = value;
+ for (uint32_t i = 1; i < state_size; ++i)
+ state[i] = i + initialization_multiplier * (state[i - 1] ^ (state[i - 1] >> 30));
+ index = 0;
+ }
+
+ result_type operator()()
+ {
+ uint32_t next = (index + 1) % state_size;
+
+ uint32_t y = (0x80000000 & state[index]) | (0x7fffffff & state[next]);
+ uint32_t r = state[index] = state[(index + shift_size) % state_size] ^ (y >> 1) ^ ((-(y & 1)) & xor_mask);
+ r ^= r >> tempering_u & tempering_d;
+ r ^= r << tempering_s & tempering_b;
+ r ^= r << tempering_t & tempering_c;
+ r ^= r >> tempering_l;
+
+ index = next;
+
+ return r;
+ }
+
+ result_type (min)() const { return 0; }
+ result_type (max)() const { return 0xffffffffUL; }
+
+ template
+ friend OStream& operator<<(OStream& os, mt19937 const& g)
+ {
+ typename OStream::fmtflags saved_flags = os.flags(os.dec);
+
+ for (uint32_t i = g.index; i < state_size; ++i)
+ os << g.state[i] << ' ';
+ for (uint32_t i = 0; i < g.index; ++i)
+ os << g.state[i] << ' ';
+
+ os.flags(saved_flags);
+
+ return os;
+ }
+
+ template
+ friend IStream& operator>>(IStream& is, mt19937& g)
+ {
+ typename IStream::fmtflags saved_flags = is.flags(is.dec | is.skipws);
+
+ uint32_t tmp[state_size];
+ for (uint32_t i = 0; i < state_size; ++i)
+ is >> tmp[i];
+
+ is.flags(saved_flags);
+
+ if (is.good()) {
+ for (uint32_t i = 0; i < state_size; ++i)
+ g.state[i] = tmp[i];
+ g.index = 0;
+ }
+
+ return is;
+ }
+
+private:
+ uint32_t state[state_size];
+ uint32_t index;
+};
+
+#endif // NK_MT19937
diff --git a/atari_py/ale_interface/src/common/scoped_ptr.hpp b/atari_py/ale_interface/src/common/scoped_ptr.hpp
new file mode 100644
index 0000000..6c3aabb
--- /dev/null
+++ b/atari_py/ale_interface/src/common/scoped_ptr.hpp
@@ -0,0 +1,63 @@
+/* Copyright (C) 2019 by Nikita Kniazev
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef NK_SCOPED_PTR
+#define NK_SCOPED_PTR
+
+namespace utils {
+
+struct bool_conversion { int padding; int truth; };
+typedef int bool_conversion::* explicit_bool;
+
+}
+
+template
+class scoped_ptr {
+public:
+ typedef T* pointer;
+ typedef T element_type;
+
+ scoped_ptr() throw() : p_() {}
+ explicit scoped_ptr(pointer p) throw() : p_(p) {}
+ ~scoped_ptr() { destroy(); }
+
+ element_type& operator*() const { return *get(); }
+ pointer operator->() const throw() { return get(); }
+ pointer get() const throw() { return p_; }
+ operator bool() const throw() { return get() != pointer(); }
+ operator utils::explicit_bool() const
+ {
+ return get() != pointer() ? &utils::bool_conversion::truth
+ : utils::explicit_bool(0);
+ }
+
+ pointer release() throw() { pointer p = p_; p_ = pointer(); return p; }
+ void reset(pointer p = pointer()) throw() { destroy(); p_ = p; }
+ void swap(scoped_ptr& u) throw()
+ {
+ pointer p = release();
+ p_ = u.release();
+ u.p_ = p;
+ }
+
+private:
+ scoped_ptr(const scoped_ptr&);
+ scoped_ptr& operator=(const scoped_ptr&);
+
+ void destroy() { delete get(); }
+
+ pointer p_;
+};
+
+#endif // ALE_SCOPED_PTR
diff --git a/atari_py/ale_interface/src/controllers/ale_controller.cpp b/atari_py/ale_interface/src/controllers/ale_controller.cpp
index 17e70db..12ed061 100644
--- a/atari_py/ale_interface/src/controllers/ale_controller.cpp
+++ b/atari_py/ale_interface/src/controllers/ale_controller.cpp
@@ -24,7 +24,7 @@
ALEController::ALEController(OSystem* osystem):
m_osystem(osystem),
- m_settings(buildRomRLWrapper(m_osystem->settings().getString("rom_file"))),
+ m_settings(buildRomRLWrapper(m_osystem->settings().getString("rom_name"))),
m_environment(m_osystem, m_settings.get()) {
if (m_settings.get() == NULL) {
diff --git a/atari_py/ale_interface/src/controllers/ale_controller.hpp b/atari_py/ale_interface/src/controllers/ale_controller.hpp
index 8491741..7b3a439 100644
--- a/atari_py/ale_interface/src/controllers/ale_controller.hpp
+++ b/atari_py/ale_interface/src/controllers/ale_controller.hpp
@@ -21,6 +21,7 @@
#include "../emucore/OSystem.hxx"
#include "../emucore/m6502/src/System.hxx"
#include "../environment/stella_environment.hpp"
+#include "../common/scoped_ptr.hpp"
class ALEController {
public:
@@ -40,7 +41,7 @@ class ALEController {
protected:
OSystem* m_osystem;
- std::auto_ptr m_settings;
+ scoped_ptr m_settings;
StellaEnvironment m_environment;
};
diff --git a/atari_py/ale_interface/src/controllers/fifo_controller.cpp b/atari_py/ale_interface/src/controllers/fifo_controller.cpp
index bca59c4..bf45984 100644
--- a/atari_py/ale_interface/src/controllers/fifo_controller.cpp
+++ b/atari_py/ale_interface/src/controllers/fifo_controller.cpp
@@ -89,7 +89,7 @@ void FIFOController::handshake() {
// send the width and height of the screen through the pipe
char out_buffer [1024];
- snprintf (out_buffer, sizeof(out_buffer), "%d-%d\n",
+ BSPF_snprintf(out_buffer, sizeof(out_buffer), "%d-%d\n",
(int)m_environment.getScreen().width(),
(int)m_environment.getScreen().height());
@@ -98,7 +98,10 @@ void FIFOController::handshake() {
// Read in agent's response
char in_buffer [1024];
- fgets (in_buffer, sizeof(in_buffer), m_fin);
+ if (fgets (in_buffer, sizeof(in_buffer), m_fin) == NULL) {
+ // If The agent hung up, stop the handshake.
+ return;
+ }
// Parse response: send_screen, send_ram, , send_RL
char * token = strtok (in_buffer,",\n");
@@ -232,8 +235,14 @@ void FIFOController::sendRL() {
void FIFOController::readAction(Action& action_a, Action& action_b) {
// Read the new action from the pipe, as a comma-separated pair
char in_buffer[2048];
- fgets (in_buffer, sizeof(in_buffer), m_fin);
-
+ if (fgets (in_buffer, sizeof(in_buffer), m_fin) == NULL) {
+ // If fgets returns NULL, we set the two actions to NOOP here. This is probably because the
+ // other side has hung up. We'll let the process terminate as usual.
+ action_a = PLAYER_A_NOOP;
+ action_b = PLAYER_B_NOOP;
+ return;
+ }
+
char * token = strtok (in_buffer,",\n");
action_a = (Action)atoi(token);
diff --git a/atari_py/ale_interface/src/emucore/Cart3E.cxx b/atari_py/ale_interface/src/emucore/Cart3E.cxx
index a2fbf1a..8d2e5fe 100644
--- a/atari_py/ale_interface/src/emucore/Cart3E.cxx
+++ b/atari_py/ale_interface/src/emucore/Cart3E.cxx
@@ -40,7 +40,7 @@ Cartridge3E::Cartridge3E(const uInt8* image, uInt32 size)
}
// Initialize RAM with random values
- class Random random;
+ class Random& random = Random::getInstance();
for(uInt32 i = 0; i < 32768; ++i)
{
myRam[i] = random.next();
diff --git a/atari_py/ale_interface/src/emucore/CartAR.cxx b/atari_py/ale_interface/src/emucore/CartAR.cxx
index f446ffe..6a93cf7 100644
--- a/atari_py/ale_interface/src/emucore/CartAR.cxx
+++ b/atari_py/ale_interface/src/emucore/CartAR.cxx
@@ -40,7 +40,8 @@ CartridgeAR::CartridgeAR(const uInt8* image, uInt32 size, bool fastbios)
memcpy(myLoadImages, image, size);
// Initialize RAM with random values
- class Random random;
+ class Random& random = Random::getInstance();
+
for(i = 0; i < 6 * 1024; ++i)
{
myImage[i] = random.next();
diff --git a/atari_py/ale_interface/src/emucore/CartCV.cxx b/atari_py/ale_interface/src/emucore/CartCV.cxx
index 84d6dae..51c2120 100644
--- a/atari_py/ale_interface/src/emucore/CartCV.cxx
+++ b/atari_py/ale_interface/src/emucore/CartCV.cxx
@@ -38,7 +38,8 @@ CartridgeCV::CartridgeCV(const uInt8* image, uInt32 size)
}
// Initialize RAM with random values
- class Random random;
+ class Random& random = Random::getInstance();
+
for(uInt32 i = 0; i < 1024; ++i)
{
myRAM[i] = random.next();
diff --git a/atari_py/ale_interface/src/emucore/CartE7.cxx b/atari_py/ale_interface/src/emucore/CartE7.cxx
index 6d279bb..4f6cdbf 100644
--- a/atari_py/ale_interface/src/emucore/CartE7.cxx
+++ b/atari_py/ale_interface/src/emucore/CartE7.cxx
@@ -35,7 +35,8 @@ CartridgeE7::CartridgeE7(const uInt8* image)
}
// Initialize RAM with random values
- class Random random;
+ class Random& random = Random::getInstance();
+
for(uInt32 i = 0; i < 2048; ++i)
{
myRAM[i] = random.next();
diff --git a/atari_py/ale_interface/src/emucore/CartF4SC.cxx b/atari_py/ale_interface/src/emucore/CartF4SC.cxx
index ceb4f94..8d26248 100644
--- a/atari_py/ale_interface/src/emucore/CartF4SC.cxx
+++ b/atari_py/ale_interface/src/emucore/CartF4SC.cxx
@@ -35,7 +35,8 @@ CartridgeF4SC::CartridgeF4SC(const uInt8* image)
}
// Initialize RAM with random values
- class Random random;
+ class Random& random = Random::getInstance();
+
for(uInt32 i = 0; i < 128; ++i)
{
myRAM[i] = random.next();
diff --git a/atari_py/ale_interface/src/emucore/CartF6SC.cxx b/atari_py/ale_interface/src/emucore/CartF6SC.cxx
index 9b156b4..cbfff3b 100644
--- a/atari_py/ale_interface/src/emucore/CartF6SC.cxx
+++ b/atari_py/ale_interface/src/emucore/CartF6SC.cxx
@@ -35,7 +35,8 @@ CartridgeF6SC::CartridgeF6SC(const uInt8* image)
}
// Initialize RAM with random values
- class Random random;
+ class Random& random = Random::getInstance();
+
for(uInt32 i = 0; i < 128; ++i)
{
myRAM[i] = random.next();
diff --git a/atari_py/ale_interface/src/emucore/CartF8SC.cxx b/atari_py/ale_interface/src/emucore/CartF8SC.cxx
index 57830e0..27d913e 100644
--- a/atari_py/ale_interface/src/emucore/CartF8SC.cxx
+++ b/atari_py/ale_interface/src/emucore/CartF8SC.cxx
@@ -35,7 +35,8 @@ CartridgeF8SC::CartridgeF8SC(const uInt8* image)
}
// Initialize RAM with random values
- class Random random;
+ class Random& random = Random::getInstance();
+
for(uInt32 i = 0; i < 128; ++i)
{
myRAM[i] = random.next();
diff --git a/atari_py/ale_interface/src/emucore/CartFASC.cxx b/atari_py/ale_interface/src/emucore/CartFASC.cxx
index c8c596c..b873a47 100644
--- a/atari_py/ale_interface/src/emucore/CartFASC.cxx
+++ b/atari_py/ale_interface/src/emucore/CartFASC.cxx
@@ -35,7 +35,8 @@ CartridgeFASC::CartridgeFASC(const uInt8* image)
}
// Initialize RAM with random values
- class Random random;
+ class Random& random = Random::getInstance();
+
for(uInt32 i = 0; i < 256; ++i)
{
myRAM[i] = random.next();
diff --git a/atari_py/ale_interface/src/emucore/CartMC.cxx b/atari_py/ale_interface/src/emucore/CartMC.cxx
index a21fd8b..63f71c7 100644
--- a/atari_py/ale_interface/src/emucore/CartMC.cxx
+++ b/atari_py/ale_interface/src/emucore/CartMC.cxx
@@ -38,7 +38,8 @@ CartridgeMC::CartridgeMC(const uInt8* image, uInt32 size)
myRAM = new uInt8[32 * 1024];
// Initialize RAM with random values
- class Random random;
+ class Random& random = Random::getInstance();
+
for(i = 0; i < 32 * 1024; ++i)
{
myRAM[i] = random.next();
diff --git a/atari_py/ale_interface/src/emucore/Console.cxx b/atari_py/ale_interface/src/emucore/Console.cxx
index 27233a8..57ebf00 100644
--- a/atari_py/ale_interface/src/emucore/Console.cxx
+++ b/atari_py/ale_interface/src/emucore/Console.cxx
@@ -72,12 +72,6 @@ Console::Console(OSystem* osystem, Cartridge* cart, const Properties& props)
mySystem = 0;
myEvent = 0;
- std::string seedStr = myOSystem->settings().getString("random_seed").c_str();
- if (seedStr == "time")
- Random::seed((uInt32)time(NULL));
- else
- Random::seed((uInt32)atoi(seedStr.c_str()));
-
// Attach the event subsystem to the current console
//ALE myEvent = myOSystem->eventHandler().event();
myEvent = myOSystem->event();
@@ -154,7 +148,7 @@ Console::Console(OSystem* osystem, Cartridge* cart, const Properties& props)
mySwitches = new Switches(*myEvent, myProperties);
// Now, we can construct the system and components
- mySystem = new System(13, 6);
+ mySystem = new System();
// Inform the controllers about the system
myControllers[0]->setSystem(mySystem);
@@ -397,8 +391,8 @@ void Console::initializeAudio()
*/
void Console::fry() const
{
- for (int ZPmem=0; ZPmem<0x100; ZPmem += randNumGen.next() % 4)
- mySystem->poke(ZPmem, mySystem->peek(ZPmem) & (uInt8)randNumGen.next() % 256);
+ for (int ZPmem=0; ZPmem<0x100; ZPmem += myOSystem->rng().next() % 4)
+ mySystem->poke(ZPmem, mySystem->peek(ZPmem) & (uInt8)myOSystem->rng().next() % 256);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/atari_py/ale_interface/src/emucore/Console.hxx b/atari_py/ale_interface/src/emucore/Console.hxx
index 23cd046..ef2f61b 100644
--- a/atari_py/ale_interface/src/emucore/Console.hxx
+++ b/atari_py/ale_interface/src/emucore/Console.hxx
@@ -104,6 +104,13 @@ class Console
*/
System& system() const { return *mySystem; }
+ /**
+ Returns the OSystem for this emulator.
+
+ @return The OSystem.
+ */
+ OSystem& osystem() const { return *myOSystem; }
+
/**
Get the cartridge used by the console which contains the ROM code
@@ -247,9 +254,6 @@ class Console
// A RIOT of my own! (...with apologies to The Clash...)
M6532 *myRiot;
- //Random number generator
- mutable Random randNumGen;
-
#ifdef ATARIVOX_SUPPORT
AtariVox *vox;
#endif
diff --git a/atari_py/ale_interface/src/emucore/Control.cxx b/atari_py/ale_interface/src/emucore/Control.cxx
index 61984ad..314f743 100644
--- a/atari_py/ale_interface/src/emucore/Control.cxx
+++ b/atari_py/ale_interface/src/emucore/Control.cxx
@@ -26,14 +26,14 @@ Controller::Controller(Jack jack, const Event& event, Type type)
myType(type)
{
}
-
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Controller::~Controller()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-const Controller::Type Controller::type()
+Controller::Type Controller::type()
{
return myType;
}
diff --git a/atari_py/ale_interface/src/emucore/Control.hxx b/atari_py/ale_interface/src/emucore/Control.hxx
index 1b3a542..07a0bb2 100644
--- a/atari_py/ale_interface/src/emucore/Control.hxx
+++ b/atari_py/ale_interface/src/emucore/Control.hxx
@@ -87,7 +87,7 @@ class Controller
@param type The type for this controller
*/
Controller(Jack jack, const Event& event, Type type);
-
+
/**
Destructor
*/
@@ -96,7 +96,7 @@ class Controller
/**
Returns the type of this controller.
*/
- const Type type();
+ Type type();
/**
Inform this controller about the current System.
diff --git a/atari_py/ale_interface/src/emucore/FSNode.hxx b/atari_py/ale_interface/src/emucore/FSNode.hxx
index 4085651..3a59c77 100644
--- a/atari_py/ale_interface/src/emucore/FSNode.hxx
+++ b/atari_py/ale_interface/src/emucore/FSNode.hxx
@@ -1,8 +1,8 @@
//============================================================================
//
-// SSSS tt lll lll
-// SS SS tt ll ll
-// SS tttttt eeee ll ll aaaa
+// SSSS tt lll lll
+// SS SS tt ll ll
+// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
@@ -47,8 +47,8 @@
* And if we ever want to support devices with no FS in the classical sense (Palm...),
* we can build upon this.
*/
-
-/*
+
+/*
* TODO - Instead of starting with getRoot(), we should rather add a getDefaultDir()
* call that on Unix might return the current dir or the users home dir...
* i.e. the root dir is usually not the best starting point for browsing.
@@ -120,8 +120,8 @@ class AbstractFilesystemNode
{
std::string first = displayName();
std::string second = node.displayName();
- transform(first.begin(), first.end(), first.begin(), (int(*)(int)) tolower);
- transform(second.begin(), second.end(), second.begin(), (int(*)(int)) tolower);
+ std::transform(first.begin(), first.end(), first.begin(), (int(*)(int)) tolower);
+ std::transform(second.begin(), second.end(), second.begin(), (int(*)(int)) tolower);
return first < second;
}
@@ -155,7 +155,7 @@ class AbstractFilesystemNode
virtual AbstractFilesystemNode *parent() const = 0;
/**
- * This method is a rather ugly hack which is used internally by the
+ * This method is a rather ugly hack which is used internally by the
* actual node implementions to wrap up raw nodes inside FilesystemNode
* objects. We probably want to get rid of this eventually and replace it
* with a cleaner / more elegant solution, but for now it works.
diff --git a/atari_py/ale_interface/src/emucore/M6532.cxx b/atari_py/ale_interface/src/emucore/M6532.cxx
index 4be0dcc..6a0c60a 100644
--- a/atari_py/ale_interface/src/emucore/M6532.cxx
+++ b/atari_py/ale_interface/src/emucore/M6532.cxx
@@ -23,6 +23,7 @@
#include "System.hxx"
#include "Serializer.hxx"
#include "Deserializer.hxx"
+#include "OSystem.hxx"
#include
using namespace std;
#include "../common/Log.hpp"
@@ -31,13 +32,11 @@ using namespace std;
M6532::M6532(const Console& console)
: myConsole(console)
{
- class Random random;
-
// Randomize the 128 bytes of memory
for(uInt32 t = 0; t < 128; ++t)
{
- myRAM[t] = random.next();
+ myRAM[t] = myConsole.osystem().rng().next();
}
// Initialize other data members
@@ -58,9 +57,7 @@ const char* M6532::name() const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6532::reset()
{
- class Random random;
-
- myTimer = 25 + (random.next() % 75);
+ myTimer = 25 + (myConsole.osystem().rng().next() % 75);
myIntervalShift = 6;
myCyclesWhenTimerSet = 0;
myCyclesWhenInterruptReset = 0;
diff --git a/atari_py/ale_interface/src/emucore/OSystem.cxx b/atari_py/ale_interface/src/emucore/OSystem.cxx
index dc41027..69c770d 100644
--- a/atari_py/ale_interface/src/emucore/OSystem.cxx
+++ b/atari_py/ale_interface/src/emucore/OSystem.cxx
@@ -20,12 +20,10 @@
#include
#include
#include
-#include
+//Kojoley #include
#include
using namespace std;
-//ALE #include "MediaFactory.hxx"
-
#ifdef DEBUGGER_SUPPORT
#include "Debugger.hxx"
#endif
@@ -35,21 +33,13 @@ using namespace std;
#endif
#include "FSNode.hxx"
-#include "unzip.h"
#include "MD5.hxx"
#include "Settings.hxx"
#include "PropsSet.hxx"
-//ALE #include "EventHandler.hxx"
-#include "Event.hxx" //ALE
-//ALE #include "Menu.hxx"
-//ALE #include "CommandMenu.hxx"
-//ALE #include "Launcher.hxx"
-//ALE #include "Font.hxx"
-//ALE #include "StellaFont.hxx"
-//ALE #include "ConsoleFont.hxx"
+#include "Event.hxx"
#include "OSystem.hxx"
#include "SoundSDL.hxx"
-//ALE #include "Widget.hxx"
+
#define MAX_ROM_SIZE 512 * 1024
#include
@@ -60,14 +50,14 @@ using namespace std;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSystem::OSystem()
:
- myEvent(NULL), //ALE
+ myEvent(NULL),
mySound(NULL),
mySettings(NULL),
myPropSet(NULL),
myConsole(NULL),
myQuitLoop(false),
mySkipEmulation(false),
- myRomFile(""),
+ //Kojoley myRomFile(""),
myFeatures(""),
p_display_screen(NULL)
{
@@ -86,24 +76,16 @@ OSystem::OSystem()
#ifdef CHEATCODE_SUPPORT
myFeatures += "Cheats";
#endif
-
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSystem::~OSystem()
{
- //ALE delete myMenu;
- //ALE delete myCommandMenu;
- //ALE delete myLauncher;
- //ALE delete myFont;
- //ALE delete myConsoleFont;
-
// Remove any game console that is currently attached
deleteConsole();
// OSystem takes responsibility for framebuffer and sound,
// since it created them
- //ALE delete myFrameBuffer;
if (mySound != NULL)
delete mySound;
@@ -121,14 +103,11 @@ OSystem::~OSystem()
if (myPropSet != NULL)
delete myPropSet;
- //ALE delete myEventHandler;
if (myEvent != NULL)
delete myEvent;
if (p_display_screen != NULL) {
delete p_display_screen;
}
-
- //ALE delete aiBase;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -174,11 +153,36 @@ bool OSystem::create()
// that only have a single sound device (no hardware mixing)
createSound();
- //ALE aiBase = new AIBase(this);
+ // Seed RNG. This will likely get re-called, e.g. by the ALEInterface, but is needed
+ // by other interfaces.
+ resetRNGSeed();
return true;
}
+void OSystem::resetRNGSeed() {
+
+ // We seed the random number generator. The 'time' seed is somewhat redundant, since the
+ // rng defaults to time. But we'll do it anyway.
+ if (mySettings->getInt("random_seed") == 0) {
+ myRandGen.seed((uInt32)time(NULL));
+ } else {
+ int seed = mySettings->getInt("random_seed");
+ assert(seed >= 0);
+ myRandGen.seed((uInt32)seed);
+ }
+}
+
+bool OSystem::saveState(Serializer& out) {
+
+ // Here we serialize the RNG state.
+ return myRandGen.saveState(out);
+}
+
+bool OSystem::loadState(Deserializer& in) {
+ return myRandGen.loadState(in);
+}
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::setConfigPaths()
{
@@ -344,7 +348,7 @@ void OSystem::createSound()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool OSystem::createConsole(const string& romfile)
+bool OSystem::createConsole(const string& rom, const string& name)
{
// Do a little error checking; it shouldn't be necessary
if(myConsole) deleteConsole();
@@ -352,27 +356,20 @@ bool OSystem::createConsole(const string& romfile)
bool retval = false;
// If a blank ROM has been given, we reload the current one (assuming one exists)
- if(romfile == "")
+ if(rom.empty())
{
- if(myRomFile == "")
- {
- ale::Logger::Error << "ERROR: Rom file not specified ..." << endl;
- return false;
- }
+ ale::Logger::Error << "ERROR: Rom not specified ..." << endl;
+ return false;
}
- else
- myRomFile = romfile;
// Open the cartridge image and read it in
- uInt8* image;
- int size = -1;
string md5;
- if(openROM(myRomFile, md5, &image, &size))
+ if(openROM(rom, name, md5))
{
// Get all required info for creating a valid console
Cartridge* cart = (Cartridge*) NULL;
Properties props;
- if(queryConsoleInfo(image, size, md5, &cart, props))
+ if(queryConsoleInfo((const uInt8 *)rom.data(), rom.size(), md5, &cart, props))
{
// Create an instance of the 2600 game console
myConsole = new Console(this, cart, props);
@@ -391,11 +388,9 @@ bool OSystem::createConsole(const string& romfile)
if(mySettings->getBool("showinfo"))
cerr << "Game console created:" << endl
- << " ROM file: " << myRomFile << endl
<< myConsole->about() << endl;
else
ale::Logger::Info << "Game console created:" << endl
- << " ROM file: " << myRomFile << endl
<< myConsole->about() << endl;
// Update the timing info for a new console run
@@ -406,20 +401,16 @@ bool OSystem::createConsole(const string& romfile)
}
else
{
- ale::Logger::Error << "ERROR: Couldn't create console for " << myRomFile << " ..." << endl;
+ ale::Logger::Error << "ERROR: Couldn't create console for rom ..." << endl;
retval = false;
}
}
else
{
- ale::Logger::Error << "ERROR: Couldn't open " << myRomFile << " ..." << endl;
+ ale::Logger::Error << "ERROR: Couldn't open rom ..." << endl;
retval = false;
}
- // Free the image since we don't need it any longer
- if(size != -1) {
- delete[] image;
- }
if (mySettings->getBool("display_screen", true)) {
#ifndef __USE_SDL
ale::Logger::Error << "Screen display requires directive __USE_SDL to be defined."
@@ -479,93 +470,32 @@ void OSystem::createLauncher()
ALE */
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool OSystem::openROM(const string& rom, string& md5, uInt8** image, int* size)
+bool OSystem::openROM(const string& rom, const string& name, string& md5)
{
- // Try to open the file as a zipped archive
- // If that fails, we assume it's just a gzipped or normal data file
- unzFile tz;
- if((tz = unzOpen(rom.c_str())) != NULL)
- {
- if(unzGoToFirstFile(tz) == UNZ_OK)
- {
- unz_file_info ufo;
-
- for(;;) // Loop through all files for valid 2600 images
- {
- // Longer filenames might be possible, but I don't
- // think people would name files that long in zip files...
- char filename[1024];
-
- unzGetCurrentFileInfo(tz, &ufo, filename, 1024, 0, 0, 0, 0);
- filename[1023] = '\0';
-
- if(strlen(filename) >= 4)
- {
- // Grab 3-character extension
- char* ext = filename + strlen(filename) - 4;
-
- if(!BSPF_strcasecmp(ext, ".bin") || !BSPF_strcasecmp(ext, ".a26"))
- break;
- }
-
- // Scan the next file in the zip
- if(unzGoToNextFile(tz) != UNZ_OK)
- break;
- }
-
- // Now see if we got a valid image
- if(ufo.uncompressed_size <= 0)
- {
- unzClose(tz);
- return false;
- }
- *size = ufo.uncompressed_size;
- *image = new uInt8[*size];
-
- // We don't have to check for any return errors from these functions,
- // since if there are, 'image' will not contain a valid ROM and the
- // calling method can take of it
- unzOpenCurrentFile(tz);
- unzReadCurrentFile(tz, *image, *size);
- unzCloseCurrentFile(tz);
- unzClose(tz);
- }
- else
- {
- unzClose(tz);
- return false;
- }
- }
- else
- {
- // Assume the file is either gzip'ed or not compressed at all
- gzFile f = gzopen(rom.c_str(), "rb");
- if(!f)
- return false;
-
- *image = new uInt8[MAX_ROM_SIZE];
- *size = gzread(f, *image, MAX_ROM_SIZE);
- gzclose(f);
- }
+ /* Kojoley
+ // Assume the file is either gzip'ed or not compressed at all
+ gzFile f = gzopen(rom.c_str(), "rb");
+ if(!f)
+ return false;
+
+ *image = new uInt8[MAX_ROM_SIZE];
+ *size = gzread(f, *image, MAX_ROM_SIZE);
+ gzclose(f);
+ Kojoley */
// If we get to this point, we know we have a valid file to open
// Now we make sure that the file has a valid properties entry
- md5 = MD5(*image, *size);
-
- // Some games may not have a name, since there may not
- // be an entry in stella.pro. In that case, we use the rom name
- // and reinsert the properties object
- Properties props;
- myPropSet->getMD5(md5, props);
+ md5 = MD5((const uInt8 *)rom.data(), rom.size());
- string name = props.get(Cartridge_Name);
- if(name == "Untitled")
- {
- // Get the filename from the rom pathname
- string::size_type pos = rom.find_last_of(BSPF_PATH_SEPARATOR);
- if(pos+1 != string::npos)
+ if (!name.empty()) {
+ // Some games may not have a name, since there may not
+ // be an entry in stella.pro. In that case, we use the rom name
+ // and reinsert the properties object
+ Properties props;
+ myPropSet->getMD5(md5, props);
+
+ if(props.get(Cartridge_Name) == "Untitled")
{
- name = rom.substr(pos+1);
props.set(Cartridge_MD5, md5);
props.set(Cartridge_Name, name);
myPropSet->insert(props, false);
@@ -576,35 +506,30 @@ bool OSystem::openROM(const string& rom, string& md5, uInt8** image, int* size)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-string OSystem::getROMInfo(const string& romfile)
+string OSystem::getROMInfo(const string& rom, const string& name)
{
ostringstream buf;
// Open the cartridge image and read it in
- uInt8* image;
- int size = -1;
string md5;
- if(openROM(romfile, md5, &image, &size))
+ if(openROM(rom, name, md5))
{
// Get all required info for creating a temporary console
Cartridge* cart = (Cartridge*) NULL;
Properties props;
- if(queryConsoleInfo(image, size, md5, &cart, props))
+ if(queryConsoleInfo((const uInt8 *)rom.data(), rom.size(), md5, &cart, props))
{
Console* console = new Console(this, cart, props);
if(console)
buf << console->about();
else
- buf << "ERROR: Couldn't get ROM info for " << romfile << " ..." << endl;
+ buf << "ERROR: Couldn't get ROM info for rom ..." << endl;
delete console;
}
else
- buf << "ERROR: Couldn't open " << romfile << " ..." << endl;
+ buf << "ERROR: Couldn't open rom ..." << endl;
}
- // Free the image and console since we don't need it any longer
- if(size != -1)
- delete[] image;
return buf.str();
}
diff --git a/atari_py/ale_interface/src/emucore/OSystem.hxx b/atari_py/ale_interface/src/emucore/OSystem.hxx
index 1cec3d1..5247e4d 100644
--- a/atari_py/ale_interface/src/emucore/OSystem.hxx
+++ b/atari_py/ale_interface/src/emucore/OSystem.hxx
@@ -39,7 +39,7 @@ class VideoDialog;
#include "m6502/src/bspf/src/bspf.hxx"
#include "../common/display_screen.h"
#include "../common/ColourPalette.hpp"
-#include "../common/ScreenExporter.hpp"
+//Kojoley #include "../common/ScreenExporter.hpp"
#include "../common/Log.hpp"
struct Resolution {
@@ -223,8 +223,8 @@ class OSystem
/**
Get the maximum dimensions of a window for the video hardware.
*/
- const uInt32 desktopWidth() const { return myDesktopWidth; }
- const uInt32 desktopHeight() const { return myDesktopHeight; }
+ uInt32 desktopWidth() const { return myDesktopWidth; }
+ uInt32 desktopHeight() const { return myDesktopHeight; }
/**
Get the supported fullscreen resolutions for the video hardware.
@@ -282,7 +282,7 @@ class OSystem
@return String representing the full path of the ROM file.
*/
- const std::string& romFile() const { return myRomFile; }
+ //Kojoley const std::string& romFile() const { return myRomFile; }
/**
Switches between software and OpenGL framebuffer modes.
@@ -293,9 +293,11 @@ class OSystem
Creates a new game console from the specified romfile.
@param romfile The full pathname of the ROM to use
+ @param name The ROM name
@return True on successful creation, otherwise false
*/
- bool createConsole(const std::string& romfile = "");
+ bool createConsole(const std::string& romfile = "",
+ const std::string& name = "");
/**
Deletes the currently defined console, if it exists.
@@ -313,9 +315,11 @@ class OSystem
Console object and querying it.
@param romfile The full pathname of the ROM to use
+ @param name The ROM name
@return Some information about this ROM
*/
- std::string getROMInfo(const std::string& romfile);
+ std::string getROMInfo(const std::string& romfile,
+ const std::string& name = "");
/**
The features which are conditionally compiled into Stella.
@@ -328,13 +332,13 @@ class OSystem
Open the given ROM and return an array containing its contents.
@param rom The absolute pathname of the ROM file
+ @param name The ROM name
@param md5 The md5 calculated from the ROM file
- @param image A pointer to store the ROM data
- Note, the calling method is responsible for deleting this
- @param size The amount of data read into the image array
@return False on any errors, else true
*/
- bool openROM(const std::string& rom, std::string& md5, uInt8** image, int* size);
+ bool openROM(const std::string& rom,
+ const std::string& name,
+ std::string& md5);
/**
Issue a quit event to the OSystem.
@@ -343,6 +347,26 @@ class OSystem
void skipEmulation() { mySkipEmulation = true; }
+ /**
+ Returns the random number generator for this emulator.
+ */
+ Random& rng() { return myRandGen; }
+
+ /**
+ Resets the seed for our random number generator.
+ */
+ void resetRNGSeed();
+
+ /**
+ Serializes the OSystem state.
+ */
+ bool saveState(Serializer& out);
+
+ /**
+ Deserializes the OSystem state.
+ */
+ bool loadState(Deserializer& in);
+
public:
//////////////////////////////////////////////////////////////////////
// The following methods are system-specific and must be implemented
@@ -390,7 +414,7 @@ class OSystem
*/
//ALE virtual void stateChanged(EventHandler::State state);
-
+
protected:
/**
Query the OSystem video hardware for resolution information.
@@ -414,7 +438,7 @@ class OSystem
void setConfigFile(const std::string& file) { myConfigFile = file; }
-
+
protected:
// Pointer to the EventHandler object
//ALE EventHandler* myEventHandler;
@@ -435,9 +459,10 @@ class OSystem
// Pointer to the (currently defined) Console object
Console* myConsole;
-
-
+ // Random number generator shared across the emulator's components
+ Random myRandGen;
+
// Pointer to the Menu object
//ALE Menu* myMenu;
@@ -455,7 +480,7 @@ class OSystem
// Pointer to the AI object
//ALE AIBase *aiBase;
-
+
// Maximum dimensions of the desktop area
uInt32 myDesktopWidth, myDesktopHeight;
@@ -482,7 +507,7 @@ class OSystem
std::string myPropertiesFile;
std::string myGameListCacheFile;
- std::string myRomFile;
+ //Kojoley std::string myRomFile;
std::string myFeatures;
@@ -494,7 +519,7 @@ class OSystem
// The font object to use for the console/debugger
//ALE GUI::Font* myConsoleFont;
-
+
public: //ALE
// Time per frame for a video update, based on the current framerate
uInt32 myTimePerFrame;
@@ -515,7 +540,7 @@ class OSystem
//ALE static uInt32 ourGUIColors[kNumUIPalettes][kNumColors-256];
public:
DisplayScreen* p_display_screen; //MHAUSKN
-
+
private:
ColourPalette m_colour_palette;
diff --git a/atari_py/ale_interface/src/emucore/Random.cxx b/atari_py/ale_interface/src/emucore/Random.cxx
index 2d4e74a..42d7c62 100644
--- a/atari_py/ale_interface/src/emucore/Random.cxx
+++ b/atari_py/ale_interface/src/emucore/Random.cxx
@@ -18,59 +18,115 @@
#include
#include "Random.hxx"
+#include "Serializer.hxx"
+#include "Deserializer.hxx"
-// TODO(mgb): bring this include in once we switch to C++11.
-// #include
-#include "TinyMT/tinymt32.h"
+#include "../common/mt19937.hpp"
+#include
-// The random number generator is defined here to avoid having to expose tinymt32.h.
-namespace RandomStatic {
+// A static Random object for compatibility purposes. Don't use this.
+Random Random::s_random;
- typedef tinymt32_t randgen_t;
- // Random number generator
- randgen_t rndGenerator;
+// Implementation of Random's random number generator wrapper.
+class Random::Impl {
+
+ typedef mt19937 randgen_t;
+
+ public:
+
+ Impl();
+
+ // Implementations of the methods defined in Random.hpp.
+ void seed(uInt32 value);
+ uInt32 next();
+ double nextDouble();
+
+ private:
+
+ friend class Random;
+
+ // Seed to use for creating new random number generators
+ uInt32 m_seed;
+
+ // Random number generator
+ randgen_t m_randgen;
+};
+
+Random::Impl::Impl()
+{
+ // Initialize seed to time
}
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Random::Impl::seed(uInt32 value)
+{
+ m_seed = value;
+ m_randgen.seed(m_seed);
+}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void Random::seed(uInt32 value)
+uInt32 Random::Impl::next()
{
- ourSeed = value;
- ourSeeded = true;
- // TODO(mgb): this is the C++11 variant.
- // rndGenerator.seed(ourSeed);
+ return m_randgen();
+}
- tinymt32_init(&RandomStatic::rndGenerator, ourSeed);
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+double Random::Impl::nextDouble()
+{
+ return m_randgen() / double(m_randgen.max() + 1.0);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Random::Random()
+Random::Random() :
+ m_pimpl(new Random::Impl())
{
- // If we haven't been seeded then seed ourself
- if(!ourSeeded)
- seed((uInt32) time(NULL));
}
-
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Random::~Random() {
+ if (m_pimpl != NULL) {
+ delete m_pimpl;
+ m_pimpl = NULL;
+ }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Random::seed(uInt32 value)
+{
+ m_pimpl->seed(value);
+}
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 Random::next()
{
- // TODO(mgb): C++11
- // return rndGenerator();
- return static_cast(tinymt32_generate_uint32(&RandomStatic::rndGenerator));
+ return m_pimpl->next();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double Random::nextDouble()
{
- // TODO(mgb): C++11
- // return rndGenerator() / double(rndGenerator.max() + 1.0);
- return tinymt32_generate_32double(&RandomStatic::rndGenerator);
+ return m_pimpl->nextDouble();
}
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-uInt32 Random::ourSeed = 0;
+Random& Random::getInstance() {
+ return s_random;
+}
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool Random::ourSeeded = false;
+bool Random::saveState(Serializer& ser) {
+ // The mt19937 object's serialization of choice is into a string.
+ std::ostringstream oss;
+ oss << m_pimpl->m_randgen;
+ ser.putString(oss.str());
+
+ return true;
+}
+bool Random::loadState(Deserializer& deser) {
+ // Deserialize into a string.
+ std::istringstream iss(deser.getString());
+
+ iss >> m_pimpl->m_randgen;
+
+ return true;
+}
diff --git a/atari_py/ale_interface/src/emucore/Random.hxx b/atari_py/ale_interface/src/emucore/Random.hxx
index 1ed0518..4aef44e 100644
--- a/atari_py/ale_interface/src/emucore/Random.hxx
+++ b/atari_py/ale_interface/src/emucore/Random.hxx
@@ -21,13 +21,12 @@
#include "m6502/src/bspf/src/bspf.hxx"
-/**
- This is a quick-and-dirty random number generator. It is based on
- information in Chapter 7 of "Numerical Recipes in C". It's a simple
- linear congruential generator.
+class Serializer;
+class Deserializer;
- @author Bradford W. Mott
- @version $Id: Random.hxx,v 1.4 2007/01/01 18:04:49 stephena Exp $
+/**
+ This Random class uses a Mersenne Twister to provide pseudorandom numbers.
+ The class itself is derived from the original 'Random' class by Bradford W. Mott.
*/
class Random
{
@@ -39,13 +38,15 @@ class Random
@param value The value to seed the random number generator with
*/
- static void seed(uInt32 value);
+ void seed(uInt32 value);
/**
Create a new random number generator
*/
Random();
-
+
+ ~Random();
+
/**
Answer the next random number from the random number generator
@@ -60,13 +61,28 @@ class Random
*/
double nextDouble();
- private:
+ // Returns a static Random object. DO NOT USE THIS. This is mostly meant for use by the
+ // code for the various cartridges.
+ static Random& getInstance();
+
+ /**
+ Serializes the RNG state.
+ */
+ bool saveState(Serializer& out);
+
+ /**
+ Deserializes the RNG state.
+ */
+ bool loadState(Deserializer& in);
+
+ private:
- // Seed to use for creating new random number generators
- static uInt32 ourSeed;
+ // Actual rng (implementation hidden away from the header to avoid depending on rng libraries).
+ class Impl;
+ Impl *m_pimpl;
- // Indicates if seed has been set or not
- static bool ourSeeded;
+ // A static Random object. Don't use this.
+ static Random s_random;
};
#endif
diff --git a/atari_py/ale_interface/src/emucore/Settings.cxx b/atari_py/ale_interface/src/emucore/Settings.cxx
index c8ccb73..b5c14e8 100644
--- a/atari_py/ale_interface/src/emucore/Settings.cxx
+++ b/atari_py/ale_interface/src/emucore/Settings.cxx
@@ -93,6 +93,8 @@ Settings::Settings(OSystem* osystem) : myOSystem(osystem) {
setInternal("uipalette", "0");
setInternal("mwheel", "4");
setInternal("autoslot", "false");
+
+ setDefaultSettings();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -108,8 +110,8 @@ void Settings::loadConfig(const char* config_file){
ifstream in(config_file);
if(!in || !in.is_open()) {
- // ale::Logger::Warning << "Warning: couldn't load settings file: " << config_file << "\n";
- return;
+ ale::Logger::Warning << "Warning: couldn't load settings file: " << config_file << std::endl;
+ return;
}
while(getline(in, line)) {
@@ -379,46 +381,58 @@ void Settings::saveConfig()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Settings::setInt(const string& key, const int value)
{
- ostringstream stream;
+ std::ostringstream stream;
stream << value;
- if(int idx = getInternalPos(key) != -1)
+ if(int idx = getInternalPos(key) != -1){
setInternal(key, stream.str(), idx);
- else
+ }
+ else{
+ verifyVariableExistence(intSettings, key);
setExternal(key, stream.str());
+ }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Settings::setFloat(const string& key, const float value)
{
- ostringstream stream;
+ std::ostringstream stream;
stream << value;
- if(int idx = getInternalPos(key) != -1)
+ if(int idx = getInternalPos(key) != -1){
setInternal(key, stream.str(), idx);
- else
+ }
+ else{
+ verifyVariableExistence(floatSettings, key);
setExternal(key, stream.str());
+ }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Settings::setBool(const string& key, const bool value)
{
- ostringstream stream;
+ std::ostringstream stream;
stream << value;
- if(int idx = getInternalPos(key) != -1)
+ if(int idx = getInternalPos(key) != -1){
setInternal(key, stream.str(), idx);
- else
+ }
+ else{
+ verifyVariableExistence(boolSettings, key);
setExternal(key, stream.str());
+ }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Settings::setString(const string& key, const string& value)
{
- if(int idx = getInternalPos(key) != -1)
+ if(int idx = getInternalPos(key) != -1){
setInternal(key, value, idx);
- else
+ }
+ else{
+ verifyVariableExistence(stringSettings, key);
setExternal(key, value);
+ }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -528,7 +542,7 @@ const string& Settings::getString(const string& key, bool strict) const {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Settings::setSize(const string& key, const int value1, const int value2)
{
- ostringstream buf;
+ std::ostringstream buf;
buf << value1 << "x" << value2;
setString(key, buf.str());
}
@@ -673,3 +687,58 @@ Settings& Settings::operator = (const Settings&)
return *this;
}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Settings::setDefaultSettings() {
+
+ // Stella settings
+ stringSettings.insert(pair("cpu", "low")); // Reduce CPU emulation fidelity for speed
+
+ // Controller settings
+ intSettings.insert(pair("max_num_frames", 0));
+ intSettings.insert(pair("max_num_frames_per_episode", 0));
+
+ // FIFO controller settings
+ boolSettings.insert(pair("run_length_encoding", true));
+
+ // Environment customization settings
+ boolSettings.insert(pair("restricted_action_set", false));
+ intSettings.insert(pair("random_seed", 0));
+ boolSettings.insert(pair("color_averaging", false));
+ boolSettings.insert(pair("send_rgb", false));
+ intSettings.insert(pair("frame_skip", 1));
+ floatSettings.insert(pair("repeat_action_probability", 0.25));
+ stringSettings.insert(pair("rom_name", ""));
+
+ // Record settings
+ intSettings.insert(pair("fragsize", 64)); // fragsize to 64 ensures proper sound sync
+ stringSettings.insert(pair("record_screen_dir", ""));
+ stringSettings.insert(pair("record_sound_filename", ""));
+
+ // Display Settings
+ boolSettings.insert(pair("display_screen", false));
+
+ for(map::iterator it = stringSettings.begin(); it != stringSettings.end(); it++) {
+ this->setString(it->first, it->second);
+ }
+
+ for(map::iterator it = floatSettings.begin(); it != floatSettings.end(); it++) {
+ this->setFloat(it->first, it->second);
+ }
+
+ for(map::iterator it = boolSettings.begin(); it != boolSettings.end(); it++) {
+ this->setBool(it->first, it->second);
+ }
+
+ for(map::iterator it = intSettings.begin(); it != intSettings.end(); it++) {
+ this->setInt(it->first, it->second);
+ }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+template
+void Settings::verifyVariableExistence(map dict, string key){
+ if(dict.find(key) == dict.end()){
+ throw std::runtime_error("The key " + key + " you are trying to set does not exist.\n");
+ }
+}
diff --git a/atari_py/ale_interface/src/emucore/Settings.hxx b/atari_py/ale_interface/src/emucore/Settings.hxx
index 175491e..98c2634 100644
--- a/atari_py/ale_interface/src/emucore/Settings.hxx
+++ b/atari_py/ale_interface/src/emucore/Settings.hxx
@@ -21,6 +21,9 @@
class OSystem;
+#include