# HG changeset patch # User John Tsiombikas # Date 1422787870 -7200 # Node ID 282da6123fd41a61b52c77c191fdec341753479e # Parent 9e3d77dad51b02bcbd369240e0eff741c6cbb4c7 lalalala diff -r 9e3d77dad51b -r 282da6123fd4 Makefile --- a/Makefile Sat Jan 31 20:01:35 2015 +0200 +++ b/Makefile Sun Feb 01 12:51:10 2015 +0200 @@ -7,10 +7,9 @@ dbg = -g CXXFLAGS = $(warn) $(opt) $(dbg) $(inc) -LDFLAGS = $(libgl) +LDFLAGS = $(libgl) -lvmath -# system-specific stuff ifeq ($(shell uname -s), Darwin) libgl = -framework OpenGL -framework GLUT -lGLEW else diff -r 9e3d77dad51b -r 282da6123fd4 src/app.cc --- a/src/app.cc Sat Jan 31 20:01:35 2015 +0200 +++ b/src/app.cc Sun Feb 01 12:51:10 2015 +0200 @@ -1,6 +1,12 @@ #include #include "opengl.h" #include "app.h" +#include "user.h" + +static void draw_grid(int num, float sep); + +static User user; +static float eye_level = 1.6; bool app_init() { @@ -18,6 +24,15 @@ { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + Matrix4x4 viewmat; + user.posrot.calc_inv_matrix(&viewmat); + glLoadTransposeMatrixf(viewmat.m[0]); + glTranslatef(0, -eye_level, 0); + + draw_grid(20, 1.0); swap_buffers(); assert(glGetError() == GL_NO_ERROR); @@ -49,3 +64,41 @@ void app_mouse_motion(int x, int y) { } + +void app_sball_motion(float x, float y, float z) +{ +} + +void app_sball_rotate(float x, float y, float z) +{ +} + +void app_sball_button(int bn, bool pressed) +{ +} + +static void draw_grid(int num, float sep) +{ + int hnum = num / 2; + float max_dist = hnum * sep; + + glBegin(GL_LINES); + glVertex3f(0, 0, -max_dist); + glVertex3f(0, 0, max_dist); + glVertex3f(-max_dist, 0, 0); + glVertex3f(max_dist, 0, 0); + + for(int i=1; i #include #include +#include #include #include #include +#include #include "fs.h" +static bool childcmpless(const FSNode *aptr, const FSNode *bptr); static char *clean_path(char *path); static char *filename(char *path); +static FSNode::Type st_mode_to_type(mode_t mode); FSNode::FSNode() { @@ -25,7 +29,9 @@ path = name = 0; parent = 0; expanded = false; + sorted = true; uid = gid = mode = 0; + type = UNKNOWN; } void FSNode::destroy() @@ -44,6 +50,32 @@ destroy(); } +void FSNode::set_type(Type type) +{ + this->type = type; +} + +FSNode::Type FSNode::get_type() const +{ + return type; +} + +bool FSNode::is_file() const +{ + return type != DIRECTORY; +} + +bool FSNode::is_directory() const +{ + return type == DIRECTORY; +} + +void FSNode::sort_children() +{ + std::sort(children.begin(), children.end(), childcmpless); + sorted = true; +} + void FSNode::set_path(const char *path) { delete [] this->path; @@ -77,25 +109,146 @@ } } -#if 0 -FSDir *create_fsdir(const char *path) +const char *FSNode::get_path() const { - char *pathbuf; + return path; +} - FSDir *node = new FSDir; - node->name = std::string(filename(path)); +const char *FSNode::get_name() const +{ + return name; +} + +bool FSNode::add_child(FSNode *node) +{ + if(node->parent == this) { + return true; + } + + if(node->parent) { + node->parent->remove_child(node); + } + node->parent = this; + + try { + children.push_back(node); + } + catch(...) { + return false; + } + + sorted = false; + return true; +} + +bool FSNode::remove_child(FSNode *node) +{ + int cidx = find_child(node); + if(cidx == -1) { + return false; + } + children.erase(children.begin() + cidx); + + if(node->parent != this) { + fprintf(stderr, "FSNode::remove_child(): target node doesn't have this node as parent\n"); + // let's not touch it if this happens... + } else { + node->parent = 0; + } + return true; +} + +int FSNode::find_child(FSNode *node) const +{ + for(size_t i=0; isort_children(); + } + + std::vector::const_iterator it; + it = std::lower_bound(children.begin(), children.end(), &key, childcmpless); + if(it == children.end() || strcmp((*it)->name, name) != 0) { + return -1; + } + return std::distance(children.begin(), it); +} + +FSNode *FSNode::get_parent() +{ + return parent; +} + +const FSNode *FSNode::get_parent() const +{ + return parent; +} + +int FSNode::get_child_count() const +{ + return (int)children.size(); +} + +FSNode *FSNode::get_child(int n) +{ + if(!sorted) { + sort_children(); + } + return children[n]; +} + +const FSNode *FSNode::get_child(int n) const +{ + if(!sorted) { + ((FSNode*)this)->sort_children(); + } + return children[n]; +} + +bool FSNode::expand() +{ + expanded = true; + return true; +} + +bool FSNode::is_expanded() const +{ + return expanded; +} + + +// ---- FSDir ---- +FSDir::FSDir() +{ + type = DIRECTORY; +} + +bool FSDir::expand() +{ + if(expanded) return true; DIR *dir = opendir(path); if(!dir) { - fprintf(stderr, "failed to open dir: %s: %s\n", path, strerror(errno)); - return 0; + fprintf(stderr, "FSDir::expand() failed to open dir: %s: %s\n", path, strerror(errno)); + return false; } - pathbuf = (char*)alloca(strlen(path) + NAME_MAX + 2); + char *pathbuf = (char*)alloca(strlen(path) + NAME_MAX + 2); struct dirent *ent; while((ent = readdir(dir))) { - sprintf(pathbuf, "%s/%s", path, ent->d_ent); + sprintf(pathbuf, "%s/%s", path, ent->d_name); struct stat st; if(stat(pathbuf, &st) == -1) { @@ -103,18 +256,49 @@ continue; } - if(S_ISDIR(st.st_type)) { - FSDir *subdir = new FSDir; - subdir->name = std::string(ent->d_ent); - add_subdir(node, subdir); + FSNode *child; + if(S_ISDIR(st.st_mode)) { + child = new FSDir; } else { - FSFile *file = new FSFile; - file->name = std::string(ent->d_ent); - file->parent = node; + FSFile *file = new FSFile; + file->set_size(st.st_size); + file->set_type(st_mode_to_type(st.st_mode)); + child = file; } + add_child(child); + child->set_name(ent->d_name); } + + closedir(dir); + + expanded = true; + return true; } -#endif + +// ---- FSFile ---- + +FSFile::FSFile() +{ + type = UNKNOWN; + size = 0; +} + +void FSFile::set_size(unsigned long s) +{ + size = s; +} + +unsigned long FSFile::get_size() const +{ + return size; +} + +// ---- static helpers ---- + +static bool childcmpless(const FSNode *aptr, const FSNode *bptr) +{ + return strcmp(aptr->get_name(), bptr->get_name()) < 0; +} static char *clean_path(char *path) { @@ -144,3 +328,25 @@ } return path; } + +static FSNode::Type st_mode_to_type(mode_t mode) +{ + switch(mode & S_IFMT) { + case S_IFDIR: + return FSNode::DIRECTORY; + case S_IFREG: + return FSNode::REGFILE; + case S_IFLNK: + return FSNode::LINK; + case S_IFBLK: + case S_IFCHR: + return FSNode::DEVICE; + case S_IFSOCK: + return FSNode::SOCKET; + case S_IFIFO: + return FSNode::FIFO; + default: + break; + } + return FSNode::UNKNOWN; +} diff -r 9e3d77dad51b -r 282da6123fd4 src/fs.h --- a/src/fs.h Sat Jan 31 20:01:35 2015 +0200 +++ b/src/fs.h Sun Feb 01 12:51:10 2015 +0200 @@ -4,26 +4,37 @@ #include class FSNode { +public: + enum Type { UNKNOWN, DIRECTORY, REGFILE, LINK, DEVICE, SOCKET, FIFO }; + protected: char *path, *name; FSNode *parent; std::vector children; - bool expanded; + bool expanded, sorted; + Type type; unsigned int uid, gid, mode; private: FSNode(const FSNode&); FSNode &operator =(const FSNode&); + void sort_children(); + public: FSNode(); virtual ~FSNode(); - void init(); - void destroy(); - void destroy_tree(); + virtual void init(); + virtual void destroy(); + virtual void destroy_tree(); + + virtual void set_type(Type type); + virtual Type get_type() const; + virtual bool is_file() const; + virtual bool is_directory() const; virtual void set_path(const char *path); virtual void set_name(const char *name); @@ -31,7 +42,11 @@ virtual const char *get_path() const; virtual const char *get_name() const; - virtual void add_child(FSNode *node); + virtual bool add_child(FSNode *node); + virtual bool remove_child(FSNode *node); + + virtual int find_child(FSNode *node) const; + virtual int find_child(const char *name) const; virtual FSNode *get_parent(); virtual const FSNode *get_parent() const; @@ -40,7 +55,7 @@ virtual FSNode *get_child(int n); virtual const FSNode *get_child(int n) const; - virtual void expand(); + virtual bool expand(); virtual bool is_expanded() const; }; @@ -48,18 +63,19 @@ public: FSDir(); - virtual void expand(); + virtual bool expand(); }; class FSFile : public FSNode { protected: unsigned long size; + enum Type type; public: FSFile(); - void set_size(unsigned long s); - unsigned long get_size() const; + virtual void set_size(unsigned long s); + virtual unsigned long get_size() const; }; #endif // FS_H_ diff -r 9e3d77dad51b -r 282da6123fd4 src/main.cc --- a/src/main.cc Sat Jan 31 20:01:35 2015 +0200 +++ b/src/main.cc Sun Feb 01 12:51:10 2015 +0200 @@ -15,6 +15,9 @@ static void key_up(unsigned char key, int x, int y); static void mouse(int bn, int state, int x, int y); static void motion(int x, int y); +static void sball_motion(int x, int y, int z); +static void sball_rotate(int x, int y, int z); +static void sball_button(int bn, int state); static int win_width, win_height; static unsigned int mod; @@ -34,6 +37,9 @@ glutMouseFunc(mouse); glutMotionFunc(motion); glutPassiveMotionFunc(motion); + glutSpaceballMotionFunc(sball_motion); + glutSpaceballRotateFunc(sball_rotate); + glutSpaceballButtonFunc(sball_button); if(app_init() == -1) { return 1; @@ -104,3 +110,18 @@ { app_mouse_motion(x, y); } + +static void sball_motion(int x, int y, int z) +{ + app_sball_motion(x / 1000.0f, y / 1000.0f, z / 1000.0f); +} + +static void sball_rotate(int x, int y, int z) +{ + app_sball_rotate(x / 1800.0f, y / 1800.0f, z / 1800.0f); +} + +static void sball_button(int bn, int state) +{ + app_sball_button(bn, state == GLUT_DOWN); +} diff -r 9e3d77dad51b -r 282da6123fd4 src/user.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/user.cc Sun Feb 01 12:51:10 2015 +0200 @@ -0,0 +1,17 @@ +#include "user.h" + +void PosRot::move(float dfwd, float dright, float dup) +{ +} + +void PosRot::rotate(float dhoriz, float dvert) +{ +} + +void PosRot::calc_matrix(Matrix4x4 *res) const +{ +} + +void PosRot::calc_inv_matrix(Matrix4x4 *res) const +{ +} diff -r 9e3d77dad51b -r 282da6123fd4 src/user.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/user.h Sun Feb 01 12:51:10 2015 +0200 @@ -0,0 +1,22 @@ +#ifndef USER_H_ +#define USER_H_ + +#include + +struct PosRot { + Vector3 pos; + Quaternion rot; + + void move(float dfwd, float dright, float dup); + void rotate(float dhoriz, float dvert); + + void calc_matrix(Matrix4x4 *res) const; + void calc_inv_matrix(Matrix4x4 *res) const; +}; + +class User { +public: + PosRot posrot; +}; + +#endif // USER_H_