13 #include "gmath/gmath.h"
18 static IconRenderer *iconrend;
20 static std::map<std::string, FSNode*> node_cache;
21 static FSNode *cur_node;
22 static int start_child;
24 static dtx_font *fat_font;
25 #define FAT_FONT_SZ 32
28 bool init_fs(const char *path)
30 iconrend = new ShapesIcons;
31 if(!iconrend->init()) {
35 if(!(fat_font = dtx_open_font("data/fat.font", FAT_FONT_SZ))) {
36 fprintf(stderr, "failed to open font file data/fat.font\n");
40 if(!(cur_node = get_fsnode(path))) {
49 std::map<std::string, FSNode*>::iterator it = node_cache.begin();
50 while(it != node_cache.end()) {
51 FSNode *node = it++->second;
55 dtx_close_font(fat_font);
59 static Vec3 icon_pos(int row, int col, int ncols, float row_spacing, float radius)
61 float angle = 2.0 * M_PI * (float)col / (float)ncols;
62 float x = sin(angle) * radius;
63 float z = -cos(angle) * radius;
64 float y = (float)row * row_spacing;
68 static float icon_angle(int col, int ncols, float max_angle = 0.0f)
71 return max_angle * ((float)col / (float)(ncols - 1) - 0.5);
73 return 2.0 * M_PI * (float)col / (float)ncols;
78 static const float row_spacing = 0.25;
79 static const float radius = 0.6;
80 static const float umax = 0.42;
81 static const float max_icon_angle = M_PI * 2.0 * umax;
83 int max_ncols = std::max<int>(1, umax * 12);
86 base_xform.rotate(time_sec, 0, 0);
87 base_xform.rotate(0, 0, time_sec * 0.5);
88 base_xform.translate(0, 1.65, 0);
91 glDisable(GL_TEXTURE_2D);
93 int nchildren = (int)cur_node->children.size();
94 int ncols = std::min(cur_node->nfiles, max_ncols);
96 int first = start_child % ncols;
99 for(int i=0; i<nchildren; i++) {
100 int idx = (i + first) % nchildren;
101 FSNode *node = cur_node->children[idx];
103 if(node->type == FSTYPE_DIR) {
107 float angle = icon_angle(col, ncols, max_icon_angle);
109 Mat4 xform = base_xform;
110 xform.translate(0, row * row_spacing, -radius);
111 xform.rotate_y(angle);
114 glMultMatrixf(xform[0]);
115 iconrend->draw(node);
119 xform = Mat4::identity;
120 xform.translate(-dtx_string_width(node->path.get_name()) / 2.0, 0, 0);
122 xform.translate(0, 1.54 + row * row_spacing, -radius);
123 xform.rotate_y(angle);
124 glMultMatrixf(xform[0]);
126 dtx_string(node->path.get_name());
136 FSNode *get_fsnode(const char *path)
138 char *abspath = make_abs_path(path);
140 FSNode *node = node_cache[abspath];
146 if(stat(node->path, &st) == -1) {
147 fprintf(stderr, "failed to stat: %s\n", node->path.get_path());
151 node->size = st.st_size;
153 switch(st.st_mode & S_IFMT) {
155 node->type = FSTYPE_FILE;
159 node->type = FSTYPE_DIR;
164 node->type = FSTYPE_DEV;
168 node->type = FSTYPE_UNKNOWN;
170 node_cache[abspath] = node;
176 FSNode *get_fsnode(const char *dir, const char *name)
179 return get_fsnode(name);
181 if(!name || *name == '/') {
185 int len = strlen(dir) + 1 + strlen(name);
186 char *buf = new char[len + 1];
187 sprintf(buf, "%s/%s", dir, name);
188 FSNode *res = get_fsnode(buf);
193 // ---- FSNode implementation ----
196 type = FSTYPE_UNKNOWN;
202 bool FSNode::expand()
204 if(type != FSTYPE_DIR) {
208 DIR *dir = opendir(path);
210 fprintf(stderr, "failed to open dir: %s: %s\n", path.get_path(), strerror(errno));
215 while((dent = readdir(dir))) {
216 if(strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) {
220 FSNode *node = get_fsnode(path, dent->d_name);
223 children.push_back(node);
234 printf("expanded %d children\n", (int)children.size());
236 parent = get_fsnode(path.get_parent());