Load zone files.
[cantaveria.git] / util.c
blob7a8f36872031d5f02a46113a4fa153de87cbf186
1 /*
2 Cantaveria - action adventure platform game
3 Copyright (C) 2009 Evan Rinehart
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to
18 The Free Software Foundation, Inc.
19 51 Franklin Street, Fifth Floor
20 Boston, MA 02110-1301, USA
23 /* error routines */
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <string.h>
30 #include "util.h"
32 void report_error(const char* format, ...){
33 va_list ap;
34 va_start(ap, format);
36 vprintf(format, ap);
38 va_end(ap);
41 void fatal_error(const char* format, ...){
42 va_list ap;
43 va_start(ap, format);
44 //report_error(format, ap);
45 vprintf(format, ap);
46 va_end(ap);
47 exit(-1);
50 void* xmalloc(size_t size){
51 void* v = malloc(size);
52 if(!v){
53 out_of_memory("xmalloc");
55 return v;
58 char* strxcpy(const char* str){
59 char* cpy = xmalloc(strlen(str)+1);
60 strcpy(cpy, str);
61 return cpy;
65 void strmcat(char* dst, const char* src, size_t n){
66 strncat(dst, src, n - strlen(src) - 1);
70 void out_of_memory(const char* prefix){
71 report_error("%s: out of memory\n", prefix);
72 exit(-2);
78 decodes utf8 encoded string str and places the
79 next character in u.
80 returns the number of bytes of str consumed.
82 int unicode_getc(char* str, utf32* u){
83 unsigned char b[4] = {str[0], str[1], str[2], str[3]};
84 unsigned char a[4] = {0,0,0,0};
85 int N;
87 /* 1111 0xf
88 1110 0xe
89 1100 0xc
90 1000 0x8 */
92 if((b[0] & 0x80) == 0){/*one byte sequence*/
93 a[3] = b[0];
94 N = 1;
96 else if(((b[0]&0xe0)==0xc0) &&
97 ((b[1]&0xc0)==0x80) ){/*two byte sequence*/
98 a[3] = ((b[0]&0x03)<<6)|(b[1]&0x3f);
99 a[2] = (b[0]&0x1c)>>2;
100 N = 2;
102 else if(((b[0]&0xf0)==0xe0) &&
103 ((b[1]&0xc0)==0x80) &&
104 ((b[2]&0xc0)==0x80) ){/*three byte sequence*/
105 a[3] = ((b[1]&0x03)<<6)|(b[2]&0x3f);
106 a[2] = ((b[0]&0x0f)<<4)|((b[1]&0x3c)>>2);
107 N = 3;
109 else if(((b[0]&0xf8)==0xf0) &&
110 ((b[1]&0xc0)==0x80) &&
111 ((b[2]&0xc0)==0x80) &&
112 ((b[3]&0xc0)==0x80) ){/*four byte sequence*/
113 a[3] =((b[2]&0x03)<<6)|(b[3]&0x3f);
114 a[2] =((b[1]&0x0f)<<4)|((b[2]&0x3c)>>2);
115 a[1] =((b[0]&0x03)<<2)|((b[1]&0x30)>>4);
116 N = 4;
118 else {
119 a[3] = '?';
120 N = 4;/*FIXME find next valid byte*/
122 *u = (a[0]<<24) | (a[1]<<16) | (a[2]<<8) | a[3];
123 return N;
128 void tree_insert(struct treenode* root,
129 int (*compare)(void* k1, void* k2),
130 void* key, void* value){
131 struct treenode* node = xmalloc(sizeof(struct treenode));
132 node->key = key;
133 node->value = value;
134 node->l = NULL;
135 node->r = NULL;
137 struct treenode* ptr = root;
138 while(1){
139 if( compare(ptr->key, key) < 0 ){
140 if(ptr->l){ptr = ptr->l;}
141 else{ptr->l = node; break;}
143 else if( compare(ptr->key, key) > 0){
144 if(ptr->r){ptr = ptr->r;}
145 else{ptr->r = node; break;}
147 else{ /* key already exists */
148 report_error("tree_insert: key already exists\n");
149 break;
154 void* tree_search(struct treenode* root,
155 int (*compare)(void* k1, void* k2),
156 void* key){
157 if(root==NULL){
158 return NULL;
160 else if(compare(root->key, key)>0){
161 //printf("%p -> go right\n",root->key);
162 return tree_search(root->r, compare, key);
164 else if(compare(root->key, key)<0){
165 //printf("%p -> go left\n",root->key);
166 return tree_search(root->l, compare, key);
168 else{
169 //printf("%p -> found\n",key);
170 return root->value;
176 int randint(int a, int b){
177 int L = b-a+1;
178 return (rand()%L)+a;
182 #define PRAND_MAX 65537
184 rng_state pseed(int s){
185 rng_state x = 2;
186 for(int i=0; i<s; i++){
187 prand(&x);
189 return x;
192 int prand(rng_state* x){
193 int G = 75;
194 *x = (*x * G) % PRAND_MAX;
195 return *x;
198 int prandi(rng_state* x, int a, int b){
199 int L = b-a+1;
200 return (prand(x)%L)+a;
203 double prandr(rng_state* x, double a, double b){
204 double R = prand(x)/((double)PRAND_MAX);
205 double L = b-a;
206 return (R*L)+a;