Fixed errors and documented everything

This commit is contained in:
2014-12-05 03:04:46 +01:00
parent 340aa29d4a
commit a659c072da
22 changed files with 3958 additions and 153 deletions
+5 -2
View File
@@ -1,7 +1,7 @@
# Makefile for the nibbles lab. # Makefile for the nibbles lab.
# ---> Compile with gamke on BSD systems! <--- # ---> Compile with gamke on BSD systems! <---
all: nibbles_asm nibbles_asm_start all: nibbles_c nibbles_asm nibbles_asm_start
# Rule for compiling C source # Rule for compiling C source
.c.o: .c.o:
@@ -25,7 +25,10 @@ nibbles_asm: main.o nibbles.o helpers.o
nibbles_asm_start: start.o nibbles.o helpers.o nibbles_asm_start: start.o nibbles.o helpers.o
gcc -m32 -lcurses -lc -nostdlib $^ -o $@ gcc -m32 -lcurses -lc -nostdlib $^ -o $@
# Documentation
docs: cnibbles.c nibbles.S start.S
docco --languages=docco-languages.json $^
clean: clean:
rm -f *~
rm -f *.o rm -f *.o
rm -f nibbles_c nibbles_asm nibbles_asm_start rm -f nibbles_c nibbles_asm nibbles_asm_start
+30 -15
View File
@@ -22,6 +22,8 @@ void spawnApple();
void tick(); void tick();
void draw(); void draw();
// start_game
// ==========
void start_game(int len, int n_apples) void start_game(int len, int n_apples)
{ {
if (startLength == 0) if (startLength == 0)
@@ -36,8 +38,6 @@ void start_game(int len, int n_apples)
nib_init(); nib_init();
//printf("Started with worm length %i and %i apples!\n", snakeLength, numApples);
// Initialize the snake array // Initialize the snake array
// Set every cell to a time value greater than the snake length // Set every cell to a time value greater than the snake length
for (unsigned int i = 0; i < WIDTH*HEIGHT; ++i) { for (unsigned int i = 0; i < WIDTH*HEIGHT; ++i) {
@@ -69,6 +69,8 @@ void start_game(int len, int n_apples)
} }
} }
// spawnApple
// ==========
void spawnApple() void spawnApple()
{ {
unsigned int x = rand() % WIDTH; unsigned int x = rand() % WIDTH;
@@ -77,26 +79,30 @@ void spawnApple()
x = rand() % WIDTH; x = rand() % WIDTH;
y = rand() % HEIGHT; y = rand() % HEIGHT;
} }
//printf("Placing apple at (%i,%i)\n", x, y);
snake[x + y*WIDTH] = -1; snake[x + y*WIDTH] = -1;
} }
// tick
// ====
void tick() void tick()
{ {
currentTick++; currentTick++;
// Increment cell times // Increment cell times
// --------------------
for (unsigned int i = 0; i < WIDTH*HEIGHT; ++i) { for (unsigned int i = 0; i < WIDTH*HEIGHT; ++i) {
int val = snake[i]; int val = snake[i];
if (val < 0) { if (val < 0) {
// Apple lifetime // Apple lifetime
//snake[i]--; /* snake[i]--; */
} else if (val >= 0 && val <= snakeLength) { } else if (val >= 0 && val <= snakeLength) {
// Other cells // Other cells
snake[i]++; snake[i]++;
} }
} }
// Input
// -----
int key = nib_poll_kbd(); int key = nib_poll_kbd();
if (key == 'w' && snakeDirY != 1) { if (key == 'w' && snakeDirY != 1) {
snakeDirX = 0; snakeDirX = 0;
@@ -116,8 +122,12 @@ void tick()
} }
// Move snake // Move snake
// ----------
snakeX = (snakeX + snakeDirX + WIDTH) % WIDTH; snakeX = (snakeX + snakeDirX + WIDTH) % WIDTH;
snakeY = (snakeY + snakeDirY + HEIGHT) % HEIGHT; snakeY = (snakeY + snakeDirY + HEIGHT) % HEIGHT;
// Collision
// ---------
// On collision with self // On collision with self
int val = snake[snakeX + snakeY*WIDTH]; int val = snake[snakeX + snakeY*WIDTH];
if (val < snakeLength && val >= 0) { if (val < snakeLength && val >= 0) {
@@ -131,45 +141,50 @@ void tick()
// Increase our length! // Increase our length!
snakeLength++; snakeLength++;
} }
// Update world
// ------------
snake[snakeX + snakeY*WIDTH] = 0; snake[snakeX + snakeY*WIDTH] = 0;
} }
// draw
// ====
void draw() void draw()
{ {
char body[] = "NIBBLES"; char body[] = "NIBBLES";
for (int y = -1; y <= HEIGHT; ++y) { for (int y = -1; y <= HEIGHT; ++y) {
for (int x = -1; x <= WIDTH; ++x) { for (int x = -1; x <= WIDTH; ++x) {
// Draw a border outside the playing field
if (x == -1 || y == -1 || x == WIDTH || y == HEIGHT) { if (x == -1 || y == -1 || x == WIDTH || y == HEIGHT) {
if (x == -1 || y == -1) { unsigned int screenX = x + 1;
unsigned int screenX = x + 1; unsigned int screenY = y + 1;
unsigned int screenY = y + 1; nib_put_scr(screenX, screenY, '#');
nib_put_scr(screenX, screenY, '#');
} else {
unsigned int screenX = x + 1;
unsigned int screenY = y + 1;
nib_put_scr(screenX, screenY, '#');
}
} else { } else {
int snakeVal = snake[x + y*WIDTH]; int snakeVal = snake[x + y*WIDTH];
unsigned int screenX = x + 1; unsigned int screenX = x + 1;
unsigned int screenY = y + 1; unsigned int screenY = y + 1;
// If the `DEBUG` flag is set, draw the raw ASCII-value for debugging purposes
if (DEBUG) { if (DEBUG) {
nib_put_scr(screenX, screenY, '0' + snakeVal); nib_put_scr(screenX, screenY, '0' + snakeVal);
continue; continue;
} }
// If the value is greater than `0` and less than `snakeLength`, it's part of the snake
if (snakeVal >= 0 && snakeVal < snakeLength) { if (snakeVal >= 0 && snakeVal < snakeLength) {
if (x == snakeX && y == snakeY) { if (x == snakeX && y == snakeY) {
// Draw the head
nib_put_scr(screenX, screenY, '@'); nib_put_scr(screenX, screenY, '@');
} else { } else {
// Draw the body
nib_put_scr(screenX, screenY, body[(snakeVal - 1) % 7]); nib_put_scr(screenX, screenY, body[(snakeVal - 1) % 7]);
} }
} else if (snakeVal < 0) { } else if (snakeVal < 0) {
// If the value is less than `0`, it's an apple
nib_put_scr(screenX, screenY, 'o'); nib_put_scr(screenX, screenY, 'o');
} else { } else {
// Otherwise it's empty.
nib_put_scr(screenX, screenY, ' '); nib_put_scr(screenX, screenY, ' ');
} }
} }
+4
View File
@@ -0,0 +1,4 @@
{
".S": {"name": "x86asm", "symbol": "//"},
".c": {"name": "c", "symbol": "//"}
}
+693
View File
@@ -0,0 +1,693 @@
<!DOCTYPE html>
<html>
<head>
<title>cnibbles.c</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page">
<a class="source" href="cnibbles.html">
cnibbles.c
</a>
<a class="source" href="nibbles.html">
nibbles.S
</a>
<a class="source" href="start.html">
start.S
</a>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>cnibbles.c</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-preprocessor">#<span class="hljs-keyword">include</span> &lt;stdio.h&gt;</span>
<span class="hljs-preprocessor">#<span class="hljs-keyword">include</span> &lt;stdbool.h&gt;</span>
<span class="hljs-preprocessor">#<span class="hljs-keyword">include</span> "helpers.c"</span>
<span class="hljs-preprocessor">#<span class="hljs-keyword">define</span> WIDTH 60</span>
<span class="hljs-preprocessor">#<span class="hljs-keyword">define</span> HEIGHT 40</span>
<span class="hljs-preprocessor">#<span class="hljs-keyword">define</span> DEBUG false</span>
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> startLength = <span class="hljs-number">0</span>;
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> startApples = <span class="hljs-number">0</span>;
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> currentTick;
<span class="hljs-keyword">int</span> snake[WIDTH*HEIGHT];
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> snakeLength;
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> snakeX;
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> snakeY;
<span class="hljs-keyword">int</span> snakeDirX;
<span class="hljs-keyword">int</span> snakeDirY;
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> numApples;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">spawnApple</span><span class="hljs-params">()</span></span>;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">tick</span><span class="hljs-params">()</span></span>;
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">draw</span><span class="hljs-params">()</span></span>;</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<h1 id="start_game">start_game</h1>
</div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">start_game</span><span class="hljs-params">(<span class="hljs-keyword">int</span> len, <span class="hljs-keyword">int</span> n_apples)</span>
</span>{
<span class="hljs-keyword">if</span> (startLength == <span class="hljs-number">0</span>)
startLength = len;
<span class="hljs-keyword">if</span> (startApples == <span class="hljs-number">0</span>)
startApples = n_apples;</pre></div></div>
</li>
<li id="section-4">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>Initialize variables</p>
</div>
<div class="content"><div class='highlight'><pre> currentTick = <span class="hljs-number">0</span>;
snakeLength = len;
numApples = n_apples;
nib_init();</pre></div></div>
</li>
<li id="section-5">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>Initialize the snake array
Set every cell to a time value greater than the snake length</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; WIDTH*HEIGHT; ++i) {
snake[i] = snakeLength;
}</pre></div></div>
</li>
<li id="section-6">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>Place the snake head in the middle</p>
</div>
<div class="content"><div class='highlight'><pre> snakeX = WIDTH / <span class="hljs-number">2</span>;
snakeY = HEIGHT / <span class="hljs-number">2</span>;
snakeDirX = <span class="hljs-number">0</span>;
snakeDirY = -<span class="hljs-number">1</span>;</pre></div></div>
</li>
<li id="section-7">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>Place the initial snake segments, downwards or something</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; snakeLength; ++i) {
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> x = snakeX % WIDTH;
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> y = (snakeY + i) % HEIGHT;
snake[x + y*WIDTH] = i;
}</pre></div></div>
</li>
<li id="section-8">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>Place apples</p>
</div>
<div class="content"><div class='highlight'><pre> srand(time(<span class="hljs-number">0</span>));
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; numApples; ++i) {
spawnApple();
}
<span class="hljs-keyword">while</span> (<span class="hljs-keyword">true</span>) {
tick();
draw();
}
}</pre></div></div>
</li>
<li id="section-9">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<h1 id="spawnapple">spawnApple</h1>
</div>
</li>
<li id="section-10">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">spawnApple</span><span class="hljs-params">()</span>
</span>{
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> x = rand() % WIDTH;
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> y = rand() % HEIGHT;
<span class="hljs-keyword">while</span> (snake[x + y*WIDTH] &lt; snakeLength) {
x = rand() % WIDTH;
y = rand() % HEIGHT;
}
snake[x + y*WIDTH] = -<span class="hljs-number">1</span>;
}</pre></div></div>
</li>
<li id="section-11">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<h1 id="tick">tick</h1>
</div>
</li>
<li id="section-12">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">tick</span><span class="hljs-params">()</span>
</span>{
currentTick++;</pre></div></div>
</li>
<li id="section-13">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<h2 id="increment-cell-times">Increment cell times</h2>
</div>
</li>
<li id="section-14">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; WIDTH*HEIGHT; ++i) {
<span class="hljs-keyword">int</span> val = snake[i];
<span class="hljs-keyword">if</span> (val &lt; <span class="hljs-number">0</span>) {</pre></div></div>
</li>
<li id="section-15">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>Apple lifetime</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-comment">/* snake[i]--; */</span>
} <span class="hljs-function"><span class="hljs-keyword">else</span> <span class="hljs-title">if</span> <span class="hljs-params">(val &gt;= 0 &amp;&amp; val &lt;= snakeLength)</span> </span>{</pre></div></div>
</li>
<li id="section-16">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</a>
</div>
<p>Other cells</p>
</div>
<div class="content"><div class='highlight'><pre> snake[i]++;
}
}</pre></div></div>
</li>
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<h2 id="input">Input</h2>
</div>
</li>
<li id="section-18">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">int</span> key = nib_poll_kbd();
<span class="hljs-keyword">if</span> (key == <span class="hljs-string">'w'</span> &amp;&amp; snakeDirY != <span class="hljs-number">1</span>) {
snakeDirX = <span class="hljs-number">0</span>;
snakeDirY = -<span class="hljs-number">1</span>;
}
<span class="hljs-keyword">if</span> (key == <span class="hljs-string">'s'</span> &amp;&amp; snakeDirY != -<span class="hljs-number">1</span>) {
snakeDirX = <span class="hljs-number">0</span>;
snakeDirY = <span class="hljs-number">1</span>;
}
<span class="hljs-keyword">if</span> (key == <span class="hljs-string">'a'</span> &amp;&amp; snakeDirX != <span class="hljs-number">1</span>) {
snakeDirX = -<span class="hljs-number">1</span>;
snakeDirY = <span class="hljs-number">0</span>;
}
<span class="hljs-keyword">if</span> (key == <span class="hljs-string">'d'</span> &amp;&amp; snakeDirX != -<span class="hljs-number">1</span>) {
snakeDirX = <span class="hljs-number">1</span>;
snakeDirY = <span class="hljs-number">0</span>;
}</pre></div></div>
</li>
<li id="section-19">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-19">&#182;</a>
</div>
<h2 id="move-snake">Move snake</h2>
</div>
</li>
<li id="section-20">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-20">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre> snakeX = (snakeX + snakeDirX + WIDTH) % WIDTH;
snakeY = (snakeY + snakeDirY + HEIGHT) % HEIGHT;</pre></div></div>
</li>
<li id="section-21">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-21">&#182;</a>
</div>
<h2 id="collision">Collision</h2>
</div>
</li>
<li id="section-22">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-22">&#182;</a>
</div>
<p>On collision with self</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">int</span> val = snake[snakeX + snakeY*WIDTH];
<span class="hljs-keyword">if</span> (val &lt; snakeLength &amp;&amp; val &gt;= <span class="hljs-number">0</span>) {</pre></div></div>
</li>
<li id="section-23">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-23">&#182;</a>
</div>
<p>nib_end();</p>
</div>
<div class="content"><div class='highlight'><pre> start_game(startLength, startApples);
}</pre></div></div>
</li>
<li id="section-24">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-24">&#182;</a>
</div>
<p>ON collision with apple</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (val &lt; <span class="hljs-number">0</span>) {</pre></div></div>
</li>
<li id="section-25">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-25">&#182;</a>
</div>
<p>Spawn a new apple somewhere</p>
</div>
<div class="content"><div class='highlight'><pre> spawnApple();</pre></div></div>
</li>
<li id="section-26">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-26">&#182;</a>
</div>
<p>Increase our length!</p>
</div>
<div class="content"><div class='highlight'><pre> snakeLength++;
}</pre></div></div>
</li>
<li id="section-27">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-27">&#182;</a>
</div>
<h2 id="update-world">Update world</h2>
</div>
</li>
<li id="section-28">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-28">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre> snake[snakeX + snakeY*WIDTH] = <span class="hljs-number">0</span>;
}</pre></div></div>
</li>
<li id="section-29">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-29">&#182;</a>
</div>
<h1 id="draw">draw</h1>
</div>
</li>
<li id="section-30">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-30">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">draw</span><span class="hljs-params">()</span>
</span>{
<span class="hljs-keyword">char</span> body[] = <span class="hljs-string">"NIBBLES"</span>;
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> y = -<span class="hljs-number">1</span>; y &lt;= HEIGHT; ++y) {
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> x = -<span class="hljs-number">1</span>; x &lt;= WIDTH; ++x) {</pre></div></div>
</li>
<li id="section-31">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-31">&#182;</a>
</div>
<p>Draw a border outside the playing field</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (x == -<span class="hljs-number">1</span> || y == -<span class="hljs-number">1</span> || x == WIDTH || y == HEIGHT) {
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> screenX = x + <span class="hljs-number">1</span>;
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> screenY = y + <span class="hljs-number">1</span>;
nib_put_scr(screenX, screenY, <span class="hljs-string">'#'</span>);
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">int</span> snakeVal = snake[x + y*WIDTH];
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> screenX = x + <span class="hljs-number">1</span>;
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> screenY = y + <span class="hljs-number">1</span>;</pre></div></div>
</li>
<li id="section-32">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-32">&#182;</a>
</div>
<p>If the <code>DEBUG</code> flag is set, draw the raw ASCII-value for debugging purposes</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (DEBUG) {
nib_put_scr(screenX, screenY, <span class="hljs-string">'0'</span> + snakeVal);
<span class="hljs-keyword">continue</span>;
}</pre></div></div>
</li>
<li id="section-33">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-33">&#182;</a>
</div>
<p>If the value is greater than <code>0</code> and less than <code>snakeLength</code>, its part of the snake</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (snakeVal &gt;= <span class="hljs-number">0</span> &amp;&amp; snakeVal &lt; snakeLength) {
<span class="hljs-keyword">if</span> (x == snakeX &amp;&amp; y == snakeY) {</pre></div></div>
</li>
<li id="section-34">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-34">&#182;</a>
</div>
<p>Draw the head</p>
</div>
<div class="content"><div class='highlight'><pre> nib_put_scr(screenX, screenY, <span class="hljs-string">'@'</span>);
} <span class="hljs-keyword">else</span> {</pre></div></div>
</li>
<li id="section-35">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-35">&#182;</a>
</div>
<p>Draw the body</p>
</div>
<div class="content"><div class='highlight'><pre> nib_put_scr(screenX, screenY, body[(snakeVal - <span class="hljs-number">1</span>) % <span class="hljs-number">7</span>]);
}
} <span class="hljs-function"><span class="hljs-keyword">else</span> <span class="hljs-title">if</span> <span class="hljs-params">(snakeVal &lt; 0)</span> </span>{</pre></div></div>
</li>
<li id="section-36">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-36">&#182;</a>
</div>
<p>If the value is less than <code>0</code>, its an apple</p>
</div>
<div class="content"><div class='highlight'><pre> nib_put_scr(screenX, screenY, <span class="hljs-string">'o'</span>);
} <span class="hljs-keyword">else</span> {</pre></div></div>
</li>
<li id="section-37">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-37">&#182;</a>
</div>
<p>Otherwise its empty.</p>
</div>
<div class="content"><div class='highlight'><pre> nib_put_scr(screenX, screenY, <span class="hljs-string">' '</span>);
}
}
}
}
}</pre></div></div>
</li>
</ul>
</div>
</body>
</html>
+506
View File
@@ -0,0 +1,506 @@
/*--------------------- Typography ----------------------------*/
@font-face {
font-family: 'aller-light';
src: url('public/fonts/aller-light.eot');
src: url('public/fonts/aller-light.eot?#iefix') format('embedded-opentype'),
url('public/fonts/aller-light.woff') format('woff'),
url('public/fonts/aller-light.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'aller-bold';
src: url('public/fonts/aller-bold.eot');
src: url('public/fonts/aller-bold.eot?#iefix') format('embedded-opentype'),
url('public/fonts/aller-bold.woff') format('woff'),
url('public/fonts/aller-bold.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'novecento-bold';
src: url('public/fonts/novecento-bold.eot');
src: url('public/fonts/novecento-bold.eot?#iefix') format('embedded-opentype'),
url('public/fonts/novecento-bold.woff') format('woff'),
url('public/fonts/novecento-bold.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
/*--------------------- Layout ----------------------------*/
html { height: 100%; }
body {
font-family: "aller-light";
font-size: 14px;
line-height: 18px;
color: #30404f;
margin: 0; padding: 0;
height:100%;
}
#container { min-height: 100%; }
a {
color: #000;
}
b, strong {
font-weight: normal;
font-family: "aller-bold";
}
p {
margin: 15px 0 0px;
}
.annotation ul, .annotation ol {
margin: 25px 0;
}
.annotation ul li, .annotation ol li {
font-size: 14px;
line-height: 18px;
margin: 10px 0;
}
h1, h2, h3, h4, h5, h6 {
color: #112233;
line-height: 1em;
font-weight: normal;
font-family: "novecento-bold";
text-transform: uppercase;
margin: 30px 0 15px 0;
}
h1 {
margin-top: 40px;
}
hr {
border: 0;
background: 1px #ddd;
height: 1px;
margin: 20px 0;
}
pre, tt, code {
font-size: 12px; line-height: 16px;
font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
margin: 0; padding: 0;
}
.annotation pre {
display: block;
margin: 0;
padding: 7px 10px;
background: #fcfcfc;
-moz-box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
-webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
overflow-x: auto;
}
.annotation pre code {
border: 0;
padding: 0;
background: transparent;
}
blockquote {
border-left: 5px solid #ccc;
margin: 0;
padding: 1px 0 1px 1em;
}
.sections blockquote p {
font-family: Menlo, Consolas, Monaco, monospace;
font-size: 12px; line-height: 16px;
color: #999;
margin: 10px 0 0;
white-space: pre-wrap;
}
ul.sections {
list-style: none;
padding:0 0 5px 0;;
margin:0;
}
/*
Force border-box so that % widths fit the parent
container without overlap because of margin/padding.
More Info : http://www.quirksmode.org/css/box.html
*/
ul.sections > li > div {
-moz-box-sizing: border-box; /* firefox */
-ms-box-sizing: border-box; /* ie */
-webkit-box-sizing: border-box; /* webkit */
-khtml-box-sizing: border-box; /* konqueror */
box-sizing: border-box; /* css3 */
}
/*---------------------- Jump Page -----------------------------*/
#jump_to, #jump_page {
margin: 0;
background: white;
-webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
-webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
font: 16px Arial;
cursor: pointer;
text-align: right;
list-style: none;
}
#jump_to a {
text-decoration: none;
}
#jump_to a.large {
display: none;
}
#jump_to a.small {
font-size: 22px;
font-weight: bold;
color: #676767;
}
#jump_to, #jump_wrapper {
position: fixed;
right: 0; top: 0;
padding: 10px 15px;
margin:0;
}
#jump_wrapper {
display: none;
padding:0;
}
#jump_to:hover #jump_wrapper {
display: block;
}
#jump_page {
padding: 5px 0 3px;
margin: 0 0 25px 25px;
}
#jump_page .source {
display: block;
padding: 15px;
text-decoration: none;
border-top: 1px solid #eee;
}
#jump_page .source:hover {
background: #f5f5ff;
}
#jump_page .source:first-child {
}
/*---------------------- Low resolutions (> 320px) ---------------------*/
@media only screen and (min-width: 320px) {
.pilwrap { display: none; }
ul.sections > li > div {
display: block;
padding:5px 10px 0 10px;
}
ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {
padding-left: 30px;
}
ul.sections > li > div.content {
overflow-x:auto;
-webkit-box-shadow: inset 0 0 5px #e5e5ee;
box-shadow: inset 0 0 5px #e5e5ee;
border: 1px solid #dedede;
margin:5px 10px 5px 10px;
padding-bottom: 5px;
}
ul.sections > li > div.annotation pre {
margin: 7px 0 7px;
padding-left: 15px;
}
ul.sections > li > div.annotation p tt, .annotation code {
background: #f8f8ff;
border: 1px solid #dedede;
font-size: 12px;
padding: 0 0.2em;
}
}
/*---------------------- (> 481px) ---------------------*/
@media only screen and (min-width: 481px) {
#container {
position: relative;
}
body {
background-color: #F5F5FF;
font-size: 15px;
line-height: 21px;
}
pre, tt, code {
line-height: 18px;
}
p, ul, ol {
margin: 0 0 15px;
}
#jump_to {
padding: 5px 10px;
}
#jump_wrapper {
padding: 0;
}
#jump_to, #jump_page {
font: 10px Arial;
text-transform: uppercase;
}
#jump_page .source {
padding: 5px 10px;
}
#jump_to a.large {
display: inline-block;
}
#jump_to a.small {
display: none;
}
#background {
position: absolute;
top: 0; bottom: 0;
width: 350px;
background: #fff;
border-right: 1px solid #e5e5ee;
z-index: -1;
}
ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {
padding-left: 40px;
}
ul.sections > li {
white-space: nowrap;
}
ul.sections > li > div {
display: inline-block;
}
ul.sections > li > div.annotation {
max-width: 350px;
min-width: 350px;
min-height: 5px;
padding: 13px;
overflow-x: hidden;
white-space: normal;
vertical-align: top;
text-align: left;
}
ul.sections > li > div.annotation pre {
margin: 15px 0 15px;
padding-left: 15px;
}
ul.sections > li > div.content {
padding: 13px;
vertical-align: top;
border: none;
-webkit-box-shadow: none;
box-shadow: none;
}
.pilwrap {
position: relative;
display: inline;
}
.pilcrow {
font: 12px Arial;
text-decoration: none;
color: #454545;
position: absolute;
top: 3px; left: -20px;
padding: 1px 2px;
opacity: 0;
-webkit-transition: opacity 0.2s linear;
}
.for-h1 .pilcrow {
top: 47px;
}
.for-h2 .pilcrow, .for-h3 .pilcrow, .for-h4 .pilcrow {
top: 35px;
}
ul.sections > li > div.annotation:hover .pilcrow {
opacity: 1;
}
}
/*---------------------- (> 1025px) ---------------------*/
@media only screen and (min-width: 1025px) {
body {
font-size: 16px;
line-height: 24px;
}
#background {
width: 525px;
}
ul.sections > li > div.annotation {
max-width: 525px;
min-width: 525px;
padding: 10px 25px 1px 50px;
}
ul.sections > li > div.content {
padding: 9px 15px 16px 25px;
}
}
/*---------------------- Syntax Highlighting -----------------------------*/
td.linenos { background-color: #f0f0f0; padding-right: 10px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
/*
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
*/
pre code {
display: block; padding: 0.5em;
color: #000;
background: #f8f8ff
}
pre .hljs-comment,
pre .hljs-template_comment,
pre .hljs-diff .hljs-header,
pre .hljs-javadoc {
color: #408080;
font-style: italic
}
pre .hljs-keyword,
pre .hljs-assignment,
pre .hljs-literal,
pre .hljs-css .hljs-rule .hljs-keyword,
pre .hljs-winutils,
pre .hljs-javascript .hljs-title,
pre .hljs-lisp .hljs-title,
pre .hljs-subst {
color: #954121;
/*font-weight: bold*/
}
pre .hljs-number,
pre .hljs-hexcolor {
color: #40a070
}
pre .hljs-string,
pre .hljs-tag .hljs-value,
pre .hljs-phpdoc,
pre .hljs-tex .hljs-formula {
color: #219161;
}
pre .hljs-title,
pre .hljs-id {
color: #19469D;
}
pre .hljs-params {
color: #00F;
}
pre .hljs-javascript .hljs-title,
pre .hljs-lisp .hljs-title,
pre .hljs-subst {
font-weight: normal
}
pre .hljs-class .hljs-title,
pre .hljs-haskell .hljs-label,
pre .hljs-tex .hljs-command {
color: #458;
font-weight: bold
}
pre .hljs-tag,
pre .hljs-tag .hljs-title,
pre .hljs-rules .hljs-property,
pre .hljs-django .hljs-tag .hljs-keyword {
color: #000080;
font-weight: normal
}
pre .hljs-attribute,
pre .hljs-variable,
pre .hljs-instancevar,
pre .hljs-lisp .hljs-body {
color: #008080
}
pre .hljs-regexp {
color: #B68
}
pre .hljs-class {
color: #458;
font-weight: bold
}
pre .hljs-symbol,
pre .hljs-ruby .hljs-symbol .hljs-string,
pre .hljs-ruby .hljs-symbol .hljs-keyword,
pre .hljs-ruby .hljs-symbol .hljs-keymethods,
pre .hljs-lisp .hljs-keyword,
pre .hljs-tex .hljs-special,
pre .hljs-input_number {
color: #990073
}
pre .hljs-builtin,
pre .hljs-constructor,
pre .hljs-built_in,
pre .hljs-lisp .hljs-title {
color: #0086b3
}
pre .hljs-preprocessor,
pre .hljs-pi,
pre .hljs-doctype,
pre .hljs-shebang,
pre .hljs-cdata {
color: #999;
font-weight: bold
}
pre .hljs-deletion {
background: #fdd
}
pre .hljs-addition {
background: #dfd
}
pre .hljs-diff .hljs-change {
background: #0086b3
}
pre .hljs-chunk {
color: #aaa
}
pre .hljs-tex .hljs-formula {
opacity: 0.5;
}
+1966
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+375
View File
@@ -0,0 +1,375 @@
/*! normalize.css v2.0.1 | MIT License | git.io/normalize */
/* ==========================================================================
HTML5 display definitions
========================================================================== */
/*
* Corrects `block` display not defined in IE 8/9.
*/
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
nav,
section,
summary {
display: block;
}
/*
* Corrects `inline-block` display not defined in IE 8/9.
*/
audio,
canvas,
video {
display: inline-block;
}
/*
* Prevents modern browsers from displaying `audio` without controls.
* Remove excess height in iOS 5 devices.
*/
audio:not([controls]) {
display: none;
height: 0;
}
/*
* Addresses styling for `hidden` attribute not present in IE 8/9.
*/
[hidden] {
display: none;
}
/* ==========================================================================
Base
========================================================================== */
/*
* 1. Sets default font family to sans-serif.
* 2. Prevents iOS text size adjust after orientation change, without disabling
* user zoom.
*/
html {
font-family: sans-serif; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
-ms-text-size-adjust: 100%; /* 2 */
}
/*
* Removes default margin.
*/
body {
margin: 0;
}
/* ==========================================================================
Links
========================================================================== */
/*
* Addresses `outline` inconsistency between Chrome and other browsers.
*/
a:focus {
outline: thin dotted;
}
/*
* Improves readability when focused and also mouse hovered in all browsers.
*/
a:active,
a:hover {
outline: 0;
}
/* ==========================================================================
Typography
========================================================================== */
/*
* Addresses `h1` font sizes within `section` and `article` in Firefox 4+,
* Safari 5, and Chrome.
*/
h1 {
font-size: 2em;
}
/*
* Addresses styling not present in IE 8/9, Safari 5, and Chrome.
*/
abbr[title] {
border-bottom: 1px dotted;
}
/*
* Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
*/
b,
strong {
font-weight: bold;
}
/*
* Addresses styling not present in Safari 5 and Chrome.
*/
dfn {
font-style: italic;
}
/*
* Addresses styling not present in IE 8/9.
*/
mark {
background: #ff0;
color: #000;
}
/*
* Corrects font family set oddly in Safari 5 and Chrome.
*/
code,
kbd,
pre,
samp {
font-family: monospace, serif;
font-size: 1em;
}
/*
* Improves readability of pre-formatted text in all browsers.
*/
pre {
white-space: pre;
white-space: pre-wrap;
word-wrap: break-word;
}
/*
* Sets consistent quote types.
*/
q {
quotes: "\201C" "\201D" "\2018" "\2019";
}
/*
* Addresses inconsistent and variable font size in all browsers.
*/
small {
font-size: 80%;
}
/*
* Prevents `sub` and `sup` affecting `line-height` in all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
/* ==========================================================================
Embedded content
========================================================================== */
/*
* Removes border when inside `a` element in IE 8/9.
*/
img {
border: 0;
}
/*
* Corrects overflow displayed oddly in IE 9.
*/
svg:not(:root) {
overflow: hidden;
}
/* ==========================================================================
Figures
========================================================================== */
/*
* Addresses margin not present in IE 8/9 and Safari 5.
*/
figure {
margin: 0;
}
/* ==========================================================================
Forms
========================================================================== */
/*
* Define consistent border, margin, and padding.
*/
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
/*
* 1. Corrects color not being inherited in IE 8/9.
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
*/
legend {
border: 0; /* 1 */
padding: 0; /* 2 */
}
/*
* 1. Corrects font family not being inherited in all browsers.
* 2. Corrects font size not being inherited in all browsers.
* 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome
*/
button,
input,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 2 */
margin: 0; /* 3 */
}
/*
* Addresses Firefox 4+ setting `line-height` on `input` using `!important` in
* the UA stylesheet.
*/
button,
input {
line-height: normal;
}
/*
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
* and `video` controls.
* 2. Corrects inability to style clickable `input` types in iOS.
* 3. Improves usability and consistency of cursor style between image-type
* `input` and others.
*/
button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button; /* 2 */
cursor: pointer; /* 3 */
}
/*
* Re-set default cursor for disabled elements.
*/
button[disabled],
input[disabled] {
cursor: default;
}
/*
* 1. Addresses box sizing set to `content-box` in IE 8/9.
* 2. Removes excess padding in IE 8/9.
*/
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/*
* 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.
* 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
* (include `-moz` to future-proof).
*/
input[type="search"] {
-webkit-appearance: textfield; /* 1 */
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box; /* 2 */
box-sizing: content-box;
}
/*
* Removes inner padding and search cancel button in Safari 5 and Chrome
* on OS X.
*/
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/*
* Removes inner padding and border in Firefox 4+.
*/
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
/*
* 1. Removes default vertical scrollbar in IE 8/9.
* 2. Improves readability and alignment in all browsers.
*/
textarea {
overflow: auto; /* 1 */
vertical-align: top; /* 2 */
}
/* ==========================================================================
Tables
========================================================================== */
/*
* Remove most spacing between table cells.
*/
table {
border-collapse: collapse;
border-spacing: 0;
}
+157
View File
@@ -0,0 +1,157 @@
<!DOCTYPE html>
<html>
<head>
<title>start.S</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page">
<a class="source" href="cnibbles.html">
cnibbles.c
</a>
<a class="source" href="nibbles.html">
nibbles.S
</a>
<a class="source" href="start.html">
start.S
</a>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>start.S</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-string">.text</span></pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<h1 id="_start">_start</h1>
</div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>The <code>_start</code> symbol. Calls <code>start_game</code> with “reasonable parameters”.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-string">.global</span> _start
<span class="hljs-label">_start:</span></pre></div></div>
</li>
<li id="section-4">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p><code>n_apples</code></p>
</div>
<div class="content"><div class='highlight'><pre> pushl <span class="hljs-number">$10</span></pre></div></div>
</li>
<li id="section-5">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p><code>len</code></p>
</div>
<div class="content"><div class='highlight'><pre> pushl <span class="hljs-number">$3</span></pre></div></div>
</li>
<li id="section-6">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p><code>start_game(int len, int n_apples)</code></p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">call</span> start_game
addl <span class="hljs-number">$4</span>*<span class="hljs-number">2</span>, %<span class="hljs-literal">esp</span></pre></div></div>
</li>
<li id="section-7">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>Exit cleanly with an exit code of 0</p>
</div>
<div class="content"><div class='highlight'><pre> pushl <span class="hljs-number">$0</span>
<span class="hljs-keyword">call</span> _exit</pre></div></div>
</li>
</ul>
</div>
</body>
</html>
+212 -131
View File
@@ -1,50 +1,80 @@
// by Simon Holmberg
//
// This is a document generated by [docco](http://jashkenas.github.io/docco/).
// My report is interleaved with the source code in the form of comments in
// [markdown](http://daringfireball.net/projects/markdown/) format.
//
//
#define WIDTH 60 #define WIDTH 60
#define HEIGHT 40 #define HEIGHT 40
// .bss
// ====
.bss .bss
// Array of longs representing the game field // Array of longs representing the game field
//
// `world` is an array of increasing time values. By having the snake head set
// the time value to 0 at its current position, the actual **snake** will be
// defined by the locations where the time value is lesser than the snake
// length. This makes the tail of the snake automatically "move" visually, and
// allows for a snake with an arbitrary length without complicated arrays of
// coordinates!
//
// **Apples** are defined by negative time values which do not get incremented
// each frame. If we wanted to, we could instead decrease this value and
// compare it with a lifetime value, to conveniently make apples disappear
// after a set amount of time.
.align 4 .align 4
world: .space WIDTH*HEIGHT*4 world: .space WIDTH*HEIGHT*4
// .data
// =====
.data .data
// Current length of the snake // Current length of the snake
snakeLength: .long 0 snakeLength: .long 0
// Snake position // Snake position (starts in the middle of the field)
snakePosX: .long WIDTH / 2 snakePosX: .long WIDTH / 2
snakePosY: .long HEIGHT / 2 snakePosY: .long HEIGHT / 2
// Snake direction // Snake direction (start moving to the right)
snakeDirX: .long 1 snakeDirX: .long 1
snakeDirY: .long 0 snakeDirY: .long 0
// Number of apples // Number of apples
numApples: .long 0 numApples: .long 0
// Optional score-keeping // Game over message
score: .long 0
// Utility strings
snibbles: .ascii "NIBBLES"
snibbles_end:
sgameover: .string " Game over! Score: %i " sgameover: .string " Game over! Score: %i "
sgameover_end: sgameover_end:
// Various utility strings mainly used for debugging
string1: .string "Started with snake length %i and %i apples!\n" string1: .string "Started with snake length %i and %i apples!\n"
string2: .string "Snake position: (%i, %i)\n" string2: .string "Snake position: (%i, %i)\n"
stringi: .string "%i\n" stringi: .string "%i\n"
stringtest: .string "> %i %i %c\n" stringtest: .string "> %i %i %c\n"
// .text
// =====
.text .text
// start_game
// ============
// `start_game(int len, int n_apples)`
.global start_game .global start_game
start_game: start_game:
// snakeLength = len // Initialization
// --------------
// Save our function arguments for later
// `snakeLength = len`
movl 4(%esp), %eax movl 4(%esp), %eax
movl %eax, snakeLength movl %eax, snakeLength
// numApples = n_apples // `numApples = n_apples`
movl 8(%esp), %eax movl 8(%esp), %eax
movl %eax, numApples movl %eax, numApples
pushl %ebx // Store all registers so we can restore their state before we return later
pushl %edi pusha
// Call nib_init // Call nib_init
call nib_init call nib_init
// Seed randomness // Seed randomness by calling `srand` with a time value from `time`
pushl $0 pushl $0
call time call time
addl $4, %esp addl $4, %esp
@@ -52,22 +82,8 @@ start_game:
call srand call srand
addl $4, %esp addl $4, %esp
// Print our arguments // Initialize the snake array by setting every cell to a time value greater
//pushl numApples // than `snakeLength`
//pushl snakeLength
//pushl $string1
//call printf
//addl $4*3, %esp
// Print worm position
//pushl snakePosY
//pushl snakePosX
//pushl $string2
//call printf
//addl $4*3, %esp
// Initialize the snake array
// Set every cell to a time value greater than the snake length
movl $world, %edi movl $world, %edi
movl snakeLength, %eax movl snakeLength, %eax
movl $WIDTH*HEIGHT, %ebx movl $WIDTH*HEIGHT, %ebx
@@ -86,25 +102,33 @@ start_game:
popl %ecx popl %ecx
loop 1b loop 1b
// Loop forever // Game loop
// ---------
loop: loop:
// Sleep for a while // Sleep for a while using `usleep` so the snake doesn't wiggle at the
// speed of light!
pushl $250*1000 pushl $250*1000
pushl %ecx
call usleep call usleep
addl $4, %esp addl $4, %esp
// Jump to `tick`, our updating function, which later chain-jumps to `draw`
jmp tick jmp tick
popl %edi // Restore all our registers as they were before `start_game` was called
popl %ebx // and return
popa
ret ret
// Update stuff // tick
// ====
// This is where we update the world.
tick: tick:
movl $world, %edi movl $world, %edi
// Increment cell times // Increment cell times
// --------------------
// Loop
movl snakeLength, %ebx movl snakeLength, %ebx
xorl %ecx, %ecx xorl %ecx, %ecx
1: 1:
@@ -123,6 +147,9 @@ tick:
jne 1b jne 1b
// Input // Input
// -----
// Call nib_poll_kbd and check down, up, left and right in succession
call nib_poll_kbd call nib_poll_kbd
// Down // Down
movl $258, %ebx movl $258, %ebx
@@ -130,20 +157,20 @@ tick:
jne 1f jne 1f
movl $0, snakeDirX movl $0, snakeDirX
movl $1, snakeDirY movl $1, snakeDirY
1: // Up // Up
movl $259, %ebx 1: movl $259, %ebx
cmpl %eax, %ebx cmpl %eax, %ebx
jne 1f jne 1f
movl $0, snakeDirX movl $0, snakeDirX
movl $-1, snakeDirY movl $-1, snakeDirY
1: // Left // Left
movl $260, %ebx 1: movl $260, %ebx
cmpl %eax, %ebx cmpl %eax, %ebx
jne 1f jne 1f
movl $-1, snakeDirX movl $-1, snakeDirX
movl $0, snakeDirY movl $0, snakeDirY
1: // Right // Right
movl $261, %ebx 1: movl $261, %ebx
cmpl %eax, %ebx cmpl %eax, %ebx
jne 1f jne 1f
movl $1, snakeDirX movl $1, snakeDirX
@@ -151,25 +178,32 @@ tick:
1: 1:
// Move snake // Move snake
// snakePosX = (snakePosX + snakeDirY + WIDTH) % WIDTH // ----------
// `snakePosX = (snakePosX + snakeDirY + WIDTH) % WIDTH`
movl snakePosX, %eax movl snakePosX, %eax
movl snakeDirX, %ebx movl snakeDirX, %ebx
addl %ebx, %eax addl %ebx, %eax
addl $WIDTH, %eax // For modulo wrap-around // Add width for modulo wrap-around
addl $WIDTH, %eax
xorl %edx, %edx xorl %edx, %edx
movl $WIDTH, %ecx movl $WIDTH, %ecx
divl %ecx divl %ecx
mov %edx, snakePosX mov %edx, snakePosX
// snakePosY = (snakePosY + snakeDirY + HEIGHT) % HEIGHT // `snakePosY = (snakePosY + snakeDirY + HEIGHT) % HEIGHT`
movl snakePosY, %eax movl snakePosY, %eax
movl snakeDirY, %ebx movl snakeDirY, %ebx
addl %ebx, %eax addl %ebx, %eax
addl $HEIGHT, %eax // For modulo wrap-around // Add height for modulo wrap-around
addl $HEIGHT, %eax
xorl %edx, %edx xorl %edx, %edx
movl $HEIGHT, %ecx movl $HEIGHT, %ecx
divl %ecx divl %ecx
mov %edx, snakePosY mov %edx, snakePosY
// Collision
// ---------
// Get value at head position // Get value at head position
movl snakePosY, %eax movl snakePosY, %eax
movl $WIDTH, %edx movl $WIDTH, %edx
@@ -180,36 +214,42 @@ tick:
// Collision with apple if negative // Collision with apple if negative
test %edx, %edx test %edx, %edx
js 1f js 1f
// No need to increment if it's already greater than snakeLength // Compare value with `snakeLength`
movl snakeLength, %ebx movl snakeLength, %ebx
cmpl %ebx, %edx cmpl %ebx, %edx
jg 2f // End the game if the snake collides with itself, i.e. `%edx < snakeLength`
// End the game when the snake collides with itself jge 2f
jmp gameOver jmp gameOver
1: // Spawn a new apple // Spawn a new apple and extend the snake!
pushl %edi 1: pushl %edi
pushl %eax pushl %eax
call spawnApple call spawnApple
popl %eax popl %eax
popl %edi popl %edi
// Extend the snake!
incl snakeLength incl snakeLength
2: 2:
// Update world
// ------------
// Set time value to 0 at snake head position // Set time value to 0 at snake head position
// i = x + y * WIDTH //
// %edi = %ebx + %ecx * $WIDTH // `i = x + y * WIDTH`
//
// `%edi = %ebx + %ecx * $WIDTH`
movl $0, (%edi, %eax, 4) movl $0, (%edi, %eax, 4)
// Proceed to `draw`
jmp draw jmp draw
//jmp debug_draw //jmp debug_draw
// Draw stuff // draw
// ====
draw: draw:
// Loop Y // Loop on Y-axis
movl $HEIGHT, %ecx movl $HEIGHT, %ecx
1: 1:
// Loop X // Loop on X-axis
movl $WIDTH, %ebx movl $WIDTH, %ebx
2: 2:
// Save loop registers // Save loop registers
@@ -218,10 +258,11 @@ draw:
subl $1, %ecx subl $1, %ecx
subl $1, %ebx subl $1, %ebx
// Call nib_put_scr // Call `nib_put_scr` depending of the value in a cell
// i = x + y * WIDTH // `i = x + y * WIDTH`
// %eax = %ebx + %ecx * $WIDTH //
// `%eax = %ebx + %ecx * $WIDTH`
movl %ecx, %eax movl %ecx, %eax
movl $WIDTH, %edx movl $WIDTH, %edx
mull %edx mull %edx
@@ -246,12 +287,15 @@ draw:
4: pushl $'o' 4: pushl $'o'
5: 5:
movl %ecx, %eax // Y // Push Y-coordinate
movl %ecx, %eax
pushl %eax pushl %eax
movl %ebx, %eax // X // Push X-coordinate
movl %ebx, %eax
pushl %eax pushl %eax
// `nib_put_scr(int x, int y, int c)`
call nib_put_scr call nib_put_scr
addl $4*3, %esp addl $4*3, %esp
@@ -259,13 +303,101 @@ draw:
popl %ebx popl %ebx
popl %ecx popl %ecx
decl %ebx // Decrement X // Decrement X
jnz 2b // End of X loop decl %ebx
loop 1b // End of Y loop // End of X-loop
jnz 2b
// End of Y-loop
loop 1b
// Jump back to the start of our game loop!
jmp loop jmp loop
// Debug drawing // gameOver
// ========
// Called when the game ends. It displays a game over message
// and score, and quits after **3 seconds**.
gameOver:
// Calculate message position
// --------------------------
// Calculate string length
movl $sgameover_end, %eax
subl $sgameover, %eax
// Discout null terminator
subl $1, %eax
// Calculate X-pos in the middle of the screen
movl $2, %ebx
xorl %edx, %edx
divl %ebx
negl %eax
addl $WIDTH/2, %eax
// Print game over message
// -----------------------
// Push `snakeLength` as score
pushl snakeLength
// Push printf-string
pushl $sgameover
// Push X-coordinate
pushl %eax
// Push Y-coordinate
pushl $HEIGHT/2
// `mvprintw(int y, int x, const char *fmt, ...)`
call mvprintw
add $4*3, %esp
// Call `refresh` to refresh the screen
call refresh
// Sleep for 3 seconds before calling `nib_end`
pushl $3000*1000
call usleep
addl $4, %esp
call nib_end
// spawnApple
// ==========
// Spawns an **apple** in a random location in the `world`.
spawnApple:
pushl %ebx
// `%ecx = rand() % HEIGHT`
call rand
xorl %edx, %edx
movl $HEIGHT, %ebx
divl %ebx
movl %edx, %ecx
// `%ebx = rand() % WIDTH`
pushl %ecx
call rand
xorl %edx, %edx
movl $WIDTH, %ebx
divl %ebx
movl %edx, %ebx
popl %ecx
// `i = x + y * WIDTH`
//
// `%eax = %ebx + %ecx * $WIDTH`
movl %ecx, %eax
movl $WIDTH, %edx
mull %edx
addl %ebx, %eax
// Set the cell negative to represent an apple
movl $world, %ecx
movl $-1, %edx
movl %edx, (%ecx, %eax, 4)
popl %ebx
ret
// debug_draw
// =============
// This is basically the same as `draw`, except it draws the actual ASCII-value
// of the world for debugging purposes.
debug_draw: debug_draw:
// Loop Y // Loop Y
movl $HEIGHT, %ecx movl $HEIGHT, %ecx
@@ -281,8 +413,9 @@ debug_draw:
// Call nib_put_scr // Call nib_put_scr
// i = x + y * WIDTH // `i = x + y * WIDTH`
// %edi = %ebx + %ecx * $WIDTH //
// `%edi = %ebx + %ecx * $WIDTH`
movl %ecx, %eax movl %ecx, %eax
movl $WIDTH, %edx movl $WIDTH, %edx
mull %edx mull %edx
@@ -292,10 +425,12 @@ debug_draw:
movl (%edi, %eax, 4), %eax movl (%edi, %eax, 4), %eax
pushl %eax pushl %eax
movl %ecx, %eax // Y // Y coordinate
movl %ecx, %eax
pushl %eax pushl %eax
movl %ebx, %eax // X // X coordinate
movl %ebx, %eax
pushl %eax pushl %eax
call nib_put_scr call nib_put_scr
@@ -305,68 +440,14 @@ debug_draw:
popl %ebx popl %ebx
popl %ecx popl %ecx
decl %ebx // Decrement X // Decrement X
jnz 2b // End of X loop decl %ebx
loop 1b // End of Y loop // End of X-loop
jnz 2b
// End of Y-loop
loop 1b
// Jump back to the start of our game loop!
jmp loop jmp loop
gameOver:
// Calculate string length
movl $sgameover_end, %eax
subl $sgameover, %eax
subl $1, %eax // Discount null terminator
// Calculate X-pos
movl $2, %ebx
xorl %edx, %edx
divl %ebx
negl %eax
addl $WIDTH/2, %eax
// Print game over message
pushl snakeLength
pushl $sgameover
pushl %eax // X
pushl $HEIGHT/2 // Y
call mvprintw
add $4*3, %esp
call refresh
pushl $3000*1000
call usleep
addl $4, %esp
call nib_end
spawnApple:
pushl %ebx
// %ecx = rand() % HEIGHT
call rand
xorl %edx, %edx
movl $HEIGHT, %ebx
divl %ebx
movl %edx, %ecx
// %ebx = rand() % WIDTH
pushl %ecx
call rand
xorl %edx, %edx
movl $WIDTH, %ebx
divl %ebx
movl %edx, %ebx
popl %ecx
// i = x + y * WIDTH
// %eax = %ebx + %ecx * $WIDTH
movl %ecx, %eax
movl $WIDTH, %edx
mull %edx
addl %ebx, %eax
// Set the cell negative to represent an apple
movl $world, %ecx
movl $-1, %edx
movl %edx, (%ecx, %eax, 4)
popl %ebx
ret
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+10 -5
View File
@@ -1,12 +1,17 @@
.text .text
// _start
// ======
// The `_start` symbol. Calls `start_game` with "reasonable parameters".
.global _start .global _start
_start: _start:
# n_apples // `n_apples`
pushl $10 pushl $10
# len // `len`
pushl $3 pushl $3
// `start_game(int len, int n_apples)`
call start_game call start_game
addl $4*2, %esp addl $4*2, %esp
movl $0, %eax // Exit cleanly with an exit code of 0
ret pushl $0
call _exit