aboutsummaryrefslogtreecommitdiff
path: root/arm9/source/types
diff options
context:
space:
mode:
Diffstat (limited to 'arm9/source/types')
-rw-r--r--arm9/source/types/circbuf.c10
-rw-r--r--arm9/source/types/circbuf.h18
-rw-r--r--arm9/source/types/pathbuf.c111
-rw-r--r--arm9/source/types/pathbuf.h24
-rw-r--r--arm9/source/types/readbuf.c14
-rw-r--r--arm9/source/types/readbuf.h13
-rw-r--r--arm9/source/types/wakequeue.c30
-rw-r--r--arm9/source/types/wakequeue.h13
8 files changed, 172 insertions, 61 deletions
diff --git a/arm9/source/types/circbuf.c b/arm9/source/types/circbuf.c
index 532a5a0..0398254 100644
--- a/arm9/source/types/circbuf.c
+++ b/arm9/source/types/circbuf.c
@@ -1,6 +1,8 @@
#include "circbuf.h"
-u8 cb_read_byte(CircBuf *buf) {
+
+// Read a byte from a circular buffer, or zero if the buffer is empty.
+u8 circbuf_read(CircBuf *buf) {
if (buf->front != buf->back) {
return buf->mem[buf->front++];
} else {
@@ -8,13 +10,15 @@ u8 cb_read_byte(CircBuf *buf) {
}
}
-void cb_write_byte(CircBuf *buf, u8 byte) {
+// Write a byte to a circular buffer if the buffer is not full.
+void circbuf_write(CircBuf *buf, u8 byte) {
if (((buf->back+1)&0xff) != buf->front) {
buf->mem[buf->back++] = byte;
}
}
-void cb_clear(CircBuf *buf) {
+// Clear a circular buffer.
+void circbuf_clear(CircBuf *buf) {
buf->front = 0;
buf->back = 0;
}
diff --git a/arm9/source/types/circbuf.h b/arm9/source/types/circbuf.h
index 305f8bf..15b3b63 100644
--- a/arm9/source/types/circbuf.h
+++ b/arm9/source/types/circbuf.h
@@ -1,16 +1,18 @@
-#include <nds.h>
-
#ifndef CIRCBUF_H_
#define CIRCBUF_H_
+ #include "../bang.h"
+
+
+ // A 256-byte circular buffer.
typedef struct {
u8 mem[256];
- u8 front; // start of buffer, read from here until back
- u8 back; // end of buffer, write past here until front
+ u8 front; // start of buffer, read from here up to back
+ u8 back; // end of buffer, write past here up to front
} CircBuf;
- u8 cb_read_byte(CircBuf *buf);
- void cb_write_byte(CircBuf *buf, u8 byte);
- void cb_clear(CircBuf *buf);
-
+ // Methods.
+ u8 circbuf_read(CircBuf *buf);
+ void circbuf_write(CircBuf *buf, u8 byte);
+ void circbuf_clear(CircBuf *buf);
#endif
diff --git a/arm9/source/types/pathbuf.c b/arm9/source/types/pathbuf.c
index 1a610c8..e94b955 100644
--- a/arm9/source/types/pathbuf.c
+++ b/arm9/source/types/pathbuf.c
@@ -1,52 +1,99 @@
-#include <nds.h>
#include "pathbuf.h"
-u8 pb_read(PathBuf *buf) {
+
+// Read the next byte of the path buffer, or zero if all bytes have been read.
+u8 pathbuf_read(PathBuf *buf) {
u8 output = buf->mem[buf->p];
if (output) buf->p++;
return output;
}
-void pb_clear(PathBuf *buf) {
- memset(&buf->mem, 0, 256);
+// Clear a path buffer.
+void pathbuf_clear(PathBuf *buf) {
+ for (int i=0; i<256; i++) buf->mem[i] = 0;
+ buf->p = 0;
}
-void pb_reset(PathBuf *buf, bool to_name) {
+// Move the pointer to either the start of the path buffer or to the start of
+// the final path component.
+void pathbuf_set_pointer(PathBuf *buf, bool to_final_component) {
buf->p = 0;
- if (to_name) for (int i=0; i<255; i++) {
- if (buf->mem[i] == '/') {
- buf->p = i+1;
- } else if (buf->mem[i] == 0) {
- break;
+ if (to_final_component) {
+ for (int i=0; i<255; i++) {
+ if (buf->mem[i] == '/') {
+ buf->p = i+1;
+ } else if (buf->mem[i] == 0) {
+ break;
+ }
}
}
}
-// Push a byte to a PathBuf, return true and reset the pointer if byte is null.
-bool pb_push_byte(PathBuf *buf, u8 byte) {
- // Stop before overwriting the pointer.
- if (buf->p != 0xff) {
- buf->mem[buf->p++] = byte;
- }
- if (byte == 0) {
- buf->p = 0;
- return true;
- } else {
- return false;
- }
+// Populate a path buffer with a bytestring.
+void pathbuf_populate(PathBuf *buf, u8 *path) {
+ pathbuf_clear(buf);
+ u8 c;
+ for (int i=0; i<256; i++) {
+ c = path[i];
+ buf->mem[i] = c;
+ if (c == 0) return;
+ };
}
-bool pb_is_terminated(PathBuf *buf) {
- for (int i=0; i<255; i++) {
- if (buf->mem[i] == 0) {
- return true;
- }
- }
- return false;
+// Push a byte to a path buffer, return true and reset pointer if byte is null.
+bool pathbuf_push(PathBuf *buf, u8 byte) {
+ buf->mem[buf->p++] = byte;
+ return byte == 0;
}
-void pb_populate(PathBuf *buf, u8 *path) {
- strncpy((char*) &buf->mem[0], (char*) path, 254);
- buf->p = 0;
+// Check if a path buffer is empty.
+bool pathbuf_is_empty(PathBuf *buf) {
+ return buf->mem[0] == 0;
+}
+
+// Check if a path buffer contains the path of the root directory.
+bool pathbuf_is_root(PathBuf *buf) {
+ return buf->mem[0] == '/' && buf->mem[1] == 0;
+}
+
+// Check if a path buffer contains a valid path.
+bool pathbuf_is_valid(PathBuf *buf) {
+ // Test that path begins with a forward slash and ends with a null byte.
+ if (buf->mem[0x00] != '/') return false;
+ if (buf->mem[0xFF] != 0 ) return false;
+ // Find the length of the path.
+ int len = 0;
+ for (; len<256; len++) if (buf->mem[len] == 0) break;
+ // End early if path is the root directory.
+ if (len == 1) return true;
+ // Test that path contains no control characters.
+ for (int i=0; i<len; i++) if (buf->mem[i] < 0x20) return false;
+ // Test that path contains no empty or relative components. This also
+ // happens to test that it doesn't end with a slash.
+ bool is_empty = false;
+ bool all_dots = false;
+ int dot_count = 0;
+ u8 c;
+ for (int i=0; i<=len; i++) {
+ c = buf->mem[i];
+ if (c == '/' || c == 0) {
+ // Test if component is empty.
+ if (is_empty) return false;
+ // Test if component is one or two periods.
+ if (all_dots && dot_count < 3) return false;
+ // Reset flags.
+ is_empty = true;
+ all_dots = true;
+ dot_count = 0;
+ } else {
+ is_empty = false;
+ if (c == '.') {
+ dot_count++;
+ } else {
+ all_dots = false;
+ }
+ }
+ }
+ return true;
}
diff --git a/arm9/source/types/pathbuf.h b/arm9/source/types/pathbuf.h
index 7fd7251..a926262 100644
--- a/arm9/source/types/pathbuf.h
+++ b/arm9/source/types/pathbuf.h
@@ -1,18 +1,22 @@
-#include <nds.h>
-
#ifndef PATHBUF_H_
#define PATHBUF_H_
+ #include "../bang.h"
+
+
+ // A 255-byte path buffer.
typedef struct {
- u8 mem[255];
+ u8 mem[256];
u8 p;
} PathBuf;
- u8 pb_read(PathBuf *buf);
- void pb_clear(PathBuf *buf);
- void pb_reset(PathBuf *buf, bool to_name);
- bool pb_push_byte(PathBuf *buf, u8 byte);
- bool pb_is_terminated(PathBuf *buf);
- void pb_populate(PathBuf *buf, u8 *path);
-
+ // Methods.
+ u8 pathbuf_read(PathBuf *buf);
+ void pathbuf_clear(PathBuf *buf);
+ void pathbuf_set_pointer(PathBuf *buf, bool to_final_component);
+ void pathbuf_populate(PathBuf *buf, u8 *path);
+ bool pathbuf_push(PathBuf *buf, u8 byte);
+ bool pathbuf_is_empty(PathBuf *buf);
+ bool pathbuf_is_root(PathBuf *buf);
+ bool pathbuf_is_valid(PathBuf *buf);
#endif
diff --git a/arm9/source/types/readbuf.c b/arm9/source/types/readbuf.c
index eaee27a..750ac4d 100644
--- a/arm9/source/types/readbuf.c
+++ b/arm9/source/types/readbuf.c
@@ -1,12 +1,20 @@
-#include <nds.h>
#include "readbuf.h"
-u8 rb_read(ReadBuf *buf) {
+
+// Populate a read buffer with a pointer to a string.
+void readbuf_populate(ReadBuf *buf, u8 *string) {
+ buf->mem = string;
+ buf->p = 0;
+}
+
+// Read the next byte of a read buffer, or zero if all bytes have been read.
+u8 readbuf_read(ReadBuf *buf) {
u8 output = buf->mem[buf->p];
if (output) buf->p++;
return output;
}
-void rb_reset(ReadBuf *buf) {
+// Move the pointer to the start of the buffer.
+void readbuf_set_pointer(ReadBuf *buf) {
buf->p = 0;
}
diff --git a/arm9/source/types/readbuf.h b/arm9/source/types/readbuf.h
index 9077a69..a88934b 100644
--- a/arm9/source/types/readbuf.h
+++ b/arm9/source/types/readbuf.h
@@ -1,14 +1,17 @@
-#include <nds.h>
-
#ifndef READBUF_H_
#define READBUF_H_
+ #include "../bang.h"
+
+
+ // A variable-length read buffer.
typedef struct {
u8 *mem;
u8 p;
} ReadBuf;
- u8 rb_read(ReadBuf *buf);
- void rb_reset(ReadBuf *buf);
-
+ // Methods.
+ void readbuf_populate(ReadBuf *buf, u8 *string);
+ u8 readbuf_read(ReadBuf *buf);
+ void readbuf_set_pointer(ReadBuf *buf);
#endif
diff --git a/arm9/source/types/wakequeue.c b/arm9/source/types/wakequeue.c
new file mode 100644
index 0000000..8876123
--- /dev/null
+++ b/arm9/source/types/wakequeue.c
@@ -0,0 +1,30 @@
+#include "wakequeue.h"
+
+/*
+TODO: This is unused at the moment. It will eventually be used for keeping
+track of which device last woke a Bedrock instance, to optimally choose
+which device to use when waking from sleep.
+*/
+
+// Reset a wake queue.
+void wakequeue_reset(WakeQueue *queue) {
+ // Populate the queue with fifteen slot numbers. Slot zero is excluded,
+ // as it always comes last in the wake order.
+ for (int i=0; i<15; i++) queue->mem[i] = i+1;
+}
+
+// TODO: Not quite done yet.
+bool wakequeue_wake(WakeQueue *queue, u16 device_list) {
+ // Test each entry in the queue against the device list.
+ for (int i=0; i<15; i++) {
+ u8 slot_number = queue->mem[i];
+ if (TEST(device_list, 0x8000 >> slot_number)) {
+ // Move the matched entry to the back of the queue.
+ for (; i<14; i++) queue->mem[i] = queue->mem[i+1];
+ queue->mem[14] = slot_number;
+ return true;
+ }
+ }
+ // Test system device last.
+ return TEST(device_list, 0x8000);
+}
diff --git a/arm9/source/types/wakequeue.h b/arm9/source/types/wakequeue.h
new file mode 100644
index 0000000..ed07d6d
--- /dev/null
+++ b/arm9/source/types/wakequeue.h
@@ -0,0 +1,13 @@
+#ifndef WAKEQUEUE_H_
+ #define WAKEQUEUE_H_
+
+ #include "../bang.h"
+
+
+ // A variable-length read buffer.
+ typedef struct {
+ u8 mem[15]; // List of slot numbers
+ } WakeQueue;
+
+ // Methods.
+#endif