diff --git a/include/SegmentDisplay.h b/include/SegmentDisplay.h new file mode 100644 index 0000000..ded5b26 --- /dev/null +++ b/include/SegmentDisplay.h @@ -0,0 +1,25 @@ +// +// SegmentDisplay.h +// Segments +// +// Created by Andrew Morton on 11/6/14. +// +// + +#ifndef __Segments__SegmentDisplay__ +#define __Segments__SegmentDisplay__ + +using namespace ci; +using namespace std; + +class SegmentDisplay { +public: + void drawChar(char c, Vec2f offset = Vec2f::zero(), float scale = 1.0); + Vec2f drawString(string s, Vec2f offset = Vec2f::zero(), float scale = 1.0); + Vec2f charDimensions(float scale = 1.0); + + Color mOn = Color(1, 0, 0); + Color mOff = Color(0.25, 0, 0); +}; + +#endif /* defined(__Segments__SegmentDisplay__) */ diff --git a/src/AlienLanderApp.cpp b/src/AlienLanderApp.cpp index ab8c56b..66324f8 100644 --- a/src/AlienLanderApp.cpp +++ b/src/AlienLanderApp.cpp @@ -15,7 +15,9 @@ TODO list: #include "cinder/Perlin.h" #include "cinder/Text.h" #include "cinder/Utilities.h" +#include #include "Resources.h" +#include "SegmentDisplay.h" using namespace ci; using namespace ci::app; @@ -48,9 +50,7 @@ class AlienLanderApp : public AppNative { float mRatio = 0.5; Perlin mPerlin = Perlin(16); Channel32f mMap = Channel32f(1024, 1024); - - gl::Texture mStatusTexture; - + SegmentDisplay mDisplay; }; void AlienLanderApp::prepareSettings( Settings *settings ) @@ -150,10 +150,6 @@ void AlienLanderApp::update() simple.addLine( string("Acc: ") + to_string(mAcc) ); simple.addLine( string("Vel: ") + to_string(mVel) ); simple.addLine( "Alt: " + to_string(mRatio) ); - mStatusTexture = gl::Texture( simple.render( true, true ) ); - - // Reset the acceleration for the next pass - mAcc = 0; } void AlienLanderApp::draw() @@ -207,16 +203,19 @@ void AlienLanderApp::draw() } - /* - // Save a frame in the home directory. - if (getElapsedFrames() == 1) { - writeImage( getHomeDirectory() / "AlienLanderAppOutput.png", copyWindowSurface() ); - } - */ gl::popModelView(); - gl::draw( mStatusTexture, Vec2f( 10, 10 ) ); + gl::lineWidth(4); + Vec2f pos = Vec2f(2, 2); + boost::format formatter("%+05f"); + mDisplay.mOn = blue; + mDisplay.mOff = Color8u::hex(0x1A3E5A); + pos.y += 2 + mDisplay.drawString("Acc " + (formatter % mAcc).str() + "m/s/s", pos, 1).y; + pos.y += 2 + mDisplay.drawString("Vel " + (formatter % mVel).str() + "m/s ", pos, 1).y; + pos.y += 2 + mDisplay.drawString("Alt " + (formatter % mRatio).str() + "km ", pos, 1).y; + // Reset the acceleration for the next pass + mAcc = 0; } CINDER_APP_NATIVE( AlienLanderApp, RendererGl ) diff --git a/src/SegmentDisplay.cpp b/src/SegmentDisplay.cpp new file mode 100644 index 0000000..64f3044 --- /dev/null +++ b/src/SegmentDisplay.cpp @@ -0,0 +1,168 @@ +// +// SegmentDisplay.cpp +// Segments +// +// Created by Andrew Morton on 11/6/14. +// +// + +#include "SegmentDisplay.h" + + +// Awesome font stolen from http://www.msarnoff.org/alpha32/ +// The first 32, non-printable ASCII characters are omitted. +const int CHAR_OFFSET = 32; +const int CHAR_LENGTH = 96; +int charPatterns[CHAR_LENGTH] = { + 0x0000, /* */ + 0x1822, /* ! */ + 0x0880, /* " */ + 0x4b3c, /* # */ + 0x4bbb, /* $ */ + 0xdb99, /* % */ + 0x2d79, /* & */ + 0x1000, /* ' */ + 0x3000, /* ( */ + 0x8400, /* ) */ + 0xff00, /* * */ + 0x4b00, /* + */ + 0x8000, /* , */ + 0x0300, /* - */ + 0x0020, /* . */ + 0x9000, /* / */ + 0x90ff, /* 0 */ + 0x100c, /* 1 */ + 0x0377, /* 2 */ + 0x123b, /* 3 */ + 0x038c, /* 4 */ + 0x21b3, /* 5 */ + 0x03fb, /* 6 */ + 0x000f, /* 7 */ + 0x03ff, /* 8 */ + 0x03bf, /* 9 */ + 0x0021, /* : */ + 0x8001, /* ; */ + 0x9030, /* < */ + 0x0330, /* = */ + 0x2430, /* > */ + 0x4207, /* ? */ + 0x417f, /* @ */ + 0x03cf, /* A */ + 0x4a3f, /* B */ + 0x00f3, /* C */ + 0x483f, /* D */ + 0x01f3, /* E */ + 0x01c3, /* F */ + 0x02fb, /* G */ + 0x03cc, /* H */ + 0x4833, /* I */ + 0x4863, /* J */ + 0x31c0, /* K */ + 0x00f0, /* L */ + 0x14cc, /* M */ + 0x24cc, /* N */ + 0x00ff, /* O */ + 0x03c7, /* P */ + 0x20ff, /* Q */ + 0x23c7, /* R */ + 0x03bb, /* S */ + 0x4803, /* T */ + 0x00fc, /* U */ + 0x90c0, /* V */ + 0xa0cc, /* W */ + 0xb400, /* X */ + 0x5400, /* Y */ + 0x9033, /* Z */ + 0x00e1, /* [ */ + 0x2400, /* \ */ + 0x001e, /* ] */ + 0xa000, /* ^ */ + 0x0030, /* _ */ + 0x0400, /* ` */ + 0x4170, /* a */ + 0x41e0, /* b */ + 0x0160, /* c */ + 0x4960, /* d */ + 0x8160, /* e */ + 0x4b02, /* f */ + 0x2238, /* g */ + 0x41c0, /* h */ + 0x4000, /* i */ + 0x4020, /* j */ + 0x6a00, /* k */ + 0x4811, /* l */ + 0x4348, /* m */ + 0x4140, /* n */ + 0x4160, /* o */ + 0x09c1, /* p */ + 0x4991, /* q */ + 0x0140, /* r */ + 0x4220, /* s */ + 0x4b10, /* t */ + 0x4060, /* u */ + 0x8040, /* v */ + 0x4078, /* w */ + 0xd800, /* x */ + 0x2038, /* y */ + 0x8120, /* z */ + 0x4912, /* { */ + 0x4800, /* | */ + 0x4a21, /* } */ + 0x0a85, /* ~ */ + 0x0000, /*  */ +}; + +Vec2f SegmentDisplay::charDimensions(float scale) +{ + return Vec2f(18, 22) * scale; +} + +void SegmentDisplay::drawChar(char c, Vec2f offset, float scale) +{ + typedef struct + { + Vec2i a, b; + } Segment; + + Segment segments[16] = { + { Vec2i(6,2), Vec2i(12,2) }, + { Vec2i(12,2), Vec2i(18,2) }, + { Vec2i(18,2), Vec2i(16,12) }, + { Vec2i(16,12), Vec2i(14,22) }, + { Vec2i(14,22), Vec2i(8,22) }, + { Vec2i(8,22), Vec2i(2,22) }, + { Vec2i(2,22), Vec2i(4,12) }, + { Vec2i(4,12), Vec2i(6,2) }, + { Vec2i(4,12), Vec2i(10,12) }, + { Vec2i(10,12), Vec2i(16,12) }, + { Vec2i(6,2), Vec2i(10,12) }, + { Vec2i(10,12), Vec2i(12,2) }, + { Vec2i(10,12), Vec2i(18,2) }, + { Vec2i(10,12), Vec2i(14,22) }, + { Vec2i(10,12), Vec2i(8,22) }, + { Vec2i(10,12), Vec2i(2,22) }, + }; + + if (c < CHAR_OFFSET || c > CHAR_OFFSET + CHAR_LENGTH - 1) return; + + int pattern = charPatterns[(int)c - 32]; + for (int i = 0; i < 16; i++) + { + Segment *s = segments+i; + Color color = (pattern & (1 << i)) ? mOn : mOff; + gl::color(color); + gl::drawLine((s->a * scale) + offset, (s->b * scale) + offset); + } +} + +Vec2f SegmentDisplay::drawString(string s, Vec2f offset, float scale) +{ + Vec2f dimensions = charDimensions(scale); + Vec2f pos = offset; + for ( std::string::iterator it=s.begin(); it!=s.end(); ++it) { + drawChar(*it, pos, scale); + pos.x += dimensions.x; + } + return Vec2f(s.length(), 1) * dimensions; +} + diff --git a/xcode/AlienLander.xcodeproj/project.pbxproj b/xcode/AlienLander.xcodeproj/project.pbxproj index 93e8f1f..c7cc2b8 100644 --- a/xcode/AlienLander.xcodeproj/project.pbxproj +++ b/xcode/AlienLander.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 00B784B50FF439BC000DE1D7 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00B784B10FF439BC000DE1D7 /* AudioUnit.framework */; }; 00B784B60FF439BC000DE1D7 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00B784B20FF439BC000DE1D7 /* CoreAudio.framework */; }; 2D2A5A2BC34D4ADF8C548077 /* CinderApp.icns in Resources */ = {isa = PBXBuildFile; fileRef = 526114993F034EFEAD0FF5B3 /* CinderApp.icns */; }; + 498566431A0C917B00A76295 /* SegmentDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 498566421A0C917B00A76295 /* SegmentDisplay.cpp */; }; 49FBDEF41A03FB5F0019CAB2 /* usa.png in Resources */ = {isa = PBXBuildFile; fileRef = 49FBDEF31A03FB5F0019CAB2 /* usa.png */; }; 5323E6B20EAFCA74003A9687 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5323E6B10EAFCA74003A9687 /* CoreVideo.framework */; }; 5323E6B60EAFCA7E003A9687 /* QTKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5323E6B50EAFCA7E003A9687 /* QTKit.framework */; }; @@ -30,6 +31,8 @@ 191AC45670D244B4BECCEE81 /* Resources.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Resources.h; path = ../include/Resources.h; sourceTree = ""; }; 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 498566411A0C917100A76295 /* SegmentDisplay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SegmentDisplay.h; path = ../include/SegmentDisplay.h; sourceTree = ""; }; + 498566421A0C917B00A76295 /* SegmentDisplay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SegmentDisplay.cpp; path = ../src/SegmentDisplay.cpp; sourceTree = ""; }; 49FBDEF31A03FB5F0019CAB2 /* usa.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = usa.png; path = ../resources/usa.png; sourceTree = ""; }; 526114993F034EFEAD0FF5B3 /* CinderApp.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = CinderApp.icns; path = ../resources/CinderApp.icns; sourceTree = ""; }; 5323E6B10EAFCA74003A9687 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = /System/Library/Frameworks/CoreVideo.framework; sourceTree = ""; }; @@ -69,6 +72,7 @@ 080E96DDFE201D6D7F000001 /* Source */ = { isa = PBXGroup; children = ( + 498566421A0C917B00A76295 /* SegmentDisplay.cpp */, FF73BB1805134F7BB644E5AA /* AlienLanderApp.cpp */, ); name = Source; @@ -123,6 +127,7 @@ 29B97315FDCFA39411CA2CEA /* Headers */ = { isa = PBXGroup; children = ( + 498566411A0C917100A76295 /* SegmentDisplay.h */, 191AC45670D244B4BECCEE81 /* Resources.h */, 53A9217A3EE34D10A08774F0 /* AlienLander_Prefix.pch */, ); @@ -213,6 +218,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 498566431A0C917B00A76295 /* SegmentDisplay.cpp in Sources */, C42E9BA72DCF4A808AD3154F /* AlienLanderApp.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0;