rnd-20040814-1-src
[rocksndiamonds.git] / src / libem / cave.c
1 /* 2000-08-10T16:43:50Z
2  *
3  * cave data structures
4  */
5
6 #include <sys/types.h>
7 #include <dirent.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <errno.h>
12
13 #include "global.h"
14 #include "tile.h"
15 #include "level.h"
16 #include "file.h"
17
18 struct cave_node *cave_list;
19
20 static void clear(void);
21
22 /* attempt load a cave
23  * 
24  * completely initializes the level structure, ready for a game
25  */
26 int cave_convert(char *filename)
27 {
28         int result;
29         FILE *file;
30         int actual;
31         unsigned long length;
32         unsigned char buffer[16384];
33
34         clear();
35
36         file = fopen(filename, "rb");
37         if(file == 0) {
38                 fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, filename, "open error", strerror(errno));
39                 result = 1;
40                 goto fail;
41         }
42         actual = fread(buffer, 1, 16384, file);
43         if(actual == -1) {
44                 fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, filename, "read error", strerror(errno));
45                 result = 1;
46                 goto fail;
47         }
48         length = actual;
49         fclose(file);
50         file = 0;
51
52         if(clean_emerald(buffer, &length)) {
53                 fprintf(stderr, "%s: \"%s\": %s\n", progname, filename, "unrecognized format");
54                 result = 1; goto fail;
55         }
56         convert_emerald(buffer);
57
58         result = 0;
59 fail:
60         if(file) fclose(file);
61         return(result);
62 }
63
64 static void clear(void)
65 {
66         lev.home = 1; /* number of players */
67         lev.width = 0;
68         lev.height = 0;
69         lev.time = 0;
70         lev.required = 0;
71         lev.score = 0;
72
73         ply1.num = 0;
74         ply1.alive = (lev.home >= 1);
75         ply1.dynamite = 0;
76         ply1.dynamite_cnt = 0;
77         ply1.keys = 0;
78         ply1.anim = 0;
79         ply1.oldx = ply1.x = 0;
80         ply1.oldy = ply1.y = 0;
81         ply1.joy_n = ply1.joy_e = ply1.joy_s = ply1.joy_w = ply1.joy_fire = ply1.joy_stick = ply1.joy_spin = 0;
82         ply2.num = 1;
83         ply2.alive = (lev.home >= 2);
84         ply2.dynamite = 0;
85         ply2.dynamite_cnt = 0;
86         ply2.keys = 0;
87         ply2.anim = 0;
88         ply2.oldx = ply2.x = 0;
89         ply2.oldy = ply2.y = 0;
90         ply2.joy_n = ply2.joy_e = ply2.joy_s = ply2.joy_w = ply2.joy_fire = ply2.joy_stick = ply2.joy_spin = 0;
91 }
92
93 void read_cave_list(void)
94 {
95         char name[MAXNAME+2];
96         struct cave_node *node, **prev;
97         DIR *dir;
98         struct dirent *entry;
99         char *cut;
100         int len;
101
102         free_cave_list(); /* delete old list if i forgot to before */
103
104         name[MAXNAME] = 0;
105         if(arg_basedir) {
106                 snprintf(name, MAXNAME+2, "%s/%s", arg_basedir, EM_LVL_DIR);
107         } else {
108                 snprintf(name, MAXNAME+2, "%s", EM_LVL_DIR);
109         }
110         if(name[MAXNAME]) snprintf_overflow("read cave/ directory");
111
112         dir = opendir(name);
113         if(dir) {
114                 prev = &cave_list;
115                 while((entry = readdir(dir))) {
116                         if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
117
118                         node = malloc(sizeof(*node)); if(node == 0) break;
119                         *prev = node; prev = &node->next;
120
121                         node->path[MAXNAME] = 0;
122                         snprintf(node->path, MAXNAME+2, "%s/%s", name, entry->d_name);
123                         if(node->path[MAXNAME]) snprintf_overflow("read cave/ directory");
124
125                         cut = strrchr(node->path, '/'); cut = cut ? cut + 1 : node->path;
126                         len = strlen(cut);
127                         if(len <= 32) {
128                                 strncpy(node->name, cut, 32);
129                         } else {
130                                 snprintf(node->name, 32, "%.8s..%s", cut, cut + len - 16);
131                         }
132                 }
133                 *prev = 0;
134                 closedir(dir);
135         } else {
136                 fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, name, "failed to open directory", strerror(errno));
137         }
138 }
139
140 void free_cave_list(void)
141 {
142         struct cave_node *node, *next;
143
144         for(node = cave_list; node; node = next) {
145                 next = node->next;
146                 free(node);
147         }
148         cave_list = 0;
149 }