Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/JapaMala/armok-vision
Browse files Browse the repository at this point in the history
  • Loading branch information
RosaryMala committed Jun 10, 2015
2 parents b5518bd + ac49935 commit f0c5b52
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 32 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
/*.booproj
/TiletypeList.csv
*.csv#
Armok Vision.app
3 changes: 3 additions & 0 deletions Assets/BasicBanner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
55 changes: 55 additions & 0 deletions Assets/BasicBanner.png.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Assets/BasicIcon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
55 changes: 55 additions & 0 deletions Assets/BasicIcon.png.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

84 changes: 58 additions & 26 deletions Assets/MapGen/DFConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// Will eventually run actual communication on a separate thread.
// Singleton-y - attached to a GameObject.
using System.Threading;
using System.Net.Sockets;

public class DFConnection : MonoBehaviour {

Expand Down Expand Up @@ -237,6 +238,10 @@ void OnDestroy() {
Disconnect();
}

public sealed class DFRemoteException : System.Exception {
public DFRemoteException(System.Exception inner) : base("Remote exception!", inner) {}
}

private abstract class ConnectionMode {
public static ConnectionMode GetConnectionMode(DFConnection connection, bool runOnAltThread) {
if (runOnAltThread) {
Expand All @@ -262,16 +267,20 @@ private sealed class UnityThreadMode : ConnectionMode {
public UnityThreadMode(DFConnection connection) : base(connection) {}

public override void Poll() {
// No need for locks, single threaded.
connection.networkClient.suspend_game();
connection.viewInfoCall.execute(null, out connection._netViewInfo);
connection.unitListCall.execute(null, out connection._netUnitList);
RemoteFortressReader.BlockList resultList;
connection.blockListCall.execute(connection.blockRequest, out resultList);
foreach (RemoteFortressReader.MapBlock block in resultList.map_blocks) {
connection.pendingBlocks.EnqueueAndDisplace(new DFCoord(block.map_x, block.map_y, block.map_z), block);
try {
// No need for locks, single threaded.
connection.networkClient.suspend_game();
connection.viewInfoCall.execute(null, out connection._netViewInfo);
connection.unitListCall.execute(null, out connection._netUnitList);
RemoteFortressReader.BlockList resultList;
connection.blockListCall.execute(connection.blockRequest, out resultList);
foreach (RemoteFortressReader.MapBlock block in resultList.map_blocks) {
connection.pendingBlocks.EnqueueAndDisplace(new DFCoord(block.map_x, block.map_y, block.map_z), block);
}
connection.networkClient.resume_game();
} catch (System.Exception e) {
throw new DFRemoteException(e);
}
connection.networkClient.resume_game();
}

public override void Terminate() {
Expand All @@ -284,41 +293,64 @@ public override void Terminate() {
private sealed class AltThreadMode : ConnectionMode {
private static readonly System.TimeSpan SLEEP_TIME = System.TimeSpan.FromMilliseconds(16);

// Use to terminate computation thread
private volatile bool finished;
// Said thread
private readonly Thread connectionThread;
// Catch errors on the throwing thread and catch them on the main thread
private System.Object errorLock;
private System.Exception crashError;

public AltThreadMode(DFConnection connection) : base(connection) {
finished = false;
errorLock = new Object();
crashError = null;
connectionThread = new Thread(new ThreadStart(this.RunForever));
connectionThread.Start();
}

public override void Poll() {}
public override void Poll() {
lock (errorLock) {
if (crashError != null) {
System.Exception error = crashError;
crashError = null;
throw new DFRemoteException(error);
}
}
}

public override void Terminate() {
finished = true;
}

private void RunForever() {
while (!finished) {
connection.networkClient.suspend_game();
lock (connection.viewInfoLock) {
connection.viewInfoCall.execute(null, out connection._netViewInfo);
}
lock (connection.unitListLock) {
connection.unitListCall.execute(null, out connection._netUnitList);
}
RemoteFortressReader.BlockList resultList;
lock (connection.blockRequest) {
connection.blockListCall.execute(connection.blockRequest, out resultList);
}
lock (connection.pendingBlocks) {
foreach (RemoteFortressReader.MapBlock block in resultList.map_blocks) {
connection.pendingBlocks.EnqueueAndDisplace(new DFCoord(block.map_x, block.map_y, block.map_z), block);
try {
connection.networkClient.suspend_game();
lock (connection.viewInfoLock) {
connection.viewInfoCall.execute(null, out connection._netViewInfo);
}
lock (connection.unitListLock) {
connection.unitListCall.execute(null, out connection._netUnitList);
}
RemoteFortressReader.BlockList resultList;
lock (connection.blockRequest) {
connection.blockListCall.execute(connection.blockRequest, out resultList);
}
lock (connection.pendingBlocks) {
foreach (RemoteFortressReader.MapBlock block in resultList.map_blocks) {
connection.pendingBlocks.EnqueueAndDisplace(new DFCoord(block.map_x, block.map_y, block.map_z), block);
}
}
connection.networkClient.resume_game();
Thread.Sleep(SLEEP_TIME);
} catch (System.Exception e) {
// For now, just pass on any exceptions and exit
lock (errorLock) {
crashError = e;
return;
}
}
connection.networkClient.resume_game();
Thread.Sleep(SLEEP_TIME);
}
// finished
connection.networkClient.disconnect();
Expand Down
9 changes: 5 additions & 4 deletions ProjectSettings/ProjectSettings.asset
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ PlayerSettings:
xboxEnableKinectAutoTracking: 0
xboxEnableFitness: 0
visibleInBackground: 0
macFullscreenMode: 2
macFullscreenMode: 1
d3d9FullscreenMode: 1
d3d11FullscreenMode: 1
xboxSpeechDB: 0
Expand Down Expand Up @@ -93,7 +93,7 @@ PlayerSettings:
ForceSDCardPermission: 0
CreateWallpaper: 0
APKExpansionFiles: 0
preloadShaders: 0
preloadShaders: 1
StripUnusedMeshComponents: 0
iPhoneSdkVersion: 988
iPhoneTargetOSVersion: 22
Expand Down Expand Up @@ -133,11 +133,12 @@ PlayerSettings:
height: 180
banner: {fileID: 0}
androidGamepadSupportLevel: 0
resolutionDialogBanner: {fileID: 0}
resolutionDialogBanner: {fileID: 2800000, guid: c5438fb44cad84d79a3b9ae867451d83,
type: 3}
m_BuildTargetIcons:
- m_BuildTarget:
m_Icons:
- m_Icon: {fileID: 0}
- m_Icon: {fileID: 2800000, guid: d57e1ad97b15e43a187111ec757683de, type: 3}
m_Size: 128
m_BuildTargetBatching:
- m_BuildTarget: Standalone
Expand Down
47 changes: 45 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,47 @@
armok-vision
Armok Vision
============

A 3d realtime visualizer for Dwarf Fortress
[Forum thread](http://www.bay12forums.com/smf/index.php?topic=146473) | [Screenshots](http://imgur.com/a/bPmeo)

A 3d realtime visualizer for Dwarf Fortress.

## To Use

1. Install Dwarf Fortress and a current DFHack.
2. Download Armok Vision from the forum thread.
3. Load into a fortress mode map.
4. Start up Armok Vision.
5. Enjoy!

## To Contribute

Want to help out? We love contributions!

#### Bugs
If you've run into any bugs: [report them!](https://github.com/JapaMala/armok-vision/issues) (You'll need a [github account](https://github.com/).) Make sure to describe the issue in as much detail as you can, and to mention what system & Armok Vision version you're using. Also, check if what you're reporting has been reported before.

#### Artists
If you're an artist and want to contribute 3D models, sounds, concept art:

- There should be a folder called `StreamingAssets` somewhere around the armok vision executable (or inside, if you're on a mac.) If you edit the files inside and restart Armok Vision, it will use your modified assets. Be careful editing the .xml files, they're finnicky. You can post your edited resources in the forum thread and we can try to integrate them with the project.
- Alternatively, load things up in Unity and edit them there (see the following instructions).
- Check the [issues](https://github.com/JapaMala/armok-vision/issues); there may be something open about things that need prettifying.

#### Developers
If you know how to code and want to hack on the engine:

1. Install [Unity 5](http://unity3d.com/get-unity). (We're using the Personal Edition.)
2. `$ git clone --depth 1 https://github.com/JapaMala/armok-vision.git` (or without `--depth 1` if you want the full history, but it's pretty big).
3. Load the `armok-vision` folder in the Unity editor.
4. Hack around. Check out the [issues](https://github.com/JapaMala/armok-vision/issues) to find things that need fixing / ideas that could be implemented.
5. Submit a [pull request](https://github.com/JapaMala/armok-vision/pulls) with your changes!

##### Structural Notes
(Some short notes for anyone getting started with the codebase.)

- Armok Vision is an application built with the [Unity engine](https://unity3d.com/). It connects to the [remotefortressreader](https://github.com/DFHack/dfhack/blob/master/plugins/remotefortressreader.cpp) DFHack plugin over TCP and exchanges [protobuf-formatted messages](https://github.com/DFHack/dfhack/blob/master/plugins/proto/RemoteFortressReader.proto). (You don't need to be familiar with DFHack to work with Armok Vision.)
- On the Unity side, [Assets/RemoteClientDF](https://github.com/JapaMala/armok-vision/tree/master/Assets/RemoteClientDF) contains the generated C# protobuf files, as well as classes for managing the network connection. The script [Assets/MapGen/DFConnection.cs](https://github.com/JapaMala/armok-vision/blob/master/Assets/MapGen/DFConnection.cs) runs the connection on a separate thread and exposes data collected from DF.
- The script that actually manages the onscreen map is [Assets/MapGen/GameMap.cs](https://github.com/JapaMala/armok-vision/blob/master/Assets/MapGen/GameMap.cs), which stores the `GameObject`s representing different map chunks. It calls the scripts in [Assets/MapGen/Meshing](https://github.com/JapaMala/armok-vision/tree/master/Assets/MapGen/Meshing) to build the actual meshes (on separate threads).
- Most assets - textures, 3d models, sprites, etc. - are loaded at runtime from [Assets/StreamingAssets](https://github.com/JapaMala/armok-vision/tree/master/Assets/StreamingAssets), which is copied directly to folder containing the generated app. The script that handles this is [Assets/MapGen/ContentLoader.cs](https://github.com/JapaMala/armok-vision/blob/master/Assets/MapGen/ContentLoader.cs).

There's a lot of other stuff but hopefully it'll be reasonably self-explanatory. Alternatively, you can ask in the forum thread, or the #dfhack IRC channel on freenode; somebody might be lurking who can help.

0 comments on commit f0c5b52

Please sign in to comment.