filename | src/util.c |
changeset | 502:c4ecae2b1b5e |
prev | 495:4db4702b0778 |
next | 535:7338e020b09b |
author | nkeynes |
date | Mon Nov 19 08:47:39 2007 +0000 (16 years ago) |
permissions | -rw-r--r-- |
last change | Move name-to-driver mappings to display.c and audio.c respectively Move responsibility for invoking texcache_gl_init() to the driver |
view | annotate | diff | log | raw |
1 /**
2 * $Id: util.c,v 1.14 2007-11-08 11:54:16 nkeynes Exp $
3 *
4 * Miscellaneous utility functions.
5 *
6 * Copyright (c) 2005 Nathan Keynes.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
19 #define HAVE_EXECINFO_H 1
21 #include <assert.h>
22 #include <ctype.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <signal.h>
27 #include <time.h>
28 #include <zlib.h>
29 #include <glib.h>
30 #include <png.h>
31 #include "dream.h"
32 #include "display.h"
33 #include "gui.h"
34 #include "sh4/sh4core.h"
36 char *msg_levels[] = { "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE" };
37 int global_msg_level = EMIT_WARN;
39 static void report_crash( int signo, siginfo_t *info, void *ptr )
40 {
41 char buf[128];
43 fprintf( stderr, "--- Aborting with signal %d ---\n", signo );
44 // Get gdb to print a nice backtrace for us
45 snprintf( buf, 128, "gdb -batch -f --quiet --pid=%d -ex bt", getpid() );
46 system(buf);
48 abort();
49 }
51 void install_crash_handler(void)
52 {
53 struct sigaction sa;
55 sa.sa_sigaction = report_crash;
56 sigemptyset(&sa.sa_mask);
57 sa.sa_flags = SA_RESETHAND|SA_SIGINFO;
58 sigaction( SIGSEGV, &sa, NULL );
59 }
62 void fwrite_string( const char *s, FILE *f )
63 {
64 uint32_t len = 0;
65 if( s == NULL ) {
66 fwrite( &len, sizeof(len), 1, f );
67 } else {
68 len = strlen(s)+1;
69 fwrite( &len, sizeof(len), 1, f );
70 fwrite( s, len, 1, f );
71 }
72 }
74 int fread_string( char *s, int maxlen, FILE *f )
75 {
76 uint32_t len;
77 fread( &len, sizeof(len), 1, f );
78 if( len != 0 ) {
79 fread( s, len > maxlen ? maxlen : len, 1, f );
80 }
81 return len;
82 }
84 void fwrite_gzip( void *p, size_t sz, size_t count, FILE *f )
85 {
86 uLongf size = sz*count;
87 uLongf csize = ((int)(size*1.001))+13;
88 unsigned char *tmp = g_malloc0( csize );
89 int status = compress( tmp, &csize, p, size );
90 assert( status == Z_OK );
91 fwrite( &csize, sizeof(csize), 1, f );
92 fwrite( tmp, csize, 1, f );
93 g_free(tmp);
94 }
96 int fread_gzip( void *p, size_t sz, size_t count, FILE *f )
97 {
98 uLongf size = sz*count;
99 uLongf csize;
100 unsigned char *tmp;
102 fread( &csize, sizeof(csize), 1, f );
103 assert( csize <= (size*2) );
104 tmp = g_malloc0( csize );
105 fread( tmp, csize, 1, f );
106 int status = uncompress( p, &size, tmp, csize );
107 g_free(tmp);
108 if( status == Z_OK ) {
109 return count;
110 } else {
111 fprintf( stderr, "Error reading compressed data\n" );
112 return 0;
113 }
114 }
116 void fwrite_dump( unsigned char *data, unsigned int length, FILE *f )
117 {
118 unsigned int i, j;
119 for( i =0; i<length; i+=16 ) {
120 fprintf( f, "%08X:", i);
121 for( j=i; j<i+16; j++ ) {
122 if( (j % 4) == 0 )
123 fprintf( f, " " );
124 if( j < length )
125 fprintf( f, " %02X", (unsigned int)(data[j]) );
126 else
127 fprintf( f, " " );
128 }
129 fprintf( f, " " );
130 for( j=i; j<i+16 && j<length; j++ ) {
131 fprintf( f, "%c", isprint(data[j]) ? data[j] : '.' );
132 }
133 fprintf( f, "\n" );
134 }
135 }
137 void fwrite_dump32( unsigned int *data, unsigned int length, FILE *f )
138 {
139 fwrite_dump32v( data, length, 8, f );
140 }
142 void fwrite_dump32v( unsigned int *data, unsigned int length, int wordsPerLine, FILE *f )
143 {
144 unsigned int i, j;
145 for( i =0; i<length>>2; i+=wordsPerLine ) {
146 fprintf( f, "%08X:", i);
147 for( j=i; j<i+wordsPerLine; j++ ) {
148 if( j < length )
149 fprintf( f, " %08X", (unsigned int)(data[j]) );
150 else
151 fprintf( f, " " );
152 }
153 fprintf( f, "\n" );
154 }
155 }
157 gboolean write_png_to_stream( FILE *f, frame_buffer_t buffer )
158 {
159 int coltype, i;
160 png_bytep p;
161 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
162 if (!png_ptr) {
163 return FALSE;
164 }
166 png_infop info_ptr = png_create_info_struct(png_ptr);
167 if (!info_ptr) {
168 png_destroy_write_struct(&png_ptr, NULL);
169 return FALSE;
170 }
172 if( setjmp(png_jmpbuf(png_ptr)) ) {
173 png_destroy_write_struct(&png_ptr, &info_ptr);
174 return FALSE;
175 }
176 png_init_io( png_ptr, f );
177 switch( buffer->colour_format ) {
178 case COLFMT_BGR888:
179 coltype = PNG_COLOR_TYPE_RGB;
180 break;
181 case COLFMT_BGRA8888:
182 coltype = PNG_COLOR_TYPE_RGB_ALPHA;
183 break;
184 case COLFMT_BGR0888:
185 coltype = PNG_COLOR_TYPE_RGB;
186 break;
187 default:
188 coltype = PNG_COLOR_TYPE_RGB;
189 }
190 png_set_IHDR(png_ptr, info_ptr, buffer->width, buffer->height,
191 8, coltype, PNG_INTERLACE_NONE,
192 PNG_COMPRESSION_TYPE_DEFAULT,
193 PNG_FILTER_TYPE_DEFAULT );
194 png_write_info(png_ptr, info_ptr);
195 if( buffer->colour_format == COLFMT_BGR0888 ) {
196 png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
197 }
198 png_set_bgr(png_ptr);
199 if( buffer->inverted ) {
200 p = (png_bytep)(buffer->data + (buffer->height*buffer->rowstride) - buffer->rowstride);
201 for(i=0; i<buffer->height; i++ ) {
202 png_write_row(png_ptr, p);
203 p-=buffer->rowstride;
204 }
205 } else {
206 p = (png_bytep)buffer->data;
207 for(i=0; i<buffer->height; i++ ) {
208 png_write_row(png_ptr, p);
209 p+=buffer->rowstride;
210 }
211 }
212 png_write_end(png_ptr, info_ptr);
213 png_destroy_write_struct(&png_ptr, &info_ptr);
214 return TRUE;
215 }
217 frame_buffer_t read_png_from_stream( FILE *f )
218 {
219 png_bytep p;
220 int i;
221 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
222 NULL, NULL, NULL);
223 if (!png_ptr) {
224 return NULL;
225 }
227 png_infop info_ptr = png_create_info_struct(png_ptr);
228 if (!info_ptr) {
229 png_destroy_read_struct(&png_ptr, NULL, NULL);
230 return NULL;
231 }
233 png_infop end_info = png_create_info_struct(png_ptr);
234 if (!end_info) {
235 png_destroy_read_struct(&png_ptr, &info_ptr, NULL );
236 return NULL;
237 }
239 if( setjmp(png_jmpbuf(png_ptr)) ) {
240 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
241 return NULL;
242 }
244 png_init_io(png_ptr, f);
245 png_read_info(png_ptr, info_ptr);
247 png_uint_32 width, height;
248 int bit_depth, color_type, interlace_type,
249 compression_type, filter_method;
250 png_get_IHDR(png_ptr, info_ptr, &width, &height,
251 &bit_depth, &color_type, &interlace_type,
252 &compression_type, &filter_method);
253 assert( interlace_type == PNG_INTERLACE_NONE );
254 int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
255 int channels = png_get_channels(png_ptr, info_ptr);
256 frame_buffer_t buffer = g_malloc( sizeof(struct frame_buffer) + rowbytes*height );
257 buffer->data = (unsigned char *)(buffer+1);
258 buffer->width = width;
259 buffer->height = height;
260 buffer->rowstride = rowbytes;
261 buffer->address = -1;
262 buffer->size = rowbytes*height;
263 buffer->inverted = FALSE;
264 if( channels == 4 ) {
265 buffer->colour_format = COLFMT_BGRA8888;
266 } else if( channels == 3 ) {
267 buffer->colour_format = COLFMT_RGB888;
268 }
270 p = (png_bytep)buffer->data;
271 for( i=0; i<height; i++ ) {
272 png_read_row(png_ptr, p, NULL );
273 p += rowbytes;
274 }
276 png_read_end(png_ptr, end_info);
277 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
278 return buffer;
279 }
281 void log_message( void *ptr, int level, const gchar *source, const char *msg, ... )
282 {
283 char buf[20];
284 time_t tm = time(NULL);
285 va_list ap;
287 if( level > global_msg_level ) {
288 return; // ignored
289 }
291 va_start(ap, msg);
293 if( level <= EMIT_ERR ) {
294 gchar *text = g_strdup_vprintf( msg, ap );
295 if( gui_error_dialog( text ) ) {
296 g_free(text);
297 va_end(ap);
298 return;
299 }
300 g_free(text);
301 }
304 strftime( buf, sizeof(buf), "%H:%M:%S", localtime(&tm) );
305 fprintf( stderr, "%s %08X %-5s ", buf, sh4r.pc, msg_levels[level] );
306 vfprintf( stderr, msg, ap );
307 va_end(ap);
308 fprintf( stderr, "\n" );
309 }
.