Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 290 lines (199 sloc) 18.422 kb
511ae14 @ByteProject added markdown read me
ByteProject authored
1 # AnsiLove.framework
2
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
3 This is a Cocoa framework I consider as modern approach of bringing back the good old days™. It's capable of rendering ANSi / ASCII art and it also handles SAUCE records. There are two classes responsible for all the magic: `ALAnsiGenerator` and `ALSauceMachine`. The former, `ALAnsiGenerator` creates Retina-ready PNG and TIFF images from ANSi source files. What with one thing and another, images are read-only. So if you're looking for something that generates output in real textmode, maybe as a NSAttributedString instance, you're wrong. However, if you're seeking the most complete and accurate rendering of ANSi art sources available these days, you came to the right place. While `ALAnsiGenerator` acts more like a Cocoa layer, there is a specifc library under the surface. It's called [AnsiLove/C](https://github.com/ByteProject/AnsiLove-C) and we spent countless hours developing it. The latter, `ALSauceMachine` is reading SAUCE records and returns these values as Objective-C properties.
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
4
79c8b2b @ByteProject massive documentation update for ALSauceMachine
ByteProject authored
5 # Version info
6
01820d3 @ByteProject documentation update to reflect new version numbers
ByteProject authored
7 Current framework release: `3.0.1` - rendering library: [AnsiLove/C](https://github.com/ByteProject/AnsiLove-C) `2.0.2`
511ae14 @ByteProject added markdown read me
ByteProject authored
8
9 # Features
10
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
11 Rendering of all known ANSi / ASCII art file types:
12
13 - ANSi (.ANS)
14 - Binary (.BIN)
15 - Artworx (.ADF)
16 - iCE Draw (.IDF)
17 - Xbin (.XB) [details](http://www.acid.org/info/xbin/xbin.htm)
18 - PCBoard (.PCB)
19 - Tundra (.TND) [details](http://sourceforge.net/projects/tundradraw)
20 - ASCII (.ASC)
21 - Release info (.NFO)
22 - Description in zipfile (.DIZ)
23
24 Files with custom suffix default to the ANSi renderer (e.g. ICE or CIA).
25
26 AnsiLove.framework is capabable of processing:
27
28 - SAUCE records
29 - DOS and Amiga fonts (embedded binary dump)
30 - iCE colors
31
32 Still not enough?
33
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
34 - Output files are highly optimized 4-bit images.
35 - Optionally generate proper Retina @2x.PNG files.
36 - Merge output as TIFF, containing regular and Retina resolutions.
37 - Use custom objects for adjusting output results.
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
38 - Built-in support for rendering Amiga ASCII.
39 - Everything's Mac App Store conform and sandboxing compliant.
16c6415 @ByteProject raiders of the lost typo...!
ByteProject authored
40 - This is an Automatic Reference Counting (ARC) project.
511ae14 @ByteProject added markdown read me
ByteProject authored
41
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
42 # Documentation
43
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
44 Let's talk about using the framework in your own projects. First of all, AnsiLove.framework is intended to run on `OS X`, it won't work on `iOS`. Yeah, sorry for that. Not even my fault, it's simply not possible at this point. You have to download the sources and compile the framework. At least OS X Mountain Lion and Xcode 4.x are necessary for compiling the framework `as is`. Generally, targeting older SDKs is supported, but for said purpose you will also have to recompile all contents in the `Library` folder, including [AnsiLove/C](https://github.com/ByteProject/AnsiLove-C). While [AnsiLove/C](https://github.com/ByteProject/AnsiLove-C) sources are up in a separate repository here on GitHub (just follow the link), sources for contained dylibs are not provided. Well, I never said it's easy to target older systems, at least it's possible. The project file contains two build targets, the framework itself and a test app `AnsiLoveGUI`, the latter is optional. Select `AnsiLoveGUI` from the Schemes dropdown in Xcode if you desire to compile that one too. The test app is a good example of implementing AnsiLove.framework, it does not contain much code and what you find there is well commented. So `AnsiLoveGUI` might be your first place to play with the framework after reading this documentation. Being an ARC framework, the test app is a pure ARC project as well. What else.
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
45
46 ## Adding the framework to your projects
47
c9681bb @ByteProject corrected to minor typos and a dead hyperlink
ByteProject authored
48 Place the compiled framework in a folder inside your project, I recommend creating a `Frameworks` folder, if not existing. In Xcode go to the File menu and select `Add Files to "MyProject"`, select the AnsiLove.framework you just dropped in the `Frameworks` folder and then drag the framework to the other frameworks in your project hierarchy. The last steps are pretty easy:
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
49
50 - In the project navigator, select your project
51 - Select your target
52 - Select the `Build Phases` tab
53 - Open `Link Binaries With Libraries` expander
54 - Click the `+` button and select AnsiLove.framework
55 - Hit `Add Build Phase` at the bottom
c9681bb @ByteProject corrected to minor typos and a dead hyperlink
ByteProject authored
56 - Add a `Copy Files` build phase with `Frameworks` as destination
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
57 - Once again select AnsiLove.framework
58
59 Now AnsiLove.framework is properly linked to your target and will be added to compiled binaries.
60
61 ## Implementing the framework in your own sources
62
63 Go to the header of the class you want to use the framework with. Import the framework like this:
64
65 #import <Ansilove/AnsiLove.h>
66
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
67 To transform ANSi source files into a beautiful images, `ALAnsiGenerator` comes with three methods you should know:
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
68
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
69 + (void)ansiFileToPNG:
70 + (void)ansiFileToRetinaPNG:
71 + (void)ansiFileToRetinaTIFF:
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
72
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
73 Method `ansiFileToPNG:` creates a single PNG image in regular resolution from any given ANSi source. `ansiFileToRetinaPNG:` generates the regular PNG and additionally creates a properly named (and sized) Retina @2x.PNG variant. `ansiFileToRetinaTIFF:` generates the two PNGs and merges them to a Retina-ready TIFF, containing both resolutions. The PNG cache files will be automatically deleted after TIFF output is done.
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
74
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
75 You can call said methods like this:
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
76
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
77 [ALAnsiGenerator ansiFileToRetinaTIFF:self.myInputFile
78 outputFile:self.myOutputFile
79 font:self.myFont
80 bits:self.myBits
81 iceColors:self.myIceColors
82 columns:self.myColumns];
83
84 Keep in mind that `ALAnsiGenerator` needs all it's objects as `NSString` instances. You can work internally with numeric types like `NSInteger` or `BOOL` but you need to convert them to strings before you pass these values to `ALAnsiGenerator`. For example, `iceColors` (I'm going to explain all objects in detail below) can only be `0` or `1`, so it's perfect to have that as `BOOL` type in your app. I did this in `AnsiLoveGUI` as well. To pass this value to ALAnsiGenerator you can do it something like this:
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
85
86 NSString *iceColors;
87 BOOL shouldUseIceColors;
88
89 if (shouldUseIceColors == NO) {
90 self.iceColors = @"0";
91 }
92 else {
93 self.iceColors = @"1";
94 }
95
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
96 Note that generally all objects except `inputFile` are optional. You can either decide to pass `nil` (AnsiLove.framework will then work with it's default values) or pass empty strings like:
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
97
98 self.myFontString = @"";
99
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
100 AnsiLove.framework will silently consume `nil` and empty string values but it will rely on it's built-in defaults in both cases. Clever? Sure. So much for the basics, let's head over to the details. The three methods seem pretty simple, but in fact they're so damn powerful if you know how to deal with objects you pass and that is what I'm going to teach you now.
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
101
102 ## (NSString *)inputFile
103
d04e53e @ByteProject typos... all over the place...
ByteProject authored
104 The only necessary object you need to pass to `ALAnsiGenerator. Well, that's logic. If there is no input file, what should be the output? I see you get it. Here is an example for a proper `inputFile` string:
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
105
106 /Users/Stefan/Desktop/MyAnsiArtwork.ans
107
46da767 @ByteProject another refinement...
ByteProject authored
108 I recommend treating this string case-sensitive. As you can see, that string explicitly needs to contain the path and the file name. That's pretty cool because it means you can work either with `NSStrings` or `NSURLs` internally. Just keep in mind that any `NSURL` needs to be converted to a string before passing to ALAnsiGenerator. NSURL has a method called `absoluteString` that can be used for easy conversion.
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
109
110 NSURL *myURL;
111 NSString *urlString = [myURL absoluteString];
112
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
113 But AnsiLove.framework is even more flexible and it will automatically resolve any tilde in `inputFile` string instances. Now you know that this is a proper `inputFile` string, too:
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
114
115 ~/Desktop/MyAnsiArtwork.ans
116
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
117 Simple, elegant, comfortable, just working? You decide.
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
118
119 ## (NSString *)outputFile
120
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
121 Formatting of string `outputFile` is identical to string `inputFile`. Only one difference: `outputFile` is optional. If you don't set this object, the framework will use the same path / file name you passed as `inputFile` string, but it adds .PNG or .TIFF as suffix, depending on what method you fired. However, if you plan to write your images into a different directory and / or under a different filename, go ahead and customize this object. Just keep in mind that for custom paths the suffix will be added automatically as well.
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
122
123 ## (NSString *)font
124
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
125 AnsiLove.framework comes with two font families both originating from the golden age of ANSi artists. These font families are `PC` and `AMIGA`, the latter restricted to 8-bit only. Let's have a look at the values you can pass as `font` string.
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
126
127 `PC` fonts can be (all case-sensitive):
128
129 - `80x25` (code page 437)
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
130 - `80x50` (code page 437, 80x50 mode)
131 - `baltic` (code page 775)
132 - `cyrillic` (code page 855)
133 - `french-canadian` (code page 863)
134 - `greek` (code page 737)
135 - `greek-869` (code page 869)
136 - `hebrew` (code page 862)
137 - `icelandic` (Code page 861)
138 - `latin1` (code page 850)
139 - `latin2` (code page 852)
140 - `nordic` (code page 865)
141 - `portuguese` (Code page 860)
5ce9aa4 @ByteProject added Terminus to font string documentation, new license information
ByteProject authored
142 - `russian` (code page 866)
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
143 - `terminus` (modern font, code page 437)
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
144 - `turkish` (code page 857)
145
146 `AMIGA` fonts can be (all case-sensitive):
147
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
148 - `amiga` (alias to Topaz)
149 - `microknight` (Original MicroKnight version)
4ecede8 @ByteProject can't believe there was a wrong font flag in docs, fixed now
ByteProject authored
150 - `microknight+` (Modified MicroKnight version)
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
151 - `mosoul` (Original mO'sOul font)
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
152 - `pot-noodle` (Original P0T-NOoDLE font)
153 - `topaz` (Original Topaz Kickstart 2.x version)
dcd2cc8 @ByteProject updated two AnsiLove font string values
ByteProject authored
154 - `topaz+` (Modified Topaz Kickstart 2.x+ version)
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
155 - `topaz500` (Original Topaz Kickstart 1.x version)
dcd2cc8 @ByteProject updated two AnsiLove font string values
ByteProject authored
156 - `topaz500+` (Modified Topaz Kickstart 1.x version)
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
157
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
158 If you don't set a `font` object either passing `nil` or an empty string to ALAnsiGenerator, AnsiLove.framework will generate images using `80x25`, which is the default DOS font.
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
159
160 ## (NSString *)bits
161
162 Bits can be (all case-sensitive):
163
164 - `8` (8-bit)
165 - `9` (9-bit)
166 - `ced`
167 - `transparent`
168 - `workbench`
169
170 Setting the bits to `9` will render the 9th column of block characters, so the output will look like it is displayed in real textmode.
171
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
172 Setting the bits to `ced` will cause the input file to be rendered in black on gray, and limit the output to 78 columns (only available for `.ans` files). Used together with an `AMIGA` font, the output will look like it is displayed on Amiga.
173
174 Setting the bits to `workbench` will cause the input file to be rendered using Amiga Workbench colors (only available for `.ans` files).
175
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
176 Settings the bits to `transparent` will produce output files with transparent background (only available for `.ans` files).
177
178 ## (NSString *)iceColors
179
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
180 Setting `iceColors` to `1` will enable iCE color codes. On the opposite `0` means that that `iceColors` are disabled, which is the default value. When an ANSi source was created using iCE colors, it was done with a special mode where the blinking was disabled, and you had 16 background colors available. Basically, you had the same choice for background colors as for foreground colors, that's iCE colors. But now the important part: when the ANSi source does not make specific use of iCE colors, you should NOT enable them. The file could look pretty weird in normal mode. So in most cases it's fine to turn iCE colors off.
181
182 ## (NSString *)columns
183
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
184 `columns` is only relevant for ANSi source files with `.BIN` extension and even for those files optional. In most cases conversion will work fine if you don't set this flag, the default value is `160` then. So please pass `columns` only to `.BIN` files and only if you exactly know what you're doing. The sun could explode or even worse: A KITTEN MAY DIE SOMEWHERE.
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
185
186 ## Supported options for each file type
187
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
188 Here's a simple overview of which file type supports which object. Note that ADF, IDF and XB sources don't support custom font objects as they come with embedded fonts:
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
189
190 ___________________________________________
191 | | | | | |
192 | | columns | font | bits | icecolors |
193 |_____|_________|_______|_______|___________|
194 | | | | | |
195 | ANS | | X | X | X |
196 |_____|_________|_______|_______|___________|
197 | | | | | |
198 | PCB | | X | X | X |
199 |_____|_________|_______|_______|___________|
200 | | | | | |
201 | BIN | X | X | X | X |
202 |_____|_________|_______|_______|___________|
203 | | | | | |
204 | ADF | | | | |
205 |_____|_________|_______|_______|___________|
206 | | | | | |
207 | IDF | | | | |
208 |_____|_________|_______|_______|___________|
209 | | | | | |
210 | TND | | X | X | |
211 |_____|_________|_______|_______|___________|
212 | | | | | |
213 | XB | | | | |
2b688b2 @ByteProject cosmetically change, table not displayed properly
ByteProject authored
214 |_____|_________|_______|_______|___________|
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
215
79c8b2b @ByteProject massive documentation update for ALSauceMachine
ByteProject authored
216 ## Rendering Process Feedback
3e5a24e @ByteProject added output file example section
ByteProject authored
217
08ecbf2 @ByteProject added documentation for rendering process feedback
ByteProject authored
218 AnsiLove.framework will post a notification once processing of given source files is finished. In most cases it's pretty important to know when rendering is done. One might want to present an informal dialog or update the UI afterwards. For making your app listen to the `AnsiLoveFinishedRendering` note, all you need is adding this to the `init` method of the class you consider as relevant:
219
220 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
221 [nc addObserver:self
222 selector:@selector(addYourCustomSelectorHere:)
223 name:@"AnsiLoveFinishedRendering"
224 object:nil];
225
226 The test app `AnsiLoveGUI` has a simple implementation that posts a message to NSLog as soon as the rendering is completed.
3e5a24e @ByteProject added output file example section
ByteProject authored
227
79c8b2b @ByteProject massive documentation update for ALSauceMachine
ByteProject authored
228 ## Output file example
ac83b58 @ByteProject supplemented App Sandboxing informations
ByteProject authored
229
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
230 You may wonder how the rendered output looks like? You'll find an example in regular resolution [here](http://cl.ly/1D0o1M2t2Y190v33462F/o).
79c8b2b @ByteProject massive documentation update for ALSauceMachine
ByteProject authored
231
232 # Reading SAUCE records
233
16c6415 @ByteProject raiders of the lost typo...!
ByteProject authored
234 The framework's class for dealing with SAUCE records is `ALSauceMachine`. But before we continue, here's your opportunity to introduce yourself to the [SAUCE specifications](http://www.acid.org/info/sauce/s_spec.htm). Plenty values retrieved from SAUCE records can be passed as objects to `ALAnsiGenerator`, so it makes sense indeed to check for a SAUCE record before you start rendering. Anyway, it's just a hint. Convenient yes, but by no means necessary. Enough theory, here is how to use the class. First we need to create an instance of `ALSauceMachine`:
79c8b2b @ByteProject massive documentation update for ALSauceMachine
ByteProject authored
235
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
236 ALSauceMachine *sauce = [ALSauceMachine new];
237
72fdd2a @ByteProject just one more typo and the sun will explode!
ByteProject authored
238 Of course `[[ALSauceMachine alloc] init];` will work fine as well. Now call `readRecordFromFile:`, this should be self-explanatory:
08ecbf2 @ByteProject added documentation for rendering process feedback
ByteProject authored
239
79c8b2b @ByteProject massive documentation update for ALSauceMachine
ByteProject authored
240 [sauce readRecordFromFile:myInputFile];
08ecbf2 @ByteProject added documentation for rendering process feedback
ByteProject authored
241
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
242 You probably guess that not all files contain SAUCE and you're right. Many ANSi files actually contain SAUCE (like [this file](http://sixteencolors.net/pack/acid-56/W7-R666.ANS)) and some just don't. So how do you know? I've implemented three handy BOOL values, they give you all the feedback you need:
79c8b2b @ByteProject massive documentation update for ALSauceMachine
ByteProject authored
243
244 BOOL fileHasRecord;
245 BOOL fileHasComments;
246 BOOL fileHasFlags;
247
4aa62c2 @ByteProject one more typo and I will just firebomb my Mac!
ByteProject authored
248 The first property, `fileHasRecord` stands above the others, which means if a file doesn't have a SAUCE record, it's evident it doesn't have SAUCE comments and flags. My advice: don't check `fileHasComments` and `fileHasFlags` if you already know there is no SAUCE record. Don't get my wrong, nothing will explode if you do so (not even the sun). But the answer will always be NO in that case so it's a waste of time. What if a file contains a SAUCE record on the other hand? It's nevertheless possible it doesn't have comments and flags. So if `fileHasRecord` is YES, you should try the other two BOOL values as well. Let's assume your class instance is still `*sauce` and you now checked for all three BOOL types, knowing the details. How to retrieve the SAUCE? Easy. `ALSauceMachine` stores the SAUCE record into properties, right at your fingertips:
79c8b2b @ByteProject massive documentation update for ALSauceMachine
ByteProject authored
249
250 NSString *ID;
251 NSString *version;
252 NSString *title;
253 NSString *author;
254 NSString *group;
255 NSString *date;
256 NSInteger dataType;
257 NSInteger fileType;
258 NSInteger tinfo1;
259 NSInteger tinfo2;
260 NSInteger tinfo3;
261 NSInteger tinfo4;
262 NSString *comments;
af5f902 @ByteProject what the....!?
ByteProject authored
263 NSInteger flags;
79c8b2b @ByteProject massive documentation update for ALSauceMachine
ByteProject authored
264
265 Now imagine you want to print SAUCE title and author in NSLog:
266
267 NSLog(@"This is: %@ by %@.", sauce.title, sauce.author);
268
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
269 That's it. If you feel like this introduction to AnsiLove.framework's SAUCE implementation left some of your questions unanswered, I suggest you take a closer look at `AnsiLoveGUI` (the sample app). It contains a full featured yet simple example how to use `ALSauceMachine`.
79c8b2b @ByteProject massive documentation update for ALSauceMachine
ByteProject authored
270
271 # App Sandboxing
272
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
273 The framework runs great in sandboxed apps. That is because I handcrafted it to be like that. No temporary exceptions, no hocus-pocus, just you on your lonely island. AnsiLove.framework comes with it's own tiny subsystem to achieve sandboxing compliance. Sounds like no big deal? Go sit on a tack. Actually that was the hardest part of the whole framework.
a1e5fb0 @ByteProject added 'Todo' section to documentation
ByteProject authored
274
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
275 # Retina support
276
b468baa @ByteProject another typo and I'm going to just firebomb my Mac
ByteProject authored
277 By investigating `ALAnsiGenerator` methods you already know this framework comes with full Retina support. Assuming you are familiar with Apple's [High Resolution Guidelines for OS X](http://developer.apple.com/library/mac/#documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Introduction/Introduction.html), there is not much more to say about the matter. Now it's up to you as developer.
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
278
d55272e @ByteProject readme for framework release 2.0.0
ByteProject authored
279 # Why?
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
280
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
281 AnsiLove.framework was created for my app [Escapes](http://escapes.byteproject.net).
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
282
283 # Credits
284
8280555 @ByteProject docs updated for the Retina implementation
ByteProject authored
285 I'd like to thank my friends [Frederic Cambus](http://www.cambus.net) and [Brian Cassidy](http://blog.alternation.net/) for their ongoing support. Both had a major impact on [AnsiLove/C](https://github.com/ByteProject/AnsiLove-C) and thus on AnsiLove.framework. While Fred is also responsible for [AnsiLove/C's](https://github.com/ByteProject/AnsiLove-C) well-known ancestor [AnsiLove/PHP](http://ansilove.sourceforge.net/), significant parts of Brian's [libsauce](https://github.com/bricas/libsauce) breathe life into `ALSauceMachine`. Finally I bow to all the great ANSi / ASCII lovers and artists around the world. You are the artscene. You keep alive what was not meant to die years ago. YOU ARE ROCKSTARS!
198c55f @ByteProject now THIS is what I call good documentation
ByteProject authored
286
287 # License
511ae14 @ByteProject added markdown read me
ByteProject authored
288
5ce9aa4 @ByteProject added Terminus to font string documentation, new license information
ByteProject authored
289 Ascension is released under a MIT-style license. See the file `LICENSE` for details.
Something went wrong with that request. Please try again.