changeset 496:a6d060a64246

pixel introspection. but entire image is upside down.
author Robert McIntyre <rlm@mit.edu>
date Mon, 11 Jun 2012 06:04:25 -0500
parents 1d81ddd4fa41
children 690811e54b51
files clojure/com/aurellem/gb/gb_driver.clj clojure/com/aurellem/run/image.clj clojure/com/aurellem/run/music.clj java/src/com/aurellem/gb/Gb.java src/VisualBoyAdvance.cfg src/clojure/clojure.cpp src/common/Util.cpp src/gb/GB.cpp src/gb/GB.h
diffstat 9 files changed, 1016 insertions(+), 907 deletions(-) [+]
line wrap: on
line diff
     1.1 --- a/clojure/com/aurellem/gb/gb_driver.clj	Mon Jun 11 00:55:51 2012 -0500
     1.2 +++ b/clojure/com/aurellem/gb/gb_driver.clj	Mon Jun 11 06:04:25 2012 -0500
     1.3 @@ -40,6 +40,7 @@
     1.4        (SaveState. buffer))))
     1.5  ;;;;;;;;;;;;;;;;
     1.6  
     1.7 +
     1.8  ;; Gameboy management
     1.9  (Gb/loadVBA)
    1.10  
    1.11 @@ -156,6 +157,17 @@
    1.12    
    1.13  ;;;;;;;;;;;
    1.14  
    1.15 +;; Get Screen Pixels, Save Screenshot
    1.16 +
    1.17 +(defn write-png!
    1.18 +  ([^SaveState state ^File target]
    1.19 +     (set-state! state)
    1.20 +     (Gb/nwritePNG (.getCanonicalPath target)))
    1.21 +  ([^File target]
    1.22 +     (write-png! @current-state target)))
    1.23 +
    1.24 +
    1.25 +
    1.26  
    1.27  ;;;;;;;;;;;;;;; CPU data
    1.28  
    1.29 @@ -176,7 +188,6 @@
    1.30           (update-state)))
    1.31      ([new-data]
    1.32         (store-data @current-state new-data))))
    1.33 -    
    1.34  
    1.35  (def memory
    1.36    (cpu-data Gb/GB_MEMORY #(Gb/getMemory %)))
    1.37 @@ -196,6 +207,10 @@
    1.38  (def registers
    1.39    (cpu-data Gb/NUM_REGISTERS #(Gb/getRegisters %)))
    1.40  
    1.41 +(def pixels
    1.42 +  (cpu-data (* Gb/DISPLAY_WIDTH Gb/DISPLAY_HEIGHT)
    1.43 +            #(Gb/getPixels %)))
    1.44 +
    1.45  (def write-memory!
    1.46    (write-cpu-data Gb/GB_MEMORY #(Gb/writeMemory %)))
    1.47  
    1.48 @@ -279,4 +294,6 @@
    1.49  (defn rgb->gb-rb [[r g b :as color]]
    1.50    (let [store (int-array 3)]
    1.51      (Gb/translateRGB (int-array color) store)
    1.52 -    (vec store)))
    1.53 \ No newline at end of file
    1.54 +    (vec store)))
    1.55 +
    1.56 +
     2.1 --- a/clojure/com/aurellem/run/image.clj	Mon Jun 11 00:55:51 2012 -0500
     2.2 +++ b/clojure/com/aurellem/run/image.clj	Mon Jun 11 06:04:25 2012 -0500
     2.3 @@ -143,7 +143,21 @@
     2.4          (PC! kernel-address))))
     2.5  
     2.6  
     2.7 +(require 'cortex.sense)
     2.8 +(import java.awt.image.BufferedImage)
     2.9  
    2.10 +(defn show-screenshot []
    2.11 +  (let [im (BufferedImage. 160 144 BufferedImage/TYPE_INT_RGB)
    2.12 +        pix (vec (pixels))
    2.13 +        view (cortex.sense/view-image)]
    2.14 +    (dorun (for [x (range 160) y (range 144)]
    2.15 +             (.setRGB im x y
    2.16 +                      ;0
    2.17 +                      (pix (+ x (* 160 y)))
    2.18 +                      )))
    2.19 +    (view im)))
    2.20 +
    2.21 +     
    2.22    
    2.23  (defn write-palette-color [palette-num r g b]
    2.24    (let [[byte-1 byte-2] (gb-rgb->bits r g b)]
     3.1 --- a/clojure/com/aurellem/run/music.clj	Mon Jun 11 00:55:51 2012 -0500
     3.2 +++ b/clojure/com/aurellem/run/music.clj	Mon Jun 11 06:04:25 2012 -0500
     3.3 @@ -450,7 +450,7 @@
     3.4  ;; want: seconds
     3.5  
     3.6  
     3.7 -(defn silence [length]
     3.8 +(defn silent-note [length]
     3.9    {:frequency 1
    3.10     :duration length
    3.11     :volume 0})
    3.12 @@ -518,9 +518,9 @@
    3.13                 (let [note-1-space (- (:time-stamp note-2)
    3.14                                       (:time-stamp note-1))
    3.15                       note-1-length (:duration note-1)]
    3.16 -                 (silence (- note-1-space note-1-length))))
    3.17 +                 (silent-note (- note-1-space note-1-length))))
    3.18               ;; to handle silence at the beginning.
    3.19 -             (concat [(assoc (silence 0)
    3.20 +             (concat [(assoc (silent-note 0)
    3.21                          :time-stamp 0)] notes)
    3.22               notes)
    3.23          
    3.24 @@ -528,7 +528,7 @@
    3.25          (concat
    3.26           (filter (comp not zero? :duration)
    3.27                   (interleave silences notes))
    3.28 -         [(silence 3)])]
    3.29 +         [(silent-note 3)])]
    3.30      notes-with-silence))
    3.31        
    3.32  (defn midi-track->mini-midi-voice [#^File midi-file track-num]
     4.1 --- a/java/src/com/aurellem/gb/Gb.java	Mon Jun 11 00:55:51 2012 -0500
     4.2 +++ b/java/src/com/aurellem/gb/Gb.java	Mon Jun 11 06:04:25 2012 -0500
     4.3 @@ -121,4 +121,12 @@
     4.4  
     4.5      public static native void translateRGB(int[] rgb, int[] store);
     4.6  
     4.7 +    public static final int DISPLAY_WIDTH = 160;
     4.8 +     
     4.9 +    public static final int DISPLAY_HEIGHT = 144;
    4.10 +
    4.11 +    public static native void getPixels(int[] store);
    4.12 +
    4.13 +    public static native void nwritePNG(String filename);
    4.14 +
    4.15  }
     5.1 --- a/src/VisualBoyAdvance.cfg	Mon Jun 11 00:55:51 2012 -0500
     5.2 +++ b/src/VisualBoyAdvance.cfg	Mon Jun 11 06:04:25 2012 -0500
     5.3 @@ -89,7 +89,7 @@
     5.4  filter=0
     5.5  
     5.6  # Disable status messages. 0=false, any other value means true
     5.7 -disableStatus=0
     5.8 +disableStatus=1
     5.9  
    5.10  # Enable Gameboy border. 0=false, any other value means true
    5.11  borderOn=0
     6.1 --- a/src/clojure/clojure.cpp	Mon Jun 11 00:55:51 2012 -0500
     6.2 +++ b/src/clojure/clojure.cpp	Mon Jun 11 06:04:25 2012 -0500
     6.3 @@ -310,3 +310,29 @@
     6.4    env->ReleaseIntArrayElements(rgb, RGB_Arr, 0);
     6.5    env->ReleaseIntArrayElements(store, store_Arr, 0);
     6.6  }
     6.7 +
     6.8 +
     6.9 +/*
    6.10 + * Class:     com_aurellem_gb_Gb
    6.11 + * Method:    getPixels
    6.12 + * Signature: ([I)V
    6.13 + */
    6.14 +JNIEXPORT void JNICALL Java_com_aurellem_gb_Gb_getPixels
    6.15 +(JNIEnv *env, jclass clazz, jintArray arr){
    6.16 +  jint *pixel_store = env->GetIntArrayElements(arr, 0);
    6.17 +  getPixels32(pixel_store);
    6.18 +  env->ReleaseIntArrayElements(arr, pixel_store, 0);
    6.19 +}
    6.20 +
    6.21 +/*
    6.22 + * Class:     com_aurellem_gb_Gb
    6.23 + * Method:    nwritePNG
    6.24 + * Signature: (Ljava/lang/String;)V
    6.25 + */
    6.26 +JNIEXPORT void JNICALL Java_com_aurellem_gb_Gb_nwritePNG
    6.27 +(JNIEnv *env, jclass clazz, jstring filename){
    6.28 +  const char *_filename = env->GetStringUTFChars(filename, 0);
    6.29 +  gbWritePNGFile(_filename);
    6.30 +}
    6.31 +
    6.32 +  
     7.1 --- a/src/common/Util.cpp	Mon Jun 11 00:55:51 2012 -0500
     7.2 +++ b/src/common/Util.cpp	Mon Jun 11 06:04:25 2012 -0500
     7.3 @@ -48,238 +48,247 @@
     7.4  //due to void* and const void* differences
     7.5  //--Felipe 
     7.6  int gzWrite(gzFile file, void* buf, unsigned len){
     7.7 -	return gzwrite(file,buf,len);
     7.8 +  return gzwrite(file,buf,len);
     7.9  }
    7.10  
    7.11  void utilPutDword(u8 *p, u32 value)
    7.12  {
    7.13 -	*p++ = value & 255;
    7.14 -	*p++ = (value >> 8) & 255;
    7.15 -	*p++ = (value >> 16) & 255;
    7.16 -	*p	 = (value >> 24) & 255;
    7.17 +  *p++ = value & 255;
    7.18 +  *p++ = (value >> 8) & 255;
    7.19 +  *p++ = (value >> 16) & 255;
    7.20 +  *p	 = (value >> 24) & 255;
    7.21  }
    7.22  
    7.23  void utilPutWord(u8 *p, u16 value)
    7.24  {
    7.25 -	*p++ = value & 255;
    7.26 -	*p	 = (value >> 8) & 255;
    7.27 +  *p++ = value & 255;
    7.28 +  *p	 = (value >> 8) & 255;
    7.29  }
    7.30  
    7.31  void utilWriteBMP(u8 *b, int w, int h, int dstDepth, u8 *pix)
    7.32  {
    7.33 -	int sizeX = w;
    7.34 -	int sizeY = h;
    7.35 +  int sizeX = w;
    7.36 +  int sizeY = h;
    7.37  
    7.38 -	switch (dstDepth > 0 ? dstDepth : systemColorDepth)
    7.39 -	{
    7.40 -	case 16:
    7.41 -	{
    7.42 -		u16 *p = (u16 *)(pix + (w + 2) * (h) * 2); // skip first black line
    7.43 -		for (int y = 0; y < sizeY; y++)
    7.44 -		{
    7.45 -			for (int x = 0; x < sizeX; x++)
    7.46 -			{
    7.47 -				u16 v = *p++;
    7.48 +  switch (dstDepth > 0 ? dstDepth : systemColorDepth)
    7.49 +    {
    7.50 +    case 16:
    7.51 +      {
    7.52 +	u16 *p = (u16 *)(pix + (w + 2) * (h) * 2); // skip first black line
    7.53 +	for (int y = 0; y < sizeY; y++)
    7.54 +	  {
    7.55 +	    for (int x = 0; x < sizeX; x++)
    7.56 +	      {
    7.57 +		u16 v = *p++;
    7.58  
    7.59 -				*b++ = ((v >> systemBlueShift) & 0x01f) << 3; // B
    7.60 -				*b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G
    7.61 -				*b++ = ((v >> systemRedShift) & 0x001f) << 3; // R
    7.62 -			}
    7.63 -			p++; // skip black pixel for filters
    7.64 -			p++; // skip black pixel for filters
    7.65 -			p -= 2 * (w + 2);
    7.66 -		}
    7.67 -		break;
    7.68 -	}
    7.69 -	case 24:
    7.70 -	{
    7.71 -		u8 *pixU8 = (u8 *)pix + 3 * w * (h - 1);
    7.72 -		for (int y = 0; y < sizeY; y++)
    7.73 -		{
    7.74 -			for (int x = 0; x < sizeX; x++)
    7.75 -			{
    7.76 -				if (systemRedShift > systemBlueShift)
    7.77 -				{
    7.78 -					*b++ = *pixU8++; // B
    7.79 -					*b++ = *pixU8++; // G
    7.80 -					*b++ = *pixU8++; // R
    7.81 -				}
    7.82 -				else
    7.83 -				{
    7.84 -					int red	  = *pixU8++;
    7.85 -					int green = *pixU8++;
    7.86 -					int blue  = *pixU8++;
    7.87 +		*b++ = ((v >> systemBlueShift) & 0x01f) << 3; // B
    7.88 +		*b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G
    7.89 +		*b++ = ((v >> systemRedShift) & 0x001f) << 3; // R
    7.90 +	      }
    7.91 +	    p++; // skip black pixel for filters
    7.92 +	    p++; // skip black pixel for filters
    7.93 +	    p -= 2 * (w + 2);
    7.94 +	  }
    7.95 +	break;
    7.96 +      }
    7.97 +    case 24:
    7.98 +      {
    7.99 +	u8 *pixU8 = (u8 *)pix + 3 * w * (h - 1);
   7.100 +	for (int y = 0; y < sizeY; y++)
   7.101 +	  {
   7.102 +	    for (int x = 0; x < sizeX; x++)
   7.103 +	      {
   7.104 +		if (systemRedShift > systemBlueShift)
   7.105 +		  {
   7.106 +		    *b++ = *pixU8++; // B
   7.107 +		    *b++ = *pixU8++; // G
   7.108 +		    *b++ = *pixU8++; // R
   7.109 +		  }
   7.110 +		else
   7.111 +		  {
   7.112 +		    int red	  = *pixU8++;
   7.113 +		    int green = *pixU8++;
   7.114 +		    int blue  = *pixU8++;
   7.115  
   7.116 -					*b++ = blue;
   7.117 -					*b++ = green;
   7.118 -					*b++ = red;
   7.119 -				}
   7.120 -			}
   7.121 -			pixU8 -= 2 * 3 * w;
   7.122 -		}
   7.123 -		break;
   7.124 -	}
   7.125 -	case 32:
   7.126 -	{
   7.127 -		u32 *pixU32 = (u32 *)(pix + 4 * (w + 1) * (h));
   7.128 -		for (int y = 0; y < sizeY; y++)
   7.129 -		{
   7.130 -			for (int x = 0; x < sizeX; x++)
   7.131 -			{
   7.132 -				u32 v = *pixU32++;
   7.133 +		    *b++ = blue;
   7.134 +		    *b++ = green;
   7.135 +		    *b++ = red;
   7.136 +		  }
   7.137 +	      }
   7.138 +	    pixU8 -= 2 * 3 * w;
   7.139 +	  }
   7.140 +	break;
   7.141 +      }
   7.142 +    case 32:
   7.143 +      {
   7.144 +	u32 *pixU32 = (u32 *)(pix + 4 * (w + 1) * (h));
   7.145 +	for (int y = 0; y < sizeY; y++)
   7.146 +	  {
   7.147 +	    for (int x = 0; x < sizeX; x++)
   7.148 +	      {
   7.149 +		u32 v = *pixU32++;
   7.150 +		//RLM pack bits for java ARGB
   7.151  
   7.152 -				*b++ = ((v >> systemBlueShift) & 0x001f) << 3; // B
   7.153 -				*b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G
   7.154 -				*b++ = ((v >> systemRedShift) & 0x001f) << 3; // R
   7.155 -			}
   7.156 -			pixU32++;
   7.157 -			pixU32 -= 2 * (w + 1);
   7.158 -		}
   7.159 -		break;
   7.160 -	}
   7.161 -	}
   7.162 +
   7.163 +		*b++ = ((v >> systemRedShift) & 0x001f) << 3; // R	
   7.164 +		*b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G
   7.165 +		*b++ = ((v >> systemBlueShift) & 0x001f) << 3; // B
   7.166 +		*b++ = 0; // Alpha
   7.167 +
   7.168 +		
   7.169 +
   7.170 +		// end RLM
   7.171 +		
   7.172 +		
   7.173 +	      }
   7.174 +	    pixU32++;
   7.175 +	    pixU32 -= 2 * (w + 1);
   7.176 +	  }
   7.177 +	break;
   7.178 +      }
   7.179 +    }
   7.180  }
   7.181  
   7.182  bool utilWriteBMPFile(const char *fileName, int w, int h, u8 *pix)
   7.183  {
   7.184 -	u8 writeBuffer[256 * 3];
   7.185 +  u8 writeBuffer[256 * 3];
   7.186  
   7.187 -	FILE *fp = fopen(fileName, "wb");
   7.188 +  FILE *fp = fopen(fileName, "wb");
   7.189  
   7.190 -	if (!fp)
   7.191 -	{
   7.192 -		systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), fileName);
   7.193 -		return false;
   7.194 -	}
   7.195 +  if (!fp)
   7.196 +    {
   7.197 +      systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), fileName);
   7.198 +      return false;
   7.199 +    }
   7.200  
   7.201 -	struct
   7.202 -	{
   7.203 -		u8 ident[2];
   7.204 -		u8 filesize[4];
   7.205 -		u8 reserved[4];
   7.206 -		u8 dataoffset[4];
   7.207 -		u8 headersize[4];
   7.208 -		u8 width[4];
   7.209 -		u8 height[4];
   7.210 -		u8 planes[2];
   7.211 -		u8 bitsperpixel[2];
   7.212 -		u8 compression[4];
   7.213 -		u8 datasize[4];
   7.214 -		u8 hres[4];
   7.215 -		u8 vres[4];
   7.216 -		u8 colors[4];
   7.217 -		u8 importantcolors[4];
   7.218 -		//    u8 pad[2];
   7.219 -	} bmpheader;
   7.220 -	memset(&bmpheader, 0, sizeof(bmpheader));
   7.221 +  struct
   7.222 +  {
   7.223 +    u8 ident[2];
   7.224 +    u8 filesize[4];
   7.225 +    u8 reserved[4];
   7.226 +    u8 dataoffset[4];
   7.227 +    u8 headersize[4];
   7.228 +    u8 width[4];
   7.229 +    u8 height[4];
   7.230 +    u8 planes[2];
   7.231 +    u8 bitsperpixel[2];
   7.232 +    u8 compression[4];
   7.233 +    u8 datasize[4];
   7.234 +    u8 hres[4];
   7.235 +    u8 vres[4];
   7.236 +    u8 colors[4];
   7.237 +    u8 importantcolors[4];
   7.238 +    //    u8 pad[2];
   7.239 +  } bmpheader;
   7.240 +  memset(&bmpheader, 0, sizeof(bmpheader));
   7.241  
   7.242 -	bmpheader.ident[0] = 'B';
   7.243 -	bmpheader.ident[1] = 'M';
   7.244 +  bmpheader.ident[0] = 'B';
   7.245 +  bmpheader.ident[1] = 'M';
   7.246  
   7.247 -	u32 fsz = sizeof(bmpheader) + w * h * 3;
   7.248 -	utilPutDword(bmpheader.filesize, fsz);
   7.249 -	utilPutDword(bmpheader.dataoffset, 0x36);
   7.250 -	utilPutDword(bmpheader.headersize, 0x28);
   7.251 -	utilPutDword(bmpheader.width, w);
   7.252 -	utilPutDword(bmpheader.height, h);
   7.253 -	utilPutDword(bmpheader.planes, 1);
   7.254 -	utilPutDword(bmpheader.bitsperpixel, 24);
   7.255 -	utilPutDword(bmpheader.datasize, 3 * w * h);
   7.256 +  u32 fsz = sizeof(bmpheader) + w * h * 3;
   7.257 +  utilPutDword(bmpheader.filesize, fsz);
   7.258 +  utilPutDword(bmpheader.dataoffset, 0x36);
   7.259 +  utilPutDword(bmpheader.headersize, 0x28);
   7.260 +  utilPutDword(bmpheader.width, w);
   7.261 +  utilPutDword(bmpheader.height, h);
   7.262 +  utilPutDword(bmpheader.planes, 1);
   7.263 +  utilPutDword(bmpheader.bitsperpixel, 24);
   7.264 +  utilPutDword(bmpheader.datasize, 3 * w * h);
   7.265  
   7.266 -	fwrite(&bmpheader, 1, sizeof(bmpheader), fp);
   7.267 +  fwrite(&bmpheader, 1, sizeof(bmpheader), fp);
   7.268  
   7.269  #if 0
   7.270 -	// FIXME: need sufficient buffer
   7.271 -	utilWriteBMP(writeBuffer, w, h, systemColorDepth, pix);
   7.272 +  // FIXME: need sufficient buffer
   7.273 +  utilWriteBMP(writeBuffer, w, h, systemColorDepth, pix);
   7.274  #else
   7.275 -	u8 *b = writeBuffer;
   7.276 +  u8 *b = writeBuffer;
   7.277  
   7.278 -	int sizeX = w;
   7.279 -	int sizeY = h;
   7.280 +  int sizeX = w;
   7.281 +  int sizeY = h;
   7.282  
   7.283 -	switch (systemColorDepth)
   7.284 -	{
   7.285 -	case 16:
   7.286 -	{
   7.287 -		u16 *p = (u16 *)(pix + (w + 2) * (h) * 2); // skip first black line
   7.288 -		for (int y = 0; y < sizeY; y++)
   7.289 -		{
   7.290 -			for (int x = 0; x < sizeX; x++)
   7.291 -			{
   7.292 -				u16 v = *p++;
   7.293 +  switch (systemColorDepth)
   7.294 +    {
   7.295 +    case 16:
   7.296 +      {
   7.297 +	u16 *p = (u16 *)(pix + (w + 2) * (h) * 2); // skip first black line
   7.298 +	for (int y = 0; y < sizeY; y++)
   7.299 +	  {
   7.300 +	    for (int x = 0; x < sizeX; x++)
   7.301 +	      {
   7.302 +		u16 v = *p++;
   7.303  
   7.304 -				*b++ = ((v >> systemBlueShift) & 0x01f) << 3; // B
   7.305 -				*b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G
   7.306 -				*b++ = ((v >> systemRedShift) & 0x001f) << 3; // R
   7.307 -			}
   7.308 -			p++; // skip black pixel for filters
   7.309 -			p++; // skip black pixel for filters
   7.310 -			p -= 2 * (w + 2);
   7.311 -			fwrite(writeBuffer, 1, 3 * w, fp);
   7.312 +		*b++ = ((v >> systemBlueShift) & 0x01f) << 3; // B
   7.313 +		*b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G
   7.314 +		*b++ = ((v >> systemRedShift) & 0x001f) << 3; // R
   7.315 +	      }
   7.316 +	    p++; // skip black pixel for filters
   7.317 +	    p++; // skip black pixel for filters
   7.318 +	    p -= 2 * (w + 2);
   7.319 +	    fwrite(writeBuffer, 1, 3 * w, fp);
   7.320  
   7.321 -			b = writeBuffer;
   7.322 -		}
   7.323 -		break;
   7.324 -	}
   7.325 -	case 24:
   7.326 -	{
   7.327 -		u8 *pixU8 = (u8 *)pix + 3 * w * (h - 1);
   7.328 -		for (int y = 0; y < sizeY; y++)
   7.329 -		{
   7.330 -			for (int x = 0; x < sizeX; x++)
   7.331 -			{
   7.332 -				if (systemRedShift > systemBlueShift)
   7.333 -				{
   7.334 -					*b++ = *pixU8++; // B
   7.335 -					*b++ = *pixU8++; // G
   7.336 -					*b++ = *pixU8++; // R
   7.337 -				}
   7.338 -				else
   7.339 -				{
   7.340 -					int red	  = *pixU8++;
   7.341 -					int green = *pixU8++;
   7.342 -					int blue  = *pixU8++;
   7.343 +	    b = writeBuffer;
   7.344 +	  }
   7.345 +	break;
   7.346 +      }
   7.347 +    case 24:
   7.348 +      {
   7.349 +	u8 *pixU8 = (u8 *)pix + 3 * w * (h - 1);
   7.350 +	for (int y = 0; y < sizeY; y++)
   7.351 +	  {
   7.352 +	    for (int x = 0; x < sizeX; x++)
   7.353 +	      {
   7.354 +		if (systemRedShift > systemBlueShift)
   7.355 +		  {
   7.356 +		    *b++ = *pixU8++; // B
   7.357 +		    *b++ = *pixU8++; // G
   7.358 +		    *b++ = *pixU8++; // R
   7.359 +		  }
   7.360 +		else
   7.361 +		  {
   7.362 +		    int red	  = *pixU8++;
   7.363 +		    int green = *pixU8++;
   7.364 +		    int blue  = *pixU8++;
   7.365  
   7.366 -					*b++ = blue;
   7.367 -					*b++ = green;
   7.368 -					*b++ = red;
   7.369 -				}
   7.370 -			}
   7.371 -			pixU8 -= 2 * 3 * w;
   7.372 -			fwrite(writeBuffer, 1, 3 * w, fp);
   7.373 +		    *b++ = blue;
   7.374 +		    *b++ = green;
   7.375 +		    *b++ = red;
   7.376 +		  }
   7.377 +	      }
   7.378 +	    pixU8 -= 2 * 3 * w;
   7.379 +	    fwrite(writeBuffer, 1, 3 * w, fp);
   7.380  
   7.381 -			b = writeBuffer;
   7.382 -		}
   7.383 -		break;
   7.384 -	}
   7.385 -	case 32:
   7.386 -	{
   7.387 -		u32 *pixU32 = (u32 *)(pix + 4 * (w + 1) * (h));
   7.388 -		for (int y = 0; y < sizeY; y++)
   7.389 -		{
   7.390 -			for (int x = 0; x < sizeX; x++)
   7.391 -			{
   7.392 -				u32 v = *pixU32++;
   7.393 +	    b = writeBuffer;
   7.394 +	  }
   7.395 +	break;
   7.396 +      }
   7.397 +    case 32:
   7.398 +      {
   7.399 +	u32 *pixU32 = (u32 *)(pix + 4 * (w + 1) * (h));
   7.400 +	for (int y = 0; y < sizeY; y++)
   7.401 +	  {
   7.402 +	    for (int x = 0; x < sizeX; x++)
   7.403 +	      {
   7.404 +		u32 v = *pixU32++;
   7.405  
   7.406 -				*b++ = ((v >> systemBlueShift) & 0x001f) << 3; // B
   7.407 -				*b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G
   7.408 -				*b++ = ((v >> systemRedShift) & 0x001f) << 3; // R
   7.409 -			}
   7.410 -			pixU32++;
   7.411 -			pixU32 -= 2 * (w + 1);
   7.412 +		*b++ = ((v >> systemBlueShift) & 0x001f) << 3; // B
   7.413 +		*b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G
   7.414 +		*b++ = ((v >> systemRedShift) & 0x001f) << 3; // R
   7.415 +	      }
   7.416 +	    pixU32++;
   7.417 +	    pixU32 -= 2 * (w + 1);
   7.418  
   7.419 -			fwrite(writeBuffer, 1, 3 * w, fp);
   7.420 +	    fwrite(writeBuffer, 1, 3 * w, fp);
   7.421  
   7.422 -			b = writeBuffer;
   7.423 -		}
   7.424 -		break;
   7.425 -	}
   7.426 -	}
   7.427 +	    b = writeBuffer;
   7.428 +	  }
   7.429 +	break;
   7.430 +      }
   7.431 +    }
   7.432  #endif
   7.433  
   7.434 -	fclose(fp);
   7.435 +  fclose(fp);
   7.436  
   7.437 -	return true;
   7.438 +  return true;
   7.439  }
   7.440  
   7.441  bool utilWritePNGFile(const char *fileName, int w, int h, u8 *pix)
   7.442 @@ -426,403 +435,403 @@
   7.443  
   7.444  static int utilReadInt2(FILE *f)
   7.445  {
   7.446 -	int res = 0;
   7.447 -	int c	= fgetc(f);
   7.448 -	if (c == EOF)
   7.449 -		return -1;
   7.450 -	res = c;
   7.451 -	c	= fgetc(f);
   7.452 -	if (c == EOF)
   7.453 -		return -1;
   7.454 -	return c + (res << 8);
   7.455 +  int res = 0;
   7.456 +  int c	= fgetc(f);
   7.457 +  if (c == EOF)
   7.458 +    return -1;
   7.459 +  res = c;
   7.460 +  c	= fgetc(f);
   7.461 +  if (c == EOF)
   7.462 +    return -1;
   7.463 +  return c + (res << 8);
   7.464  }
   7.465  
   7.466  static int utilReadInt3(FILE *f)
   7.467  {
   7.468 -	int res = 0;
   7.469 -	int c	= fgetc(f);
   7.470 -	if (c == EOF)
   7.471 -		return -1;
   7.472 -	res = c;
   7.473 -	c	= fgetc(f);
   7.474 -	if (c == EOF)
   7.475 -		return -1;
   7.476 -	res = c + (res << 8);
   7.477 -	c	= fgetc(f);
   7.478 -	if (c == EOF)
   7.479 -		return -1;
   7.480 -	return c + (res << 8);
   7.481 +  int res = 0;
   7.482 +  int c	= fgetc(f);
   7.483 +  if (c == EOF)
   7.484 +    return -1;
   7.485 +  res = c;
   7.486 +  c	= fgetc(f);
   7.487 +  if (c == EOF)
   7.488 +    return -1;
   7.489 +  res = c + (res << 8);
   7.490 +  c	= fgetc(f);
   7.491 +  if (c == EOF)
   7.492 +    return -1;
   7.493 +  return c + (res << 8);
   7.494  }
   7.495  
   7.496  void utilApplyIPS(const char *ips, u8 * *r, int *s)
   7.497  {
   7.498 -	// from the IPS spec at http://zerosoft.zophar.net/ips.htm
   7.499 -	FILE *f = fopen(ips, "rb");
   7.500 -	if (!f)
   7.501 -		return;
   7.502 -	u8 *rom	 = *r;
   7.503 -	int size = *s;
   7.504 -	if (fgetc(f) == 'P' &&
   7.505 -	    fgetc(f) == 'A' &&
   7.506 -	    fgetc(f) == 'T' &&
   7.507 -	    fgetc(f) == 'C' &&
   7.508 -	    fgetc(f) == 'H')
   7.509 +  // from the IPS spec at http://zerosoft.zophar.net/ips.htm
   7.510 +  FILE *f = fopen(ips, "rb");
   7.511 +  if (!f)
   7.512 +    return;
   7.513 +  u8 *rom	 = *r;
   7.514 +  int size = *s;
   7.515 +  if (fgetc(f) == 'P' &&
   7.516 +      fgetc(f) == 'A' &&
   7.517 +      fgetc(f) == 'T' &&
   7.518 +      fgetc(f) == 'C' &&
   7.519 +      fgetc(f) == 'H')
   7.520 +    {
   7.521 +      int b;
   7.522 +      int offset;
   7.523 +      int len;
   7.524 +      for (;; )
   7.525  	{
   7.526 -		int b;
   7.527 -		int offset;
   7.528 -		int len;
   7.529 -		for (;; )
   7.530 +	  // read offset
   7.531 +	  offset = utilReadInt3(f);
   7.532 +	  // if offset == EOF, end of patch
   7.533 +	  if (offset == 0x454f46)
   7.534 +	    break;
   7.535 +	  // read length
   7.536 +	  len = utilReadInt2(f);
   7.537 +	  if (!len)
   7.538 +	    {
   7.539 +	      // len == 0, RLE block
   7.540 +	      len = utilReadInt2(f);
   7.541 +	      // byte to fill
   7.542 +	      int c = fgetc(f);
   7.543 +	      if (c == -1)
   7.544 +		break;
   7.545 +	      b = (u8)c;
   7.546 +	    }
   7.547 +	  else
   7.548 +	    b = -1;
   7.549 +	  // check if we need to reallocate our ROM
   7.550 +	  if ((offset + len) >= size)
   7.551 +	    {
   7.552 +	      size *= 2;
   7.553 +	      rom	  = (u8 *)realloc(rom, size);
   7.554 +	      *r	  = rom;
   7.555 +	      *s	  = size;
   7.556 +	    }
   7.557 +	  if (b == -1)
   7.558 +	    {
   7.559 +	      // normal block, just read the data
   7.560 +	      if (fread(&rom[offset], 1, len, f) != (size_t)len)
   7.561 +		break;
   7.562 +	    }
   7.563 +	  else
   7.564 +	    {
   7.565 +	      // fill the region with the given byte
   7.566 +	      while (len--)
   7.567  		{
   7.568 -			// read offset
   7.569 -			offset = utilReadInt3(f);
   7.570 -			// if offset == EOF, end of patch
   7.571 -			if (offset == 0x454f46)
   7.572 -				break;
   7.573 -			// read length
   7.574 -			len = utilReadInt2(f);
   7.575 -			if (!len)
   7.576 -			{
   7.577 -				// len == 0, RLE block
   7.578 -				len = utilReadInt2(f);
   7.579 -				// byte to fill
   7.580 -				int c = fgetc(f);
   7.581 -				if (c == -1)
   7.582 -					break;
   7.583 -				b = (u8)c;
   7.584 -			}
   7.585 -			else
   7.586 -				b = -1;
   7.587 -			// check if we need to reallocate our ROM
   7.588 -			if ((offset + len) >= size)
   7.589 -			{
   7.590 -				size *= 2;
   7.591 -				rom	  = (u8 *)realloc(rom, size);
   7.592 -				*r	  = rom;
   7.593 -				*s	  = size;
   7.594 -			}
   7.595 -			if (b == -1)
   7.596 -			{
   7.597 -				// normal block, just read the data
   7.598 -				if (fread(&rom[offset], 1, len, f) != (size_t)len)
   7.599 -					break;
   7.600 -			}
   7.601 -			else
   7.602 -			{
   7.603 -				// fill the region with the given byte
   7.604 -				while (len--)
   7.605 -				{
   7.606 -					rom[offset++] = b;
   7.607 -				}
   7.608 -			}
   7.609 +		  rom[offset++] = b;
   7.610  		}
   7.611 +	    }
   7.612  	}
   7.613 -	// close the file
   7.614 -	fclose(f);
   7.615 +    }
   7.616 +  // close the file
   7.617 +  fclose(f);
   7.618  }
   7.619  
   7.620  extern bool8 cpuIsMultiBoot;
   7.621  
   7.622  bool utilIsGBAImage(const char *file)
   7.623  {
   7.624 -	cpuIsMultiBoot = false;
   7.625 -	if (strlen(file) > 4)
   7.626 +  cpuIsMultiBoot = false;
   7.627 +  if (strlen(file) > 4)
   7.628 +    {
   7.629 +      const char *p = strrchr(file, '.');
   7.630 +
   7.631 +      if (p != NULL)
   7.632  	{
   7.633 -		const char *p = strrchr(file, '.');
   7.634 +	  if (_stricmp(p, ".gba") == 0)
   7.635 +	    return true;
   7.636 +	  if (_stricmp(p, ".agb") == 0)
   7.637 +	    return true;
   7.638 +	  if (_stricmp(p, ".bin") == 0)
   7.639 +	    return true;
   7.640 +	  if (_stricmp(p, ".elf") == 0)
   7.641 +	    return true;
   7.642 +	  if (_stricmp(p, ".mb") == 0)
   7.643 +	    {
   7.644 +	      cpuIsMultiBoot = true;
   7.645 +	      return true;
   7.646 +	    }
   7.647 +	}
   7.648 +    }
   7.649  
   7.650 -		if (p != NULL)
   7.651 -		{
   7.652 -			if (_stricmp(p, ".gba") == 0)
   7.653 -				return true;
   7.654 -			if (_stricmp(p, ".agb") == 0)
   7.655 -				return true;
   7.656 -			if (_stricmp(p, ".bin") == 0)
   7.657 -				return true;
   7.658 -			if (_stricmp(p, ".elf") == 0)
   7.659 -				return true;
   7.660 -			if (_stricmp(p, ".mb") == 0)
   7.661 -			{
   7.662 -				cpuIsMultiBoot = true;
   7.663 -				return true;
   7.664 -			}
   7.665 -		}
   7.666 -	}
   7.667 -
   7.668 -	return false;
   7.669 +  return false;
   7.670  }
   7.671  
   7.672  bool utilIsGBImage(const char *file)
   7.673  {
   7.674 -	if (strlen(file) > 4)
   7.675 +  if (strlen(file) > 4)
   7.676 +    {
   7.677 +      const char *p = strrchr(file, '.');
   7.678 +
   7.679 +      if (p != NULL)
   7.680  	{
   7.681 -		const char *p = strrchr(file, '.');
   7.682 +	  if (_stricmp(p, ".gb") == 0)
   7.683 +	    return true;
   7.684 +	  if (_stricmp(p, ".gbc") == 0)
   7.685 +	    return true;
   7.686 +	  if (_stricmp(p, ".cgb") == 0)
   7.687 +	    return true;
   7.688 +	  if (_stricmp(p, ".sgb") == 0)
   7.689 +	    return true;
   7.690 +	}
   7.691 +    }
   7.692  
   7.693 -		if (p != NULL)
   7.694 -		{
   7.695 -			if (_stricmp(p, ".gb") == 0)
   7.696 -				return true;
   7.697 -			if (_stricmp(p, ".gbc") == 0)
   7.698 -				return true;
   7.699 -			if (_stricmp(p, ".cgb") == 0)
   7.700 -				return true;
   7.701 -			if (_stricmp(p, ".sgb") == 0)
   7.702 -				return true;
   7.703 -		}
   7.704 -	}
   7.705 -
   7.706 -	return false;
   7.707 +  return false;
   7.708  }
   7.709  
   7.710  bool utilIsGBABios(const char *file)
   7.711  {
   7.712 -	if (strlen(file) > 4)
   7.713 +  if (strlen(file) > 4)
   7.714 +    {
   7.715 +      const char *p = strrchr(file, '.');
   7.716 +
   7.717 +      if (p != NULL)
   7.718  	{
   7.719 -		const char *p = strrchr(file, '.');
   7.720 +	  if (_stricmp(p, ".gba") == 0)
   7.721 +	    return true;
   7.722 +	  if (_stricmp(p, ".agb") == 0)
   7.723 +	    return true;
   7.724 +	  if (_stricmp(p, ".bin") == 0)
   7.725 +	    return true;
   7.726 +	  if (_stricmp(p, ".bios") == 0)
   7.727 +	    return true;
   7.728 +	  if (_stricmp(p, ".rom") == 0)
   7.729 +	    return true;
   7.730 +	}
   7.731 +    }
   7.732  
   7.733 -		if (p != NULL)
   7.734 -		{
   7.735 -			if (_stricmp(p, ".gba") == 0)
   7.736 -				return true;
   7.737 -			if (_stricmp(p, ".agb") == 0)
   7.738 -				return true;
   7.739 -			if (_stricmp(p, ".bin") == 0)
   7.740 -				return true;
   7.741 -			if (_stricmp(p, ".bios") == 0)
   7.742 -				return true;
   7.743 -			if (_stricmp(p, ".rom") == 0)
   7.744 -				return true;
   7.745 -		}
   7.746 -	}
   7.747 -
   7.748 -	return false;
   7.749 +  return false;
   7.750  }
   7.751  
   7.752  bool utilIsGBBios(const char *file)
   7.753  {
   7.754 -	if (strlen(file) > 4)
   7.755 +  if (strlen(file) > 4)
   7.756 +    {
   7.757 +      const char *p = strrchr(file, '.');
   7.758 +
   7.759 +      if (p != NULL)
   7.760  	{
   7.761 -		const char *p = strrchr(file, '.');
   7.762 +	  if (_stricmp(p, ".gb") == 0)
   7.763 +	    return true;
   7.764 +	  if (_stricmp(p, ".bin") == 0)
   7.765 +	    return true;
   7.766 +	  if (_stricmp(p, ".bios") == 0)
   7.767 +	    return true;
   7.768 +	  if (_stricmp(p, ".rom") == 0)
   7.769 +	    return true;
   7.770 +	}
   7.771 +    }
   7.772  
   7.773 -		if (p != NULL)
   7.774 -		{
   7.775 -			if (_stricmp(p, ".gb") == 0)
   7.776 -				return true;
   7.777 -			if (_stricmp(p, ".bin") == 0)
   7.778 -				return true;
   7.779 -			if (_stricmp(p, ".bios") == 0)
   7.780 -				return true;
   7.781 -			if (_stricmp(p, ".rom") == 0)
   7.782 -				return true;
   7.783 -		}
   7.784 -	}
   7.785 -
   7.786 -	return false;
   7.787 +  return false;
   7.788  }
   7.789  
   7.790  bool utilIsELF(const char *file)
   7.791  {
   7.792 -	if (strlen(file) > 4)
   7.793 +  if (strlen(file) > 4)
   7.794 +    {
   7.795 +      const char *p = strrchr(file, '.');
   7.796 +
   7.797 +      if (p != NULL)
   7.798  	{
   7.799 -		const char *p = strrchr(file, '.');
   7.800 -
   7.801 -		if (p != NULL)
   7.802 -		{
   7.803 -			if (_stricmp(p, ".elf") == 0)
   7.804 -				return true;
   7.805 -		}
   7.806 +	  if (_stricmp(p, ".elf") == 0)
   7.807 +	    return true;
   7.808  	}
   7.809 -	return false;
   7.810 +    }
   7.811 +  return false;
   7.812  }
   7.813  
   7.814  bool utilIsZipFile(const char *file)
   7.815  {
   7.816 -	if (strlen(file) > 4)
   7.817 +  if (strlen(file) > 4)
   7.818 +    {
   7.819 +      const char *p = strrchr(file, '.');
   7.820 +
   7.821 +      if (p != NULL)
   7.822  	{
   7.823 -		const char *p = strrchr(file, '.');
   7.824 +	  if (_stricmp(p, ".zip") == 0)
   7.825 +	    return true;
   7.826 +	}
   7.827 +    }
   7.828  
   7.829 -		if (p != NULL)
   7.830 -		{
   7.831 -			if (_stricmp(p, ".zip") == 0)
   7.832 -				return true;
   7.833 -		}
   7.834 -	}
   7.835 -
   7.836 -	return false;
   7.837 +  return false;
   7.838  }
   7.839  
   7.840  #if 0
   7.841  bool utilIsRarFile(const char *file)
   7.842  {
   7.843 -	if (strlen(file) > 4)
   7.844 +  if (strlen(file) > 4)
   7.845 +    {
   7.846 +      char *p = strrchr(file, '.');
   7.847 +
   7.848 +      if (p != NULL)
   7.849  	{
   7.850 -		char *p = strrchr(file, '.');
   7.851 +	  if (_stricmp(p, ".rar") == 0)
   7.852 +	    return true;
   7.853 +	}
   7.854 +    }
   7.855  
   7.856 -		if (p != NULL)
   7.857 -		{
   7.858 -			if (_stricmp(p, ".rar") == 0)
   7.859 -				return true;
   7.860 -		}
   7.861 -	}
   7.862 -
   7.863 -	return false;
   7.864 +  return false;
   7.865  }
   7.866  
   7.867  #endif
   7.868  
   7.869  bool utilIsGzipFile(const char *file)
   7.870  {
   7.871 -	if (strlen(file) > 3)
   7.872 +  if (strlen(file) > 3)
   7.873 +    {
   7.874 +      const char *p = strrchr(file, '.');
   7.875 +
   7.876 +      if (p != NULL)
   7.877  	{
   7.878 -		const char *p = strrchr(file, '.');
   7.879 +	  if (_stricmp(p, ".gz") == 0)
   7.880 +	    return true;
   7.881 +	  if (_stricmp(p, ".z") == 0)
   7.882 +	    return true;
   7.883 +	}
   7.884 +    }
   7.885  
   7.886 -		if (p != NULL)
   7.887 -		{
   7.888 -			if (_stricmp(p, ".gz") == 0)
   7.889 -				return true;
   7.890 -			if (_stricmp(p, ".z") == 0)
   7.891 -				return true;
   7.892 -		}
   7.893 -	}
   7.894 -
   7.895 -	return false;
   7.896 +  return false;
   7.897  }
   7.898  
   7.899  void utilGetBaseName(const char *file, char *buffer)
   7.900  {
   7.901 -	strcpy(buffer, file);
   7.902 +  strcpy(buffer, file);
   7.903  
   7.904 -	if (utilIsGzipFile(file))
   7.905 -	{
   7.906 -		char *p = strrchr(buffer, '.');
   7.907 +  if (utilIsGzipFile(file))
   7.908 +    {
   7.909 +      char *p = strrchr(buffer, '.');
   7.910  
   7.911 -		if (p)
   7.912 -			*p = 0;
   7.913 -	}
   7.914 +      if (p)
   7.915 +	*p = 0;
   7.916 +    }
   7.917  }
   7.918  
   7.919  IMAGE_TYPE utilFindType(const char *file)
   7.920  {
   7.921 -	char buffer[2048];
   7.922 +  char buffer[2048];
   7.923  
   7.924 -	if (utilIsZipFile(file))
   7.925 +  if (utilIsZipFile(file))
   7.926 +    {
   7.927 +      unzFile unz = unzOpen(file);
   7.928 +
   7.929 +      if (unz == NULL)
   7.930  	{
   7.931 -		unzFile unz = unzOpen(file);
   7.932 +	  systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), file);
   7.933 +	  return IMAGE_UNKNOWN;
   7.934 +	}
   7.935  
   7.936 -		if (unz == NULL)
   7.937 +      int r = unzGoToFirstFile(unz);
   7.938 +
   7.939 +      if (r != UNZ_OK)
   7.940 +	{
   7.941 +	  unzClose(unz);
   7.942 +	  systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file);
   7.943 +	  return IMAGE_UNKNOWN;
   7.944 +	}
   7.945 +
   7.946 +      IMAGE_TYPE found = IMAGE_UNKNOWN;
   7.947 +
   7.948 +      unz_file_info info;
   7.949 +
   7.950 +      while (true)
   7.951 +	{
   7.952 +	  r = unzGetCurrentFileInfo(unz,
   7.953 +				    &info,
   7.954 +				    buffer,
   7.955 +				    sizeof(buffer),
   7.956 +				    NULL,
   7.957 +				    0,
   7.958 +				    NULL,
   7.959 +				    0);
   7.960 +
   7.961 +	  if (r != UNZ_OK)
   7.962 +	    {
   7.963 +	      unzClose(unz);
   7.964 +	      systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file);
   7.965 +	      return IMAGE_UNKNOWN;
   7.966 +	    }
   7.967 +
   7.968 +	  if (utilIsGBAImage(buffer))
   7.969 +	    {
   7.970 +	      found = IMAGE_GBA;
   7.971 +	      break;
   7.972 +	    }
   7.973 +
   7.974 +	  if (utilIsGBImage(buffer))
   7.975 +	    {
   7.976 +	      found = IMAGE_GB;
   7.977 +	      break;
   7.978 +	    }
   7.979 +
   7.980 +	  r = unzGoToNextFile(unz);
   7.981 +
   7.982 +	  if (r != UNZ_OK)
   7.983 +	    break;
   7.984 +	}
   7.985 +      unzClose(unz);
   7.986 +
   7.987 +      if (found == IMAGE_UNKNOWN)
   7.988 +	{
   7.989 +	  systemMessage(MSG_NO_IMAGE_ON_ZIP,
   7.990 +			N_("No image found on ZIP file %s"), file);
   7.991 +	  return found;
   7.992 +	}
   7.993 +      return found;
   7.994 +#if 0
   7.995 +    }
   7.996 +  else if (utilIsRarFile(file))
   7.997 +    {
   7.998 +      IMAGE_TYPE found = IMAGE_UNKNOWN;
   7.999 +
  7.1000 +      ArchiveList_struct *rarList = NULL;
  7.1001 +      if (urarlib_list((void *)file, (ArchiveList_struct *)&rarList))
  7.1002 +	{
  7.1003 +	  ArchiveList_struct *p = rarList;
  7.1004 +
  7.1005 +	  while (p)
  7.1006 +	    {
  7.1007 +	      if (utilIsGBAImage(p->item.Name))
  7.1008  		{
  7.1009 -			systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), file);
  7.1010 -			return IMAGE_UNKNOWN;
  7.1011 +		  found = IMAGE_GBA;
  7.1012 +		  break;
  7.1013  		}
  7.1014  
  7.1015 -		int r = unzGoToFirstFile(unz);
  7.1016 +	      if (utilIsGBImage(p->item.Name))
  7.1017 +		{
  7.1018 +		  found = IMAGE_GB;
  7.1019 +		  break;
  7.1020 +		}
  7.1021 +	      p = p->next;
  7.1022 +	    }
  7.1023  
  7.1024 -		if (r != UNZ_OK)
  7.1025 -		{
  7.1026 -			unzClose(unz);
  7.1027 -			systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file);
  7.1028 -			return IMAGE_UNKNOWN;
  7.1029 -		}
  7.1030 +	  urarlib_freelist(rarList);
  7.1031 +	}
  7.1032 +      return found;
  7.1033 +#endif
  7.1034 +    }
  7.1035 +  else
  7.1036 +    {
  7.1037 +      if (utilIsGzipFile(file))
  7.1038 +	utilGetBaseName(file, buffer);
  7.1039 +      else
  7.1040 +	strcpy(buffer, file);
  7.1041  
  7.1042 -		IMAGE_TYPE found = IMAGE_UNKNOWN;
  7.1043 -
  7.1044 -		unz_file_info info;
  7.1045 -
  7.1046 -		while (true)
  7.1047 -		{
  7.1048 -			r = unzGetCurrentFileInfo(unz,
  7.1049 -			                          &info,
  7.1050 -			                          buffer,
  7.1051 -			                          sizeof(buffer),
  7.1052 -			                          NULL,
  7.1053 -			                          0,
  7.1054 -			                          NULL,
  7.1055 -			                          0);
  7.1056 -
  7.1057 -			if (r != UNZ_OK)
  7.1058 -			{
  7.1059 -				unzClose(unz);
  7.1060 -				systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file);
  7.1061 -				return IMAGE_UNKNOWN;
  7.1062 -			}
  7.1063 -
  7.1064 -			if (utilIsGBAImage(buffer))
  7.1065 -			{
  7.1066 -				found = IMAGE_GBA;
  7.1067 -				break;
  7.1068 -			}
  7.1069 -
  7.1070 -			if (utilIsGBImage(buffer))
  7.1071 -			{
  7.1072 -				found = IMAGE_GB;
  7.1073 -				break;
  7.1074 -			}
  7.1075 -
  7.1076 -			r = unzGoToNextFile(unz);
  7.1077 -
  7.1078 -			if (r != UNZ_OK)
  7.1079 -				break;
  7.1080 -		}
  7.1081 -		unzClose(unz);
  7.1082 -
  7.1083 -		if (found == IMAGE_UNKNOWN)
  7.1084 -		{
  7.1085 -			systemMessage(MSG_NO_IMAGE_ON_ZIP,
  7.1086 -			              N_("No image found on ZIP file %s"), file);
  7.1087 -			return found;
  7.1088 -		}
  7.1089 -		return found;
  7.1090 -#if 0
  7.1091 -	}
  7.1092 -	else if (utilIsRarFile(file))
  7.1093 -	{
  7.1094 -		IMAGE_TYPE found = IMAGE_UNKNOWN;
  7.1095 -
  7.1096 -		ArchiveList_struct *rarList = NULL;
  7.1097 -		if (urarlib_list((void *)file, (ArchiveList_struct *)&rarList))
  7.1098 -		{
  7.1099 -			ArchiveList_struct *p = rarList;
  7.1100 -
  7.1101 -			while (p)
  7.1102 -			{
  7.1103 -				if (utilIsGBAImage(p->item.Name))
  7.1104 -				{
  7.1105 -					found = IMAGE_GBA;
  7.1106 -					break;
  7.1107 -				}
  7.1108 -
  7.1109 -				if (utilIsGBImage(p->item.Name))
  7.1110 -				{
  7.1111 -					found = IMAGE_GB;
  7.1112 -					break;
  7.1113 -				}
  7.1114 -				p = p->next;
  7.1115 -			}
  7.1116 -
  7.1117 -			urarlib_freelist(rarList);
  7.1118 -		}
  7.1119 -		return found;
  7.1120 -#endif
  7.1121 -	}
  7.1122 -	else
  7.1123 -	{
  7.1124 -		if (utilIsGzipFile(file))
  7.1125 -			utilGetBaseName(file, buffer);
  7.1126 -		else
  7.1127 -			strcpy(buffer, file);
  7.1128 -
  7.1129 -		if (utilIsGBAImage(buffer))
  7.1130 -			return IMAGE_GBA;
  7.1131 -		if (utilIsGBImage(buffer))
  7.1132 -			return IMAGE_GB;
  7.1133 -	}
  7.1134 -	return IMAGE_UNKNOWN;
  7.1135 +      if (utilIsGBAImage(buffer))
  7.1136 +	return IMAGE_GBA;
  7.1137 +      if (utilIsGBImage(buffer))
  7.1138 +	return IMAGE_GB;
  7.1139 +    }
  7.1140 +  return IMAGE_UNKNOWN;
  7.1141  }
  7.1142  
  7.1143  static int utilGetSize(int size)
  7.1144  {
  7.1145 -	int res = 1;
  7.1146 -	while (res < size)
  7.1147 -		res <<= 1;
  7.1148 -	return res;
  7.1149 +  int res = 1;
  7.1150 +  while (res < size)
  7.1151 +    res <<= 1;
  7.1152 +  return res;
  7.1153  }
  7.1154  
  7.1155  static u8 *utilLoadFromZip(const char *file,
  7.1156 @@ -830,113 +839,113 @@
  7.1157                             u8 *data,
  7.1158                             int &size)
  7.1159  {
  7.1160 -	char buffer[2048];
  7.1161 +  char buffer[2048];
  7.1162  
  7.1163 -	unzFile unz = unzOpen(file);
  7.1164 +  unzFile unz = unzOpen(file);
  7.1165  
  7.1166 -	if (unz == NULL)
  7.1167 +  if (unz == NULL)
  7.1168 +    {
  7.1169 +      systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), file);
  7.1170 +      return NULL;
  7.1171 +    }
  7.1172 +  int r = unzGoToFirstFile(unz);
  7.1173 +
  7.1174 +  if (r != UNZ_OK)
  7.1175 +    {
  7.1176 +      unzClose(unz);
  7.1177 +      systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file);
  7.1178 +      return NULL;
  7.1179 +    }
  7.1180 +
  7.1181 +  bool found = false;
  7.1182 +
  7.1183 +  unz_file_info info;
  7.1184 +
  7.1185 +  while (true)
  7.1186 +    {
  7.1187 +      r = unzGetCurrentFileInfo(unz,
  7.1188 +				&info,
  7.1189 +				buffer,
  7.1190 +				sizeof(buffer),
  7.1191 +				NULL,
  7.1192 +				0,
  7.1193 +				NULL,
  7.1194 +				0);
  7.1195 +
  7.1196 +      if (r != UNZ_OK)
  7.1197  	{
  7.1198 -		systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), file);
  7.1199 -		return NULL;
  7.1200 -	}
  7.1201 -	int r = unzGoToFirstFile(unz);
  7.1202 -
  7.1203 -	if (r != UNZ_OK)
  7.1204 -	{
  7.1205 -		unzClose(unz);
  7.1206 -		systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file);
  7.1207 -		return NULL;
  7.1208 +	  unzClose(unz);
  7.1209 +	  systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file);
  7.1210 +	  return NULL;
  7.1211  	}
  7.1212  
  7.1213 -	bool found = false;
  7.1214 -
  7.1215 -	unz_file_info info;
  7.1216 -
  7.1217 -	while (true)
  7.1218 +      if (accept(buffer))
  7.1219  	{
  7.1220 -		r = unzGetCurrentFileInfo(unz,
  7.1221 -		                          &info,
  7.1222 -		                          buffer,
  7.1223 -		                          sizeof(buffer),
  7.1224 -		                          NULL,
  7.1225 -		                          0,
  7.1226 -		                          NULL,
  7.1227 -		                          0);
  7.1228 -
  7.1229 -		if (r != UNZ_OK)
  7.1230 -		{
  7.1231 -			unzClose(unz);
  7.1232 -			systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file);
  7.1233 -			return NULL;
  7.1234 -		}
  7.1235 -
  7.1236 -		if (accept(buffer))
  7.1237 -		{
  7.1238 -			found = true;
  7.1239 -			break;
  7.1240 -		}
  7.1241 -
  7.1242 -		r = unzGoToNextFile(unz);
  7.1243 -
  7.1244 -		if (r != UNZ_OK)
  7.1245 -			break;
  7.1246 +	  found = true;
  7.1247 +	  break;
  7.1248  	}
  7.1249  
  7.1250 -	if (!found)
  7.1251 +      r = unzGoToNextFile(unz);
  7.1252 +
  7.1253 +      if (r != UNZ_OK)
  7.1254 +	break;
  7.1255 +    }
  7.1256 +
  7.1257 +  if (!found)
  7.1258 +    {
  7.1259 +      unzClose(unz);
  7.1260 +      systemMessage(MSG_NO_IMAGE_ON_ZIP,
  7.1261 +		    N_("No image found on ZIP file %s"), file);
  7.1262 +      return NULL;
  7.1263 +    }
  7.1264 +
  7.1265 +  int fileSize = info.uncompressed_size;
  7.1266 +  if (size == 0)
  7.1267 +    size = fileSize;
  7.1268 +  r = unzOpenCurrentFile(unz);
  7.1269 +
  7.1270 +  if (r != UNZ_OK)
  7.1271 +    {
  7.1272 +      unzClose(unz);
  7.1273 +      systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), buffer);
  7.1274 +      return NULL;
  7.1275 +    }
  7.1276 +
  7.1277 +  u8 *image = data;
  7.1278 +
  7.1279 +  if (image == NULL)
  7.1280 +    {
  7.1281 +      image = (u8 *)malloc(utilGetSize(size));
  7.1282 +      if (image == NULL)
  7.1283  	{
  7.1284 -		unzClose(unz);
  7.1285 -		systemMessage(MSG_NO_IMAGE_ON_ZIP,
  7.1286 -		              N_("No image found on ZIP file %s"), file);
  7.1287 -		return NULL;
  7.1288 +	  unzCloseCurrentFile(unz);
  7.1289 +	  unzClose(unz);
  7.1290 +	  systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
  7.1291 +			"data");
  7.1292 +	  return NULL;
  7.1293  	}
  7.1294 +      size = fileSize;
  7.1295 +    }
  7.1296 +  int read = fileSize <= size ? fileSize : size;
  7.1297 +  r = unzReadCurrentFile(unz,
  7.1298 +			 image,
  7.1299 +			 read);
  7.1300  
  7.1301 -	int fileSize = info.uncompressed_size;
  7.1302 -	if (size == 0)
  7.1303 -		size = fileSize;
  7.1304 -	r = unzOpenCurrentFile(unz);
  7.1305 +  unzCloseCurrentFile(unz);
  7.1306 +  unzClose(unz);
  7.1307  
  7.1308 -	if (r != UNZ_OK)
  7.1309 -	{
  7.1310 -		unzClose(unz);
  7.1311 -		systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), buffer);
  7.1312 -		return NULL;
  7.1313 -	}
  7.1314 +  if (r != (int)read)
  7.1315 +    {
  7.1316 +      systemMessage(MSG_ERROR_READING_IMAGE,
  7.1317 +		    N_("Error reading image %s"), buffer);
  7.1318 +      if (data == NULL)
  7.1319 +	free(image);
  7.1320 +      return NULL;
  7.1321 +    }
  7.1322  
  7.1323 -	u8 *image = data;
  7.1324 +  size = fileSize;
  7.1325  
  7.1326 -	if (image == NULL)
  7.1327 -	{
  7.1328 -		image = (u8 *)malloc(utilGetSize(size));
  7.1329 -		if (image == NULL)
  7.1330 -		{
  7.1331 -			unzCloseCurrentFile(unz);
  7.1332 -			unzClose(unz);
  7.1333 -			systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
  7.1334 -			              "data");
  7.1335 -			return NULL;
  7.1336 -		}
  7.1337 -		size = fileSize;
  7.1338 -	}
  7.1339 -	int read = fileSize <= size ? fileSize : size;
  7.1340 -	r = unzReadCurrentFile(unz,
  7.1341 -	                       image,
  7.1342 -	                       read);
  7.1343 -
  7.1344 -	unzCloseCurrentFile(unz);
  7.1345 -	unzClose(unz);
  7.1346 -
  7.1347 -	if (r != (int)read)
  7.1348 -	{
  7.1349 -		systemMessage(MSG_ERROR_READING_IMAGE,
  7.1350 -		              N_("Error reading image %s"), buffer);
  7.1351 -		if (data == NULL)
  7.1352 -			free(image);
  7.1353 -		return NULL;
  7.1354 -	}
  7.1355 -
  7.1356 -	size = fileSize;
  7.1357 -
  7.1358 -	return image;
  7.1359 +  return image;
  7.1360  }
  7.1361  
  7.1362  static u8 *utilLoadGzipFile(const char *file,
  7.1363 @@ -944,59 +953,59 @@
  7.1364                              u8 *data,
  7.1365                              int &size)
  7.1366  {
  7.1367 -	FILE *f = fopen(file, "rb");
  7.1368 +  FILE *f = fopen(file, "rb");
  7.1369  
  7.1370 -	if (f == NULL)
  7.1371 +  if (f == NULL)
  7.1372 +    {
  7.1373 +      systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), file);
  7.1374 +      return NULL;
  7.1375 +    }
  7.1376 +
  7.1377 +  fseek(f, -4, SEEK_END);
  7.1378 +  int fileSize = fgetc(f) | (fgetc(f) << 8) | (fgetc(f) << 16) | (fgetc(f) << 24);
  7.1379 +  fclose(f);
  7.1380 +  if (size == 0)
  7.1381 +    size = fileSize;
  7.1382 +
  7.1383 +  gzFile gz = gzopen(file, "rb");
  7.1384 +
  7.1385 +  if (gz == NULL)
  7.1386 +    {
  7.1387 +      // should not happen, but who knows?
  7.1388 +      systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), file);
  7.1389 +      return NULL;
  7.1390 +    }
  7.1391 +
  7.1392 +  u8 *image = data;
  7.1393 +
  7.1394 +  if (image == NULL)
  7.1395 +    {
  7.1396 +      image = (u8 *)malloc(utilGetSize(size));
  7.1397 +      if (image == NULL)
  7.1398  	{
  7.1399 -		systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), file);
  7.1400 -		return NULL;
  7.1401 +	  systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
  7.1402 +			"data");
  7.1403 +	  fclose(f);
  7.1404 +	  return NULL;
  7.1405  	}
  7.1406 +      size = fileSize;
  7.1407 +    }
  7.1408 +  int read = fileSize <= size ? fileSize : size;
  7.1409 +  int r	 = gzread(gz, image, read);
  7.1410 +  gzclose(gz);
  7.1411  
  7.1412 -	fseek(f, -4, SEEK_END);
  7.1413 -	int fileSize = fgetc(f) | (fgetc(f) << 8) | (fgetc(f) << 16) | (fgetc(f) << 24);
  7.1414 -	fclose(f);
  7.1415 -	if (size == 0)
  7.1416 -		size = fileSize;
  7.1417 +  if (r != (int)read)
  7.1418 +    {
  7.1419 +      systemMessage(MSG_ERROR_READING_IMAGE,
  7.1420 +		    N_("Error reading image %s"), file);
  7.1421 +      if (data == NULL)
  7.1422 +	free(image);
  7.1423 +      return NULL;
  7.1424 +    }
  7.1425  
  7.1426 -	gzFile gz = gzopen(file, "rb");
  7.1427 +  size = fileSize;
  7.1428  
  7.1429 -	if (gz == NULL)
  7.1430 -	{
  7.1431 -		// should not happen, but who knows?
  7.1432 -		systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), file);
  7.1433 -		return NULL;
  7.1434 -	}
  7.1435 -
  7.1436 -	u8 *image = data;
  7.1437 -
  7.1438 -	if (image == NULL)
  7.1439 -	{
  7.1440 -		image = (u8 *)malloc(utilGetSize(size));
  7.1441 -		if (image == NULL)
  7.1442 -		{
  7.1443 -			systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
  7.1444 -			              "data");
  7.1445 -			fclose(f);
  7.1446 -			return NULL;
  7.1447 -		}
  7.1448 -		size = fileSize;
  7.1449 -	}
  7.1450 -	int read = fileSize <= size ? fileSize : size;
  7.1451 -	int r	 = gzread(gz, image, read);
  7.1452 -	gzclose(gz);
  7.1453 -
  7.1454 -	if (r != (int)read)
  7.1455 -	{
  7.1456 -		systemMessage(MSG_ERROR_READING_IMAGE,
  7.1457 -		              N_("Error reading image %s"), file);
  7.1458 -		if (data == NULL)
  7.1459 -			free(image);
  7.1460 -		return NULL;
  7.1461 -	}
  7.1462 -
  7.1463 -	size = fileSize;
  7.1464 -
  7.1465 -	return image;
  7.1466 +  return image;
  7.1467  }
  7.1468  
  7.1469  #if 0
  7.1470 @@ -1005,52 +1014,52 @@
  7.1471                             u8 *data,
  7.1472                             int &size)
  7.1473  {
  7.1474 -	char buffer[2048];
  7.1475 +  char buffer[2048];
  7.1476  
  7.1477 -	ArchiveList_struct *rarList = NULL;
  7.1478 -	if (urarlib_list((void *)file, (ArchiveList_struct *)&rarList))
  7.1479 +  ArchiveList_struct *rarList = NULL;
  7.1480 +  if (urarlib_list((void *)file, (ArchiveList_struct *)&rarList))
  7.1481 +    {
  7.1482 +      ArchiveList_struct *p = rarList;
  7.1483 +
  7.1484 +      bool found = false;
  7.1485 +      while (p)
  7.1486  	{
  7.1487 -		ArchiveList_struct *p = rarList;
  7.1488 -
  7.1489 -		bool found = false;
  7.1490 -		while (p)
  7.1491 -		{
  7.1492 -			if (accept(p->item.Name))
  7.1493 -			{
  7.1494 -				strcpy(buffer, p->item.Name);
  7.1495 -				found = true;
  7.1496 -				break;
  7.1497 -			}
  7.1498 -			p = p->next;
  7.1499 -		}
  7.1500 -		if (found)
  7.1501 -		{
  7.1502 -			void *memory		= NULL;
  7.1503 -			unsigned long lsize = 0;
  7.1504 -			size = p->item.UnpSize;
  7.1505 -			int r = urarlib_get((void *)&memory, &lsize, buffer, (void *)file, "");
  7.1506 -			if (!r)
  7.1507 -			{
  7.1508 -				systemMessage(MSG_ERROR_READING_IMAGE,
  7.1509 -				              N_("Error reading image %s"), buffer);
  7.1510 -				urarlib_freelist(rarList);
  7.1511 -				return NULL;
  7.1512 -			}
  7.1513 -			u8 *image = (u8 *)memory;
  7.1514 -			if (data != NULL)
  7.1515 -			{
  7.1516 -				memcpy(image, data, size);
  7.1517 -			}
  7.1518 -			urarlib_freelist(rarList);
  7.1519 -			return image;
  7.1520 -		}
  7.1521 -		systemMessage(MSG_NO_IMAGE_ON_ZIP,
  7.1522 -		              N_("No image found on RAR file %s"), file);
  7.1523 -		urarlib_freelist(rarList);
  7.1524 -		return NULL;
  7.1525 +	  if (accept(p->item.Name))
  7.1526 +	    {
  7.1527 +	      strcpy(buffer, p->item.Name);
  7.1528 +	      found = true;
  7.1529 +	      break;
  7.1530 +	    }
  7.1531 +	  p = p->next;
  7.1532  	}
  7.1533 -	// nothing found
  7.1534 -	return NULL;
  7.1535 +      if (found)
  7.1536 +	{
  7.1537 +	  void *memory		= NULL;
  7.1538 +	  unsigned long lsize = 0;
  7.1539 +	  size = p->item.UnpSize;
  7.1540 +	  int r = urarlib_get((void *)&memory, &lsize, buffer, (void *)file, "");
  7.1541 +	  if (!r)
  7.1542 +	    {
  7.1543 +	      systemMessage(MSG_ERROR_READING_IMAGE,
  7.1544 +			    N_("Error reading image %s"), buffer);
  7.1545 +	      urarlib_freelist(rarList);
  7.1546 +	      return NULL;
  7.1547 +	    }
  7.1548 +	  u8 *image = (u8 *)memory;
  7.1549 +	  if (data != NULL)
  7.1550 +	    {
  7.1551 +	      memcpy(image, data, size);
  7.1552 +	    }
  7.1553 +	  urarlib_freelist(rarList);
  7.1554 +	  return image;
  7.1555 +	}
  7.1556 +      systemMessage(MSG_NO_IMAGE_ON_ZIP,
  7.1557 +		    N_("No image found on RAR file %s"), file);
  7.1558 +      urarlib_freelist(rarList);
  7.1559 +      return NULL;
  7.1560 +    }
  7.1561 +  // nothing found
  7.1562 +  return NULL;
  7.1563  }
  7.1564  
  7.1565  #endif
  7.1566 @@ -1061,245 +1070,245 @@
  7.1567               u8 *data,
  7.1568               int &size)
  7.1569  {
  7.1570 -	if (utilIsZipFile(file))
  7.1571 -	{
  7.1572 -		return utilLoadFromZip(file, accept, data, size);
  7.1573 -	}
  7.1574 -	if (utilIsGzipFile(file))
  7.1575 -	{
  7.1576 -		return utilLoadGzipFile(file, accept, data, size);
  7.1577 -	}
  7.1578 +  if (utilIsZipFile(file))
  7.1579 +    {
  7.1580 +      return utilLoadFromZip(file, accept, data, size);
  7.1581 +    }
  7.1582 +  if (utilIsGzipFile(file))
  7.1583 +    {
  7.1584 +      return utilLoadGzipFile(file, accept, data, size);
  7.1585 +    }
  7.1586  #if 0
  7.1587 -	if (utilIsRarFile(file))
  7.1588 -	{
  7.1589 -		return utilLoadRarFile(file, accept, data, size);
  7.1590 -	}
  7.1591 +  if (utilIsRarFile(file))
  7.1592 +    {
  7.1593 +      return utilLoadRarFile(file, accept, data, size);
  7.1594 +    }
  7.1595  #endif
  7.1596  
  7.1597 -	u8 *image = data;
  7.1598 +  u8 *image = data;
  7.1599  
  7.1600 -	FILE *f = fopen(file, "rb");
  7.1601 +  FILE *f = fopen(file, "rb");
  7.1602  
  7.1603 -	if (!f)
  7.1604 +  if (!f)
  7.1605 +    {
  7.1606 +      systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), file);
  7.1607 +      return NULL;
  7.1608 +    }
  7.1609 +
  7.1610 +  fseek(f, 0, SEEK_END);
  7.1611 +  int fileSize = ftell(f);
  7.1612 +  fseek(f, 0, SEEK_SET);
  7.1613 +  if (size == 0)
  7.1614 +    size = fileSize;
  7.1615 +
  7.1616 +  if (image == NULL)
  7.1617 +    {
  7.1618 +      image = (u8 *)malloc(utilGetSize(size));
  7.1619 +      if (image == NULL)
  7.1620  	{
  7.1621 -		systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), file);
  7.1622 -		return NULL;
  7.1623 +	  systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
  7.1624 +			"data");
  7.1625 +	  fclose(f);
  7.1626 +	  return NULL;
  7.1627  	}
  7.1628 +      size = fileSize;
  7.1629 +    }
  7.1630 +  int read = fileSize <= size ? fileSize : size;
  7.1631 +  int r	 = fread(image, 1, read, f);
  7.1632 +  fclose(f);
  7.1633  
  7.1634 -	fseek(f, 0, SEEK_END);
  7.1635 -	int fileSize = ftell(f);
  7.1636 -	fseek(f, 0, SEEK_SET);
  7.1637 -	if (size == 0)
  7.1638 -		size = fileSize;
  7.1639 +  if (r != (int)read)
  7.1640 +    {
  7.1641 +      systemMessage(MSG_ERROR_READING_IMAGE,
  7.1642 +		    N_("Error reading image %s"), file);
  7.1643 +      if (data == NULL)
  7.1644 +	free(image);
  7.1645 +      return NULL;
  7.1646 +    }
  7.1647  
  7.1648 -	if (image == NULL)
  7.1649 -	{
  7.1650 -		image = (u8 *)malloc(utilGetSize(size));
  7.1651 -		if (image == NULL)
  7.1652 -		{
  7.1653 -			systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
  7.1654 -			              "data");
  7.1655 -			fclose(f);
  7.1656 -			return NULL;
  7.1657 -		}
  7.1658 -		size = fileSize;
  7.1659 -	}
  7.1660 -	int read = fileSize <= size ? fileSize : size;
  7.1661 -	int r	 = fread(image, 1, read, f);
  7.1662 -	fclose(f);
  7.1663 +  size = fileSize;
  7.1664  
  7.1665 -	if (r != (int)read)
  7.1666 -	{
  7.1667 -		systemMessage(MSG_ERROR_READING_IMAGE,
  7.1668 -		              N_("Error reading image %s"), file);
  7.1669 -		if (data == NULL)
  7.1670 -			free(image);
  7.1671 -		return NULL;
  7.1672 -	}
  7.1673 -
  7.1674 -	size = fileSize;
  7.1675 -
  7.1676 -	return image;
  7.1677 +  return image;
  7.1678  }
  7.1679  
  7.1680  void utilWriteInt(gzFile gzFile, int32 i)
  7.1681  {
  7.1682 -	utilGzWrite(gzFile, &i, sizeof(int32));
  7.1683 +  utilGzWrite(gzFile, &i, sizeof(int32));
  7.1684  }
  7.1685  
  7.1686  int32 utilReadInt(gzFile gzFile)
  7.1687  {
  7.1688 -	int32 i = 0;
  7.1689 -	utilGzRead(gzFile, &i, sizeof(int32));
  7.1690 -	return i;
  7.1691 +  int32 i = 0;
  7.1692 +  utilGzRead(gzFile, &i, sizeof(int32));
  7.1693 +  return i;
  7.1694  }
  7.1695  
  7.1696  void utilReadData(gzFile gzFile, variable_desc *data)
  7.1697  {
  7.1698 -	while (data->address)
  7.1699 -	{
  7.1700 -		utilGzRead(gzFile, data->address, data->size);
  7.1701 -		data++;
  7.1702 -	}
  7.1703 +  while (data->address)
  7.1704 +    {
  7.1705 +      utilGzRead(gzFile, data->address, data->size);
  7.1706 +      data++;
  7.1707 +    }
  7.1708  }
  7.1709  
  7.1710  void utilWriteData(gzFile gzFile, variable_desc *data)
  7.1711  {
  7.1712 -	while (data->address)
  7.1713 -	{
  7.1714 -		utilGzWrite(gzFile, data->address, data->size);
  7.1715 -		data++;
  7.1716 -	}
  7.1717 +  while (data->address)
  7.1718 +    {
  7.1719 +      utilGzWrite(gzFile, data->address, data->size);
  7.1720 +      data++;
  7.1721 +    }
  7.1722  }
  7.1723  
  7.1724  gzFile utilGzOpen(const char *file, const char *mode)
  7.1725  {
  7.1726 -	utilGzWriteFunc = gzWrite;
  7.1727 -	utilGzReadFunc	= gzread;
  7.1728 -	utilGzCloseFunc = gzclose;
  7.1729 -	utilGzSeekFunc	= gzseek;
  7.1730 -	utilGzTellFunc	= gztell;
  7.1731 +  utilGzWriteFunc = gzWrite;
  7.1732 +  utilGzReadFunc	= gzread;
  7.1733 +  utilGzCloseFunc = gzclose;
  7.1734 +  utilGzSeekFunc	= gzseek;
  7.1735 +  utilGzTellFunc	= gztell;
  7.1736  
  7.1737 -	return gzopen(file, mode);
  7.1738 +  return gzopen(file, mode);
  7.1739  }
  7.1740  
  7.1741  gzFile utilGzReopen(int id, const char *mode)
  7.1742  {
  7.1743 -	utilGzWriteFunc = gzWrite;
  7.1744 -	utilGzReadFunc	= gzread;
  7.1745 -	utilGzCloseFunc = gzclose;
  7.1746 -	utilGzSeekFunc	= gzseek;
  7.1747 -	utilGzTellFunc	= gztell;
  7.1748 +  utilGzWriteFunc = gzWrite;
  7.1749 +  utilGzReadFunc	= gzread;
  7.1750 +  utilGzCloseFunc = gzclose;
  7.1751 +  utilGzSeekFunc	= gzseek;
  7.1752 +  utilGzTellFunc	= gztell;
  7.1753  
  7.1754 -	return gzdopen(id, mode);
  7.1755 +  return gzdopen(id, mode);
  7.1756  }
  7.1757  
  7.1758  gzFile utilMemGzOpen(char *memory, int available, char *mode)
  7.1759  {
  7.1760 -	utilGzWriteFunc = memgzwrite;
  7.1761 -	utilGzReadFunc	= memgzread;
  7.1762 -	utilGzCloseFunc = memgzclose;
  7.1763 -	utilGzSeekFunc	= NULL;	// FIXME: not implemented...
  7.1764 -	utilGzTellFunc	= memtell;
  7.1765 +  utilGzWriteFunc = memgzwrite;
  7.1766 +  utilGzReadFunc	= memgzread;
  7.1767 +  utilGzCloseFunc = memgzclose;
  7.1768 +  utilGzSeekFunc	= NULL;	// FIXME: not implemented...
  7.1769 +  utilGzTellFunc	= memtell;
  7.1770  
  7.1771 -	return memgzopen(memory, available, mode);
  7.1772 +  return memgzopen(memory, available, mode);
  7.1773  }
  7.1774  
  7.1775  int utilGzWrite(gzFile file, voidp buffer, unsigned int len)
  7.1776  {
  7.1777 -	return utilGzWriteFunc(file, buffer, len);
  7.1778 +  return utilGzWriteFunc(file, buffer, len);
  7.1779  }
  7.1780  
  7.1781  int utilGzRead(gzFile file, voidp buffer, unsigned int len)
  7.1782  {
  7.1783 -	return utilGzReadFunc(file, buffer, len);
  7.1784 +  return utilGzReadFunc(file, buffer, len);
  7.1785  }
  7.1786  
  7.1787  int utilGzClose(gzFile file)
  7.1788  {
  7.1789 -	return utilGzCloseFunc(file);
  7.1790 +  return utilGzCloseFunc(file);
  7.1791  }
  7.1792  
  7.1793  z_off_t utilGzSeek(gzFile file, z_off_t offset, int whence)
  7.1794  {
  7.1795 -	return utilGzSeekFunc(file, offset, whence);
  7.1796 +  return utilGzSeekFunc(file, offset, whence);
  7.1797  }
  7.1798  
  7.1799  z_off_t utilGzTell(gzFile file)
  7.1800  {
  7.1801 -	return utilGzTellFunc(file);
  7.1802 +  return utilGzTellFunc(file);
  7.1803  }
  7.1804  
  7.1805  void utilGBAFindSave(const u8 *data, const int size)
  7.1806  {
  7.1807 -	u32 *p		   = (u32 *)data;
  7.1808 -	u32 *end	   = (u32 *)(data + size);
  7.1809 -	int	 saveType  = 0;
  7.1810 -	int	 flashSize = 0x10000;
  7.1811 -	bool rtcFound  = false;
  7.1812 +  u32 *p		   = (u32 *)data;
  7.1813 +  u32 *end	   = (u32 *)(data + size);
  7.1814 +  int	 saveType  = 0;
  7.1815 +  int	 flashSize = 0x10000;
  7.1816 +  bool rtcFound  = false;
  7.1817  
  7.1818 -	while (p  < end)
  7.1819 +  while (p  < end)
  7.1820 +    {
  7.1821 +      u32 d = READ32LE(p);
  7.1822 +
  7.1823 +      if (d == 0x52504545)
  7.1824  	{
  7.1825 -		u32 d = READ32LE(p);
  7.1826 -
  7.1827 -		if (d == 0x52504545)
  7.1828 +	  if (memcmp(p, "EEPROM_", 7) == 0)
  7.1829 +	    {
  7.1830 +	      if (saveType == 0)
  7.1831 +		saveType = 1;
  7.1832 +	    }
  7.1833 +	}
  7.1834 +      else if (d == 0x4D415253)
  7.1835 +	{
  7.1836 +	  if (memcmp(p, "SRAM_", 5) == 0)
  7.1837 +	    {
  7.1838 +	      if (saveType == 0)
  7.1839 +		saveType = 2;
  7.1840 +	    }
  7.1841 +	}
  7.1842 +      else if (d == 0x53414C46)
  7.1843 +	{
  7.1844 +	  if (memcmp(p, "FLASH1M_", 8) == 0)
  7.1845 +	    {
  7.1846 +	      if (saveType == 0)
  7.1847  		{
  7.1848 -			if (memcmp(p, "EEPROM_", 7) == 0)
  7.1849 -			{
  7.1850 -				if (saveType == 0)
  7.1851 -					saveType = 1;
  7.1852 -			}
  7.1853 +		  saveType  = 3;
  7.1854 +		  flashSize = 0x20000;
  7.1855  		}
  7.1856 -		else if (d == 0x4D415253)
  7.1857 +	    }
  7.1858 +	  else if (memcmp(p, "FLASH", 5) == 0)
  7.1859 +	    {
  7.1860 +	      if (saveType == 0)
  7.1861  		{
  7.1862 -			if (memcmp(p, "SRAM_", 5) == 0)
  7.1863 -			{
  7.1864 -				if (saveType == 0)
  7.1865 -					saveType = 2;
  7.1866 -			}
  7.1867 +		  saveType  = 3;
  7.1868 +		  flashSize = 0x10000;
  7.1869  		}
  7.1870 -		else if (d == 0x53414C46)
  7.1871 -		{
  7.1872 -			if (memcmp(p, "FLASH1M_", 8) == 0)
  7.1873 -			{
  7.1874 -				if (saveType == 0)
  7.1875 -				{
  7.1876 -					saveType  = 3;
  7.1877 -					flashSize = 0x20000;
  7.1878 -				}
  7.1879 -			}
  7.1880 -			else if (memcmp(p, "FLASH", 5) == 0)
  7.1881 -			{
  7.1882 -				if (saveType == 0)
  7.1883 -				{
  7.1884 -					saveType  = 3;
  7.1885 -					flashSize = 0x10000;
  7.1886 -				}
  7.1887 -			}
  7.1888 -		}
  7.1889 -		else if (d == 0x52494953)
  7.1890 -		{
  7.1891 -			if (memcmp(p, "SIIRTC_V", 8) == 0)
  7.1892 -				rtcFound = true;
  7.1893 -		}
  7.1894 -		p++;
  7.1895 +	    }
  7.1896  	}
  7.1897 -	// if no matches found, then set it to NONE
  7.1898 -	if (saveType == 0)
  7.1899 +      else if (d == 0x52494953)
  7.1900  	{
  7.1901 -		saveType = 5;
  7.1902 +	  if (memcmp(p, "SIIRTC_V", 8) == 0)
  7.1903 +	    rtcFound = true;
  7.1904  	}
  7.1905 -	rtcEnable(rtcFound);
  7.1906 -	cpuSaveType = saveType;
  7.1907 -	flashSetSize(flashSize);
  7.1908 +      p++;
  7.1909 +    }
  7.1910 +  // if no matches found, then set it to NONE
  7.1911 +  if (saveType == 0)
  7.1912 +    {
  7.1913 +      saveType = 5;
  7.1914 +    }
  7.1915 +  rtcEnable(rtcFound);
  7.1916 +  cpuSaveType = saveType;
  7.1917 +  flashSetSize(flashSize);
  7.1918  }
  7.1919  
  7.1920  void utilUpdateSystemColorMaps()
  7.1921  {
  7.1922 -	switch (systemColorDepth)
  7.1923 -	{
  7.1924 -	case 16:
  7.1925 -	{
  7.1926 -		for (int i = 0; i < 0x10000; i++)
  7.1927 -		{
  7.1928 -			systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |
  7.1929 -			                      (((i & 0x3e0) >> 5) << systemGreenShift) |
  7.1930 -			                      (((i & 0x7c00) >> 10) << systemBlueShift);
  7.1931 -		}
  7.1932 -		break;
  7.1933 -	}
  7.1934 -	case 24:
  7.1935 -	case 32:
  7.1936 -	{
  7.1937 -		for (int i = 0; i < 0x10000; i++)
  7.1938 -		{
  7.1939 -			systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |
  7.1940 -			                      (((i & 0x3e0) >> 5) << systemGreenShift) |
  7.1941 -			                      (((i & 0x7c00) >> 10) << systemBlueShift);
  7.1942 -		}
  7.1943 -		break;
  7.1944 -	}
  7.1945 -	}
  7.1946 +  switch (systemColorDepth)
  7.1947 +    {
  7.1948 +    case 16:
  7.1949 +      {
  7.1950 +	for (int i = 0; i < 0x10000; i++)
  7.1951 +	  {
  7.1952 +	    systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |
  7.1953 +	      (((i & 0x3e0) >> 5) << systemGreenShift) |
  7.1954 +	      (((i & 0x7c00) >> 10) << systemBlueShift);
  7.1955 +	  }
  7.1956 +	break;
  7.1957 +      }
  7.1958 +    case 24:
  7.1959 +    case 32:
  7.1960 +      {
  7.1961 +	for (int i = 0; i < 0x10000; i++)
  7.1962 +	  {
  7.1963 +	    systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |
  7.1964 +	      (((i & 0x3e0) >> 5) << systemGreenShift) |
  7.1965 +	      (((i & 0x7c00) >> 10) << systemBlueShift);
  7.1966 +	  }
  7.1967 +	break;
  7.1968 +      }
  7.1969 +    }
  7.1970  }
  7.1971  
  7.1972  //// BIOS stuff
  7.1973 @@ -1307,94 +1316,94 @@
  7.1974  
  7.1975  bool utilLoadBIOS(u8 *bios, const char *biosFileName, int systemType)
  7.1976  {
  7.1977 -	if (bios == NULL || strlen(biosFileName) == 0)
  7.1978 -		return false;
  7.1979 +  if (bios == NULL || strlen(biosFileName) == 0)
  7.1980 +    return false;
  7.1981  
  7.1982 -	if (systemType == 4)
  7.1983 +  if (systemType == 4)
  7.1984 +    {
  7.1985 +      int biosSize = 0x4000;
  7.1986 +      if (utilLoad(biosFileName, utilIsGBABios, bios, biosSize))
  7.1987  	{
  7.1988 -		int biosSize = 0x4000;
  7.1989 -		if (utilLoad(biosFileName, utilIsGBABios, bios, biosSize))
  7.1990 -		{
  7.1991 -			if (biosSize == 0x4000)
  7.1992 -				return true;
  7.1993 -		}
  7.1994 +	  if (biosSize == 0x4000)
  7.1995 +	    return true;
  7.1996  	}
  7.1997 -	else
  7.1998 +    }
  7.1999 +  else
  7.2000 +    {
  7.2001 +      int biosSize = 0x100;
  7.2002 +      if (utilLoad(biosFileName, utilIsGBBios, bios, biosSize))
  7.2003  	{
  7.2004 -		int biosSize = 0x100;
  7.2005 -		if (utilLoad(biosFileName, utilIsGBBios, bios, biosSize))
  7.2006 -		{
  7.2007 -			if (biosSize == 0x100)
  7.2008 -				return true;
  7.2009 -		}
  7.2010 +	  if (biosSize == 0x100)
  7.2011 +	    return true;
  7.2012  	}
  7.2013 +    }
  7.2014  
  7.2015 -	return false;
  7.2016 +  return false;
  7.2017  }
  7.2018  
  7.2019  bool utilCheckBIOS(const char *biosFileName, int systemType)
  7.2020  {
  7.2021 -	if (strlen(biosFileName) == 0)
  7.2022 -		return false;
  7.2023 +  if (strlen(biosFileName) == 0)
  7.2024 +    return false;
  7.2025  
  7.2026 -	u8 * tempBIOS = (u8 *)malloc(systemType == 4 ? 0x4000 : 0x100);
  7.2027 -	bool result	  = utilLoadBIOS(tempBIOS, biosFileName, systemType);
  7.2028 -	free(tempBIOS);
  7.2029 +  u8 * tempBIOS = (u8 *)malloc(systemType == 4 ? 0x4000 : 0x100);
  7.2030 +  bool result	  = utilLoadBIOS(tempBIOS, biosFileName, systemType);
  7.2031 +  free(tempBIOS);
  7.2032  
  7.2033 -	return result;
  7.2034 +  return result;
  7.2035  }
  7.2036  
  7.2037  #if 0
  7.2038  // returns the checksum of the BIOS that will be loaded after the next restart
  7.2039  u16 utilCalcBIOSChecksum(const u8 *bios, int systemType)
  7.2040  {
  7.2041 -	u32	biosChecksum = 0;
  7.2042 -	if (bios)
  7.2043 -	{
  7.2044 -		int biosSize	= (systemType == 4 ? 0x4000 : 0x100);
  7.2045 -		const u16 *data = reinterpret_cast<const u16 *>(bios);
  7.2046 -		for (int i = biosSize; i > 0; i -= 2)
  7.2047 -			biosChecksum += *data++;
  7.2048 -	}
  7.2049 +  u32	biosChecksum = 0;
  7.2050 +  if (bios)
  7.2051 +    {
  7.2052 +      int biosSize	= (systemType == 4 ? 0x4000 : 0x100);
  7.2053 +      const u16 *data = reinterpret_cast<const u16 *>(bios);
  7.2054 +      for (int i = biosSize; i > 0; i -= 2)
  7.2055 +	biosChecksum += *data++;
  7.2056 +    }
  7.2057  
  7.2058 -	while ((biosChecksum >> 16) & 0xFFFF)
  7.2059 -		biosChecksum = (biosChecksum &0xFFFF) + ((biosChecksum >> 16) & 0xFFFF);
  7.2060 +  while ((biosChecksum >> 16) & 0xFFFF)
  7.2061 +    biosChecksum = (biosChecksum &0xFFFF) + ((biosChecksum >> 16) & 0xFFFF);
  7.2062  
  7.2063 -	return biosChecksum & 0xFFFF;
  7.2064 +  return biosChecksum & 0xFFFF;
  7.2065  }
  7.2066  #else
  7.2067  // returns the checksum of the BIOS that will be loaded after the next restart
  7.2068  u16 utilCalcBIOSChecksum(const u8 *bios, int systemType)
  7.2069  {
  7.2070 -	u32	biosChecksum = 0;
  7.2071 -	if (bios)
  7.2072 -	{
  7.2073 -		int biosSize	= (systemType == 4 ? 0x4000 : 0x100);
  7.2074 -		const u32 *data = reinterpret_cast<const u32 *>(bios);
  7.2075 -		for (int i = biosSize; i > 0; i -= 4)
  7.2076 -			biosChecksum += *data++;
  7.2077 -	}
  7.2078 +  u32	biosChecksum = 0;
  7.2079 +  if (bios)
  7.2080 +    {
  7.2081 +      int biosSize	= (systemType == 4 ? 0x4000 : 0x100);
  7.2082 +      const u32 *data = reinterpret_cast<const u32 *>(bios);
  7.2083 +      for (int i = biosSize; i > 0; i -= 4)
  7.2084 +	biosChecksum += *data++;
  7.2085 +    }
  7.2086  
  7.2087 -	return biosChecksum & 0xFFFF;
  7.2088 +  return biosChecksum & 0xFFFF;
  7.2089  }
  7.2090  #endif
  7.2091  
  7.2092  // returns the checksum of the BIOS file
  7.2093  u16 utilCalcBIOSFileChecksum(const char *biosFileName, int systemType)
  7.2094  {
  7.2095 -	if (strlen(biosFileName) == 0)
  7.2096 -		return 0;
  7.2097 +  if (strlen(biosFileName) == 0)
  7.2098 +    return 0;
  7.2099  
  7.2100 -	u16		  biosChecksum = 0;
  7.2101 -	const int biosSize	   = (systemType == 4 ? 0x4000 : 0x100);
  7.2102 -	u8 *	  tempBIOS	   = (u8 *)malloc(biosSize);
  7.2103 -	bool	  hasBIOS	   = utilLoadBIOS(tempBIOS, biosFileName, systemType);
  7.2104 -	if (hasBIOS)
  7.2105 -	{
  7.2106 -		biosChecksum = utilCalcBIOSChecksum(tempBIOS, systemType);
  7.2107 -	}
  7.2108 -	free(tempBIOS);
  7.2109 +  u16		  biosChecksum = 0;
  7.2110 +  const int biosSize	   = (systemType == 4 ? 0x4000 : 0x100);
  7.2111 +  u8 *	  tempBIOS	   = (u8 *)malloc(biosSize);
  7.2112 +  bool	  hasBIOS	   = utilLoadBIOS(tempBIOS, biosFileName, systemType);
  7.2113 +  if (hasBIOS)
  7.2114 +    {
  7.2115 +      biosChecksum = utilCalcBIOSChecksum(tempBIOS, systemType);
  7.2116 +    }
  7.2117 +  free(tempBIOS);
  7.2118  
  7.2119 -	return biosChecksum;
  7.2120 +  return biosChecksum;
  7.2121  }
  7.2122  
     8.1 --- a/src/gb/GB.cpp	Mon Jun 11 00:55:51 2012 -0500
     8.2 +++ b/src/gb/GB.cpp	Mon Jun 11 06:04:25 2012 -0500
     8.3 @@ -3878,6 +3878,39 @@
     8.4  
     8.5  
     8.6  //RLM: 
     8.7 +/**
     8.8 +void getPixels32(int32* store){
     8.9 +  utilWriteBMP((u8*)store, 144, 160, 32, pix);
    8.10 +}
    8.11 +**/
    8.12 +
    8.13 +void getPixels32(int32* store){
    8.14 +  int w = 160;
    8.15 +  int h = 144;
    8.16 +
    8.17 +  int sizeX = w;
    8.18 +  int sizeY = h;
    8.19 +
    8.20 +  u32 *pixU32 = (u32 *)(pix + 4 * (w + 1) * (h));
    8.21 +  for (int y = 0; y < sizeY; y++)
    8.22 +    {
    8.23 +      for (int x = 0; x < sizeX; x++)
    8.24 +	{
    8.25 +	  u32 v = *pixU32++;
    8.26 +
    8.27 +	  u8 b = ((v >> systemBlueShift) & 0x001f) << 3; // B
    8.28 +	  u8 g = ((v >> systemGreenShift) & 0x001f) << 3; // G
    8.29 +	  u8 r = ((v >> systemRedShift) & 0x001f) << 3; // R
    8.30 +
    8.31 +	  int32 rgb = (r << 16 ) + (g << 8) + b;
    8.32 +	  *store++ = rgb;
    8.33 +	}
    8.34 +      pixU32++;
    8.35 +      pixU32 -= 2 * (w + 1);
    8.36 +    }
    8.37 +}
    8.38 +
    8.39 +
    8.40  int getRamSize(){
    8.41    return gbRamSize;
    8.42  }
     9.1 --- a/src/gb/GB.h	Mon Jun 11 00:55:51 2012 -0500
     9.2 +++ b/src/gb/GB.h	Mon Jun 11 06:04:25 2012 -0500
     9.3 @@ -44,6 +44,8 @@
     9.4  extern bool gbWriteBMPFile(const char *);
     9.5  extern bool gbReadGSASnapshot(const char *);
     9.6  
     9.7 +extern void getPixels32(int32 *);
     9.8 +
     9.9  extern int getRamSize();
    9.10  extern int getRomSize();
    9.11