io.cc (3464B)
1 /* Copyright 2013 Brian Swetland <swetland@frotz.net> 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <stdarg.h> 19 #include <string.h> 20 #include <sys/stat.h> 21 22 #include "util.h" 23 #include "io.h" 24 25 static char _base_path[1024 + 8] = ""; 26 static stringptr base_path; 27 28 static const char *defaultsearch[] = { 29 #ifdef _WIN32 30 "assets\\", 31 #else 32 "assets/", 33 #endif 34 NULL, 35 }; 36 37 static const char *nosearch[] = { 38 "", 39 NULL, 40 }; 41 42 static const char **search = defaultsearch; 43 44 void io_ignore_asset_paths(void) { 45 _base_path[0] = 0; 46 base_path = stringptr(_base_path); 47 search = nosearch; 48 } 49 50 FILE *io_fopen_asset(stringptr fn, const char *kind) { 51 stackstring<4096> path(base_path); 52 int len = path.length(); 53 FILE *fp; 54 int i; 55 for (i = 0; search[i]; i++) { 56 path.trim(len).append(search[i]).append(fn); 57 fp = fopen(path, "rb"); 58 if (fp != NULL) { 59 printx("Loading %s from '%s'...\n", kind, path.cstr()); 60 return fp; 61 } 62 } 63 printx("Cannot find %s '%s'.\n", kind, fn); 64 return NULL; 65 } 66 67 #ifdef _WIN32 68 #include <windows.h> 69 void init_io(void) { 70 char *x; 71 GetModuleFileName(NULL, _base_path, 1024); 72 _base_path[1023] = 0; 73 x = strrchr(_base_path, '\\'); 74 if (x) 75 x[1] = 0; 76 else 77 strcpy(_base_path,".\\"); 78 base_path = stringptr(_base_path); 79 } 80 #else 81 #include <unistd.h> 82 void init_io(void) { 83 char *x; 84 int r; 85 r = readlink("/proc/self/exe", _base_path, 1024); 86 if (r < 0) 87 return; 88 x = strrchr(_base_path, '/'); 89 if (x) 90 x[1] = 0; 91 else 92 strcpy(_base_path,"./"); 93 base_path = stringptr(_base_path); 94 } 95 #endif 96 97 int file_get_mtime(stringptr fn) { 98 struct stat s; 99 stackstring<4096> path(base_path); 100 path.append(search[0]).append(fn); 101 if (path.error()) 102 return -1; 103 if (stat(path, &s)) 104 return -1; 105 return s.st_mtime; 106 } 107 108 void vprintx(const char *fmt, va_list ap) { 109 char buf[128]; 110 vsnprintf(buf, sizeof(buf), fmt, ap); 111 buf[127] = 0; 112 #if defined(_WIN32) && defined(_DEBUG) 113 OutputDebugString(buf); 114 #else 115 fwrite(buf, strlen(buf), 1, stderr); 116 #endif 117 } 118 119 void printx(const char *fmt, ...) { 120 va_list ap; 121 va_start(ap, fmt); 122 vprintx(fmt, ap); 123 va_end(ap); 124 } 125 126 void die(const char *fmt, ...) { 127 va_list ap; 128 printx("ERROR: "); 129 va_start(ap, fmt); 130 vprintx(fmt, ap); 131 va_end(ap); 132 printx("\n"); 133 exit(-1); 134 } 135 136 void printmtx(float *m, const char *name) { 137 printx("| %8.4f %8.4f %8.4f %8.4f | \"%s\"\n", m[0], m[1], m[2], m[3], name); 138 printx("| %8.4f %8.4f %8.4f %8.4f |\n", m[4], m[5], m[6], m[7]); 139 printx("| %8.4f %8.4f %8.4f %8.4f |\n", m[8], m[9], m[10], m[11]); 140 printx("| %8.4f %8.4f %8.4f %8.4f |\n", m[12], m[13], m[14], m[15]); 141 } 142 143 int error(const char *fmt, ...) { 144 char buf[1024]; 145 va_list ap; 146 va_start(ap, fmt); 147 vsnprintf(buf, sizeof(buf), fmt, ap); 148 va_end(ap); 149 buf[1023] = 0; 150 #if defined(_WIN32) && !defined(_DEBUG) 151 MessageBox(NULL, buf, "Error", MB_OK); 152 #else 153 if (buf[0] && (buf[strlen(buf) - 1] == '\n')) { 154 printx("ERROR: %s", buf); 155 } else { 156 printx("ERROR: %s\n", buf); 157 } 158 #endif 159 return -1; 160 }