2 * $Id: util.c,v 1.11 2007-10-31 09:10:23 nkeynes Exp $
4 * Miscellaneous utility functions.
6 * Copyright (c) 2005 Nathan Keynes.
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.
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.
30 #include "sh4/sh4core.h"
32 char *msg_levels[] = { "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE" };
33 int global_msg_level = EMIT_WARN;
35 void fwrite_string( const char *s, FILE *f )
39 fwrite( &len, sizeof(len), 1, f );
42 fwrite( &len, sizeof(len), 1, f );
43 fwrite( s, len, 1, f );
47 int fread_string( char *s, int maxlen, FILE *f )
50 fread( &len, sizeof(len), 1, f );
52 fread( s, len > maxlen ? maxlen : len, 1, f );
57 void fwrite_gzip( void *p, size_t sz, size_t count, FILE *f )
59 uLongf size = sz*count;
60 uLongf csize = ((int)(size*1.001))+13;
61 unsigned char *tmp = g_malloc0( csize );
62 int status = compress( tmp, &csize, p, size );
63 assert( status == Z_OK );
64 fwrite( &csize, sizeof(csize), 1, f );
65 fwrite( tmp, csize, 1, f );
69 int fread_gzip( void *p, size_t sz, size_t count, FILE *f )
71 uLongf size = sz*count;
75 fread( &csize, sizeof(csize), 1, f );
76 assert( csize <= (size*2) );
77 tmp = g_malloc0( csize );
78 fread( tmp, csize, 1, f );
79 int status = uncompress( p, &size, tmp, csize );
81 if( status == Z_OK ) {
84 fprintf( stderr, "Error reading compressed data\n" );
89 void fwrite_dump( unsigned char *data, unsigned int length, FILE *f )
92 for( i =0; i<length; i+=16 ) {
93 fprintf( f, "%08X:", i);
94 for( j=i; j<i+16; j++ ) {
98 fprintf( f, " %02X", (unsigned int)(data[j]) );
103 for( j=i; j<i+16 && j<length; j++ ) {
104 fprintf( f, "%c", isprint(data[j]) ? data[j] : '.' );
110 void fwrite_dump32( unsigned int *data, unsigned int length, FILE *f )
112 fwrite_dump32v( data, length, 8, f );
115 void fwrite_dump32v( unsigned int *data, unsigned int length, int wordsPerLine, FILE *f )
118 for( i =0; i<length>>2; i+=wordsPerLine ) {
119 fprintf( f, "%08X:", i);
120 for( j=i; j<i+wordsPerLine; j++ ) {
122 fprintf( f, " %08X", (unsigned int)(data[j]) );
130 gboolean write_png_to_stream( FILE *f, frame_buffer_t buffer )
134 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
139 png_infop info_ptr = png_create_info_struct(png_ptr);
141 png_destroy_write_struct(&png_ptr, NULL);
145 if( setjmp(png_jmpbuf(png_ptr)) ) {
146 png_destroy_write_struct(&png_ptr, &info_ptr);
149 png_init_io( png_ptr, f );
150 switch( buffer->colour_format ) {
152 coltype = PNG_COLOR_TYPE_RGB;
154 case COLFMT_BGRA8888:
155 coltype = PNG_COLOR_TYPE_RGB_ALPHA;
158 coltype = PNG_COLOR_TYPE_RGB;
161 coltype = PNG_COLOR_TYPE_RGB;
163 png_set_IHDR(png_ptr, info_ptr, buffer->width, buffer->height,
164 8, coltype, PNG_INTERLACE_NONE,
165 PNG_COMPRESSION_TYPE_DEFAULT,
166 PNG_FILTER_TYPE_DEFAULT );
167 png_write_info(png_ptr, info_ptr);
168 if( buffer->colour_format == COLFMT_BGR0888 ) {
169 png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
171 png_set_bgr(png_ptr);
172 if( buffer->inverted ) {
173 p = buffer->data + (buffer->height*buffer->rowstride) - buffer->rowstride;
174 for(i=0; i<buffer->height; i++ ) {
175 png_write_row(png_ptr, p);
176 p-=buffer->rowstride;
180 for(i=0; i<buffer->height; i++ ) {
181 png_write_row(png_ptr, p);
182 p+=buffer->rowstride;
185 png_write_end(png_ptr, info_ptr);
186 png_destroy_write_struct(&png_ptr, &info_ptr);
190 frame_buffer_t read_png_from_stream( FILE *f )
194 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
200 png_infop info_ptr = png_create_info_struct(png_ptr);
202 png_destroy_read_struct(&png_ptr, NULL, NULL);
206 png_infop end_info = png_create_info_struct(png_ptr);
208 png_destroy_read_struct(&png_ptr, &info_ptr, NULL );
212 if( setjmp(png_jmpbuf(png_ptr)) ) {
213 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
217 png_init_io(png_ptr, f);
218 png_read_info(png_ptr, info_ptr);
220 png_uint_32 width, height;
221 int bit_depth, color_type, interlace_type,
222 compression_type, filter_method;
223 png_get_IHDR(png_ptr, info_ptr, &width, &height,
224 &bit_depth, &color_type, &interlace_type,
225 &compression_type, &filter_method);
226 assert( interlace_type == PNG_INTERLACE_NONE );
227 int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
228 int channels = png_get_channels(png_ptr, info_ptr);
229 frame_buffer_t buffer = g_malloc( sizeof(struct frame_buffer) + rowbytes*height );
230 buffer->data = (char *)(buffer+1);
231 buffer->width = width;
232 buffer->height = height;
233 buffer->rowstride = rowbytes;
234 buffer->address = -1;
235 buffer->size = rowbytes*height;
236 buffer->inverted = FALSE;
237 if( channels == 4 ) {
238 buffer->colour_format = COLFMT_BGRA8888;
239 } else if( channels == 3 ) {
240 buffer->colour_format = COLFMT_RGB888;
244 for( i=0; i<height; i++ ) {
245 png_read_row(png_ptr, p, NULL );
249 png_read_end(png_ptr, end_info);
250 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
254 void log_message( void *ptr, int level, const gchar *source, const char *msg, ... )
256 char buf[20], addr[10] = "", *p;
257 const gchar *arr[4] = {buf, source, addr};
259 time_t tm = time(NULL);
262 if( level > global_msg_level ) {
268 if( level <= EMIT_ERR ) {
269 gchar *text = g_strdup_vprintf( msg, ap );
270 if( gui_error_dialog( text ) ) {
279 strftime( buf, sizeof(buf), "%H:%M:%S", localtime(&tm) );
280 fprintf( stderr, "%s %08X %-5s ", buf, sh4r.pc, msg_levels[level] );
281 vfprintf( stderr, msg, ap );
283 fprintf( stderr, "\n" );
.