changeset 33:44974c3e093b

found source of problem for video recording
author Robert McIntyre <rlm@mit.edu>
date Mon, 05 Mar 2012 01:25:11 -0600
parents 0dc331ec7f27
children 6bde5b67a2b8
files commands.sh src/common/movie.cpp src/gb/GB.cpp src/lua/loadlib.c src/sdl/SDL.cpp
diffstat 5 files changed, 4723 insertions(+), 4684 deletions(-) [+]
line wrap: on
line diff
     1.1 --- a/commands.sh	Sun Mar 04 22:44:42 2012 -0600
     1.2 +++ b/commands.sh	Mon Mar 05 01:25:11 2012 -0600
     1.3 @@ -1,12 +1,21 @@
     1.4 +
     1.5  # This buffer is for notes you don't want to save, and for Lisp evaluation.
     1.6  # If you want to create a file, visit that file with C-x C-f,
     1.7  # then enter the text in that file's own buffer.
     1.8  
     1.9  
    1.10 -./VisualBoyAdvance ../../../pokemon-escape/roms/Pokemon\ Yellow\ \(U\)\ \[C\]\[\!\].gbc                                     
    1.11 +#./VisualBoyAdvance ../../../pokemon-escape/roms/Pokemon\ Yellow\ \(U\)\ \[C\]\[\!\].gbc                                     
    1.12  
    1.13  
    1.14 -./VisualBoyAdvance --recordmovie=./rlm.vbm ../../../pokemon-escape/roms/Pokemon\ Yellow\ \(U\)\ \[C\]\[\!\].gbc                                     
    1.15 +#./VisualBoyAdvance --recordmovie=./rlm.vbm ../../../pokemon-escape/roms/Pokemon\ Yellow\ \(U\)\ \[C\]\[\!\].gbc                                     
    1.16  
    1.17 +rm -f /home/r/proj/vba-restore/build/movie.vba
    1.18  
    1.19 -./VisualBoyAdvance --recordmovie=/home/r/proj/vba-restore/build/ /home/r/proj/pokemon-escape/roms/Pokemon\ Yellow\ \(U\)\ \[C\]\[\!\].gbc                             
    1.20 \ No newline at end of file
    1.21 +cd /home/r/proj/vba-restore/build
    1.22 +make install
    1.23 +
    1.24 +/home/r/proj/vba-restore/build/artifacts/bin/VisualBoyAdvance --recordmovie=/home/r/proj/vba-restore/build/movie.vba /home/r/proj/pokemon-escape/roms/yellow.gbc                           
    1.25 +
    1.26 +#.//VisualBoyAdvance --playmovie=/home/r/proj/vba-restore/build/movie.vba /home/r/proj/pokemon-escape/roms/Pokemon\ Yellow\ \(U\)\ \[C\]\[\!\].gbc                             
    1.27 +
    1.28 +hexdump -C /home/r/proj/vba-restore/build/movie.vba
     2.1 --- a/src/common/movie.cpp	Sun Mar 04 22:44:42 2012 -0600
     2.2 +++ b/src/common/movie.cpp	Mon Mar 05 01:25:11 2012 -0600
     2.3 @@ -73,1613 +73,1628 @@
     2.4  // little-endian integer pop/push functions:
     2.5  static inline uint32 Pop32(const uint8 * &ptr)
     2.6  {
     2.7 -	uint32 v = (ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24));
     2.8 -	ptr += 4;
     2.9 -	return v;
    2.10 +  uint32 v = (ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24));
    2.11 +  ptr += 4;
    2.12 +  return v;
    2.13  }
    2.14  
    2.15  static inline uint16 Pop16(const uint8 * &ptr) /* const version */
    2.16  {
    2.17 -	uint16 v = (ptr[0] | (ptr[1] << 8));
    2.18 -	ptr += 2;
    2.19 -	return v;
    2.20 +  uint16 v = (ptr[0] | (ptr[1] << 8));
    2.21 +  ptr += 2;
    2.22 +  return v;
    2.23  }
    2.24  
    2.25  static inline uint16 Pop16(uint8 * &ptr) /* non-const version */
    2.26  {
    2.27 -	uint16 v = (ptr[0] | (ptr[1] << 8));
    2.28 -	ptr += 2;
    2.29 -	return v;
    2.30 +  uint16 v = (ptr[0] | (ptr[1] << 8));
    2.31 +  ptr += 2;
    2.32 +  return v;
    2.33  }
    2.34  
    2.35  static inline uint8 Pop8(const uint8 * &ptr)
    2.36  {
    2.37 -	return *(ptr)++;
    2.38 +  return *(ptr)++;
    2.39  }
    2.40  
    2.41  static inline void Push32(uint32 v, uint8 * &ptr)
    2.42  {
    2.43 -	ptr[0] = (uint8)(v & 0xff);
    2.44 -	ptr[1] = (uint8)((v >> 8) & 0xff);
    2.45 -	ptr[2] = (uint8)((v >> 16) & 0xff);
    2.46 -	ptr[3] = (uint8)((v >> 24) & 0xff);
    2.47 -	ptr	  += 4;
    2.48 +  ptr[0] = (uint8)(v & 0xff);
    2.49 +  ptr[1] = (uint8)((v >> 8) & 0xff);
    2.50 +  ptr[2] = (uint8)((v >> 16) & 0xff);
    2.51 +  ptr[3] = (uint8)((v >> 24) & 0xff);
    2.52 +  ptr	  += 4;
    2.53  }
    2.54  
    2.55  static inline void Push16(uint16 v, uint8 * &ptr)
    2.56  {
    2.57 -	ptr[0] = (uint8)(v & 0xff);
    2.58 -	ptr[1] = (uint8)((v >> 8) & 0xff);
    2.59 -	ptr	  += 2;
    2.60 +  ptr[0] = (uint8)(v & 0xff);
    2.61 +  ptr[1] = (uint8)((v >> 8) & 0xff);
    2.62 +  ptr	  += 2;
    2.63  }
    2.64  
    2.65  static inline void Push8(uint8 v, uint8 * &ptr)
    2.66  {
    2.67 -	*ptr++ = v;
    2.68 +  *ptr++ = v;
    2.69  }
    2.70  
    2.71  // little-endian integer read/write functions:
    2.72  static inline uint16 Read16(const uint8 *ptr)
    2.73  {
    2.74 -	return ptr[0] | (ptr[1] << 8);
    2.75 +  return ptr[0] | (ptr[1] << 8);
    2.76  }
    2.77  
    2.78  static inline void Write16(uint16 v, uint8 *ptr)
    2.79  {
    2.80 -	ptr[0] = uint8(v & 0xff);
    2.81 -	ptr[1] = uint8((v >> 8) & 0xff);
    2.82 +  ptr[0] = uint8(v & 0xff);
    2.83 +  ptr[1] = uint8((v >> 8) & 0xff);
    2.84  }
    2.85  
    2.86  static long file_length(FILE *fp)
    2.87  {
    2.88 -	long cur_pos = ftell(fp);
    2.89 -	fseek(fp, 0, SEEK_END);
    2.90 -	long length = ftell(fp);
    2.91 -	fseek(fp, cur_pos, SEEK_SET);
    2.92 -	return length;
    2.93 +  long cur_pos = ftell(fp);
    2.94 +  fseek(fp, 0, SEEK_END);
    2.95 +  long length = ftell(fp);
    2.96 +  fseek(fp, cur_pos, SEEK_SET);
    2.97 +  return length;
    2.98  }
    2.99  
   2.100  static int bytes_per_frame(SMovie &mov)
   2.101  {
   2.102 -	int num_controllers = 0;
   2.103 +  int num_controllers = 0;
   2.104  
   2.105 -	for (int i = 0; i < MOVIE_NUM_OF_POSSIBLE_CONTROLLERS; ++i)
   2.106 -		if (mov.header.controllerFlags & MOVIE_CONTROLLER(i))
   2.107 -			++num_controllers;
   2.108 +  for (int i = 0; i < MOVIE_NUM_OF_POSSIBLE_CONTROLLERS; ++i)
   2.109 +    if (mov.header.controllerFlags & MOVIE_CONTROLLER(i))
   2.110 +      ++num_controllers;
   2.111  
   2.112 -	return CONTROLLER_DATA_SIZE * num_controllers;
   2.113 +  return CONTROLLER_DATA_SIZE * num_controllers;
   2.114  }
   2.115  
   2.116  static void reserve_buffer_space(uint32 space_needed)
   2.117  {
   2.118 -	if (space_needed > Movie.inputBufferSize)
   2.119 -	{
   2.120 -		uint32 ptr_offset	= Movie.inputBufferPtr - Movie.inputBuffer;
   2.121 -		uint32 alloc_chunks = (space_needed - 1) / BUFFER_GROWTH_SIZE + 1;
   2.122 -		uint32 old_size     = Movie.inputBufferSize;
   2.123 -		Movie.inputBufferSize = BUFFER_GROWTH_SIZE * alloc_chunks;
   2.124 -		Movie.inputBuffer	  = (uint8 *)realloc(Movie.inputBuffer, Movie.inputBufferSize);
   2.125 -		// FIXME: this only fixes the random input problem during dma-frame-skip, but not the skip
   2.126 -		memset(Movie.inputBuffer + old_size, 0, Movie.inputBufferSize - old_size);
   2.127 -		Movie.inputBufferPtr  = Movie.inputBuffer + ptr_offset;
   2.128 -	}
   2.129 +  if (space_needed > Movie.inputBufferSize)
   2.130 +    {
   2.131 +      uint32 ptr_offset	= Movie.inputBufferPtr - Movie.inputBuffer;
   2.132 +      uint32 alloc_chunks = (space_needed - 1) / BUFFER_GROWTH_SIZE + 1;
   2.133 +      uint32 old_size     = Movie.inputBufferSize;
   2.134 +      Movie.inputBufferSize = BUFFER_GROWTH_SIZE * alloc_chunks;
   2.135 +      Movie.inputBuffer	  = (uint8 *)realloc(Movie.inputBuffer, Movie.inputBufferSize);
   2.136 +      // FIXME: this only fixes the random input problem during dma-frame-skip, but not the skip
   2.137 +      memset(Movie.inputBuffer + old_size, 0, Movie.inputBufferSize - old_size);
   2.138 +      Movie.inputBufferPtr  = Movie.inputBuffer + ptr_offset;
   2.139 +    }
   2.140  }
   2.141  
   2.142  static int read_movie_header(FILE *file, SMovie &movie)
   2.143  {
   2.144 -	assert(file != NULL);
   2.145 -	assert(VBM_HEADER_SIZE == sizeof(SMovieFileHeader)); // sanity check on the header type definition
   2.146 +  assert(file != NULL);
   2.147 +  assert(VBM_HEADER_SIZE == sizeof(SMovieFileHeader)); // sanity check on the header type definition
   2.148  
   2.149 -	uint8 headerData [VBM_HEADER_SIZE];
   2.150 +  uint8 headerData [VBM_HEADER_SIZE];
   2.151  
   2.152 -	if (fread(headerData, 1, VBM_HEADER_SIZE, file) != VBM_HEADER_SIZE)
   2.153 -		return MOVIE_WRONG_FORMAT;  // if we failed to read in all VBM_HEADER_SIZE bytes of the header
   2.154 +  if (fread(headerData, 1, VBM_HEADER_SIZE, file) != VBM_HEADER_SIZE)
   2.155 +    return MOVIE_WRONG_FORMAT;  // if we failed to read in all VBM_HEADER_SIZE bytes of the header
   2.156  
   2.157 -	const uint8 *	  ptr	 = headerData;
   2.158 -	SMovieFileHeader &header = movie.header;
   2.159 +  const uint8 *	  ptr	 = headerData;
   2.160 +  SMovieFileHeader &header = movie.header;
   2.161  
   2.162 -	header.magic = Pop32(ptr);
   2.163 -	if (header.magic != VBM_MAGIC)
   2.164 -		return MOVIE_WRONG_FORMAT;
   2.165 +  header.magic = Pop32(ptr);
   2.166 +  if (header.magic != VBM_MAGIC)
   2.167 +    return MOVIE_WRONG_FORMAT;
   2.168  
   2.169 -	header.version = Pop32(ptr);
   2.170 -	if (header.version != VBM_VERSION)
   2.171 -		return MOVIE_WRONG_VERSION;
   2.172 +  header.version = Pop32(ptr);
   2.173 +  if (header.version != VBM_VERSION)
   2.174 +    return MOVIE_WRONG_VERSION;
   2.175  
   2.176 -	header.uid = Pop32(ptr);
   2.177 -	header.length_frames  = Pop32(ptr) + 1;    // HACK: add 1 to the length for compatibility
   2.178 -	header.rerecord_count = Pop32(ptr);
   2.179 +  header.uid = Pop32(ptr);
   2.180 +  header.length_frames  = Pop32(ptr) + 1;    // HACK: add 1 to the length for compatibility
   2.181 +  header.rerecord_count = Pop32(ptr);
   2.182  
   2.183 -	header.startFlags	   = Pop8(ptr);
   2.184 -	header.controllerFlags = Pop8(ptr);
   2.185 -	header.typeFlags	   = Pop8(ptr);
   2.186 -	header.optionFlags	   = Pop8(ptr);
   2.187 +  header.startFlags	   = Pop8(ptr);
   2.188 +  header.controllerFlags = Pop8(ptr);
   2.189 +  header.typeFlags	   = Pop8(ptr);
   2.190 +  header.optionFlags	   = Pop8(ptr);
   2.191  
   2.192 -	header.saveType		  = Pop32(ptr);
   2.193 -	header.flashSize	  = Pop32(ptr);
   2.194 -	header.gbEmulatorType = Pop32(ptr);
   2.195 +  header.saveType		  = Pop32(ptr);
   2.196 +  header.flashSize	  = Pop32(ptr);
   2.197 +  header.gbEmulatorType = Pop32(ptr);
   2.198  
   2.199 -	for (int i = 0; i < 12; i++)
   2.200 -		header.romTitle[i] = Pop8(ptr);
   2.201 +  for (int i = 0; i < 12; i++)
   2.202 +    header.romTitle[i] = Pop8(ptr);
   2.203  
   2.204 -	header.minorVersion = Pop8(ptr);
   2.205 +  header.minorVersion = Pop8(ptr);
   2.206  
   2.207 -	header.romCRC = Pop8(ptr);
   2.208 -	header.romOrBiosChecksum = Pop16(ptr);
   2.209 -	header.romGameCode		 = Pop32(ptr);
   2.210 +  header.romCRC = Pop8(ptr);
   2.211 +  header.romOrBiosChecksum = Pop16(ptr);
   2.212 +  header.romGameCode		 = Pop32(ptr);
   2.213  
   2.214 -	header.offset_to_savestate		 = Pop32(ptr);
   2.215 -	header.offset_to_controller_data = Pop32(ptr);
   2.216 +  header.offset_to_savestate		 = Pop32(ptr);
   2.217 +  header.offset_to_controller_data = Pop32(ptr);
   2.218  
   2.219 -	return MOVIE_SUCCESS;
   2.220 +  return MOVIE_SUCCESS;
   2.221  }
   2.222  
   2.223  static void write_movie_header(FILE *file, const SMovie &movie)
   2.224  {
   2.225 -	assert(ftell(file) == 0); // we assume file points to beginning of movie file
   2.226 +  assert(ftell(file) == 0); // we assume file points to beginning of movie file
   2.227  
   2.228 -	uint8  headerData [VBM_HEADER_SIZE];
   2.229 -	uint8 *ptr = headerData;
   2.230 -	const SMovieFileHeader &header = movie.header;
   2.231 +  uint8  headerData [VBM_HEADER_SIZE];
   2.232 +  uint8 *ptr = headerData;
   2.233 +  const SMovieFileHeader &header = movie.header;
   2.234  
   2.235 -	Push32(header.magic, ptr);
   2.236 -	Push32(header.version, ptr);
   2.237 +  Push32(header.magic, ptr);
   2.238 +  Push32(header.version, ptr);
   2.239  
   2.240 -	Push32(header.uid, ptr);
   2.241 -	Push32(header.length_frames - 1, ptr);     // HACK: reduce the length by 1 for compatibility with certain faulty old tools
   2.242 -	                                           // like TME
   2.243 -	Push32(header.rerecord_count, ptr);
   2.244 +  Push32(header.uid, ptr);
   2.245 +  Push32(header.length_frames - 1, ptr);     // HACK: reduce the length by 1 for compatibility with certain faulty old tools
   2.246 +  // like TME
   2.247 +  Push32(header.rerecord_count, ptr);
   2.248  
   2.249 -	Push8(header.startFlags, ptr);
   2.250 -	Push8(header.controllerFlags, ptr);
   2.251 -	Push8(header.typeFlags, ptr);
   2.252 -	Push8(header.optionFlags, ptr);
   2.253 +  Push8(header.startFlags, ptr);
   2.254 +  Push8(header.controllerFlags, ptr);
   2.255 +  Push8(header.typeFlags, ptr);
   2.256 +  Push8(header.optionFlags, ptr);
   2.257  
   2.258 -	Push32(header.saveType, ptr);
   2.259 -	Push32(header.flashSize, ptr);
   2.260 -	Push32(header.gbEmulatorType, ptr);
   2.261 +  Push32(header.saveType, ptr);
   2.262 +  Push32(header.flashSize, ptr);
   2.263 +  Push32(header.gbEmulatorType, ptr);
   2.264  
   2.265 -	for (int i = 0; i < 12; ++i)
   2.266 -		Push8(header.romTitle[i], ptr);
   2.267 +  for (int i = 0; i < 12; ++i)
   2.268 +    Push8(header.romTitle[i], ptr);
   2.269  
   2.270 -	Push8(header.minorVersion, ptr);
   2.271 +  Push8(header.minorVersion, ptr);
   2.272  
   2.273 -	Push8(header.romCRC, ptr);
   2.274 -	Push16(header.romOrBiosChecksum, ptr);
   2.275 -	Push32(header.romGameCode, ptr);
   2.276 +  Push8(header.romCRC, ptr);
   2.277 +  Push16(header.romOrBiosChecksum, ptr);
   2.278 +  Push32(header.romGameCode, ptr);
   2.279  
   2.280 -	Push32(header.offset_to_savestate, ptr);
   2.281 -	Push32(header.offset_to_controller_data, ptr);
   2.282 +  Push32(header.offset_to_savestate, ptr);
   2.283 +  Push32(header.offset_to_controller_data, ptr);
   2.284  
   2.285 -	fwrite(headerData, 1, VBM_HEADER_SIZE, file);
   2.286 +  fwrite(headerData, 1, VBM_HEADER_SIZE, file);
   2.287  }
   2.288  
   2.289  static void flush_movie_header()
   2.290  {
   2.291 -	assert(Movie.file != 0 && "logical error!");
   2.292 -	if (!Movie.file)
   2.293 -		return;
   2.294 +  assert(Movie.file != 0 && "logical error!");
   2.295 +  if (!Movie.file)
   2.296 +    return;
   2.297  
   2.298 -	long originalPos = ftell(Movie.file);
   2.299 +  long originalPos = ftell(Movie.file);
   2.300  
   2.301 -	// (over-)write the header
   2.302 -	fseek(Movie.file, 0, SEEK_SET);
   2.303 -	write_movie_header(Movie.file, Movie);
   2.304 +  // (over-)write the header
   2.305 +  fseek(Movie.file, 0, SEEK_SET);
   2.306 +  write_movie_header(Movie.file, Movie);
   2.307  
   2.308 -	fflush(Movie.file);
   2.309 +  fflush(Movie.file);
   2.310  
   2.311 -	fseek(Movie.file, originalPos, SEEK_SET);
   2.312 +  fseek(Movie.file, originalPos, SEEK_SET);
   2.313  }
   2.314  
   2.315  static void flush_movie_frames()
   2.316  {
   2.317 -	assert(Movie.file && "logical error!");
   2.318 -	if (!Movie.file)
   2.319 -		return;
   2.320 +  assert(Movie.file && "logical error!");
   2.321 +  if (!Movie.file)
   2.322 +    return;
   2.323  
   2.324 -	long originalPos = ftell(Movie.file);
   2.325 +  long originalPos = ftell(Movie.file);
   2.326  
   2.327 -	// overwrite the controller data
   2.328 -	fseek(Movie.file, Movie.header.offset_to_controller_data, SEEK_SET);
   2.329 -	fwrite(Movie.inputBuffer, 1, Movie.bytesPerFrame * Movie.header.length_frames, Movie.file);
   2.330 +  // overwrite the controller data
   2.331 +  fseek(Movie.file, Movie.header.offset_to_controller_data, SEEK_SET);
   2.332 +  fwrite(Movie.inputBuffer, 1, Movie.bytesPerFrame * Movie.header.length_frames, Movie.file);
   2.333  
   2.334 -	fflush(Movie.file);
   2.335 +  fflush(Movie.file);
   2.336  
   2.337 -	fseek(Movie.file, originalPos, SEEK_SET);
   2.338 +  fseek(Movie.file, originalPos, SEEK_SET);
   2.339  }
   2.340  
   2.341  static void truncate_movie(long length)
   2.342  {
   2.343 -	// truncate movie to length
   2.344 -	// NOTE: it's certain that the savestate block is never after the
   2.345 -	//       controller data block, because the VBM format decrees it.
   2.346 +  // truncate movie to length
   2.347 +  // NOTE: it's certain that the savestate block is never after the
   2.348 +  //       controller data block, because the VBM format decrees it.
   2.349  
   2.350 -	assert(Movie.file && length >= 0);
   2.351 -	if (!Movie.file || length < 0)
   2.352 -		return;
   2.353 +  assert(Movie.file && length >= 0);
   2.354 +  if (!Movie.file || length < 0)
   2.355 +    return;
   2.356  
   2.357 -	assert(Movie.header.offset_to_savestate <= Movie.header.offset_to_controller_data);
   2.358 -	if (Movie.header.offset_to_savestate > Movie.header.offset_to_controller_data)
   2.359 -		return;
   2.360 +  assert(Movie.header.offset_to_savestate <= Movie.header.offset_to_controller_data);
   2.361 +  if (Movie.header.offset_to_savestate > Movie.header.offset_to_controller_data)
   2.362 +    return;
   2.363  
   2.364 -	Movie.header.length_frames = length;
   2.365 -	flush_movie_header();
   2.366 -	const long truncLen = long(Movie.header.offset_to_controller_data + Movie.bytesPerFrame * length);
   2.367 -	if (file_length(Movie.file) != truncLen)
   2.368 -	{
   2.369 -		ftruncate(fileno(Movie.file), truncLen);
   2.370 -	}
   2.371 +  Movie.header.length_frames = length;
   2.372 +  flush_movie_header();
   2.373 +  const long truncLen = long(Movie.header.offset_to_controller_data + Movie.bytesPerFrame * length);
   2.374 +  if (file_length(Movie.file) != truncLen)
   2.375 +    {
   2.376 +      ftruncate(fileno(Movie.file), truncLen);
   2.377 +    }
   2.378  }
   2.379  
   2.380  static void remember_input_state()
   2.381  {
   2.382 -	for (int i = 0; i < MOVIE_NUM_OF_POSSIBLE_CONTROLLERS; ++i)
   2.383 +  for (int i = 0; i < MOVIE_NUM_OF_POSSIBLE_CONTROLLERS; ++i)
   2.384 +    {
   2.385 +      if (systemCartridgeType == 0)
   2.386  	{
   2.387 -		if (systemCartridgeType == 0)
   2.388 -		{
   2.389 -			initialInputs[i] = u16(~P1 & 0x03FF);
   2.390 -		}
   2.391 -		else
   2.392 -		{
   2.393 -			extern int32 gbJoymask[4];
   2.394 -			for (int i = 0; i < 4; ++i)
   2.395 -				initialInputs[i] = u16(gbJoymask[i] & 0xFFFF);
   2.396 -		}
   2.397 +	  initialInputs[i] = u16(~P1 & 0x03FF);
   2.398  	}
   2.399 +      else
   2.400 +	{
   2.401 +	  extern int32 gbJoymask[4];
   2.402 +	  for (int i = 0; i < 4; ++i)
   2.403 +	    initialInputs[i] = u16(gbJoymask[i] & 0xFFFF);
   2.404 +	}
   2.405 +    }
   2.406  }
   2.407  
   2.408  static void change_state(MovieState new_state)
   2.409  {
   2.410  #if (defined(WIN32) && !defined(SDL))
   2.411 -	theApp.frameSearching	   = false;
   2.412 -	theApp.frameSearchSkipping = false;
   2.413 +  theApp.frameSearching	   = false;
   2.414 +  theApp.frameSearchSkipping = false;
   2.415  #endif
   2.416  
   2.417 -	if (new_state == MOVIE_STATE_NONE)
   2.418 +  if (new_state == MOVIE_STATE_NONE)
   2.419 +    {
   2.420 +      Movie.pauseFrame = -1;
   2.421 +
   2.422 +      if (Movie.state == MOVIE_STATE_NONE)
   2.423 +	return;
   2.424 +
   2.425 +      truncate_movie(Movie.header.length_frames);
   2.426 +
   2.427 +      fclose(Movie.file);
   2.428 +      Movie.file		   = NULL;
   2.429 +      Movie.currentFrame = 0;
   2.430 +#if (defined(WIN32) && !defined(SDL))
   2.431 +      // undo changes to border settings
   2.432 +      {
   2.433 +	gbBorderOn = prevBorder;
   2.434 +	theApp.winGbBorderOn = prevWinBorder;
   2.435 +	gbBorderAutomatic	 = prevBorderAuto;
   2.436 +	systemGbBorderOn();
   2.437 +      }
   2.438 +#endif
   2.439 +      gbEmulatorType = prevEmulatorType;
   2.440 +
   2.441 +      extern int32 gbDMASpeedVersion;
   2.442 +      gbDMASpeedVersion = 1;
   2.443 +
   2.444 +      extern int32 gbEchoRAMFixOn;
   2.445 +      gbEchoRAMFixOn = 1;
   2.446 +
   2.447 +      gbNullInputHackTempEnabled = gbNullInputHackEnabled;
   2.448 +
   2.449 +      if (Movie.inputBuffer)
   2.450  	{
   2.451 -		Movie.pauseFrame = -1;
   2.452 +	  free(Movie.inputBuffer);
   2.453 +	  Movie.inputBuffer = NULL;
   2.454 +	}
   2.455 +    }
   2.456 +  else if (new_state == MOVIE_STATE_PLAY)
   2.457 +    {
   2.458 +      assert(Movie.file);
   2.459  
   2.460 -		if (Movie.state == MOVIE_STATE_NONE)
   2.461 -			return;
   2.462 +      // this would cause problems if not dealt with
   2.463 +      if (Movie.currentFrame >= Movie.header.length_frames)
   2.464 +	{
   2.465 +	  new_state = MOVIE_STATE_END;
   2.466 +	  Movie.inputBufferPtr = Movie.inputBuffer + Movie.bytesPerFrame * Movie.header.length_frames;
   2.467 +	}
   2.468 +    }
   2.469 +  else if (new_state == MOVIE_STATE_RECORD)
   2.470 +    {
   2.471 +      assert(Movie.file);
   2.472  
   2.473 -		truncate_movie(Movie.header.length_frames);
   2.474 -
   2.475 -		fclose(Movie.file);
   2.476 -		Movie.file		   = NULL;
   2.477 -		Movie.currentFrame = 0;
   2.478 -#if (defined(WIN32) && !defined(SDL))
   2.479 -		// undo changes to border settings
   2.480 -		{
   2.481 -			gbBorderOn = prevBorder;
   2.482 -			theApp.winGbBorderOn = prevWinBorder;
   2.483 -			gbBorderAutomatic	 = prevBorderAuto;
   2.484 -			systemGbBorderOn();
   2.485 -		}
   2.486 -#endif
   2.487 -		gbEmulatorType = prevEmulatorType;
   2.488 -
   2.489 -		extern int32 gbDMASpeedVersion;
   2.490 -		gbDMASpeedVersion = 1;
   2.491 -
   2.492 -		extern int32 gbEchoRAMFixOn;
   2.493 -		gbEchoRAMFixOn = 1;
   2.494 -
   2.495 -		gbNullInputHackTempEnabled = gbNullInputHackEnabled;
   2.496 -
   2.497 -		if (Movie.inputBuffer)
   2.498 -		{
   2.499 -			free(Movie.inputBuffer);
   2.500 -			Movie.inputBuffer = NULL;
   2.501 -		}
   2.502 -	}
   2.503 -	else if (new_state == MOVIE_STATE_PLAY)
   2.504 +      // this would cause problems if not dealt with
   2.505 +      if (Movie.currentFrame > Movie.header.length_frames)
   2.506  	{
   2.507 -		assert(Movie.file);
   2.508 -
   2.509 -		// this would cause problems if not dealt with
   2.510 -		if (Movie.currentFrame >= Movie.header.length_frames)
   2.511 -		{
   2.512 -			new_state = MOVIE_STATE_END;
   2.513 -			Movie.inputBufferPtr = Movie.inputBuffer + Movie.bytesPerFrame * Movie.header.length_frames;
   2.514 -		}
   2.515 -	}
   2.516 -	else if (new_state == MOVIE_STATE_RECORD)
   2.517 -	{
   2.518 -		assert(Movie.file);
   2.519 -
   2.520 -		// this would cause problems if not dealt with
   2.521 -		if (Movie.currentFrame > Movie.header.length_frames)
   2.522 -		{
   2.523 -			new_state = MOVIE_STATE_END;
   2.524 -			Movie.inputBufferPtr = Movie.inputBuffer + Movie.bytesPerFrame * Movie.header.length_frames;
   2.525 -		}
   2.526 -
   2.527 -		fseek(Movie.file, Movie.header.offset_to_controller_data + Movie.bytesPerFrame * Movie.currentFrame, SEEK_SET);
   2.528 +	  new_state = MOVIE_STATE_END;
   2.529 +	  Movie.inputBufferPtr = Movie.inputBuffer + Movie.bytesPerFrame * Movie.header.length_frames;
   2.530  	}
   2.531  
   2.532 -	if (new_state == MOVIE_STATE_END && Movie.state != MOVIE_STATE_END)
   2.533 +      fseek(Movie.file, Movie.header.offset_to_controller_data + Movie.bytesPerFrame * Movie.currentFrame, SEEK_SET);
   2.534 +    }
   2.535 +
   2.536 +  if (new_state == MOVIE_STATE_END && Movie.state != MOVIE_STATE_END)
   2.537 +    {
   2.538 +#if defined(SDL)		
   2.539 +      systemClearJoypads();
   2.540 +#endif
   2.541 +      systemScreenMessage("Movie end");
   2.542 +    }
   2.543 +
   2.544 +  Movie.state = new_state;
   2.545 +
   2.546 +  // checking for movie end
   2.547 +  bool willPause = false;
   2.548 +
   2.549 +  // if the movie's been set to pause at a certain frame
   2.550 +  if (Movie.state != MOVIE_STATE_NONE && Movie.pauseFrame >= 0 && Movie.currentFrame == (uint32)Movie.pauseFrame)
   2.551 +    {
   2.552 +      Movie.pauseFrame = -1;
   2.553 +      willPause		 = true;
   2.554 +    }
   2.555 +
   2.556 +  if (Movie.state == MOVIE_STATE_END)
   2.557 +    {
   2.558 +      if (Movie.currentFrame == Movie.header.length_frames)
   2.559  	{
   2.560 -#if defined(SDL)		
   2.561 -		systemClearJoypads();
   2.562 -#endif
   2.563 -		systemScreenMessage("Movie end");
   2.564 -	}
   2.565 -
   2.566 -	Movie.state = new_state;
   2.567 -
   2.568 -	// checking for movie end
   2.569 -	bool willPause = false;
   2.570 -
   2.571 -	// if the movie's been set to pause at a certain frame
   2.572 -	if (Movie.state != MOVIE_STATE_NONE && Movie.pauseFrame >= 0 && Movie.currentFrame == (uint32)Movie.pauseFrame)
   2.573 -	{
   2.574 -		Movie.pauseFrame = -1;
   2.575 -		willPause		 = true;
   2.576 -	}
   2.577 -
   2.578 -	if (Movie.state == MOVIE_STATE_END)
   2.579 -	{
   2.580 -		if (Movie.currentFrame == Movie.header.length_frames)
   2.581 -		{
   2.582  #if (defined(WIN32) && !defined(SDL))
   2.583 -			if (theApp.movieOnEndPause)
   2.584 -			{
   2.585 -				willPause = true;
   2.586 -			}
   2.587 +	  if (theApp.movieOnEndPause)
   2.588 +	    {
   2.589 +	      willPause = true;
   2.590 +	    }
   2.591  #else
   2.592 -			// SDL FIXME
   2.593 +	  // SDL FIXME
   2.594  #endif
   2.595  
   2.596  #if (defined(WIN32) && !defined(SDL))
   2.597 -			switch (theApp.movieOnEndBehavior)
   2.598 -			{
   2.599 -			case 1:
   2.600 -				// the old behavior
   2.601 -				//VBAMovieRestart();
   2.602 -				break;
   2.603 -			case 2:
   2.604 +	  switch (theApp.movieOnEndBehavior)
   2.605 +	    {
   2.606 +	    case 1:
   2.607 +	      // the old behavior
   2.608 +	      //VBAMovieRestart();
   2.609 +	      break;
   2.610 +	    case 2:
   2.611  #else
   2.612 -			// SDL FIXME
   2.613 +	      // SDL FIXME
   2.614  #endif
   2.615 -				if (Movie.RecordedThisSession)
   2.616 -				{
   2.617 -					// if user has been recording this movie since the last time it started playing,
   2.618 -					// they probably don't want the movie to end now during playback,
   2.619 -					// so switch back to recording when it reaches the end
   2.620 -					VBAMovieSwitchToRecording();
   2.621 -					systemScreenMessage("Recording resumed");
   2.622 -					willPause = true;
   2.623 -				}
   2.624 +	      if (Movie.RecordedThisSession)
   2.625 +		{
   2.626 +		  // if user has been recording this movie since the last time it started playing,
   2.627 +		  // they probably don't want the movie to end now during playback,
   2.628 +		  // so switch back to recording when it reaches the end
   2.629 +		  VBAMovieSwitchToRecording();
   2.630 +		  systemScreenMessage("Recording resumed");
   2.631 +		  willPause = true;
   2.632 +		}
   2.633  #if (defined(WIN32) && !defined(SDL))
   2.634 -				break;
   2.635 -			case 3:
   2.636 -				// keep open
   2.637 -				break;
   2.638 -			case 0:
   2.639 -				// fall through
   2.640 -			default:
   2.641 -				// close movie
   2.642 -				//VBAMovieStop(false);
   2.643 -				break;
   2.644 -			}
   2.645 +	      break;
   2.646 +	    case 3:
   2.647 +	      // keep open
   2.648 +	      break;
   2.649 +	    case 0:
   2.650 +	      // fall through
   2.651 +	    default:
   2.652 +	      // close movie
   2.653 +	      //VBAMovieStop(false);
   2.654 +	      break;
   2.655 +	    }
   2.656  #else
   2.657 -				// SDL FIXME
   2.658 +	  // SDL FIXME
   2.659  #endif
   2.660 -		}
   2.661 +	}
   2.662  #if 1
   2.663 -		else if (Movie.currentFrame > Movie.header.length_frames)
   2.664 -		{
   2.665 +      else if (Movie.currentFrame > Movie.header.length_frames)
   2.666 +	{
   2.667  #if (defined(WIN32) && !defined(SDL))
   2.668 -			switch (theApp.movieOnEndBehavior)
   2.669 -			{
   2.670 -			case 1:
   2.671 -				// FIXME: this should be delayed till the current frame ends
   2.672 -				VBAMovieRestart();
   2.673 -				break;
   2.674 -			case 2:
   2.675 -				// nothing
   2.676 -				break;
   2.677 -			case 3:
   2.678 -				// keep open
   2.679 -				break;
   2.680 -			case 0:
   2.681 -				// fall through
   2.682 -			default:
   2.683 -				// close movie
   2.684 -				VBAMovieStop(false);
   2.685 -				break;
   2.686 -			}
   2.687 +	  switch (theApp.movieOnEndBehavior)
   2.688 +	    {
   2.689 +	    case 1:
   2.690 +	      // FIXME: this should be delayed till the current frame ends
   2.691 +	      VBAMovieRestart();
   2.692 +	      break;
   2.693 +	    case 2:
   2.694 +	      // nothing
   2.695 +	      break;
   2.696 +	    case 3:
   2.697 +	      // keep open
   2.698 +	      break;
   2.699 +	    case 0:
   2.700 +	      // fall through
   2.701 +	    default:
   2.702 +	      // close movie
   2.703 +	      VBAMovieStop(false);
   2.704 +	      break;
   2.705 +	    }
   2.706  #else
   2.707 -			// SDLFIXME
   2.708 +	  // SDLFIXME
   2.709  #endif
   2.710 -		}
   2.711 +	}
   2.712  #endif
   2.713 -	} // end if (Movie.state == MOVIE_STATE_END)
   2.714 +    } // end if (Movie.state == MOVIE_STATE_END)
   2.715  
   2.716 -	if (willPause)
   2.717 -	{
   2.718 -		systemSetPause(true);
   2.719 -	}
   2.720 +  if (willPause)
   2.721 +    {
   2.722 +      systemSetPause(true);
   2.723 +    }
   2.724  }
   2.725  
   2.726  void VBAMovieInit()
   2.727  {
   2.728 -	memset(&Movie, 0, sizeof(Movie));
   2.729 -	Movie.state		 = MOVIE_STATE_NONE;
   2.730 -	Movie.pauseFrame = -1;
   2.731 +  memset(&Movie, 0, sizeof(Movie));
   2.732 +  Movie.state		 = MOVIE_STATE_NONE;
   2.733 +  Movie.pauseFrame = -1;
   2.734  
   2.735 -	resetSignaled	  = false;
   2.736 -	resetSignaledLast = false;
   2.737 +  resetSignaled	  = false;
   2.738 +  resetSignaledLast = false;
   2.739  }
   2.740  
   2.741  void VBAMovieGetRomInfo(const SMovie &movieInfo, char romTitle [12], uint32 &romGameCode, uint16 &checksum, uint8 &crc)
   2.742  {
   2.743 -	if (systemCartridgeType == 0) // GBA
   2.744 -	{
   2.745 -		extern u8 *bios, *rom;
   2.746 -		memcpy(romTitle, &rom[0xa0], 12); // GBA TITLE
   2.747 -		memcpy(&romGameCode, &rom[0xac], 4); // GBA ROM GAME CODE
   2.748 -		if ((movieInfo.header.optionFlags & MOVIE_SETTING_USEBIOSFILE) != 0)
   2.749 -			checksum = utilCalcBIOSChecksum(bios, 4);  // GBA BIOS CHECKSUM
   2.750 -		else
   2.751 -			checksum = 0;
   2.752 -		crc = rom[0xbd]; // GBA ROM CRC
   2.753 -	}
   2.754 -	else // non-GBA
   2.755 -	{
   2.756 -		extern u8 *gbRom;
   2.757 -		memcpy(romTitle, &gbRom[0x134], 12); // GB TITLE (note this can be 15 but is truncated to 12)
   2.758 -		romGameCode = (uint32)gbRom[0x146]; // GB ROM UNIT CODE
   2.759 +  if (systemCartridgeType == 0) // GBA
   2.760 +    {
   2.761 +      extern u8 *bios, *rom;
   2.762 +      memcpy(romTitle, &rom[0xa0], 12); // GBA TITLE
   2.763 +      memcpy(&romGameCode, &rom[0xac], 4); // GBA ROM GAME CODE
   2.764 +      if ((movieInfo.header.optionFlags & MOVIE_SETTING_USEBIOSFILE) != 0)
   2.765 +	checksum = utilCalcBIOSChecksum(bios, 4);  // GBA BIOS CHECKSUM
   2.766 +      else
   2.767 +	checksum = 0;
   2.768 +      crc = rom[0xbd]; // GBA ROM CRC
   2.769 +    }
   2.770 +  else // non-GBA
   2.771 +    {
   2.772 +      extern u8 *gbRom;
   2.773 +      memcpy(romTitle, &gbRom[0x134], 12); // GB TITLE (note this can be 15 but is truncated to 12)
   2.774 +      romGameCode = (uint32)gbRom[0x146]; // GB ROM UNIT CODE
   2.775  
   2.776 -		checksum = (gbRom[0x14e] << 8) | gbRom[0x14f]; // GB ROM CHECKSUM, read from big-endian
   2.777 -		crc		 = gbRom[0x14d]; // GB ROM CRC
   2.778 -	}
   2.779 +      checksum = (gbRom[0x14e] << 8) | gbRom[0x14f]; // GB ROM CHECKSUM, read from big-endian
   2.780 +      crc		 = gbRom[0x14d]; // GB ROM CRC
   2.781 +    }
   2.782  }
   2.783  
   2.784  #ifdef SDL
   2.785  static void GetBatterySaveName(char *buffer)
   2.786  {
   2.787 -	extern char batteryDir[2048], filename[2048];     // from SDL.cpp
   2.788 -	extern char *sdlGetFilename(char *name);     // from SDL.cpp
   2.789 -	if (batteryDir[0])
   2.790 -		sprintf(buffer, "%s/%s.sav", batteryDir, sdlGetFilename(filename));
   2.791 -	else
   2.792 -		sprintf(buffer, "%s.sav", filename);
   2.793 +  extern char batteryDir[2048], filename[2048];     // from SDL.cpp
   2.794 +  extern char *sdlGetFilename(char *name);     // from SDL.cpp
   2.795 +  if (batteryDir[0])
   2.796 +    sprintf(buffer, "%s/%s.sav", batteryDir, sdlGetFilename(filename));
   2.797 +  else
   2.798 +    sprintf(buffer, "%s.sav", filename);
   2.799  }
   2.800  
   2.801  #endif
   2.802  
   2.803  static void SetPlayEmuSettings()
   2.804  {
   2.805 -	prevEmulatorType = gbEmulatorType;
   2.806 -	gbEmulatorType	 = Movie.header.gbEmulatorType;
   2.807 +  prevEmulatorType = gbEmulatorType;
   2.808 +  gbEmulatorType	 = Movie.header.gbEmulatorType;
   2.809  
   2.810  #if (defined(WIN32) && !defined(SDL))
   2.811 -//    theApp.removeIntros   = false;
   2.812 -	theApp.skipBiosFile = (Movie.header.optionFlags & MOVIE_SETTING_SKIPBIOSFILE) != 0;
   2.813 -	theApp.useBiosFile	= (Movie.header.optionFlags & MOVIE_SETTING_USEBIOSFILE) != 0;
   2.814 +  //    theApp.removeIntros   = false;
   2.815 +  theApp.skipBiosFile = (Movie.header.optionFlags & MOVIE_SETTING_SKIPBIOSFILE) != 0;
   2.816 +  theApp.useBiosFile	= (Movie.header.optionFlags & MOVIE_SETTING_USEBIOSFILE) != 0;
   2.817  #else
   2.818 -	extern int	 saveType, sdlRtcEnable, sdlFlashSize;   // from SDL.cpp
   2.819 -	extern bool8 useBios, skipBios, removeIntros;     // from SDL.cpp
   2.820 -	useBios		 = (Movie.header.optionFlags & MOVIE_SETTING_USEBIOSFILE) != 0;
   2.821 -	skipBios	 = (Movie.header.optionFlags & MOVIE_SETTING_SKIPBIOSFILE) != 0;
   2.822 -	removeIntros = false /*(Movie.header.optionFlags & MOVIE_SETTING_REMOVEINTROS) != 0*/;
   2.823 +  extern int	 saveType, sdlRtcEnable, sdlFlashSize;   // from SDL.cpp
   2.824 +  extern bool8 useBios, skipBios, removeIntros;     // from SDL.cpp
   2.825 +  useBios		 = (Movie.header.optionFlags & MOVIE_SETTING_USEBIOSFILE) != 0;
   2.826 +  skipBios	 = (Movie.header.optionFlags & MOVIE_SETTING_SKIPBIOSFILE) != 0;
   2.827 +  removeIntros = false /*(Movie.header.optionFlags & MOVIE_SETTING_REMOVEINTROS) != 0*/;
   2.828  #endif
   2.829  
   2.830 -	extern void SetPrefetchHack(bool);
   2.831 -	if (systemCartridgeType == 0)    // lag disablement applies only to GBA
   2.832 -		SetPrefetchHack((Movie.header.optionFlags & MOVIE_SETTING_LAGHACK) != 0);
   2.833 +  extern void SetPrefetchHack(bool);
   2.834 +  if (systemCartridgeType == 0)    // lag disablement applies only to GBA
   2.835 +    SetPrefetchHack((Movie.header.optionFlags & MOVIE_SETTING_LAGHACK) != 0);
   2.836  
   2.837 -	gbNullInputHackTempEnabled = ((Movie.header.optionFlags & MOVIE_SETTING_GBINPUTHACK) != 0);
   2.838 +  gbNullInputHackTempEnabled = ((Movie.header.optionFlags & MOVIE_SETTING_GBINPUTHACK) != 0);
   2.839  
   2.840 -	// some GB/GBC games depend on the sound rate, so just use the highest one
   2.841 -	systemSoundSetQuality(1);
   2.842 -	useOldFrameTiming = false;
   2.843 +  // some GB/GBC games depend on the sound rate, so just use the highest one
   2.844 +  systemSoundSetQuality(1);
   2.845 +  useOldFrameTiming = false;
   2.846  
   2.847 -	extern int32 gbDMASpeedVersion;
   2.848 -	if ((Movie.header.optionFlags & MOVIE_SETTING_GBCFF55FIX) != 0)
   2.849 -		gbDMASpeedVersion = 1;
   2.850 -	else
   2.851 -		gbDMASpeedVersion = 0;     // old CGB HDMA5 timing was used
   2.852 +  extern int32 gbDMASpeedVersion;
   2.853 +  if ((Movie.header.optionFlags & MOVIE_SETTING_GBCFF55FIX) != 0)
   2.854 +    gbDMASpeedVersion = 1;
   2.855 +  else
   2.856 +    gbDMASpeedVersion = 0;     // old CGB HDMA5 timing was used
   2.857  
   2.858 -	extern int32 gbEchoRAMFixOn;
   2.859 -	if ((Movie.header.optionFlags & MOVIE_SETTING_GBECHORAMFIX) != 0)
   2.860 -		gbEchoRAMFixOn = 1;
   2.861 -	else
   2.862 -		gbEchoRAMFixOn = 0;
   2.863 +  extern int32 gbEchoRAMFixOn;
   2.864 +  if ((Movie.header.optionFlags & MOVIE_SETTING_GBECHORAMFIX) != 0)
   2.865 +    gbEchoRAMFixOn = 1;
   2.866 +  else
   2.867 +    gbEchoRAMFixOn = 0;
   2.868  
   2.869  #if (defined(WIN32) && !defined(SDL))
   2.870 -	rtcEnable((Movie.header.optionFlags & MOVIE_SETTING_RTCENABLE) != 0);
   2.871 -	theApp.winSaveType	= Movie.header.saveType;
   2.872 -	theApp.winFlashSize = Movie.header.flashSize;
   2.873 +  rtcEnable((Movie.header.optionFlags & MOVIE_SETTING_RTCENABLE) != 0);
   2.874 +  theApp.winSaveType	= Movie.header.saveType;
   2.875 +  theApp.winFlashSize = Movie.header.flashSize;
   2.876  
   2.877 -	prevBorder	   = gbBorderOn;
   2.878 -	prevWinBorder  = theApp.winGbBorderOn;
   2.879 -	prevBorderAuto = gbBorderAutomatic;
   2.880 -	if ((gbEmulatorType == 2 || gbEmulatorType == 5)
   2.881 -	    && !theApp.hideMovieBorder) // games played in SGB mode can have a border
   2.882 +  prevBorder	   = gbBorderOn;
   2.883 +  prevWinBorder  = theApp.winGbBorderOn;
   2.884 +  prevBorderAuto = gbBorderAutomatic;
   2.885 +  if ((gbEmulatorType == 2 || gbEmulatorType == 5)
   2.886 +      && !theApp.hideMovieBorder) // games played in SGB mode can have a border
   2.887 +    {
   2.888 +      gbBorderOn = true;
   2.889 +      theApp.winGbBorderOn = true;
   2.890 +      gbBorderAutomatic	 = false;
   2.891 +    }
   2.892 +  else
   2.893 +    {
   2.894 +      gbBorderOn = false;
   2.895 +      theApp.winGbBorderOn = false;
   2.896 +      gbBorderAutomatic	 = false;
   2.897 +      if (theApp.hideMovieBorder)
   2.898  	{
   2.899 -		gbBorderOn = true;
   2.900 -		theApp.winGbBorderOn = true;
   2.901 -		gbBorderAutomatic	 = false;
   2.902 +	  theApp.hideMovieBorder = false;
   2.903 +	  prevBorder = false;     // it might be expected behaviour that it stays hidden after the movie
   2.904  	}
   2.905 -	else
   2.906 -	{
   2.907 -		gbBorderOn = false;
   2.908 -		theApp.winGbBorderOn = false;
   2.909 -		gbBorderAutomatic	 = false;
   2.910 -		if (theApp.hideMovieBorder)
   2.911 -		{
   2.912 -			theApp.hideMovieBorder = false;
   2.913 -			prevBorder = false;     // it might be expected behaviour that it stays hidden after the movie
   2.914 -		}
   2.915 -	}
   2.916 -	systemGbBorderOn();
   2.917 +    }
   2.918 +  systemGbBorderOn();
   2.919  #else
   2.920 -	sdlRtcEnable = (Movie.header.optionFlags & MOVIE_SETTING_RTCENABLE) != 0;
   2.921 -	saveType	 = Movie.header.saveType;
   2.922 -	sdlFlashSize = Movie.header.flashSize;
   2.923 +  sdlRtcEnable = (Movie.header.optionFlags & MOVIE_SETTING_RTCENABLE) != 0;
   2.924 +  saveType	 = Movie.header.saveType;
   2.925 +  sdlFlashSize = Movie.header.flashSize;
   2.926  #endif
   2.927  }
   2.928  
   2.929  static void HardResetAndSRAMClear()
   2.930  {
   2.931  #if (defined(WIN32) && !defined(SDL))
   2.932 -	winEraseBatteryFile(); // delete the damn SRAM file and keep it from being resurrected from RAM
   2.933 -	MainWnd *temp = ((MainWnd *)theApp.m_pMainWnd);
   2.934 -	if (!temp->winFileRun(true)) // restart running the game
   2.935 -	{
   2.936 -		temp->winFileClose();
   2.937 -	}
   2.938 +  winEraseBatteryFile(); // delete the damn SRAM file and keep it from being resurrected from RAM
   2.939 +  MainWnd *temp = ((MainWnd *)theApp.m_pMainWnd);
   2.940 +  if (!temp->winFileRun(true)) // restart running the game
   2.941 +    {
   2.942 +      temp->winFileClose();
   2.943 +    }
   2.944  #else
   2.945 -	char fname [1024];
   2.946 -	GetBatterySaveName(fname);
   2.947 -	remove(fname);     // delete the damn SRAM file
   2.948 +  char fname [1024];
   2.949 +  GetBatterySaveName(fname);
   2.950 +  remove(fname);     // delete the damn SRAM file
   2.951  
   2.952 -	// Henceforth, emuCleanUp means "clear out SRAM"
   2.953 -	//theEmulator.emuCleanUp();     // keep it from being resurrected from RAM <--This is wrong, it'll deallocate all variables --Felipe
   2.954 +  // Henceforth, emuCleanUp means "clear out SRAM"
   2.955 +  //theEmulator.emuCleanUp();     // keep it from being resurrected from RAM <--This is wrong, it'll deallocate all variables --Felipe
   2.956  
   2.957 -	/// FIXME the correct SDL code to call for a full restart isn't in a function yet
   2.958 -	theEmulator.emuReset(false);
   2.959 +  /// FIXME the correct SDL code to call for a full restart isn't in a function yet
   2.960 +  theEmulator.emuReset(false);
   2.961  #endif
   2.962  }
   2.963  
   2.964  int VBAMovieOpen(const char *filename, bool8 read_only)
   2.965  {
   2.966 -	loadingMovie = true;
   2.967 -	uint8 movieReadOnly = read_only ? 1 : 0;
   2.968 +  loadingMovie = true;
   2.969 +  uint8 movieReadOnly = read_only ? 1 : 0;
   2.970  
   2.971 -	FILE * file;
   2.972 -	STREAM stream;
   2.973 -	int	   result;
   2.974 -	int	   fn;
   2.975 +  FILE * file;
   2.976 +  STREAM stream;
   2.977 +  int	   result;
   2.978 +  int	   fn;
   2.979  
   2.980 -	char movie_filename[_MAX_PATH];
   2.981 +  char movie_filename[_MAX_PATH];
   2.982  #ifdef WIN32
   2.983 -	_fullpath(movie_filename, filename, _MAX_PATH);
   2.984 +  _fullpath(movie_filename, filename, _MAX_PATH);
   2.985  #else
   2.986 -	// SDL FIXME: convert to fullpath
   2.987 -	strncpy(movie_filename, filename, _MAX_PATH);
   2.988 -	movie_filename[_MAX_PATH - 1] = '\0';
   2.989 +  // SDL FIXME: convert to fullpath
   2.990 +  strncpy(movie_filename, filename, _MAX_PATH);
   2.991 +  movie_filename[_MAX_PATH - 1] = '\0';
   2.992  #endif
   2.993  
   2.994 -	if (movie_filename[0] == '\0')
   2.995 -	{ loadingMovie = false; return MOVIE_FILE_NOT_FOUND; }
   2.996 +  if (movie_filename[0] == '\0')
   2.997 +    { loadingMovie = false; return MOVIE_FILE_NOT_FOUND; }
   2.998  
   2.999 -	if (!emulating)
  2.1000 -	{ loadingMovie = false; return MOVIE_UNKNOWN_ERROR; }
  2.1001 +  if (!emulating)
  2.1002 +    { loadingMovie = false; return MOVIE_UNKNOWN_ERROR; }
  2.1003  
  2.1004 -//	bool alreadyOpen = (Movie.file != NULL && _stricmp(movie_filename, Movie.filename) == 0);
  2.1005 +  //	bool alreadyOpen = (Movie.file != NULL && _stricmp(movie_filename, Movie.filename) == 0);
  2.1006  
  2.1007 -//	if (alreadyOpen)
  2.1008 -	change_state(MOVIE_STATE_NONE);     // have to stop current movie before trying to re-open it
  2.1009 +  //	if (alreadyOpen)
  2.1010 +  change_state(MOVIE_STATE_NONE);     // have to stop current movie before trying to re-open it
  2.1011  
  2.1012 -	if (!(file = fopen(movie_filename, "rb+")))
  2.1013 -		if (!(file = fopen(movie_filename, "rb")))
  2.1014 -		{ loadingMovie = false; return MOVIE_FILE_NOT_FOUND; }
  2.1015 -	//else
  2.1016 -	//	movieReadOnly = 2; // we have to open the movie twice, no need to do this both times
  2.1017 +  if (!(file = fopen(movie_filename, "rb+")))
  2.1018 +    if (!(file = fopen(movie_filename, "rb")))
  2.1019 +      { loadingMovie = false; return MOVIE_FILE_NOT_FOUND; }
  2.1020 +  //else
  2.1021 +  //	movieReadOnly = 2; // we have to open the movie twice, no need to do this both times
  2.1022  
  2.1023 -//	if (!alreadyOpen)
  2.1024 -//		change_state(MOVIE_STATE_NONE); // stop current movie when we're able to open the other one
  2.1025 -//
  2.1026 -//	if (!(file = fopen(movie_filename, "rb+")))
  2.1027 -//		if(!(file = fopen(movie_filename, "rb")))
  2.1028 -//			{loadingMovie = false; return MOVIE_FILE_NOT_FOUND;}
  2.1029 -//		else
  2.1030 -//			movieReadOnly = 2;
  2.1031 +  //	if (!alreadyOpen)
  2.1032 +  //		change_state(MOVIE_STATE_NONE); // stop current movie when we're able to open the other one
  2.1033 +  //
  2.1034 +  //	if (!(file = fopen(movie_filename, "rb+")))
  2.1035 +  //		if(!(file = fopen(movie_filename, "rb")))
  2.1036 +  //			{loadingMovie = false; return MOVIE_FILE_NOT_FOUND;}
  2.1037 +  //		else
  2.1038 +  //			movieReadOnly = 2;
  2.1039  
  2.1040 -	// clear out the current movie
  2.1041 -	VBAMovieInit();
  2.1042 +  // clear out the current movie
  2.1043 +  VBAMovieInit();
  2.1044  
  2.1045 -	// read header
  2.1046 -	if ((result = read_movie_header(file, Movie)) != MOVIE_SUCCESS)
  2.1047 -	{
  2.1048 -		fclose(file);
  2.1049 -		{ loadingMovie = false; return result; }
  2.1050 -	}
  2.1051 +  // read header
  2.1052 +  if ((result = read_movie_header(file, Movie)) != MOVIE_SUCCESS)
  2.1053 +    {
  2.1054 +      fclose(file);
  2.1055 +      { loadingMovie = false; return result; }
  2.1056 +    }
  2.1057  
  2.1058 -	// set emulator settings that make the movie more likely to stay synchronized
  2.1059 -	SetPlayEmuSettings();
  2.1060 +  // set emulator settings that make the movie more likely to stay synchronized
  2.1061 +  SetPlayEmuSettings();
  2.1062  
  2.1063 -//	extern bool systemLoadBIOS();
  2.1064 -//	if (!systemLoadBIOS())
  2.1065 -//	{ loadingMovie = false; return MOVIE_UNKNOWN_ERROR; }
  2.1066 +  //	extern bool systemLoadBIOS();
  2.1067 +  //	if (!systemLoadBIOS())
  2.1068 +  //	{ loadingMovie = false; return MOVIE_UNKNOWN_ERROR; }
  2.1069  
  2.1070 -	// read the metadata / author info from file
  2.1071 -	fread(Movie.authorInfo, 1, MOVIE_METADATA_SIZE, file);
  2.1072 -	fn = dup(fileno(file)); // XXX: why does this fail?? it returns -1 but errno == 0
  2.1073 -	fclose(file);
  2.1074 +  // read the metadata / author info from file
  2.1075 +  fread(Movie.authorInfo, 1, MOVIE_METADATA_SIZE, file);
  2.1076 +  fn = dup(fileno(file)); // XXX: why does this fail?? it returns -1 but errno == 0
  2.1077 +  fclose(file);
  2.1078  
  2.1079 -	// apparently this lseek is necessary
  2.1080 -	lseek(fn, Movie.header.offset_to_savestate, SEEK_SET);
  2.1081 -	if (!(stream = utilGzReopen(fn, "rb")))
  2.1082 -		if (!(stream = utilGzOpen(movie_filename, "rb")))
  2.1083 -		{ loadingMovie = false; return MOVIE_FILE_NOT_FOUND; }
  2.1084 -		else
  2.1085 -			fn = dup(fileno(file));
  2.1086 -	// in case the above dup failed but opening the file normally doesn't fail
  2.1087 +  // apparently this lseek is necessary
  2.1088 +  lseek(fn, Movie.header.offset_to_savestate, SEEK_SET);
  2.1089 +  if (!(stream = utilGzReopen(fn, "rb")))
  2.1090 +    if (!(stream = utilGzOpen(movie_filename, "rb")))
  2.1091 +      { loadingMovie = false; return MOVIE_FILE_NOT_FOUND; }
  2.1092 +    else
  2.1093 +      fn = dup(fileno(file));
  2.1094 +  // in case the above dup failed but opening the file normally doesn't fail
  2.1095  
  2.1096 -	if (Movie.header.startFlags & MOVIE_START_FROM_SNAPSHOT)
  2.1097 -	{
  2.1098 -		// load the snapshot
  2.1099 -		result = theEmulator.emuReadStateFromStream(stream) ? MOVIE_SUCCESS : MOVIE_WRONG_FORMAT;
  2.1100 +  if (Movie.header.startFlags & MOVIE_START_FROM_SNAPSHOT)
  2.1101 +    {
  2.1102 +      // load the snapshot
  2.1103 +      result = theEmulator.emuReadStateFromStream(stream) ? MOVIE_SUCCESS : MOVIE_WRONG_FORMAT;
  2.1104  
  2.1105 -		// FIXME: Kludge for conversion
  2.1106 -		remember_input_state();
  2.1107 -	}
  2.1108 -	else if (Movie.header.startFlags & MOVIE_START_FROM_SRAM)
  2.1109 -	{
  2.1110 -		// 'soft' reset:
  2.1111 -		theEmulator.emuReset(false);
  2.1112 +      // FIXME: Kludge for conversion
  2.1113 +      remember_input_state();
  2.1114 +    }
  2.1115 +  else if (Movie.header.startFlags & MOVIE_START_FROM_SRAM)
  2.1116 +    {
  2.1117 +      // 'soft' reset:
  2.1118 +      theEmulator.emuReset(false);
  2.1119  
  2.1120 -		// load the SRAM
  2.1121 -		result = theEmulator.emuReadBatteryFromStream(stream) ? MOVIE_SUCCESS : MOVIE_WRONG_FORMAT;
  2.1122 -	}
  2.1123 -	else
  2.1124 -	{
  2.1125 -		HardResetAndSRAMClear();
  2.1126 -	}
  2.1127 +      // load the SRAM
  2.1128 +      result = theEmulator.emuReadBatteryFromStream(stream) ? MOVIE_SUCCESS : MOVIE_WRONG_FORMAT;
  2.1129 +    }
  2.1130 +  else
  2.1131 +    {
  2.1132 +      HardResetAndSRAMClear();
  2.1133 +    }
  2.1134  
  2.1135 -	utilGzClose(stream);
  2.1136 +  utilGzClose(stream);
  2.1137  
  2.1138 -	if (result != MOVIE_SUCCESS)
  2.1139 -	{ loadingMovie = false; return result; }
  2.1140 +  if (result != MOVIE_SUCCESS)
  2.1141 +    { loadingMovie = false; return result; }
  2.1142  
  2.1143 -//	if (!(file = fopen(movie_filename, /*read_only ? "rb" :*/ "rb+"))) // want to be able to switch out of read-only later
  2.1144 -//	{
  2.1145 -//		if(!Movie.readOnly || !(file = fopen(movie_filename, "rb"))) // try read-only if failed
  2.1146 -//			return MOVIE_FILE_NOT_FOUND;
  2.1147 -//	}
  2.1148 -	if (!(file = fopen(movie_filename, "rb+")))
  2.1149 -		if (!(file = fopen(movie_filename, "rb")))
  2.1150 -		{ loadingMovie = false; return MOVIE_FILE_NOT_FOUND; }
  2.1151 -		else
  2.1152 -			movieReadOnly = 2;
  2.1153 +  //	if (!(file = fopen(movie_filename, /*read_only ? "rb" :*/ "rb+"))) // want to be able to switch out of read-only later
  2.1154 +  //	{
  2.1155 +  //		if(!Movie.readOnly || !(file = fopen(movie_filename, "rb"))) // try read-only if failed
  2.1156 +  //			return MOVIE_FILE_NOT_FOUND;
  2.1157 +  //	}
  2.1158 +  if (!(file = fopen(movie_filename, "rb+")))
  2.1159 +    if (!(file = fopen(movie_filename, "rb")))
  2.1160 +      { loadingMovie = false; return MOVIE_FILE_NOT_FOUND; }
  2.1161 +    else
  2.1162 +      movieReadOnly = 2;
  2.1163  
  2.1164 -	// recalculate length of movie from the file size
  2.1165 -	Movie.bytesPerFrame = bytes_per_frame(Movie);
  2.1166 -	fseek(file, 0, SEEK_END);
  2.1167 -	long fileSize = ftell(file);
  2.1168 -	Movie.header.length_frames = (fileSize - Movie.header.offset_to_controller_data) / Movie.bytesPerFrame;
  2.1169 +  // recalculate length of movie from the file size
  2.1170 +  Movie.bytesPerFrame = bytes_per_frame(Movie);
  2.1171 +  fseek(file, 0, SEEK_END);
  2.1172 +  long fileSize = ftell(file);
  2.1173 +  Movie.header.length_frames = (fileSize - Movie.header.offset_to_controller_data) / Movie.bytesPerFrame;
  2.1174  
  2.1175 -	if (fseek(file, Movie.header.offset_to_controller_data, SEEK_SET))
  2.1176 -	{ fclose(file); loadingMovie = false; return MOVIE_WRONG_FORMAT; }
  2.1177 +  if (fseek(file, Movie.header.offset_to_controller_data, SEEK_SET))
  2.1178 +    { fclose(file); loadingMovie = false; return MOVIE_WRONG_FORMAT; }
  2.1179  
  2.1180 -	strcpy(Movie.filename, movie_filename);
  2.1181 -	Movie.file = file;
  2.1182 -	Movie.inputBufferPtr	  = Movie.inputBuffer;
  2.1183 -	Movie.currentFrame		  = 0;
  2.1184 -	Movie.readOnly			  = movieReadOnly;
  2.1185 -	Movie.RecordedThisSession = false;
  2.1186 +  strcpy(Movie.filename, movie_filename);
  2.1187 +  Movie.file = file;
  2.1188 +  Movie.inputBufferPtr	  = Movie.inputBuffer;
  2.1189 +  Movie.currentFrame		  = 0;
  2.1190 +  Movie.readOnly			  = movieReadOnly;
  2.1191 +  Movie.RecordedThisSession = false;
  2.1192  
  2.1193 -	// read controller data
  2.1194 -	uint32 to_read = Movie.bytesPerFrame * Movie.header.length_frames;
  2.1195 -	reserve_buffer_space(to_read);
  2.1196 -	fread(Movie.inputBuffer, 1, to_read, file);
  2.1197 +  // read controller data
  2.1198 +  uint32 to_read = Movie.bytesPerFrame * Movie.header.length_frames;
  2.1199 +  reserve_buffer_space(to_read);
  2.1200 +  fread(Movie.inputBuffer, 1, to_read, file);
  2.1201  
  2.1202 -	change_state(MOVIE_STATE_PLAY);
  2.1203 +  change_state(MOVIE_STATE_PLAY);
  2.1204  
  2.1205 -	char messageString[64] = "Movie ";
  2.1206 -	bool converted		   = false;
  2.1207 -	if (autoConvertMovieWhenPlaying)
  2.1208 -	{
  2.1209 -		int result = VBAMovieConvertCurrent();
  2.1210 -		if (result == MOVIE_SUCCESS)
  2.1211 -			strcat(messageString, "converted and ");
  2.1212 -		else if (result == MOVIE_WRONG_VERSION)
  2.1213 -			strcat(messageString, "higher revision ");
  2.1214 -	}
  2.1215 +  char messageString[64] = "Movie ";
  2.1216 +  bool converted		   = false;
  2.1217 +  if (autoConvertMovieWhenPlaying)
  2.1218 +    {
  2.1219 +      int result = VBAMovieConvertCurrent();
  2.1220 +      if (result == MOVIE_SUCCESS)
  2.1221 +	strcat(messageString, "converted and ");
  2.1222 +      else if (result == MOVIE_WRONG_VERSION)
  2.1223 +	strcat(messageString, "higher revision ");
  2.1224 +    }
  2.1225  
  2.1226 -	if (Movie.state == MOVIE_STATE_PLAY)
  2.1227 -		strcat(messageString, "replaying ");
  2.1228 -	else
  2.1229 -		strcat(messageString, "finished ");
  2.1230 -	if (Movie.readOnly)
  2.1231 -		strcat(messageString, "(read)");
  2.1232 -	else
  2.1233 -		strcat(messageString, "(edit)");
  2.1234 -	systemScreenMessage(messageString);
  2.1235 +  if (Movie.state == MOVIE_STATE_PLAY)
  2.1236 +    strcat(messageString, "replaying ");
  2.1237 +  else
  2.1238 +    strcat(messageString, "finished ");
  2.1239 +  if (Movie.readOnly)
  2.1240 +    strcat(messageString, "(read)");
  2.1241 +  else
  2.1242 +    strcat(messageString, "(edit)");
  2.1243 +  systemScreenMessage(messageString);
  2.1244  
  2.1245 -	VBAUpdateButtonPressDisplay();
  2.1246 -	VBAUpdateFrameCountDisplay();
  2.1247 -	systemRefreshScreen();
  2.1248 +  VBAUpdateButtonPressDisplay();
  2.1249 +  VBAUpdateFrameCountDisplay();
  2.1250 +  systemRefreshScreen();
  2.1251  
  2.1252 -	{ loadingMovie = false; return MOVIE_SUCCESS; }
  2.1253 +  { loadingMovie = false; return MOVIE_SUCCESS; }
  2.1254  }
  2.1255  
  2.1256  static void SetRecordEmuSettings()
  2.1257  {
  2.1258 -	Movie.header.optionFlags = 0;
  2.1259 +  Movie.header.optionFlags = 0;
  2.1260  #if (defined(WIN32) && !defined(SDL))
  2.1261 -	if (theApp.useBiosFile)
  2.1262 -		Movie.header.optionFlags |= MOVIE_SETTING_USEBIOSFILE;
  2.1263 -	if (theApp.skipBiosFile)
  2.1264 -		Movie.header.optionFlags |= MOVIE_SETTING_SKIPBIOSFILE;
  2.1265 -	if (rtcIsEnabled())
  2.1266 -		Movie.header.optionFlags |= MOVIE_SETTING_RTCENABLE;
  2.1267 -	Movie.header.saveType  = theApp.winSaveType;
  2.1268 -	Movie.header.flashSize = theApp.winFlashSize;
  2.1269 +  if (theApp.useBiosFile)
  2.1270 +    Movie.header.optionFlags |= MOVIE_SETTING_USEBIOSFILE;
  2.1271 +  if (theApp.skipBiosFile)
  2.1272 +    Movie.header.optionFlags |= MOVIE_SETTING_SKIPBIOSFILE;
  2.1273 +  if (rtcIsEnabled())
  2.1274 +    Movie.header.optionFlags |= MOVIE_SETTING_RTCENABLE;
  2.1275 +  Movie.header.saveType  = theApp.winSaveType;
  2.1276 +  Movie.header.flashSize = theApp.winFlashSize;
  2.1277  #else
  2.1278 -	extern int	 saveType, sdlRtcEnable, sdlFlashSize;   // from SDL.cpp
  2.1279 -	extern bool8 useBios, skipBios;     // from SDL.cpp
  2.1280 -	if (useBios)
  2.1281 -		Movie.header.optionFlags |= MOVIE_SETTING_USEBIOSFILE;
  2.1282 -	if (skipBios)
  2.1283 -		Movie.header.optionFlags |= MOVIE_SETTING_SKIPBIOSFILE;
  2.1284 -	if (sdlRtcEnable)
  2.1285 -		Movie.header.optionFlags |= MOVIE_SETTING_RTCENABLE;
  2.1286 -	Movie.header.saveType  = saveType;
  2.1287 -	Movie.header.flashSize = sdlFlashSize;
  2.1288 +  extern int	 saveType, sdlRtcEnable, sdlFlashSize;   // from SDL.cpp
  2.1289 +  extern bool8 useBios, skipBios;     // from SDL.cpp
  2.1290 +  if (useBios)
  2.1291 +    Movie.header.optionFlags |= MOVIE_SETTING_USEBIOSFILE;
  2.1292 +  if (skipBios)
  2.1293 +    Movie.header.optionFlags |= MOVIE_SETTING_SKIPBIOSFILE;
  2.1294 +  if (sdlRtcEnable)
  2.1295 +    Movie.header.optionFlags |= MOVIE_SETTING_RTCENABLE;
  2.1296 +  Movie.header.saveType  = saveType;
  2.1297 +  Movie.header.flashSize = sdlFlashSize;
  2.1298  #endif
  2.1299 -	prevEmulatorType = Movie.header.gbEmulatorType = gbEmulatorType;
  2.1300 +  prevEmulatorType = Movie.header.gbEmulatorType = gbEmulatorType;
  2.1301  
  2.1302 -	if (!memLagTempEnabled)
  2.1303 -		Movie.header.optionFlags |= MOVIE_SETTING_LAGHACK;
  2.1304 +  if (!memLagTempEnabled)
  2.1305 +    Movie.header.optionFlags |= MOVIE_SETTING_LAGHACK;
  2.1306  
  2.1307 -	if (gbNullInputHackTempEnabled)
  2.1308 -		Movie.header.optionFlags |= MOVIE_SETTING_GBINPUTHACK;
  2.1309 +  if (gbNullInputHackTempEnabled)
  2.1310 +    Movie.header.optionFlags |= MOVIE_SETTING_GBINPUTHACK;
  2.1311  
  2.1312 -	Movie.header.optionFlags |= MOVIE_SETTING_GBCFF55FIX;
  2.1313 -	extern int32 gbDMASpeedVersion;
  2.1314 -	gbDMASpeedVersion = 1;
  2.1315 +  Movie.header.optionFlags |= MOVIE_SETTING_GBCFF55FIX;
  2.1316 +  extern int32 gbDMASpeedVersion;
  2.1317 +  gbDMASpeedVersion = 1;
  2.1318  
  2.1319 -	Movie.header.optionFlags |= MOVIE_SETTING_GBECHORAMFIX;
  2.1320 -	extern int32 gbEchoRAMFixOn;
  2.1321 -	gbEchoRAMFixOn = 1;
  2.1322 +  Movie.header.optionFlags |= MOVIE_SETTING_GBECHORAMFIX;
  2.1323 +  extern int32 gbEchoRAMFixOn;
  2.1324 +  gbEchoRAMFixOn = 1;
  2.1325  
  2.1326 -	// some GB/GBC games depend on the sound rate, so just use the highest one
  2.1327 -	systemSoundSetQuality(1);
  2.1328 +  // some GB/GBC games depend on the sound rate, so just use the highest one
  2.1329 +  systemSoundSetQuality(1);
  2.1330  
  2.1331 -	useOldFrameTiming = false;
  2.1332 +  useOldFrameTiming = false;
  2.1333  
  2.1334  #if (defined(WIN32) && !defined(SDL))
  2.1335 -//    theApp.removeIntros   = false;
  2.1336 +  //    theApp.removeIntros   = false;
  2.1337  
  2.1338 -	prevBorder	   = gbBorderOn;
  2.1339 -	prevWinBorder  = theApp.winGbBorderOn;
  2.1340 -	prevBorderAuto = gbBorderAutomatic;
  2.1341 -	if (gbEmulatorType == 2 || gbEmulatorType == 5)     // only games played in SGB mode will have a border
  2.1342 -	{
  2.1343 -		gbBorderOn = true;
  2.1344 -		theApp.winGbBorderOn = true;
  2.1345 -		gbBorderAutomatic	 = false;
  2.1346 -	}
  2.1347 -	else
  2.1348 -	{
  2.1349 -		gbBorderOn = false;
  2.1350 -		theApp.winGbBorderOn = false;
  2.1351 -		gbBorderAutomatic	 = false;
  2.1352 -	}
  2.1353 -	systemGbBorderOn();
  2.1354 +  prevBorder	   = gbBorderOn;
  2.1355 +  prevWinBorder  = theApp.winGbBorderOn;
  2.1356 +  prevBorderAuto = gbBorderAutomatic;
  2.1357 +  if (gbEmulatorType == 2 || gbEmulatorType == 5)     // only games played in SGB mode will have a border
  2.1358 +    {
  2.1359 +      gbBorderOn = true;
  2.1360 +      theApp.winGbBorderOn = true;
  2.1361 +      gbBorderAutomatic	 = false;
  2.1362 +    }
  2.1363 +  else
  2.1364 +    {
  2.1365 +      gbBorderOn = false;
  2.1366 +      theApp.winGbBorderOn = false;
  2.1367 +      gbBorderAutomatic	 = false;
  2.1368 +    }
  2.1369 +  systemGbBorderOn();
  2.1370  #else
  2.1371 -	/// SDLFIXME
  2.1372 +  /// SDLFIXME
  2.1373  #endif
  2.1374  }
  2.1375  
  2.1376  uint16 VBAMovieGetCurrentInputOf(int controllerNum, bool normalOnly)
  2.1377  {
  2.1378 -	if (controllerNum < 0 || controllerNum >= MOVIE_NUM_OF_POSSIBLE_CONTROLLERS)
  2.1379 -		return 0;
  2.1380 +  if (controllerNum < 0 || controllerNum >= MOVIE_NUM_OF_POSSIBLE_CONTROLLERS)
  2.1381 +    return 0;
  2.1382  
  2.1383 -	return normalOnly ? (currentButtons[controllerNum] & BUTTON_REGULAR_MASK) : currentButtons[controllerNum];
  2.1384 +  return normalOnly ? (currentButtons[controllerNum] & BUTTON_REGULAR_MASK) : currentButtons[controllerNum];
  2.1385  }
  2.1386  
  2.1387  int VBAMovieCreate(const char *filename, const char *authorInfo, uint8 startFlags, uint8 controllerFlags, uint8 typeFlags)
  2.1388  {
  2.1389 -	// make sure at least one controller is enabled
  2.1390 -	if ((controllerFlags & MOVIE_CONTROLLERS_ANY_MASK) == 0)
  2.1391 -		return MOVIE_WRONG_FORMAT;
  2.1392 +  // make sure at least one controller is enabled
  2.1393 +  if ((controllerFlags & MOVIE_CONTROLLERS_ANY_MASK) == 0)
  2.1394 +    return MOVIE_WRONG_FORMAT;
  2.1395  
  2.1396 -	if (!emulating)
  2.1397 -		return MOVIE_UNKNOWN_ERROR;
  2.1398 +  if (!emulating)
  2.1399 +    return MOVIE_UNKNOWN_ERROR;
  2.1400  
  2.1401 -	loadingMovie = true;
  2.1402 +  loadingMovie = true;
  2.1403  
  2.1404 -	FILE * file;
  2.1405 -	STREAM stream;
  2.1406 -	int	   fn;
  2.1407 +  FILE * file;
  2.1408 +  STREAM stream;
  2.1409 +  int	   fn;
  2.1410  
  2.1411 -	char movie_filename [_MAX_PATH];
  2.1412 +  char movie_filename [_MAX_PATH];
  2.1413  #ifdef WIN32
  2.1414 -	_fullpath(movie_filename, filename, _MAX_PATH);
  2.1415 +  _fullpath(movie_filename, filename, _MAX_PATH);
  2.1416  #else
  2.1417 -	// FIXME: convert to fullpath
  2.1418 -	strncpy(movie_filename, filename, _MAX_PATH);
  2.1419 -	movie_filename[_MAX_PATH - 1] = '\0';
  2.1420 +  // FIXME: convert to fullpath
  2.1421 +  strncpy(movie_filename, filename, _MAX_PATH);
  2.1422 +  movie_filename[_MAX_PATH - 1] = '\0';
  2.1423  #endif
  2.1424  
  2.1425 -	bool alreadyOpen = (Movie.file != NULL && stricmp(movie_filename, Movie.filename) == 0);
  2.1426 +  bool alreadyOpen = (Movie.file != NULL && stricmp(movie_filename, Movie.filename) == 0);
  2.1427  
  2.1428 -	if (alreadyOpen)
  2.1429 -		change_state(MOVIE_STATE_NONE);  // have to stop current movie before trying to re-open it
  2.1430 +  if (alreadyOpen)
  2.1431 +    change_state(MOVIE_STATE_NONE);  // have to stop current movie before trying to re-open it
  2.1432  
  2.1433 -	if (movie_filename[0] == '\0')
  2.1434 +  if (movie_filename[0] == '\0')
  2.1435 +    { loadingMovie = false; return MOVIE_FILE_NOT_FOUND; }
  2.1436 +
  2.1437 +  if (!(file = fopen(movie_filename, "wb")))
  2.1438 +    { loadingMovie = false; return MOVIE_FILE_NOT_FOUND; }
  2.1439 +
  2.1440 +  if (!alreadyOpen)
  2.1441 +    change_state(MOVIE_STATE_NONE);  // stop current movie when we're able to open the other one
  2.1442 +
  2.1443 +  // clear out the current movie
  2.1444 +  printf("RLM: movie init\n");
  2.1445 +
  2.1446 +  VBAMovieInit();
  2.1447 +
  2.1448 +  // fill in the movie's header
  2.1449 +  Movie.header.uid   = (uint32)time(NULL);
  2.1450 +  Movie.header.magic = VBM_MAGIC;
  2.1451 +  Movie.header.version		 = VBM_VERSION;
  2.1452 +  Movie.header.rerecord_count	 = 0;
  2.1453 +  Movie.header.length_frames	 = 0;
  2.1454 +  Movie.header.startFlags		 = startFlags;
  2.1455 +  Movie.header.controllerFlags = controllerFlags;
  2.1456 +  Movie.header.typeFlags		 = typeFlags;
  2.1457 +  Movie.header.minorVersion	 = VBM_REVISION;
  2.1458 +
  2.1459 +  // set emulator settings that make the movie more likely to stay synchronized when it's later played back
  2.1460 +  SetRecordEmuSettings();
  2.1461 +
  2.1462 +  // set ROM and BIOS checksums and stuff
  2.1463 +  VBAMovieGetRomInfo(Movie, Movie.header.romTitle, Movie.header.romGameCode, Movie.header.romOrBiosChecksum, Movie.header.romCRC);
  2.1464 +	
  2.1465 +  printf("RLM: Writing movie header\n");
  2.1466 +  // write the header to file
  2.1467 +  write_movie_header(file, Movie);
  2.1468 +
  2.1469 +  printf("RLM: setting metadata\n");
  2.1470 +
  2.1471 +  // copy over the metadata / author info
  2.1472 +  VBAMovieSetMetadata("________________Robert  McIntyre______________________________________________________________________________________________________________________________________________________________________________________________________________________");
  2.1473 +	
  2.1474 +  printf("RLM: writing metadata\n");
  2.1475 +
  2.1476 +  // write the metadata / author info to file
  2.1477 +
  2.1478 +
  2.1479 +  fwrite(Movie.authorInfo, 1, sizeof(char) * MOVIE_METADATA_SIZE, file);
  2.1480 +
  2.1481 +  // write snapshot or SRAM if applicable
  2.1482 +  if (Movie.header.startFlags & MOVIE_START_FROM_SNAPSHOT
  2.1483 +      || Movie.header.startFlags & MOVIE_START_FROM_SRAM)
  2.1484 +    {
  2.1485 +      Movie.header.offset_to_savestate = (uint32)ftell(file);
  2.1486 +
  2.1487 +      // close the file and reopen it as a stream:
  2.1488 +
  2.1489 +      fn = dup(fileno(file));
  2.1490 +      fclose(file);
  2.1491 +
  2.1492 +      if (!(stream = utilGzReopen(fn, "ab"))) // append mode to start at end, no seek necessary
  2.1493  	{ loadingMovie = false; return MOVIE_FILE_NOT_FOUND; }
  2.1494  
  2.1495 -	if (!(file = fopen(movie_filename, "wb")))
  2.1496 +      // write the save data:
  2.1497 +      if (Movie.header.startFlags & MOVIE_START_FROM_SNAPSHOT)
  2.1498 +	{
  2.1499 +	  // save snapshot
  2.1500 +	  if (!theEmulator.emuWriteStateToStream(stream))
  2.1501 +	    {
  2.1502 +	      utilGzClose(stream);
  2.1503 +	      { loadingMovie = false; return MOVIE_UNKNOWN_ERROR; }
  2.1504 +	    }
  2.1505 +	}
  2.1506 +      else if (Movie.header.startFlags & MOVIE_START_FROM_SRAM)
  2.1507 +	{
  2.1508 +	  // save SRAM
  2.1509 +	  if (!theEmulator.emuWriteBatteryToStream(stream))
  2.1510 +	    {
  2.1511 +	      utilGzClose(stream);
  2.1512 +	      { loadingMovie = false; return MOVIE_UNKNOWN_ERROR; }
  2.1513 +	    }
  2.1514 +
  2.1515 +	  // 'soft' reset:
  2.1516 +	  theEmulator.emuReset(false);
  2.1517 +	}
  2.1518 +
  2.1519 +      utilGzClose(stream);
  2.1520 +
  2.1521 +      // reopen the file and seek back to the end
  2.1522 +
  2.1523 +      if (!(file = fopen(movie_filename, "rb+")))
  2.1524  	{ loadingMovie = false; return MOVIE_FILE_NOT_FOUND; }
  2.1525  
  2.1526 -	if (!alreadyOpen)
  2.1527 -		change_state(MOVIE_STATE_NONE);  // stop current movie when we're able to open the other one
  2.1528 +      fseek(file, 0, SEEK_END);
  2.1529 +    }
  2.1530 +  else // no snapshot or SRAM
  2.1531 +    {
  2.1532 +      HardResetAndSRAMClear();
  2.1533 +    }
  2.1534  
  2.1535 -	// clear out the current movie
  2.1536 -	VBAMovieInit();
  2.1537 +  Movie.header.offset_to_controller_data = (uint32)ftell(file);
  2.1538  
  2.1539 -	// fill in the movie's header
  2.1540 -	Movie.header.uid   = (uint32)time(NULL);
  2.1541 -	Movie.header.magic = VBM_MAGIC;
  2.1542 -	Movie.header.version		 = VBM_VERSION;
  2.1543 -	Movie.header.rerecord_count	 = 0;
  2.1544 -	Movie.header.length_frames	 = 0;
  2.1545 -	Movie.header.startFlags		 = startFlags;
  2.1546 -	Movie.header.controllerFlags = controllerFlags;
  2.1547 -	Movie.header.typeFlags		 = typeFlags;
  2.1548 -	Movie.header.minorVersion	 = VBM_REVISION;
  2.1549 +  strcpy(Movie.filename, movie_filename);
  2.1550 +  Movie.file = file;
  2.1551 +  Movie.bytesPerFrame		  = bytes_per_frame(Movie);
  2.1552 +  Movie.inputBufferPtr	  = Movie.inputBuffer;
  2.1553 +  Movie.currentFrame		  = 0;
  2.1554 +  Movie.readOnly			  = false;
  2.1555 +  Movie.RecordedThisSession = true;
  2.1556  
  2.1557 -	// set emulator settings that make the movie more likely to stay synchronized when it's later played back
  2.1558 -	SetRecordEmuSettings();
  2.1559 +  change_state(MOVIE_STATE_RECORD);
  2.1560  
  2.1561 -	// set ROM and BIOS checksums and stuff
  2.1562 -	VBAMovieGetRomInfo(Movie, Movie.header.romTitle, Movie.header.romGameCode, Movie.header.romOrBiosChecksum, Movie.header.romCRC);
  2.1563 -
  2.1564 -	// write the header to file
  2.1565 -	write_movie_header(file, Movie);
  2.1566 -
  2.1567 -	// copy over the metadata / author info
  2.1568 -	VBAMovieSetMetadata(authorInfo);
  2.1569 -
  2.1570 -	// write the metadata / author info to file
  2.1571 -	fwrite(Movie.authorInfo, 1, sizeof(char) * MOVIE_METADATA_SIZE, file);
  2.1572 -
  2.1573 -	// write snapshot or SRAM if applicable
  2.1574 -	if (Movie.header.startFlags & MOVIE_START_FROM_SNAPSHOT
  2.1575 -	    || Movie.header.startFlags & MOVIE_START_FROM_SRAM)
  2.1576 -	{
  2.1577 -		Movie.header.offset_to_savestate = (uint32)ftell(file);
  2.1578 -
  2.1579 -		// close the file and reopen it as a stream:
  2.1580 -
  2.1581 -		fn = dup(fileno(file));
  2.1582 -		fclose(file);
  2.1583 -
  2.1584 -		if (!(stream = utilGzReopen(fn, "ab"))) // append mode to start at end, no seek necessary
  2.1585 -		{ loadingMovie = false; return MOVIE_FILE_NOT_FOUND; }
  2.1586 -
  2.1587 -		// write the save data:
  2.1588 -		if (Movie.header.startFlags & MOVIE_START_FROM_SNAPSHOT)
  2.1589 -		{
  2.1590 -			// save snapshot
  2.1591 -			if (!theEmulator.emuWriteStateToStream(stream))
  2.1592 -			{
  2.1593 -				utilGzClose(stream);
  2.1594 -				{ loadingMovie = false; return MOVIE_UNKNOWN_ERROR; }
  2.1595 -			}
  2.1596 -		}
  2.1597 -		else if (Movie.header.startFlags & MOVIE_START_FROM_SRAM)
  2.1598 -		{
  2.1599 -			// save SRAM
  2.1600 -			if (!theEmulator.emuWriteBatteryToStream(stream))
  2.1601 -			{
  2.1602 -				utilGzClose(stream);
  2.1603 -				{ loadingMovie = false; return MOVIE_UNKNOWN_ERROR; }
  2.1604 -			}
  2.1605 -
  2.1606 -			// 'soft' reset:
  2.1607 -			theEmulator.emuReset(false);
  2.1608 -		}
  2.1609 -
  2.1610 -		utilGzClose(stream);
  2.1611 -
  2.1612 -		// reopen the file and seek back to the end
  2.1613 -
  2.1614 -		if (!(file = fopen(movie_filename, "rb+")))
  2.1615 -		{ loadingMovie = false; return MOVIE_FILE_NOT_FOUND; }
  2.1616 -
  2.1617 -		fseek(file, 0, SEEK_END);
  2.1618 -	}
  2.1619 -	else // no snapshot or SRAM
  2.1620 -	{
  2.1621 -		HardResetAndSRAMClear();
  2.1622 -	}
  2.1623 -
  2.1624 -	Movie.header.offset_to_controller_data = (uint32)ftell(file);
  2.1625 -
  2.1626 -	strcpy(Movie.filename, movie_filename);
  2.1627 -	Movie.file = file;
  2.1628 -	Movie.bytesPerFrame		  = bytes_per_frame(Movie);
  2.1629 -	Movie.inputBufferPtr	  = Movie.inputBuffer;
  2.1630 -	Movie.currentFrame		  = 0;
  2.1631 -	Movie.readOnly			  = false;
  2.1632 -	Movie.RecordedThisSession = true;
  2.1633 -
  2.1634 -	change_state(MOVIE_STATE_RECORD);
  2.1635 -
  2.1636 -	systemScreenMessage("Recording movie...");
  2.1637 -	{ loadingMovie = false; return MOVIE_SUCCESS; }
  2.1638 +  systemScreenMessage("Recording movie...");
  2.1639 +  { loadingMovie = false; return MOVIE_SUCCESS; }
  2.1640  }
  2.1641  
  2.1642  void VBAUpdateButtonPressDisplay()
  2.1643  {
  2.1644 -	uint32 keys = currentButtons[0] & BUTTON_REGULAR_RECORDING_MASK;
  2.1645 +  uint32 keys = currentButtons[0] & BUTTON_REGULAR_RECORDING_MASK;
  2.1646  
  2.1647 -	const static char KeyMap[]	 =  { 'A', 'B', 's', 'S', '>', '<', '^', 'v', 'R', 'L', '!', '?', '{', '}', 'v', '^' };
  2.1648 -	const static int  KeyOrder[] = { 5, 6, 4, 7, 0, 1, 9, 8, 3, 2, 12, 15, 13, 14, 11, 10 }; // < ^ > v   A B  L R  S s  { = } _
  2.1649 -	                                                                                         // ? !
  2.1650 -	char buffer[256];
  2.1651 -	sprintf(buffer, "                    ");
  2.1652 +  const static char KeyMap[]	 =  { 'A', 'B', 's', 'S', '>', '<', '^', 'v', 'R', 'L', '!', '?', '{', '}', 'v', '^' };
  2.1653 +  const static int  KeyOrder[] = { 5, 6, 4, 7, 0, 1, 9, 8, 3, 2, 12, 15, 13, 14, 11, 10 }; // < ^ > v   A B  L R  S s  { = } _
  2.1654 +  // ? !
  2.1655 +  char buffer[256];
  2.1656 +  sprintf(buffer, "                    ");
  2.1657  
  2.1658  #ifndef WIN32
  2.1659 -	// don't bother color-coding autofire and such
  2.1660 -	int i;
  2.1661 -	for (i = 0; i < 15; i++)
  2.1662 +  // don't bother color-coding autofire and such
  2.1663 +  int i;
  2.1664 +  for (i = 0; i < 15; i++)
  2.1665 +    {
  2.1666 +      int j	 = KeyOrder[i];
  2.1667 +      int mask = (1 << (j));
  2.1668 +      buffer[strlen("    ") + i] = ((keys & mask) != 0) ? KeyMap[j] : ' ';
  2.1669 +    }
  2.1670 +
  2.1671 +  systemScreenMessage(buffer, 2, -1);
  2.1672 +#else
  2.1673 +  const bool eraseAll		= !theApp.inputDisplay;
  2.1674 +  uint32	   autoHeldKeys = eraseAll ? 0 : theApp.autoHold & BUTTON_REGULAR_RECORDING_MASK;
  2.1675 +  uint32	   autoFireKeys = eraseAll ? 0 : (theApp.autoFire | theApp.autoFire2) & BUTTON_REGULAR_RECORDING_MASK;
  2.1676 +  uint32	   pressedKeys	= eraseAll ? 0 : keys;
  2.1677 +
  2.1678 +  char colorList[64];
  2.1679 +  memset(colorList, 1, strlen(buffer));
  2.1680 +
  2.1681 +  if (!eraseAll)
  2.1682 +    {
  2.1683 +      for (int i = 0; i < 15; i++)
  2.1684  	{
  2.1685 -		int j	 = KeyOrder[i];
  2.1686 -		int mask = (1 << (j));
  2.1687 -		buffer[strlen("    ") + i] = ((keys & mask) != 0) ? KeyMap[j] : ' ';
  2.1688 +	  const int  j		 = KeyOrder[i];
  2.1689 +	  const int  mask		 = (1 << (j));
  2.1690 +	  bool	   pressed	 = (pressedKeys  & mask) != 0;
  2.1691 +	  const bool autoHeld	 = (autoHeldKeys & mask) != 0;
  2.1692 +	  const bool autoFired = (autoFireKeys & mask) != 0;
  2.1693 +	  const bool erased	 = (lastKeys & mask) != 0 && (!pressed && !autoHeld && !autoFired);
  2.1694 +	  extern int textMethod;
  2.1695 +	  if (textMethod != 2 && (autoHeld || (autoFired && !pressed) || erased))
  2.1696 +	    {
  2.1697 +	      int colorNum = 1;     // default is white
  2.1698 +	      if (autoHeld)
  2.1699 +		colorNum += (pressed ? 2 : 1);     // yellow if pressed, red if not
  2.1700 +	      else if (autoFired)
  2.1701 +		colorNum += 5;     // blue if autofired and not currently pressed
  2.1702 +	      else if (erased)
  2.1703 +		colorNum += 8;     // black on black
  2.1704 +
  2.1705 +	      colorList[strlen("    ") + i] = colorNum;
  2.1706 +	      pressed = true;
  2.1707 +	    }
  2.1708 +	  buffer[strlen("    ") + i] = pressed ? KeyMap[j] : ' ';
  2.1709  	}
  2.1710 +    }
  2.1711  
  2.1712 -	systemScreenMessage(buffer, 2, -1);
  2.1713 -#else
  2.1714 -	const bool eraseAll		= !theApp.inputDisplay;
  2.1715 -	uint32	   autoHeldKeys = eraseAll ? 0 : theApp.autoHold & BUTTON_REGULAR_RECORDING_MASK;
  2.1716 -	uint32	   autoFireKeys = eraseAll ? 0 : (theApp.autoFire | theApp.autoFire2) & BUTTON_REGULAR_RECORDING_MASK;
  2.1717 -	uint32	   pressedKeys	= eraseAll ? 0 : keys;
  2.1718 +  lastKeys  = currentButtons[0];
  2.1719 +  lastKeys |= theApp.autoHold & BUTTON_REGULAR_RECORDING_MASK;
  2.1720 +  lastKeys |= (theApp.autoFire | theApp.autoFire2) & BUTTON_REGULAR_RECORDING_MASK;
  2.1721  
  2.1722 -	char colorList[64];
  2.1723 -	memset(colorList, 1, strlen(buffer));
  2.1724 -
  2.1725 -	if (!eraseAll)
  2.1726 -	{
  2.1727 -		for (int i = 0; i < 15; i++)
  2.1728 -		{
  2.1729 -			const int  j		 = KeyOrder[i];
  2.1730 -			const int  mask		 = (1 << (j));
  2.1731 -			bool	   pressed	 = (pressedKeys  & mask) != 0;
  2.1732 -			const bool autoHeld	 = (autoHeldKeys & mask) != 0;
  2.1733 -			const bool autoFired = (autoFireKeys & mask) != 0;
  2.1734 -			const bool erased	 = (lastKeys & mask) != 0 && (!pressed && !autoHeld && !autoFired);
  2.1735 -			extern int textMethod;
  2.1736 -			if (textMethod != 2 && (autoHeld || (autoFired && !pressed) || erased))
  2.1737 -			{
  2.1738 -				int colorNum = 1;     // default is white
  2.1739 -				if (autoHeld)
  2.1740 -					colorNum += (pressed ? 2 : 1);     // yellow if pressed, red if not
  2.1741 -				else if (autoFired)
  2.1742 -					colorNum += 5;     // blue if autofired and not currently pressed
  2.1743 -				else if (erased)
  2.1744 -					colorNum += 8;     // black on black
  2.1745 -
  2.1746 -				colorList[strlen("    ") + i] = colorNum;
  2.1747 -				pressed = true;
  2.1748 -			}
  2.1749 -			buffer[strlen("    ") + i] = pressed ? KeyMap[j] : ' ';
  2.1750 -		}
  2.1751 -	}
  2.1752 -
  2.1753 -	lastKeys  = currentButtons[0];
  2.1754 -	lastKeys |= theApp.autoHold & BUTTON_REGULAR_RECORDING_MASK;
  2.1755 -	lastKeys |= (theApp.autoFire | theApp.autoFire2) & BUTTON_REGULAR_RECORDING_MASK;
  2.1756 -
  2.1757 -	systemScreenMessage(buffer, 2, -1, colorList);
  2.1758 +  systemScreenMessage(buffer, 2, -1, colorList);
  2.1759  #endif
  2.1760  }
  2.1761  
  2.1762  void VBAUpdateFrameCountDisplay()
  2.1763  {
  2.1764 -	const int MAGICAL_NUMBER = 64;  // FIXME: this won't do any better, but only to remind you of sz issues
  2.1765 -	char	  frameDisplayString[MAGICAL_NUMBER];
  2.1766 -	char	  lagFrameDisplayString[MAGICAL_NUMBER];
  2.1767 -	char      extraCountDisplayString[MAGICAL_NUMBER];
  2.1768 +  const int MAGICAL_NUMBER = 64;  // FIXME: this won't do any better, but only to remind you of sz issues
  2.1769 +  char	  frameDisplayString[MAGICAL_NUMBER];
  2.1770 +  char	  lagFrameDisplayString[MAGICAL_NUMBER];
  2.1771 +  char      extraCountDisplayString[MAGICAL_NUMBER];
  2.1772  
  2.1773  #if (defined(WIN32) && !defined(SDL))
  2.1774 -	if (theApp.frameCounter)
  2.1775 +  if (theApp.frameCounter)
  2.1776 +#else
  2.1777 +    /// SDL FIXME
  2.1778 +#endif
  2.1779 +    {
  2.1780 +      switch (Movie.state)
  2.1781 +	{
  2.1782 +	case MOVIE_STATE_PLAY:
  2.1783 +	case MOVIE_STATE_END:
  2.1784 +	  {
  2.1785 +	    sprintf(frameDisplayString, "%d / %d", Movie.currentFrame, Movie.header.length_frames);
  2.1786 +	    if (!Movie.readOnly)
  2.1787 +	      strcat(frameDisplayString, " (edit)");
  2.1788 +	    break;
  2.1789 +	  }
  2.1790 +	case MOVIE_STATE_RECORD:
  2.1791 +	  {
  2.1792 +	    sprintf(frameDisplayString, "%d (record)", Movie.currentFrame);
  2.1793 +	    break;
  2.1794 +	  }
  2.1795 +	default:
  2.1796 +	  {
  2.1797 +	    sprintf(frameDisplayString, "%d (no movie)", systemCounters.frameCount);
  2.1798 +	    break;
  2.1799 +	  }
  2.1800 +	}
  2.1801 +
  2.1802 +#if (defined(WIN32) && !defined(SDL))
  2.1803 +      if (theApp.lagCounter)
  2.1804  #else
  2.1805  	/// SDL FIXME
  2.1806  #endif
  2.1807  	{
  2.1808 -		switch (Movie.state)
  2.1809 -		{
  2.1810 -		case MOVIE_STATE_PLAY:
  2.1811 -		case MOVIE_STATE_END:
  2.1812 -		{
  2.1813 -			sprintf(frameDisplayString, "%d / %d", Movie.currentFrame, Movie.header.length_frames);
  2.1814 -			if (!Movie.readOnly)
  2.1815 -				strcat(frameDisplayString, " (edit)");
  2.1816 -			break;
  2.1817 -		}
  2.1818 -		case MOVIE_STATE_RECORD:
  2.1819 -		{
  2.1820 -			sprintf(frameDisplayString, "%d (record)", Movie.currentFrame);
  2.1821 -			break;
  2.1822 -		}
  2.1823 -		default:
  2.1824 -		{
  2.1825 -			sprintf(frameDisplayString, "%d (no movie)", systemCounters.frameCount);
  2.1826 -			break;
  2.1827 -		}
  2.1828 -		}
  2.1829 +	  //			sprintf(lagFrameDisplayString, " %c %d", systemCounters.laggedLast ? '*' : '|', systemCounters.lagCount);
  2.1830 +	  sprintf(lagFrameDisplayString, " | %d%s", systemCounters.lagCount, systemCounters.laggedLast ? " *" : "");
  2.1831 +	  strcat(frameDisplayString, lagFrameDisplayString);
  2.1832 +	}
  2.1833  
  2.1834  #if (defined(WIN32) && !defined(SDL))
  2.1835 -		if (theApp.lagCounter)
  2.1836 -#else
  2.1837 -		/// SDL FIXME
  2.1838 -#endif
  2.1839 -		{
  2.1840 -//			sprintf(lagFrameDisplayString, " %c %d", systemCounters.laggedLast ? '*' : '|', systemCounters.lagCount);
  2.1841 -			sprintf(lagFrameDisplayString, " | %d%s", systemCounters.lagCount, systemCounters.laggedLast ? " *" : "");
  2.1842 -			strcat(frameDisplayString, lagFrameDisplayString);
  2.1843 -		}
  2.1844 -
  2.1845 -#if (defined(WIN32) && !defined(SDL))
  2.1846 -		if (theApp.extraCounter)
  2.1847 -#else
  2.1848 -		/// SDL FIXME
  2.1849 -#endif
  2.1850 -		{
  2.1851 -			sprintf(extraCountDisplayString, " | %d", systemCounters.frameCount - systemCounters.extraCount);
  2.1852 -			strcat(frameDisplayString, extraCountDisplayString);
  2.1853 -		}
  2.1854 -	}
  2.1855 -#if (defined(WIN32) && !defined(SDL))
  2.1856 -	else
  2.1857 -	{
  2.1858 -		frameDisplayString[0] = '\0';
  2.1859 -	}
  2.1860 +      if (theApp.extraCounter)
  2.1861  #else
  2.1862  	/// SDL FIXME
  2.1863  #endif
  2.1864 -	systemScreenMessage(frameDisplayString, 1, -1);
  2.1865 +	{
  2.1866 +	  sprintf(extraCountDisplayString, " | %d", systemCounters.frameCount - systemCounters.extraCount);
  2.1867 +	  strcat(frameDisplayString, extraCountDisplayString);
  2.1868 +	}
  2.1869 +    }
  2.1870 +#if (defined(WIN32) && !defined(SDL))
  2.1871 +  else
  2.1872 +    {
  2.1873 +      frameDisplayString[0] = '\0';
  2.1874 +    }
  2.1875 +#else
  2.1876 +  /// SDL FIXME
  2.1877 +#endif
  2.1878 +  systemScreenMessage(frameDisplayString, 1, -1);
  2.1879  }
  2.1880  
  2.1881  // this function should only be called once every frame
  2.1882  void VBAMovieUpdateState()
  2.1883  {
  2.1884 -	++Movie.currentFrame;
  2.1885 -
  2.1886 -	if (Movie.state == MOVIE_STATE_PLAY)
  2.1887 +  ++Movie.currentFrame;
  2.1888 +  printf("RLM: inside updateState\n");
  2.1889 +  if (Movie.state == MOVIE_STATE_PLAY)
  2.1890 +    {
  2.1891 +      Movie.inputBufferPtr += Movie.bytesPerFrame;
  2.1892 +      if (Movie.currentFrame >= Movie.header.length_frames)
  2.1893  	{
  2.1894 -		Movie.inputBufferPtr += Movie.bytesPerFrame;
  2.1895 -		if (Movie.currentFrame >= Movie.header.length_frames)
  2.1896 -		{
  2.1897 -			// the movie ends anyway; what to do next depends on the settings
  2.1898 -			change_state(MOVIE_STATE_END);
  2.1899 -		}
  2.1900 +	  // the movie ends anyway; what to do next depends on the settings
  2.1901 +	  change_state(MOVIE_STATE_END);
  2.1902  	}
  2.1903 -	else if (Movie.state == MOVIE_STATE_RECORD)
  2.1904 -	{
  2.1905 -		// use first fseek?
  2.1906 -		fwrite(Movie.inputBufferPtr, 1, Movie.bytesPerFrame, Movie.file);
  2.1907 -		Movie.header.length_frames = Movie.currentFrame;
  2.1908 -		Movie.inputBufferPtr	 += Movie.bytesPerFrame;
  2.1909 -		Movie.RecordedThisSession = true;
  2.1910 -		flush_movie_header();
  2.1911 -	}
  2.1912 -	else if (Movie.state == MOVIE_STATE_END)
  2.1913 -	{
  2.1914 -		change_state(MOVIE_STATE_END);
  2.1915 -	}
  2.1916 +    }
  2.1917 +  else if (Movie.state == MOVIE_STATE_RECORD)
  2.1918 +    {
  2.1919 +      printf("RLM: Movie_STATE_RECORD\n");
  2.1920 +      // use first fseek?
  2.1921 +      //TODO: THis is the problem.
  2.1922 +      //fwrite(Movie.inputBufferPtr, 1, Movie.bytesPerFrame, Movie.file);
  2.1923 +      printf("RLM: fuck.\n");
  2.1924 +      Movie.header.length_frames = Movie.currentFrame;
  2.1925 +      Movie.inputBufferPtr	 += Movie.bytesPerFrame;
  2.1926 +      Movie.RecordedThisSession = true;
  2.1927 +      flush_movie_header();
  2.1928 +    }
  2.1929 +  else if (Movie.state == MOVIE_STATE_END)
  2.1930 +    {
  2.1931 +      change_state(MOVIE_STATE_END);
  2.1932 +    }
  2.1933  }
  2.1934  
  2.1935  void VBAMovieRead(int i, bool /*sensor*/)
  2.1936  {
  2.1937 -	if (Movie.state != MOVIE_STATE_PLAY)
  2.1938 -		return;
  2.1939 +  if (Movie.state != MOVIE_STATE_PLAY)
  2.1940 +    return;
  2.1941  
  2.1942 -	if (i < 0 || i >= MOVIE_NUM_OF_POSSIBLE_CONTROLLERS)
  2.1943 -		return;      // not a controller we're recognizing
  2.1944 +  if (i < 0 || i >= MOVIE_NUM_OF_POSSIBLE_CONTROLLERS)
  2.1945 +    return;      // not a controller we're recognizing
  2.1946  
  2.1947 -	if (Movie.header.controllerFlags & MOVIE_CONTROLLER(i))
  2.1948 -	{
  2.1949 -		currentButtons[i] = Read16(Movie.inputBufferPtr + CONTROLLER_DATA_SIZE * i);
  2.1950 -	}
  2.1951 -	else
  2.1952 -	{
  2.1953 -		currentButtons[i] = 0;        // pretend the controller is disconnected
  2.1954 -	}
  2.1955 +  if (Movie.header.controllerFlags & MOVIE_CONTROLLER(i))
  2.1956 +    {
  2.1957 +      currentButtons[i] = Read16(Movie.inputBufferPtr + CONTROLLER_DATA_SIZE * i);
  2.1958 +    }
  2.1959 +  else
  2.1960 +    {
  2.1961 +      currentButtons[i] = 0;        // pretend the controller is disconnected
  2.1962 +    }
  2.1963  
  2.1964 -	if ((currentButtons[i] & BUTTON_MASK_NEW_RESET) != 0)
  2.1965 -		resetSignaled = true;
  2.1966 +  if ((currentButtons[i] & BUTTON_MASK_NEW_RESET) != 0)
  2.1967 +    resetSignaled = true;
  2.1968  }
  2.1969  
  2.1970  void VBAMovieWrite(int i, bool /*sensor*/)
  2.1971  {
  2.1972 -	if (Movie.state != MOVIE_STATE_RECORD)
  2.1973 -		return;
  2.1974 +  if (Movie.state != MOVIE_STATE_RECORD)
  2.1975 +    return;
  2.1976  
  2.1977 -	if (i < 0 || i >= MOVIE_NUM_OF_POSSIBLE_CONTROLLERS)
  2.1978 -		return;      // not a controller we're recognizing
  2.1979 +  if (i < 0 || i >= MOVIE_NUM_OF_POSSIBLE_CONTROLLERS)
  2.1980 +    return;      // not a controller we're recognizing
  2.1981  
  2.1982 -	reserve_buffer_space((uint32)((Movie.inputBufferPtr - Movie.inputBuffer) + Movie.bytesPerFrame));
  2.1983 +  reserve_buffer_space((uint32)((Movie.inputBufferPtr - Movie.inputBuffer) + Movie.bytesPerFrame));
  2.1984  
  2.1985 -	if (Movie.header.controllerFlags & MOVIE_CONTROLLER(i))
  2.1986 +  if (Movie.header.controllerFlags & MOVIE_CONTROLLER(i))
  2.1987 +    {
  2.1988 +      // get the current controller data
  2.1989 +      uint16 buttonData = currentButtons[i];
  2.1990 +
  2.1991 +      // mask away the irrelevent bits
  2.1992 +      buttonData &= BUTTON_REGULAR_MASK | BUTTON_MOTION_MASK;
  2.1993 +
  2.1994 +      // soft-reset "button" for 1 frame if the game is reset while recording
  2.1995 +      if (resetSignaled)
  2.1996  	{
  2.1997 -		// get the current controller data
  2.1998 -		uint16 buttonData = currentButtons[i];
  2.1999 +	  buttonData |= BUTTON_MASK_NEW_RESET;
  2.2000 +	}
  2.2001  
  2.2002 -		// mask away the irrelevent bits
  2.2003 -		buttonData &= BUTTON_REGULAR_MASK | BUTTON_MOTION_MASK;
  2.2004 +      // backward compatibility kludge
  2.2005 +      if (resetSignaledLast)
  2.2006 +	{
  2.2007 +	  buttonData |= BUTTON_MASK_OLD_RESET;
  2.2008 +	}
  2.2009  
  2.2010 -		// soft-reset "button" for 1 frame if the game is reset while recording
  2.2011 -		if (resetSignaled)
  2.2012 -		{
  2.2013 -			buttonData |= BUTTON_MASK_NEW_RESET;
  2.2014 -		}
  2.2015 +      Write16(buttonData, Movie.inputBufferPtr + CONTROLLER_DATA_SIZE * i);
  2.2016  
  2.2017 -		// backward compatibility kludge
  2.2018 -		if (resetSignaledLast)
  2.2019 -		{
  2.2020 -			buttonData |= BUTTON_MASK_OLD_RESET;
  2.2021 -		}
  2.2022 -
  2.2023 -		Write16(buttonData, Movie.inputBufferPtr + CONTROLLER_DATA_SIZE * i);
  2.2024 -
  2.2025 -		// and for display
  2.2026 -		currentButtons[i] = buttonData;
  2.2027 -	}
  2.2028 -	else
  2.2029 -	{
  2.2030 -		// pretend the controller is disconnected (otherwise input it gives could cause desync since we're not writing it to the
  2.2031 -		// movie)
  2.2032 -		currentButtons[i] = 0;
  2.2033 -	}
  2.2034 +      // and for display
  2.2035 +      currentButtons[i] = buttonData;
  2.2036 +    }
  2.2037 +  else
  2.2038 +    {
  2.2039 +      // pretend the controller is disconnected (otherwise input it gives could cause desync since we're not writing it to the
  2.2040 +      // movie)
  2.2041 +      currentButtons[i] = 0;
  2.2042 +    }
  2.2043  }
  2.2044  
  2.2045  void VBAMovieStop(bool8 suppress_message)
  2.2046  {
  2.2047 -	if (Movie.state != MOVIE_STATE_NONE)
  2.2048 -	{
  2.2049 -		change_state(MOVIE_STATE_NONE);
  2.2050 -		if (!suppress_message)
  2.2051 -			systemScreenMessage("Movie stop");
  2.2052 -	}
  2.2053 +  if (Movie.state != MOVIE_STATE_NONE)
  2.2054 +    {
  2.2055 +      change_state(MOVIE_STATE_NONE);
  2.2056 +      if (!suppress_message)
  2.2057 +	systemScreenMessage("Movie stop");
  2.2058 +    }
  2.2059  }
  2.2060  
  2.2061  int VBAMovieGetInfo(const char *filename, SMovie *info)
  2.2062  {
  2.2063 -	assert(info != NULL);
  2.2064 -	if (info == NULL)
  2.2065 -		return -1;
  2.2066 +  assert(info != NULL);
  2.2067 +  if (info == NULL)
  2.2068 +    return -1;
  2.2069  
  2.2070 -	FILE *	file;
  2.2071 -	int		result;
  2.2072 -	SMovie &local_movie = *info;
  2.2073 +  FILE *	file;
  2.2074 +  int		result;
  2.2075 +  SMovie &local_movie = *info;
  2.2076  
  2.2077 -	memset(info, 0, sizeof(*info));
  2.2078 -	if (filename[0] == '\0')
  2.2079 -		return MOVIE_FILE_NOT_FOUND;
  2.2080 -	if (!(file = fopen(filename, "rb")))
  2.2081 -		return MOVIE_FILE_NOT_FOUND;
  2.2082 +  memset(info, 0, sizeof(*info));
  2.2083 +  if (filename[0] == '\0')
  2.2084 +    return MOVIE_FILE_NOT_FOUND;
  2.2085 +  if (!(file = fopen(filename, "rb")))
  2.2086 +    return MOVIE_FILE_NOT_FOUND;
  2.2087  
  2.2088 -	// read header
  2.2089 -	if ((result = (read_movie_header(file, local_movie))) != MOVIE_SUCCESS)
  2.2090 -	{
  2.2091 -		fclose(file);
  2.2092 -		return result;
  2.2093 -	}
  2.2094 +  // read header
  2.2095 +  if ((result = (read_movie_header(file, local_movie))) != MOVIE_SUCCESS)
  2.2096 +    {
  2.2097 +      fclose(file);
  2.2098 +      return result;
  2.2099 +    }
  2.2100  
  2.2101 -	// read the metadata / author info from file
  2.2102 -	fread(local_movie.authorInfo, 1, sizeof(char) * MOVIE_METADATA_SIZE, file);
  2.2103 +  // read the metadata / author info from file
  2.2104 +  fread(local_movie.authorInfo, 1, sizeof(char) * MOVIE_METADATA_SIZE, file);
  2.2105  
  2.2106 -	strncpy(local_movie.filename, filename, _MAX_PATH);
  2.2107 -	local_movie.filename[_MAX_PATH - 1] = '\0';
  2.2108 +  strncpy(local_movie.filename, filename, _MAX_PATH);
  2.2109 +  local_movie.filename[_MAX_PATH - 1] = '\0';
  2.2110  
  2.2111 -	if (Movie.file != NULL && stricmp(local_movie.filename, Movie.filename) == 0) // alreadyOpen
  2.2112 -	{
  2.2113 -		local_movie.bytesPerFrame		 = Movie.bytesPerFrame;
  2.2114 -		local_movie.header.length_frames = Movie.header.length_frames;
  2.2115 -	}
  2.2116 -	else
  2.2117 -	{
  2.2118 -		// recalculate length of movie from the file size
  2.2119 -		local_movie.bytesPerFrame = bytes_per_frame(local_movie);
  2.2120 -		fseek(file, 0, SEEK_END);
  2.2121 -		int fileSize = ftell(file);
  2.2122 -		local_movie.header.length_frames =
  2.2123 -		    (fileSize - local_movie.header.offset_to_controller_data) / local_movie.bytesPerFrame;
  2.2124 -	}
  2.2125 +  if (Movie.file != NULL && stricmp(local_movie.filename, Movie.filename) == 0) // alreadyOpen
  2.2126 +    {
  2.2127 +      local_movie.bytesPerFrame		 = Movie.bytesPerFrame;
  2.2128 +      local_movie.header.length_frames = Movie.header.length_frames;
  2.2129 +    }
  2.2130 +  else
  2.2131 +    {
  2.2132 +      // recalculate length of movie from the file size
  2.2133 +      local_movie.bytesPerFrame = bytes_per_frame(local_movie);
  2.2134 +      fseek(file, 0, SEEK_END);
  2.2135 +      int fileSize = ftell(file);
  2.2136 +      local_movie.header.length_frames =
  2.2137 +	(fileSize - local_movie.header.offset_to_controller_data) / local_movie.bytesPerFrame;
  2.2138 +    }
  2.2139  
  2.2140 -	fclose(file);
  2.2141 +  fclose(file);
  2.2142  
  2.2143 -	if (access(filename, W_OK))
  2.2144 -		info->readOnly = true;
  2.2145 +  if (access(filename, W_OK))
  2.2146 +    info->readOnly = true;
  2.2147  
  2.2148 -	return MOVIE_SUCCESS;
  2.2149 +  return MOVIE_SUCCESS;
  2.2150  }
  2.2151  
  2.2152  bool8 VBAMovieActive()
  2.2153  {
  2.2154 -	return (Movie.state != MOVIE_STATE_NONE);
  2.2155 +  return (Movie.state != MOVIE_STATE_NONE);
  2.2156  }
  2.2157  
  2.2158  bool8 VBAMovieLoading()
  2.2159  {
  2.2160 -	return loadingMovie;
  2.2161 +  return loadingMovie;
  2.2162  }
  2.2163  
  2.2164  bool8 VBAMoviePlaying()
  2.2165  {
  2.2166 -	return (Movie.state == MOVIE_STATE_PLAY);
  2.2167 +  return (Movie.state == MOVIE_STATE_PLAY);
  2.2168  }
  2.2169  
  2.2170  bool8 VBAMovieRecording()
  2.2171  {
  2.2172 -	return (Movie.state == MOVIE_STATE_RECORD);
  2.2173 +  return (Movie.state == MOVIE_STATE_RECORD);
  2.2174  }
  2.2175  
  2.2176  bool8 VBAMovieReadOnly()
  2.2177  {
  2.2178 -	if (!VBAMovieActive())
  2.2179 -		return false;
  2.2180 +  if (!VBAMovieActive())
  2.2181 +    return false;
  2.2182  
  2.2183 -	return Movie.readOnly;
  2.2184 +  return Movie.readOnly;
  2.2185  }
  2.2186  
  2.2187  void VBAMovieToggleReadOnly()
  2.2188  {
  2.2189 -	if (!VBAMovieActive())
  2.2190 -		return;
  2.2191 +  if (!VBAMovieActive())
  2.2192 +    return;
  2.2193  
  2.2194 -	if (Movie.readOnly != 2)
  2.2195 -	{
  2.2196 -		Movie.readOnly = !Movie.readOnly;
  2.2197 +  if (Movie.readOnly != 2)
  2.2198 +    {
  2.2199 +      Movie.readOnly = !Movie.readOnly;
  2.2200  
  2.2201 -		systemScreenMessage(Movie.readOnly ? "Movie now read-only" : "Movie now editable");
  2.2202 -	}
  2.2203 -	else
  2.2204 -	{
  2.2205 -		systemScreenMessage("Can't toggle read-only movie");
  2.2206 -	}
  2.2207 +      systemScreenMessage(Movie.readOnly ? "Movie now read-only" : "Movie now editable");
  2.2208 +    }
  2.2209 +  else
  2.2210 +    {
  2.2211 +      systemScreenMessage("Can't toggle read-only movie");
  2.2212 +    }
  2.2213  }
  2.2214  
  2.2215  uint32 VBAMovieGetVersion()
  2.2216  {
  2.2217 -	if (!VBAMovieActive())
  2.2218 -		return 0;
  2.2219 +  if (!VBAMovieActive())
  2.2220 +    return 0;
  2.2221  
  2.2222 -	return Movie.header.version;
  2.2223 +  return Movie.header.version;
  2.2224  }
  2.2225  
  2.2226  uint32 VBAMovieGetMinorVersion()
  2.2227  {
  2.2228 -	if (!VBAMovieActive())
  2.2229 -		return 0;
  2.2230 +  if (!VBAMovieActive())
  2.2231 +    return 0;
  2.2232  
  2.2233 -	return Movie.header.minorVersion;
  2.2234 +  return Movie.header.minorVersion;
  2.2235  }
  2.2236  
  2.2237  uint32 VBAMovieGetId()
  2.2238  {
  2.2239 -	if (!VBAMovieActive())
  2.2240 -		return 0;
  2.2241 +  if (!VBAMovieActive())
  2.2242 +    return 0;
  2.2243  
  2.2244 -	return Movie.header.uid;
  2.2245 +  return Movie.header.uid;
  2.2246  }
  2.2247  
  2.2248  uint32 VBAMovieGetLength()
  2.2249  {
  2.2250 -	if (!VBAMovieActive())
  2.2251 -		return 0;
  2.2252 +  if (!VBAMovieActive())
  2.2253 +    return 0;
  2.2254  
  2.2255 -	return Movie.header.length_frames;
  2.2256 +  return Movie.header.length_frames;
  2.2257  }
  2.2258  
  2.2259  uint32 VBAMovieGetFrameCounter()
  2.2260  {
  2.2261 -	if (!VBAMovieActive())
  2.2262 -		return 0;
  2.2263 +  if (!VBAMovieActive())
  2.2264 +    return 0;
  2.2265  
  2.2266 -	return Movie.currentFrame;
  2.2267 +  return Movie.currentFrame;
  2.2268  }
  2.2269  
  2.2270  uint32 VBAMovieGetRerecordCount()
  2.2271  {
  2.2272 -	if (!VBAMovieActive())
  2.2273 -		return 0;
  2.2274 +  if (!VBAMovieActive())
  2.2275 +    return 0;
  2.2276  
  2.2277 -	return Movie.header.rerecord_count;
  2.2278 +  return Movie.header.rerecord_count;
  2.2279  }
  2.2280  
  2.2281  uint32 VBAMovieSetRerecordCount(uint32 newRerecordCount)
  2.2282  {
  2.2283 -	uint32 oldRerecordCount = 0;
  2.2284 -	if (!VBAMovieActive())
  2.2285 -		return 0;
  2.2286 +  uint32 oldRerecordCount = 0;
  2.2287 +  if (!VBAMovieActive())
  2.2288 +    return 0;
  2.2289  
  2.2290 -	oldRerecordCount = Movie.header.rerecord_count;
  2.2291 -	Movie.header.rerecord_count = newRerecordCount;
  2.2292 -	return oldRerecordCount;
  2.2293 +  oldRerecordCount = Movie.header.rerecord_count;
  2.2294 +  Movie.header.rerecord_count = newRerecordCount;
  2.2295 +  return oldRerecordCount;
  2.2296  }
  2.2297  
  2.2298  std::string VBAMovieGetAuthorInfo()
  2.2299  {
  2.2300 -	if (!VBAMovieActive())
  2.2301 -		return "";
  2.2302 +  if (!VBAMovieActive())
  2.2303 +    return "";
  2.2304  
  2.2305 -	return Movie.authorInfo;
  2.2306 +  return Movie.authorInfo;
  2.2307  }
  2.2308  
  2.2309  std::string VBAMovieGetFilename()
  2.2310  {
  2.2311 -	if (!VBAMovieActive())
  2.2312 -		return "";
  2.2313 +  if (!VBAMovieActive())
  2.2314 +    return "";
  2.2315  
  2.2316 -	return Movie.filename;
  2.2317 +  return Movie.filename;
  2.2318  }
  2.2319  
  2.2320  void VBAMovieFreeze(uint8 * *buf, uint32 *size)
  2.2321  {
  2.2322 -	// sanity check
  2.2323 -	if (!VBAMovieActive())
  2.2324 -	{
  2.2325 -		return;
  2.2326 -	}
  2.2327 +  // sanity check
  2.2328 +  if (!VBAMovieActive())
  2.2329 +    {
  2.2330 +      return;
  2.2331 +    }
  2.2332  
  2.2333 -	*buf  = NULL;
  2.2334 -	*size = 0;
  2.2335 +  *buf  = NULL;
  2.2336 +  *size = 0;
  2.2337  
  2.2338 -	// compute size needed for the buffer
  2.2339 -	// room for header.uid, currentFrame, and header.length_frames
  2.2340 -	uint32 size_needed = sizeof(Movie.header.uid) + sizeof(Movie.currentFrame) + sizeof(Movie.header.length_frames);
  2.2341 -	size_needed += (uint32)(Movie.bytesPerFrame * Movie.header.length_frames);
  2.2342 -	*buf		 = new uint8[size_needed];
  2.2343 -	*size		 = size_needed;
  2.2344 +  // compute size needed for the buffer
  2.2345 +  // room for header.uid, currentFrame, and header.length_frames
  2.2346 +  uint32 size_needed = sizeof(Movie.header.uid) + sizeof(Movie.currentFrame) + sizeof(Movie.header.length_frames);
  2.2347 +  size_needed += (uint32)(Movie.bytesPerFrame * Movie.header.length_frames);
  2.2348 +  *buf		 = new uint8[size_needed];
  2.2349 +  *size		 = size_needed;
  2.2350  
  2.2351 -	uint8 *ptr = *buf;
  2.2352 -	if (!ptr)
  2.2353 -	{
  2.2354 -		return;
  2.2355 -	}
  2.2356 +  uint8 *ptr = *buf;
  2.2357 +  if (!ptr)
  2.2358 +    {
  2.2359 +      return;
  2.2360 +    }
  2.2361  
  2.2362 -	Push32(Movie.header.uid, ptr);
  2.2363 -	Push32(Movie.currentFrame, ptr);
  2.2364 -	Push32(Movie.header.length_frames - 1, ptr);   // HACK: shorten the length by 1 for backward compatibility
  2.2365 +  Push32(Movie.header.uid, ptr);
  2.2366 +  Push32(Movie.currentFrame, ptr);
  2.2367 +  Push32(Movie.header.length_frames - 1, ptr);   // HACK: shorten the length by 1 for backward compatibility
  2.2368  
  2.2369 -	memcpy(ptr, Movie.inputBuffer, Movie.bytesPerFrame * Movie.header.length_frames);
  2.2370 +  memcpy(ptr, Movie.inputBuffer, Movie.bytesPerFrame * Movie.header.length_frames);
  2.2371  }
  2.2372  
  2.2373  int VBAMovieUnfreeze(const uint8 *buf, uint32 size)
  2.2374  {
  2.2375 -	// sanity check
  2.2376 -	if (!VBAMovieActive())
  2.2377 +  // sanity check
  2.2378 +  if (!VBAMovieActive())
  2.2379 +    {
  2.2380 +      return MOVIE_NOT_FROM_A_MOVIE;
  2.2381 +    }
  2.2382 +
  2.2383 +  const uint8 *ptr = buf;
  2.2384 +  if (size < sizeof(Movie.header.uid) + sizeof(Movie.currentFrame) + sizeof(Movie.header.length_frames))
  2.2385 +    {
  2.2386 +      return MOVIE_WRONG_FORMAT;
  2.2387 +    }
  2.2388 +
  2.2389 +  uint32 movie_id		 = Pop32(ptr);
  2.2390 +  uint32 current_frame = Pop32(ptr);
  2.2391 +  uint32 end_frame	 = Pop32(ptr) + 1;     // HACK: restore the length for backward compatibility
  2.2392 +  uint32 space_needed	 = Movie.bytesPerFrame * end_frame;
  2.2393 +
  2.2394 +  if (movie_id != Movie.header.uid)
  2.2395 +    return MOVIE_NOT_FROM_THIS_MOVIE;
  2.2396 +
  2.2397 +  if (space_needed > size)
  2.2398 +    return MOVIE_WRONG_FORMAT;
  2.2399 +
  2.2400 +  if (Movie.readOnly)
  2.2401 +    {
  2.2402 +      // here, we are going to keep the input data from the movie file
  2.2403 +      // and simply rewind to the currentFrame pointer
  2.2404 +      // this will cause a desync if the savestate is not in sync // <-- NOT ANYMORE
  2.2405 +      // with the on-disk recording data, but it's easily solved
  2.2406 +      // by loading another savestate or playing the movie from the beginning
  2.2407 +
  2.2408 +      // don't allow loading a state inconsistent with the current movie
  2.2409 +      uint32 length_history = min(current_frame, Movie.header.length_frames);
  2.2410 +      if (end_frame < length_history)
  2.2411 +	return MOVIE_SNAPSHOT_INCONSISTENT;
  2.2412 +
  2.2413 +      uint32 space_shared = Movie.bytesPerFrame * length_history;
  2.2414 +      if (memcmp(Movie.inputBuffer, ptr, space_shared))
  2.2415 +	return MOVIE_SNAPSHOT_INCONSISTENT;
  2.2416 +
  2.2417 +      Movie.currentFrame	 = current_frame;
  2.2418 +      Movie.inputBufferPtr = Movie.inputBuffer + Movie.bytesPerFrame * min(current_frame, Movie.header.length_frames);
  2.2419 +    }
  2.2420 +  else
  2.2421 +    {
  2.2422 +      // here, we are going to take the input data from the savestate
  2.2423 +      // and make it the input data for the current movie, then continue
  2.2424 +      // writing new input data at the currentFrame pointer
  2.2425 +      Movie.currentFrame		   = current_frame;
  2.2426 +      Movie.header.length_frames = end_frame;
  2.2427 +      if (!VBALuaRerecordCountSkip())
  2.2428 +	++Movie.header.rerecord_count;
  2.2429 +
  2.2430 +      Movie.RecordedThisSession = true;
  2.2431 +
  2.2432 +      // do this before calling reserve_buffer_space()
  2.2433 +      Movie.inputBufferPtr = Movie.inputBuffer + Movie.bytesPerFrame * min(current_frame, Movie.header.length_frames);
  2.2434 +      reserve_buffer_space(space_needed);
  2.2435 +      memcpy(Movie.inputBuffer, ptr, space_needed);
  2.2436 +
  2.2437 +      // for consistency, no auto movie conversion here since we don't auto convert the corresponding savestate
  2.2438 +      flush_movie_header();
  2.2439 +      flush_movie_frames();
  2.2440 +    }
  2.2441 +
  2.2442 +  change_state(MOVIE_STATE_PLAY);	// check for movie end
  2.2443 +
  2.2444 +  // necessary!
  2.2445 +  resetSignaled	  = false;
  2.2446 +  resetSignaledLast = false;
  2.2447 +
  2.2448 +  // necessary to check if there's a reset signal at the previous frame
  2.2449 +  if (current_frame > 0)
  2.2450 +    {
  2.2451 +      const u8 NEW_RESET = u8(BUTTON_MASK_NEW_RESET >> 8);
  2.2452 +      for (int i = 0; i < MOVIE_NUM_OF_POSSIBLE_CONTROLLERS; ++i)
  2.2453  	{
  2.2454 -		return MOVIE_NOT_FROM_A_MOVIE;
  2.2455 +	  if ((Movie.header.controllerFlags & MOVIE_CONTROLLER(i)) && (*(Movie.inputBufferPtr+1- Movie.bytesPerFrame) & NEW_RESET))
  2.2456 +	    {
  2.2457 +	      resetSignaledLast = true;
  2.2458 +	      break;
  2.2459 +	    }
  2.2460  	}
  2.2461 +    }
  2.2462  
  2.2463 -	const uint8 *ptr = buf;
  2.2464 -	if (size < sizeof(Movie.header.uid) + sizeof(Movie.currentFrame) + sizeof(Movie.header.length_frames))
  2.2465 -	{
  2.2466 -		return MOVIE_WRONG_FORMAT;
  2.2467 -	}
  2.2468 -
  2.2469 -	uint32 movie_id		 = Pop32(ptr);
  2.2470 -	uint32 current_frame = Pop32(ptr);
  2.2471 -	uint32 end_frame	 = Pop32(ptr) + 1;     // HACK: restore the length for backward compatibility
  2.2472 -	uint32 space_needed	 = Movie.bytesPerFrame * end_frame;
  2.2473 -
  2.2474 -	if (movie_id != Movie.header.uid)
  2.2475 -		return MOVIE_NOT_FROM_THIS_MOVIE;
  2.2476 -
  2.2477 -	if (space_needed > size)
  2.2478 -		return MOVIE_WRONG_FORMAT;
  2.2479 -
  2.2480 -	if (Movie.readOnly)
  2.2481 -	{
  2.2482 -		// here, we are going to keep the input data from the movie file
  2.2483 -		// and simply rewind to the currentFrame pointer
  2.2484 -		// this will cause a desync if the savestate is not in sync // <-- NOT ANYMORE
  2.2485 -		// with the on-disk recording data, but it's easily solved
  2.2486 -		// by loading another savestate or playing the movie from the beginning
  2.2487 -
  2.2488 -		// don't allow loading a state inconsistent with the current movie
  2.2489 -		uint32 length_history = min(current_frame, Movie.header.length_frames);
  2.2490 -		if (end_frame < length_history)
  2.2491 -			return MOVIE_SNAPSHOT_INCONSISTENT;
  2.2492 -
  2.2493 -		uint32 space_shared = Movie.bytesPerFrame * length_history;
  2.2494 -		if (memcmp(Movie.inputBuffer, ptr, space_shared))
  2.2495 -			return MOVIE_SNAPSHOT_INCONSISTENT;
  2.2496 -
  2.2497 -		Movie.currentFrame	 = current_frame;
  2.2498 -		Movie.inputBufferPtr = Movie.inputBuffer + Movie.bytesPerFrame * min(current_frame, Movie.header.length_frames);
  2.2499 -	}
  2.2500 -	else
  2.2501 -	{
  2.2502 -		// here, we are going to take the input data from the savestate
  2.2503 -		// and make it the input data for the current movie, then continue
  2.2504 -		// writing new input data at the currentFrame pointer
  2.2505 -		Movie.currentFrame		   = current_frame;
  2.2506 -		Movie.header.length_frames = end_frame;
  2.2507 -		if (!VBALuaRerecordCountSkip())
  2.2508 -			++Movie.header.rerecord_count;
  2.2509 -
  2.2510 -		Movie.RecordedThisSession = true;
  2.2511 -
  2.2512 -		// do this before calling reserve_buffer_space()
  2.2513 -		Movie.inputBufferPtr = Movie.inputBuffer + Movie.bytesPerFrame * min(current_frame, Movie.header.length_frames);
  2.2514 -		reserve_buffer_space(space_needed);
  2.2515 -		memcpy(Movie.inputBuffer, ptr, space_needed);
  2.2516 -
  2.2517 -		// for consistency, no auto movie conversion here since we don't auto convert the corresponding savestate
  2.2518 -		flush_movie_header();
  2.2519 -		flush_movie_frames();
  2.2520 -	}
  2.2521 -
  2.2522 -	change_state(MOVIE_STATE_PLAY);	// check for movie end
  2.2523 -
  2.2524 -	// necessary!
  2.2525 -	resetSignaled	  = false;
  2.2526 -	resetSignaledLast = false;
  2.2527 -
  2.2528 -	// necessary to check if there's a reset signal at the previous frame
  2.2529 -	if (current_frame > 0)
  2.2530 -	{
  2.2531 -		const u8 NEW_RESET = u8(BUTTON_MASK_NEW_RESET >> 8);
  2.2532 -		for (int i = 0; i < MOVIE_NUM_OF_POSSIBLE_CONTROLLERS; ++i)
  2.2533 -		{
  2.2534 -			if ((Movie.header.controllerFlags & MOVIE_CONTROLLER(i)) && (*(Movie.inputBufferPtr+1- Movie.bytesPerFrame) & NEW_RESET))
  2.2535 -			{
  2.2536 -				resetSignaledLast = true;
  2.2537 -				break;
  2.2538 -			}
  2.2539 -		}
  2.2540 -	}
  2.2541 -
  2.2542 -	return MOVIE_SUCCESS;
  2.2543 +  return MOVIE_SUCCESS;
  2.2544  }
  2.2545  
  2.2546  bool VBAMovieEnded()
  2.2547  {
  2.2548 -	return (Movie.state == MOVIE_STATE_END);
  2.2549 -//	return (Movie.state != MOVIE_STATE_NONE && Movie.currentFrame >= Movie.header.length_frames);
  2.2550 +  return (Movie.state == MOVIE_STATE_END);
  2.2551 +  //	return (Movie.state != MOVIE_STATE_NONE && Movie.currentFrame >= Movie.header.length_frames);
  2.2552  }
  2.2553  
  2.2554  bool VBAMovieAllowsRerecording()
  2.2555  {
  2.2556 -	bool allows = (Movie.state != MOVIE_STATE_NONE) && (Movie.currentFrame <= Movie.header.length_frames);
  2.2557 -	return /*!VBAMovieReadOnly() &&*/ allows;
  2.2558 +  bool allows = (Movie.state != MOVIE_STATE_NONE) && (Movie.currentFrame <= Movie.header.length_frames);
  2.2559 +  return /*!VBAMovieReadOnly() &&*/ allows;
  2.2560  }
  2.2561  
  2.2562  bool VBAMovieSwitchToPlaying()
  2.2563  {
  2.2564 -	if (!VBAMovieActive())
  2.2565 -		return false;
  2.2566 +  if (!VBAMovieActive())
  2.2567 +    return false;
  2.2568  
  2.2569 -	if (!Movie.readOnly)
  2.2570 -	{
  2.2571 -		VBAMovieToggleReadOnly();
  2.2572 -	}
  2.2573 +  if (!Movie.readOnly)
  2.2574 +    {
  2.2575 +      VBAMovieToggleReadOnly();
  2.2576 +    }
  2.2577  
  2.2578 -	change_state(MOVIE_STATE_PLAY);
  2.2579 -	if (Movie.state == MOVIE_STATE_PLAY)
  2.2580 -		systemScreenMessage("Movie replay (continue)");
  2.2581 -	else
  2.2582 -		systemScreenMessage("Movie end");
  2.2583 +  change_state(MOVIE_STATE_PLAY);
  2.2584 +  if (Movie.state == MOVIE_STATE_PLAY)
  2.2585 +    systemScreenMessage("Movie replay (continue)");
  2.2586 +  else
  2.2587 +    systemScreenMessage("Movie end");
  2.2588  
  2.2589 -	return true;
  2.2590 +  return true;
  2.2591  }
  2.2592  
  2.2593  bool VBAMovieSwitchToRecording()
  2.2594  {
  2.2595 -	if (!VBAMovieAllowsRerecording())
  2.2596 -		return false;
  2.2597 +  if (!VBAMovieAllowsRerecording())
  2.2598 +    return false;
  2.2599  
  2.2600 -	if (Movie.readOnly)
  2.2601 -	{
  2.2602 -		VBAMovieToggleReadOnly();
  2.2603 -	}
  2.2604 +  if (Movie.readOnly)
  2.2605 +    {
  2.2606 +      VBAMovieToggleReadOnly();
  2.2607 +    }
  2.2608  
  2.2609 -	if (!VBALuaRerecordCountSkip())
  2.2610 -		++Movie.header.rerecord_count;
  2.2611 +  if (!VBALuaRerecordCountSkip())
  2.2612 +    ++Movie.header.rerecord_count;
  2.2613  
  2.2614 -	change_state(MOVIE_STATE_RECORD);
  2.2615 -	systemScreenMessage("Movie re-record");
  2.2616 +  change_state(MOVIE_STATE_RECORD);
  2.2617 +  systemScreenMessage("Movie re-record");
  2.2618  
  2.2619 -	//truncate_movie(Movie.currentFrame);
  2.2620 +  //truncate_movie(Movie.currentFrame);
  2.2621  
  2.2622 -	return true;
  2.2623 +  return true;
  2.2624  }
  2.2625  
  2.2626  uint32 VBAMovieGetState()
  2.2627  {
  2.2628 -	// ?
  2.2629 -	if (!VBAMovieActive())
  2.2630 -		return MOVIE_STATE_NONE;
  2.2631 +  // ?
  2.2632 +  if (!VBAMovieActive())
  2.2633 +    return MOVIE_STATE_NONE;
  2.2634  
  2.2635 -	return Movie.state;
  2.2636 +  return Movie.state;
  2.2637  }
  2.2638  
  2.2639  void VBAMovieSignalReset()
  2.2640  {
  2.2641 -	if (VBAMovieActive())
  2.2642 -		resetSignaled = true;
  2.2643 +  if (VBAMovieActive())
  2.2644 +    resetSignaled = true;
  2.2645  }
  2.2646  
  2.2647  void VBAMovieResetIfRequested()
  2.2648  {
  2.2649 -	if (resetSignaled)
  2.2650 -	{
  2.2651 -		theEmulator.emuReset(false);
  2.2652 -		resetSignaled	  = false;
  2.2653 -		resetSignaledLast = true;
  2.2654 -	}
  2.2655 -	else
  2.2656 -	{
  2.2657 -		resetSignaledLast = false;
  2.2658 -	}
  2.2659 +  if (resetSignaled)
  2.2660 +    {
  2.2661 +      theEmulator.emuReset(false);
  2.2662 +      resetSignaled	  = false;
  2.2663 +      resetSignaledLast = true;
  2.2664 +    }
  2.2665 +  else
  2.2666 +    {
  2.2667 +      resetSignaledLast = false;
  2.2668 +    }
  2.2669  }
  2.2670  
  2.2671  void VBAMovieSetMetadata(const char *info)
  2.2672  {
  2.2673 -	if (!memcmp(Movie.authorInfo, info, MOVIE_METADATA_SIZE))
  2.2674 -		return;
  2.2675 +  if (!memcmp(Movie.authorInfo, info, MOVIE_METADATA_SIZE))
  2.2676 +    return;
  2.2677  
  2.2678 -	memcpy(Movie.authorInfo, info, MOVIE_METADATA_SIZE); // strncpy would omit post-0 bytes
  2.2679 -	Movie.authorInfo[MOVIE_METADATA_SIZE - 1] = '\0';
  2.2680 +  memcpy(Movie.authorInfo, info, MOVIE_METADATA_SIZE); // strncpy would omit post-0 bytes
  2.2681 +  Movie.authorInfo[MOVIE_METADATA_SIZE - 1] = '\0';
  2.2682  
  2.2683 -	if (Movie.file)
  2.2684 -	{
  2.2685 -		// (over-)write the header
  2.2686 -		fseek(Movie.file, 0, SEEK_SET);
  2.2687 -		write_movie_header(Movie.file, Movie);
  2.2688 +  if (Movie.file)
  2.2689 +    {
  2.2690 +      // (over-)write the header
  2.2691 +      fseek(Movie.file, 0, SEEK_SET);
  2.2692  
  2.2693 -		// write the metadata / author info to file
  2.2694 -		fwrite(Movie.authorInfo, 1, sizeof(char) * MOVIE_METADATA_SIZE, Movie.file);
  2.2695 +      write_movie_header(Movie.file, Movie);
  2.2696  
  2.2697 -		fflush(Movie.file);
  2.2698 -	}
  2.2699 +      // write the metadata / author info to file
  2.2700 +      fwrite(Movie.authorInfo, 1, sizeof(char) * MOVIE_METADATA_SIZE, Movie.file);
  2.2701 +
  2.2702 +      fflush(Movie.file);
  2.2703 +    }
  2.2704 +  printf("RLM: setMetadata called\n");
  2.2705 +
  2.2706  }
  2.2707  
  2.2708  void VBAMovieRestart()
  2.2709  {
  2.2710 -	if (VBAMovieActive())
  2.2711 -	{
  2.2712 -		systemSoundClearBuffer();
  2.2713 +  if (VBAMovieActive())
  2.2714 +    {
  2.2715 +      systemSoundClearBuffer();
  2.2716  
  2.2717 -		bool8 modified = Movie.RecordedThisSession;
  2.2718 +      bool8 modified = Movie.RecordedThisSession;
  2.2719  
  2.2720 -		VBAMovieStop(true);
  2.2721 +      VBAMovieStop(true);
  2.2722  
  2.2723 -		char movieName [_MAX_PATH];
  2.2724 -		strncpy(movieName, Movie.filename, _MAX_PATH);
  2.2725 -		movieName[_MAX_PATH - 1] = '\0';
  2.2726 -		VBAMovieOpen(movieName, Movie.readOnly); // can't just pass in Movie.filename, since VBAMovieOpen clears out Movie's
  2.2727 -		                                         // variables
  2.2728 +      char movieName [_MAX_PATH];
  2.2729 +      strncpy(movieName, Movie.filename, _MAX_PATH);
  2.2730 +      movieName[_MAX_PATH - 1] = '\0';
  2.2731 +      VBAMovieOpen(movieName, Movie.readOnly); // can't just pass in Movie.filename, since VBAMovieOpen clears out Movie's
  2.2732 +      // variables
  2.2733  
  2.2734 -		Movie.RecordedThisSession = modified;
  2.2735 +      Movie.RecordedThisSession = modified;
  2.2736  
  2.2737 -		systemScreenMessage("Movie replay (restart)");
  2.2738 -	}
  2.2739 +      systemScreenMessage("Movie replay (restart)");
  2.2740 +    }
  2.2741  }
  2.2742  
  2.2743  int VBAMovieGetPauseAt()
  2.2744  {
  2.2745 -	return Movie.pauseFrame;
  2.2746 +  return Movie.pauseFrame;
  2.2747  }
  2.2748  
  2.2749  void VBAMovieSetPauseAt(int at)
  2.2750  {
  2.2751 -	Movie.pauseFrame = at;
  2.2752 +  Movie.pauseFrame = at;
  2.2753  }
  2.2754  
  2.2755  ///////////////////////
  2.2756 @@ -1688,85 +1703,85 @@
  2.2757  // FIXME: is it safe to convert/flush a movie while recording it (considering fseek() problem)?
  2.2758  int VBAMovieConvertCurrent()
  2.2759  {
  2.2760 -	if (!VBAMovieActive())
  2.2761 +  if (!VBAMovieActive())
  2.2762 +    {
  2.2763 +      return MOVIE_NOTHING;
  2.2764 +    }
  2.2765 +
  2.2766 +  if (Movie.header.minorVersion > VBM_REVISION)
  2.2767 +    {
  2.2768 +      return MOVIE_WRONG_VERSION;
  2.2769 +    }
  2.2770 +
  2.2771 +  if (Movie.header.minorVersion == VBM_REVISION)
  2.2772 +    {
  2.2773 +      return MOVIE_NOTHING;
  2.2774 +    }
  2.2775 +
  2.2776 +  Movie.header.minorVersion = VBM_REVISION;
  2.2777 +
  2.2778 +  if (Movie.header.length_frames == 0) // this could happen
  2.2779 +    {
  2.2780 +      truncate_movie(0);
  2.2781 +      return MOVIE_SUCCESS;
  2.2782 +    }
  2.2783 +
  2.2784 +  // fix movies recorded from snapshots
  2.2785 +  if (Movie.header.startFlags & MOVIE_START_FROM_SNAPSHOT)
  2.2786 +    {
  2.2787 +      uint8 *firstFramePtr = Movie.inputBuffer;
  2.2788 +      for (int i = 0; i < MOVIE_NUM_OF_POSSIBLE_CONTROLLERS; ++i)
  2.2789  	{
  2.2790 -		return MOVIE_NOTHING;
  2.2791 +	  if (Movie.header.controllerFlags & MOVIE_CONTROLLER(i))
  2.2792 +	    {
  2.2793 +	      Push16(initialInputs[i], firstFramePtr);
  2.2794 +	      // note: this is correct since Push16 advances the dest pointer by sizeof u16
  2.2795 +	    }
  2.2796  	}
  2.2797 +    }
  2.2798  
  2.2799 -	if (Movie.header.minorVersion > VBM_REVISION)
  2.2800 +  // convert old resets to new ones
  2.2801 +  const u8 OLD_RESET = u8(BUTTON_MASK_OLD_RESET >> 8);
  2.2802 +  const u8 NEW_RESET = u8(BUTTON_MASK_NEW_RESET >> 8);
  2.2803 +  for (int i = 0; i < MOVIE_NUM_OF_POSSIBLE_CONTROLLERS; ++i)
  2.2804 +    {
  2.2805 +      if (Movie.header.controllerFlags & MOVIE_CONTROLLER(i))
  2.2806  	{
  2.2807 -		return MOVIE_WRONG_VERSION;
  2.2808 +	  uint8 *startPtr = Movie.inputBuffer + sizeof(u16) * i + 1;
  2.2809 +	  uint8 *endPtr	= Movie.inputBuffer + Movie.bytesPerFrame * (Movie.header.length_frames - 1);
  2.2810 +	  for (; startPtr < endPtr; startPtr += Movie.bytesPerFrame)
  2.2811 +	    {
  2.2812 +	      if (startPtr[Movie.bytesPerFrame] & OLD_RESET)
  2.2813 +		{
  2.2814 +		  startPtr[0] |= NEW_RESET;
  2.2815 +		}
  2.2816 +	    }
  2.2817  	}
  2.2818 +    }
  2.2819  
  2.2820 -	if (Movie.header.minorVersion == VBM_REVISION)
  2.2821 -	{
  2.2822 -		return MOVIE_NOTHING;
  2.2823 -	}
  2.2824 -
  2.2825 -	Movie.header.minorVersion = VBM_REVISION;
  2.2826 -
  2.2827 -	if (Movie.header.length_frames == 0) // this could happen
  2.2828 -	{
  2.2829 -		truncate_movie(0);
  2.2830 -		return MOVIE_SUCCESS;
  2.2831 -	}
  2.2832 -
  2.2833 -	// fix movies recorded from snapshots
  2.2834 -	if (Movie.header.startFlags & MOVIE_START_FROM_SNAPSHOT)
  2.2835 -	{
  2.2836 -		uint8 *firstFramePtr = Movie.inputBuffer;
  2.2837 -		for (int i = 0; i < MOVIE_NUM_OF_POSSIBLE_CONTROLLERS; ++i)
  2.2838 -		{
  2.2839 -			if (Movie.header.controllerFlags & MOVIE_CONTROLLER(i))
  2.2840 -			{
  2.2841 -				Push16(initialInputs[i], firstFramePtr);
  2.2842 -				// note: this is correct since Push16 advances the dest pointer by sizeof u16
  2.2843 -			}
  2.2844 -		}
  2.2845 -	}
  2.2846 -
  2.2847 -	// convert old resets to new ones
  2.2848 -	const u8 OLD_RESET = u8(BUTTON_MASK_OLD_RESET >> 8);
  2.2849 -	const u8 NEW_RESET = u8(BUTTON_MASK_NEW_RESET >> 8);
  2.2850 -	for (int i = 0; i < MOVIE_NUM_OF_POSSIBLE_CONTROLLERS; ++i)
  2.2851 -	{
  2.2852 -		if (Movie.header.controllerFlags & MOVIE_CONTROLLER(i))
  2.2853 -		{
  2.2854 -			uint8 *startPtr = Movie.inputBuffer + sizeof(u16) * i + 1;
  2.2855 -			uint8 *endPtr	= Movie.inputBuffer + Movie.bytesPerFrame * (Movie.header.length_frames - 1);
  2.2856 -			for (; startPtr < endPtr; startPtr += Movie.bytesPerFrame)
  2.2857 -			{
  2.2858 -				if (startPtr[Movie.bytesPerFrame] & OLD_RESET)
  2.2859 -				{
  2.2860 -					startPtr[0] |= NEW_RESET;
  2.2861 -				}
  2.2862 -			}
  2.2863 -		}
  2.2864 -	}
  2.2865 -
  2.2866 -	flush_movie_header();
  2.2867 -	flush_movie_frames();
  2.2868 -	return MOVIE_SUCCESS;
  2.2869 +  flush_movie_header();
  2.2870 +  flush_movie_frames();
  2.2871 +  return MOVIE_SUCCESS;
  2.2872  }
  2.2873  
  2.2874  bool VBAMovieTuncateAtCurrentFrame()
  2.2875  {
  2.2876 -	if (!VBAMovieActive())
  2.2877 -		return false;
  2.2878 +  if (!VBAMovieActive())
  2.2879 +    return false;
  2.2880  
  2.2881 -	truncate_movie(Movie.currentFrame);
  2.2882 -	change_state(MOVIE_STATE_END);
  2.2883 -	systemScreenMessage("Movie truncated");
  2.2884 +  truncate_movie(Movie.currentFrame);
  2.2885 +  change_state(MOVIE_STATE_END);
  2.2886 +  systemScreenMessage("Movie truncated");
  2.2887  
  2.2888 -	return true;
  2.2889 +  return true;
  2.2890  }
  2.2891  
  2.2892  bool VBAMovieFixHeader()
  2.2893  {
  2.2894 -	if (!VBAMovieActive())
  2.2895 -		return false;
  2.2896 +  if (!VBAMovieActive())
  2.2897 +    return false;
  2.2898  
  2.2899 -	flush_movie_header();
  2.2900 -	systemScreenMessage("Movie header fixed");
  2.2901 -	return true;
  2.2902 +  flush_movie_header();
  2.2903 +  systemScreenMessage("Movie header fixed");
  2.2904 +  return true;
  2.2905  }
     3.1 --- a/src/gb/GB.cpp	Sun Mar 04 22:44:42 2012 -0600
     3.2 +++ b/src/gb/GB.cpp	Mon Mar 05 01:25:11 2012 -0600
     3.3 @@ -163,361 +163,361 @@
     3.4  static bool pauseAfterFrameAdvance = false;
     3.5  
     3.6  int32 gbRomSizes[] = { 0x00008000, // 32K
     3.7 -	                   0x00010000, // 64K
     3.8 -	                   0x00020000, // 128K
     3.9 -	                   0x00040000, // 256K
    3.10 -	                   0x00080000, // 512K
    3.11 -	                   0x00100000, // 1024K
    3.12 -	                   0x00200000, // 2048K
    3.13 -	                   0x00400000, // 4096K
    3.14 -	                   0x00800000 // 8192K
    3.15 +		       0x00010000, // 64K
    3.16 +		       0x00020000, // 128K
    3.17 +		       0x00040000, // 256K
    3.18 +		       0x00080000, // 512K
    3.19 +		       0x00100000, // 1024K
    3.20 +		       0x00200000, // 2048K
    3.21 +		       0x00400000, // 4096K
    3.22 +		       0x00800000 // 8192K
    3.23  };
    3.24  int32 gbRomSizesMasks[] = { 0x00007fff,
    3.25 -	                        0x0000ffff,
    3.26 -	                        0x0001ffff,
    3.27 -	                        0x0003ffff,
    3.28 -	                        0x0007ffff,
    3.29 -	                        0x000fffff,
    3.30 -	                        0x001fffff,
    3.31 -	                        0x003fffff,
    3.32 -	                        0x007fffff };
    3.33 +			    0x0000ffff,
    3.34 +			    0x0001ffff,
    3.35 +			    0x0003ffff,
    3.36 +			    0x0007ffff,
    3.37 +			    0x000fffff,
    3.38 +			    0x001fffff,
    3.39 +			    0x003fffff,
    3.40 +			    0x007fffff };
    3.41  
    3.42  int32 gbRamSizes[6] = { 0x00000000, // 0K
    3.43 -	                    0x00000800, // 2K
    3.44 -	                    0x00002000, // 8K
    3.45 -	                    0x00008000, // 32K
    3.46 -	                    0x00020000, // 128K
    3.47 -	                    0x00010000 // 64K
    3.48 +			0x00000800, // 2K
    3.49 +			0x00002000, // 8K
    3.50 +			0x00008000, // 32K
    3.51 +			0x00020000, // 128K
    3.52 +			0x00010000 // 64K
    3.53  };
    3.54  
    3.55  int32 gbRamSizesMasks[6] = { 0x00000000,
    3.56 -	                         0x000007ff,
    3.57 -	                         0x00001fff,
    3.58 -	                         0x00007fff,
    3.59 -	                         0x0001ffff,
    3.60 -	                         0x0000ffff };
    3.61 +			     0x000007ff,
    3.62 +			     0x00001fff,
    3.63 +			     0x00007fff,
    3.64 +			     0x0001ffff,
    3.65 +			     0x0000ffff };
    3.66  
    3.67  int32 gbCycles[] =
    3.68 -{
    3.69 -//  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    3.70 -	1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1,  // 0
    3.71 -	1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1,  // 1
    3.72 -	2, 3, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 1, 1, 2, 1,  // 2
    3.73 -	2, 3, 2, 2, 3, 3, 3, 1, 2, 2, 2, 2, 1, 1, 2, 1,  // 3
    3.74 -	1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 4
    3.75 -	1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 5
    3.76 -	1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 6
    3.77 -	2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1,  // 7
    3.78 -	1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 8
    3.79 -	1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 9
    3.80 -	1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // a
    3.81 -	1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // b
    3.82 -	2, 3, 3, 4, 3, 4, 2, 4, 2, 4, 3, 2, 3, 6, 2, 4,  // c
    3.83 -	2, 3, 3, 0, 3, 4, 2, 4, 2, 4, 3, 0, 3, 0, 2, 4,  // d
    3.84 -	3, 3, 2, 0, 0, 4, 2, 4, 4, 1, 4, 0, 0, 0, 2, 4,  // e
    3.85 -	3, 3, 2, 1, 0, 4, 2, 4, 3, 2, 4, 1, 0, 0, 2, 4   // f
    3.86 -};
    3.87 +  {
    3.88 +    //  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    3.89 +    1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1,  // 0
    3.90 +    1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1,  // 1
    3.91 +    2, 3, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 1, 1, 2, 1,  // 2
    3.92 +    2, 3, 2, 2, 3, 3, 3, 1, 2, 2, 2, 2, 1, 1, 2, 1,  // 3
    3.93 +    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 4
    3.94 +    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 5
    3.95 +    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 6
    3.96 +    2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1,  // 7
    3.97 +    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 8
    3.98 +    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 9
    3.99 +    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // a
   3.100 +    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // b
   3.101 +    2, 3, 3, 4, 3, 4, 2, 4, 2, 4, 3, 2, 3, 6, 2, 4,  // c
   3.102 +    2, 3, 3, 0, 3, 4, 2, 4, 2, 4, 3, 0, 3, 0, 2, 4,  // d
   3.103 +    3, 3, 2, 0, 0, 4, 2, 4, 4, 1, 4, 0, 0, 0, 2, 4,  // e
   3.104 +    3, 3, 2, 1, 0, 4, 2, 4, 3, 2, 4, 1, 0, 0, 2, 4   // f
   3.105 +  };
   3.106  
   3.107  int32 gbCyclesCB[] =
   3.108 -{
   3.109 -//  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
   3.110 -	2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 0
   3.111 -	2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 1
   3.112 -	2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 2
   3.113 -	2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 3
   3.114 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 4
   3.115 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 5
   3.116 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 6
   3.117 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 7
   3.118 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 8
   3.119 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 9
   3.120 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // a
   3.121 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // b
   3.122 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // c
   3.123 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // d
   3.124 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // e
   3.125 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2   // f
   3.126 -};
   3.127 +  {
   3.128 +    //  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
   3.129 +    2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 0
   3.130 +    2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 1
   3.131 +    2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 2
   3.132 +    2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 3
   3.133 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 4
   3.134 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 5
   3.135 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 6
   3.136 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 7
   3.137 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 8
   3.138 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 9
   3.139 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // a
   3.140 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // b
   3.141 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // c
   3.142 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // d
   3.143 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // e
   3.144 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2   // f
   3.145 +  };
   3.146  
   3.147  u16 DAATable[] =
   3.148 -{
   3.149 -	0x0080, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700,
   3.150 -	0x0800, 0x0900, 0x1020, 0x1120, 0x1220, 0x1320, 0x1420, 0x1520,
   3.151 -	0x1000, 0x1100, 0x1200, 0x1300, 0x1400, 0x1500, 0x1600, 0x1700,
   3.152 -	0x1800, 0x1900, 0x2020, 0x2120, 0x2220, 0x2320, 0x2420, 0x2520,
   3.153 -	0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x2600, 0x2700,
   3.154 -	0x2800, 0x2900, 0x3020, 0x3120, 0x3220, 0x3320, 0x3420, 0x3520,
   3.155 -	0x3000, 0x3100, 0x3200, 0x3300, 0x3400, 0x3500, 0x3600, 0x3700,
   3.156 -	0x3800, 0x3900, 0x4020, 0x4120, 0x4220, 0x4320, 0x4420, 0x4520,
   3.157 -	0x4000, 0x4100, 0x4200, 0x4300, 0x4400, 0x4500, 0x4600, 0x4700,
   3.158 -	0x4800, 0x4900, 0x5020, 0x5120, 0x5220, 0x5320, 0x5420, 0x5520,
   3.159 -	0x5000, 0x5100, 0x5200, 0x5300, 0x5400, 0x5500, 0x5600, 0x5700,
   3.160 -	0x5800, 0x5900, 0x6020, 0x6120, 0x6220, 0x6320, 0x6420, 0x6520,
   3.161 -	0x6000, 0x6100, 0x6200, 0x6300, 0x6400, 0x6500, 0x6600, 0x6700,
   3.162 -	0x6800, 0x6900, 0x7020, 0x7120, 0x7220, 0x7320, 0x7420, 0x7520,
   3.163 -	0x7000, 0x7100, 0x7200, 0x7300, 0x7400, 0x7500, 0x7600, 0x7700,
   3.164 -	0x7800, 0x7900, 0x8020, 0x8120, 0x8220, 0x8320, 0x8420, 0x8520,
   3.165 -	0x8000, 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700,
   3.166 -	0x8800, 0x8900, 0x9020, 0x9120, 0x9220, 0x9320, 0x9420, 0x9520,
   3.167 -	0x9000, 0x9100, 0x9200, 0x9300, 0x9400, 0x9500, 0x9600, 0x9700,
   3.168 -	0x9800, 0x9900, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   3.169 -	0x0090, 0x0110, 0x0210, 0x0310, 0x0410, 0x0510, 0x0610, 0x0710,
   3.170 -	0x0810, 0x0910, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   3.171 -	0x1010, 0x1110, 0x1210, 0x1310, 0x1410, 0x1510, 0x1610, 0x1710,
   3.172 -	0x1810, 0x1910, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   3.173 -	0x2010, 0x2110, 0x2210, 0x2310, 0x2410, 0x2510, 0x2610, 0x2710,
   3.174 -	0x2810, 0x2910, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   3.175 -	0x3010, 0x3110, 0x3210, 0x3310, 0x3410, 0x3510, 0x3610, 0x3710,
   3.176 -	0x3810, 0x3910, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   3.177 -	0x4010, 0x4110, 0x4210, 0x4310, 0x4410, 0x4510, 0x4610, 0x4710,
   3.178 -	0x4810, 0x4910, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   3.179 -	0x5010, 0x5110, 0x5210, 0x5310, 0x5410, 0x5510, 0x5610, 0x5710,
   3.180 -	0x5810, 0x5910, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   3.181 -	0x6010, 0x6110, 0x6210, 0x6310, 0x6410, 0x6510, 0x6610, 0x6710,
   3.182 -	0x6810, 0x6910, 0x7030, 0x7130, 0x7230, 0x7330, 0x7430, 0x7530,
   3.183 -	0x7010, 0x7110, 0x7210, 0x7310, 0x7410, 0x7510, 0x7610, 0x7710,
   3.184 -	0x7810, 0x7910, 0x8030, 0x8130, 0x8230, 0x8330, 0x8430, 0x8530,
   3.185 -	0x8010, 0x8110, 0x8210, 0x8310, 0x8410, 0x8510, 0x8610, 0x8710,
   3.186 -	0x8810, 0x8910, 0x9030, 0x9130, 0x9230, 0x9330, 0x9430, 0x9530,
   3.187 -	0x9010, 0x9110, 0x9210, 0x9310, 0x9410, 0x9510, 0x9610, 0x9710,
   3.188 -	0x9810, 0x9910, 0xA030, 0xA130, 0xA230, 0xA330, 0xA430, 0xA530,
   3.189 -	0xA010, 0xA110, 0xA210, 0xA310, 0xA410, 0xA510, 0xA610, 0xA710,
   3.190 -	0xA810, 0xA910, 0xB030, 0xB130, 0xB230, 0xB330, 0xB430, 0xB530,
   3.191 -	0xB010, 0xB110, 0xB210, 0xB310, 0xB410, 0xB510, 0xB610, 0xB710,
   3.192 -	0xB810, 0xB910, 0xC030, 0xC130, 0xC230, 0xC330, 0xC430, 0xC530,
   3.193 -	0xC010, 0xC110, 0xC210, 0xC310, 0xC410, 0xC510, 0xC610, 0xC710,
   3.194 -	0xC810, 0xC910, 0xD030, 0xD130, 0xD230, 0xD330, 0xD430, 0xD530,
   3.195 -	0xD010, 0xD110, 0xD210, 0xD310, 0xD410, 0xD510, 0xD610, 0xD710,
   3.196 -	0xD810, 0xD910, 0xE030, 0xE130, 0xE230, 0xE330, 0xE430, 0xE530,
   3.197 -	0xE010, 0xE110, 0xE210, 0xE310, 0xE410, 0xE510, 0xE610, 0xE710,
   3.198 -	0xE810, 0xE910, 0xF030, 0xF130, 0xF230, 0xF330, 0xF430, 0xF530,
   3.199 -	0xF010, 0xF110, 0xF210, 0xF310, 0xF410, 0xF510, 0xF610, 0xF710,
   3.200 -	0xF810, 0xF910, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   3.201 -	0x0090, 0x0110, 0x0210, 0x0310, 0x0410, 0x0510, 0x0610, 0x0710,
   3.202 -	0x0810, 0x0910, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   3.203 -	0x1010, 0x1110, 0x1210, 0x1310, 0x1410, 0x1510, 0x1610, 0x1710,
   3.204 -	0x1810, 0x1910, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   3.205 -	0x2010, 0x2110, 0x2210, 0x2310, 0x2410, 0x2510, 0x2610, 0x2710,
   3.206 -	0x2810, 0x2910, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   3.207 -	0x3010, 0x3110, 0x3210, 0x3310, 0x3410, 0x3510, 0x3610, 0x3710,
   3.208 -	0x3810, 0x3910, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   3.209 -	0x4010, 0x4110, 0x4210, 0x4310, 0x4410, 0x4510, 0x4610, 0x4710,
   3.210 -	0x4810, 0x4910, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   3.211 -	0x5010, 0x5110, 0x5210, 0x5310, 0x5410, 0x5510, 0x5610, 0x5710,
   3.212 -	0x5810, 0x5910, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   3.213 -	0x0600, 0x0700, 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00,
   3.214 -	0x0E00, 0x0F00, 0x1020, 0x1120, 0x1220, 0x1320, 0x1420, 0x1520,
   3.215 -	0x1600, 0x1700, 0x1800, 0x1900, 0x1A00, 0x1B00, 0x1C00, 0x1D00,
   3.216 -	0x1E00, 0x1F00, 0x2020, 0x2120, 0x2220, 0x2320, 0x2420, 0x2520,
   3.217 -	0x2600, 0x2700, 0x2800, 0x2900, 0x2A00, 0x2B00, 0x2C00, 0x2D00,
   3.218 -	0x2E00, 0x2F00, 0x3020, 0x3120, 0x3220, 0x3320, 0x3420, 0x3520,
   3.219 -	0x3600, 0x3700, 0x3800, 0x3900, 0x3A00, 0x3B00, 0x3C00, 0x3D00,
   3.220 -	0x3E00, 0x3F00, 0x4020, 0x4120, 0x4220, 0x4320, 0x4420, 0x4520,
   3.221 -	0x4600, 0x4700, 0x4800, 0x4900, 0x4A00, 0x4B00, 0x4C00, 0x4D00,
   3.222 -	0x4E00, 0x4F00, 0x5020, 0x5120, 0x5220, 0x5320, 0x5420, 0x5520,
   3.223 -	0x5600, 0x5700, 0x5800, 0x5900, 0x5A00, 0x5B00, 0x5C00, 0x5D00,
   3.224 -	0x5E00, 0x5F00, 0x6020, 0x6120, 0x6220, 0x6320, 0x6420, 0x6520,
   3.225 -	0x6600, 0x6700, 0x6800, 0x6900, 0x6A00, 0x6B00, 0x6C00, 0x6D00,
   3.226 -	0x6E00, 0x6F00, 0x7020, 0x7120, 0x7220, 0x7320, 0x7420, 0x7520,
   3.227 -	0x7600, 0x7700, 0x7800, 0x7900, 0x7A00, 0x7B00, 0x7C00, 0x7D00,
   3.228 -	0x7E00, 0x7F00, 0x8020, 0x8120, 0x8220, 0x8320, 0x8420, 0x8520,
   3.229 -	0x8600, 0x8700, 0x8800, 0x8900, 0x8A00, 0x8B00, 0x8C00, 0x8D00,
   3.230 -	0x8E00, 0x8F00, 0x9020, 0x9120, 0x9220, 0x9320, 0x9420, 0x9520,
   3.231 -	0x9600, 0x9700, 0x9800, 0x9900, 0x9A00, 0x9B00, 0x9C00, 0x9D00,
   3.232 -	0x9E00, 0x9F00, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   3.233 -	0x0610, 0x0710, 0x0810, 0x0910, 0x0A10, 0x0B10, 0x0C10, 0x0D10,
   3.234 -	0x0E10, 0x0F10, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   3.235 -	0x1610, 0x1710, 0x1810, 0x1910, 0x1A10, 0x1B10, 0x1C10, 0x1D10,
   3.236 -	0x1E10, 0x1F10, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   3.237 -	0x2610, 0x2710, 0x2810, 0x2910, 0x2A10, 0x2B10, 0x2C10, 0x2D10,
   3.238 -	0x2E10, 0x2F10, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   3.239 -	0x3610, 0x3710, 0x3810, 0x3910, 0x3A10, 0x3B10, 0x3C10, 0x3D10,
   3.240 -	0x3E10, 0x3F10, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   3.241 -	0x4610, 0x4710, 0x4810, 0x4910, 0x4A10, 0x4B10, 0x4C10, 0x4D10,
   3.242 -	0x4E10, 0x4F10, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   3.243 -	0x5610, 0x5710, 0x5810, 0x5910, 0x5A10, 0x5B10, 0x5C10, 0x5D10,
   3.244 -	0x5E10, 0x5F10, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   3.245 -	0x6610, 0x6710, 0x6810, 0x6910, 0x6A10, 0x6B10, 0x6C10, 0x6D10,
   3.246 -	0x6E10, 0x6F10, 0x7030, 0x7130, 0x7230, 0x7330, 0x7430, 0x7530,
   3.247 -	0x7610, 0x7710, 0x7810, 0x7910, 0x7A10, 0x7B10, 0x7C10, 0x7D10,
   3.248 -	0x7E10, 0x7F10, 0x8030, 0x8130, 0x8230, 0x8330, 0x8430, 0x8530,
   3.249 -	0x8610, 0x8710, 0x8810, 0x8910, 0x8A10, 0x8B10, 0x8C10, 0x8D10,
   3.250 -	0x8E10, 0x8F10, 0x9030, 0x9130, 0x9230, 0x9330, 0x9430, 0x9530,
   3.251 -	0x9610, 0x9710, 0x9810, 0x9910, 0x9A10, 0x9B10, 0x9C10, 0x9D10,
   3.252 -	0x9E10, 0x9F10, 0xA030, 0xA130, 0xA230, 0xA330, 0xA430, 0xA530,
   3.253 -	0xA610, 0xA710, 0xA810, 0xA910, 0xAA10, 0xAB10, 0xAC10, 0xAD10,
   3.254 -	0xAE10, 0xAF10, 0xB030, 0xB130, 0xB230, 0xB330, 0xB430, 0xB530,
   3.255 -	0xB610, 0xB710, 0xB810, 0xB910, 0xBA10, 0xBB10, 0xBC10, 0xBD10,
   3.256 -	0xBE10, 0xBF10, 0xC030, 0xC130, 0xC230, 0xC330, 0xC430, 0xC530,
   3.257 -	0xC610, 0xC710, 0xC810, 0xC910, 0xCA10, 0xCB10, 0xCC10, 0xCD10,
   3.258 -	0xCE10, 0xCF10, 0xD030, 0xD130, 0xD230, 0xD330, 0xD430, 0xD530,
   3.259 -	0xD610, 0xD710, 0xD810, 0xD910, 0xDA10, 0xDB10, 0xDC10, 0xDD10,
   3.260 -	0xDE10, 0xDF10, 0xE030, 0xE130, 0xE230, 0xE330, 0xE430, 0xE530,
   3.261 -	0xE610, 0xE710, 0xE810, 0xE910, 0xEA10, 0xEB10, 0xEC10, 0xED10,
   3.262 -	0xEE10, 0xEF10, 0xF030, 0xF130, 0xF230, 0xF330, 0xF430, 0xF530,
   3.263 -	0xF610, 0xF710, 0xF810, 0xF910, 0xFA10, 0xFB10, 0xFC10, 0xFD10,
   3.264 -	0xFE10, 0xFF10, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   3.265 -	0x0610, 0x0710, 0x0810, 0x0910, 0x0A10, 0x0B10, 0x0C10, 0x0D10,
   3.266 -	0x0E10, 0x0F10, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   3.267 -	0x1610, 0x1710, 0x1810, 0x1910, 0x1A10, 0x1B10, 0x1C10, 0x1D10,
   3.268 -	0x1E10, 0x1F10, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   3.269 -	0x2610, 0x2710, 0x2810, 0x2910, 0x2A10, 0x2B10, 0x2C10, 0x2D10,
   3.270 -	0x2E10, 0x2F10, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   3.271 -	0x3610, 0x3710, 0x3810, 0x3910, 0x3A10, 0x3B10, 0x3C10, 0x3D10,
   3.272 -	0x3E10, 0x3F10, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   3.273 -	0x4610, 0x4710, 0x4810, 0x4910, 0x4A10, 0x4B10, 0x4C10, 0x4D10,
   3.274 -	0x4E10, 0x4F10, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   3.275 -	0x5610, 0x5710, 0x5810, 0x5910, 0x5A10, 0x5B10, 0x5C10, 0x5D10,
   3.276 -	0x5E10, 0x5F10, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   3.277 -	0x00C0, 0x0140, 0x0240, 0x0340, 0x0440, 0x0540, 0x0640, 0x0740,
   3.278 -	0x0840, 0x0940, 0x0440, 0x0540, 0x0640, 0x0740, 0x0840, 0x0940,
   3.279 -	0x1040, 0x1140, 0x1240, 0x1340, 0x1440, 0x1540, 0x1640, 0x1740,
   3.280 -	0x1840, 0x1940, 0x1440, 0x1540, 0x1640, 0x1740, 0x1840, 0x1940,
   3.281 -	0x2040, 0x2140, 0x2240, 0x2340, 0x2440, 0x2540, 0x2640, 0x2740,
   3.282 -	0x2840, 0x2940, 0x2440, 0x2540, 0x2640, 0x2740, 0x2840, 0x2940,
   3.283 -	0x3040, 0x3140, 0x3240, 0x3340, 0x3440, 0x3540, 0x3640, 0x3740,
   3.284 -	0x3840, 0x3940, 0x3440, 0x3540, 0x3640, 0x3740, 0x3840, 0x3940,
   3.285 -	0x4040, 0x4140, 0x4240, 0x4340, 0x4440, 0x4540, 0x4640, 0x4740,
   3.286 -	0x4840, 0x4940, 0x4440, 0x4540, 0x4640, 0x4740, 0x4840, 0x4940,
   3.287 -	0x5040, 0x5140, 0x5240, 0x5340, 0x5440, 0x5540, 0x5640, 0x5740,
   3.288 -	0x5840, 0x5940, 0x5440, 0x5540, 0x5640, 0x5740, 0x5840, 0x5940,
   3.289 -	0x6040, 0x6140, 0x6240, 0x6340, 0x6440, 0x6540, 0x6640, 0x6740,
   3.290 -	0x6840, 0x6940, 0x6440, 0x6540, 0x6640, 0x6740, 0x6840, 0x6940,
   3.291 -	0x7040, 0x7140, 0x7240, 0x7340, 0x7440, 0x7540, 0x7640, 0x7740,
   3.292 -	0x7840, 0x7940, 0x7440, 0x7540, 0x7640, 0x7740, 0x7840, 0x7940,
   3.293 -	0x8040, 0x8140, 0x8240, 0x8340, 0x8440, 0x8540, 0x8640, 0x8740,
   3.294 -	0x8840, 0x8940, 0x8440, 0x8540, 0x8640, 0x8740, 0x8840, 0x8940,
   3.295 -	0x9040, 0x9140, 0x9240, 0x9340, 0x9440, 0x9540, 0x9640, 0x9740,
   3.296 -	0x9840, 0x9940, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   3.297 -	0x4050, 0x4150, 0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750,
   3.298 -	0x4850, 0x4950, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   3.299 -	0x5050, 0x5150, 0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750,
   3.300 -	0x5850, 0x5950, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   3.301 -	0x6050, 0x6150, 0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750,
   3.302 -	0x6850, 0x6950, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   3.303 -	0x7050, 0x7150, 0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750,
   3.304 -	0x7850, 0x7950, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   3.305 -	0x8050, 0x8150, 0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750,
   3.306 -	0x8850, 0x8950, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   3.307 -	0x9050, 0x9150, 0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750,
   3.308 -	0x9850, 0x9950, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   3.309 -	0xA050, 0xA150, 0xA250, 0xA350, 0xA450, 0xA550, 0xA650, 0xA750,
   3.310 -	0xA850, 0xA950, 0xA450, 0xA550, 0xA650, 0xA750, 0xA850, 0xA950,
   3.311 -	0xB050, 0xB150, 0xB250, 0xB350, 0xB450, 0xB550, 0xB650, 0xB750,
   3.312 -	0xB850, 0xB950, 0xB450, 0xB550, 0xB650, 0xB750, 0xB850, 0xB950,
   3.313 -	0xC050, 0xC150, 0xC250, 0xC350, 0xC450, 0xC550, 0xC650, 0xC750,
   3.314 -	0xC850, 0xC950, 0xC450, 0xC550, 0xC650, 0xC750, 0xC850, 0xC950,
   3.315 -	0xD050, 0xD150, 0xD250, 0xD350, 0xD450, 0xD550, 0xD650, 0xD750,
   3.316 -	0xD850, 0xD950, 0xD450, 0xD550, 0xD650, 0xD750, 0xD850, 0xD950,
   3.317 -	0xE050, 0xE150, 0xE250, 0xE350, 0xE450, 0xE550, 0xE650, 0xE750,
   3.318 -	0xE850, 0xE950, 0xE450, 0xE550, 0xE650, 0xE750, 0xE850, 0xE950,
   3.319 -	0xF050, 0xF150, 0xF250, 0xF350, 0xF450, 0xF550, 0xF650, 0xF750,
   3.320 -	0xF850, 0xF950, 0xF450, 0xF550, 0xF650, 0xF750, 0xF850, 0xF950,
   3.321 -	0x00D0, 0x0150, 0x0250, 0x0350, 0x0450, 0x0550, 0x0650, 0x0750,
   3.322 -	0x0850, 0x0950, 0x0450, 0x0550, 0x0650, 0x0750, 0x0850, 0x0950,
   3.323 -	0x1050, 0x1150, 0x1250, 0x1350, 0x1450, 0x1550, 0x1650, 0x1750,
   3.324 -	0x1850, 0x1950, 0x1450, 0x1550, 0x1650, 0x1750, 0x1850, 0x1950,
   3.325 -	0x2050, 0x2150, 0x2250, 0x2350, 0x2450, 0x2550, 0x2650, 0x2750,
   3.326 -	0x2850, 0x2950, 0x2450, 0x2550, 0x2650, 0x2750, 0x2850, 0x2950,
   3.327 -	0x3050, 0x3150, 0x3250, 0x3350, 0x3450, 0x3550, 0x3650, 0x3750,
   3.328 -	0x3850, 0x3950, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   3.329 -	0x4050, 0x4150, 0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750,
   3.330 -	0x4850, 0x4950, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   3.331 -	0x5050, 0x5150, 0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750,
   3.332 -	0x5850, 0x5950, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   3.333 -	0x6050, 0x6150, 0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750,
   3.334 -	0x6850, 0x6950, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   3.335 -	0x7050, 0x7150, 0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750,
   3.336 -	0x7850, 0x7950, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   3.337 -	0x8050, 0x8150, 0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750,
   3.338 -	0x8850, 0x8950, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   3.339 -	0x9050, 0x9150, 0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750,
   3.340 -	0x9850, 0x9950, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   3.341 -	0xFA60, 0xFB60, 0xFC60, 0xFD60, 0xFE60, 0xFF60, 0x00C0, 0x0140,
   3.342 -	0x0240, 0x0340, 0x0440, 0x0540, 0x0640, 0x0740, 0x0840, 0x0940,
   3.343 -	0x0A60, 0x0B60, 0x0C60, 0x0D60, 0x0E60, 0x0F60, 0x1040, 0x1140,
   3.344 -	0x1240, 0x1340, 0x1440, 0x1540, 0x1640, 0x1740, 0x1840, 0x1940,
   3.345 -	0x1A60, 0x1B60, 0x1C60, 0x1D60, 0x1E60, 0x1F60, 0x2040, 0x2140,
   3.346 -	0x2240, 0x2340, 0x2440, 0x2540, 0x2640, 0x2740, 0x2840, 0x2940,
   3.347 -	0x2A60, 0x2B60, 0x2C60, 0x2D60, 0x2E60, 0x2F60, 0x3040, 0x3140,
   3.348 -	0x3240, 0x3340, 0x3440, 0x3540, 0x3640, 0x3740, 0x3840, 0x3940,
   3.349 -	0x3A60, 0x3B60, 0x3C60, 0x3D60, 0x3E60, 0x3F60, 0x4040, 0x4140,
   3.350 -	0x4240, 0x4340, 0x4440, 0x4540, 0x4640, 0x4740, 0x4840, 0x4940,
   3.351 -	0x4A60, 0x4B60, 0x4C60, 0x4D60, 0x4E60, 0x4F60, 0x5040, 0x5140,
   3.352 -	0x5240, 0x5340, 0x5440, 0x5540, 0x5640, 0x5740, 0x5840, 0x5940,
   3.353 -	0x5A60, 0x5B60, 0x5C60, 0x5D60, 0x5E60, 0x5F60, 0x6040, 0x6140,
   3.354 -	0x6240, 0x6340, 0x6440, 0x6540, 0x6640, 0x6740, 0x6840, 0x6940,
   3.355 -	0x6A60, 0x6B60, 0x6C60, 0x6D60, 0x6E60, 0x6F60, 0x7040, 0x7140,
   3.356 -	0x7240, 0x7340, 0x7440, 0x7540, 0x7640, 0x7740, 0x7840, 0x7940,
   3.357 -	0x7A60, 0x7B60, 0x7C60, 0x7D60, 0x7E60, 0x7F60, 0x8040, 0x8140,
   3.358 -	0x8240, 0x8340, 0x8440, 0x8540, 0x8640, 0x8740, 0x8840, 0x8940,
   3.359 -	0x8A60, 0x8B60, 0x8C60, 0x8D60, 0x8E60, 0x8F60, 0x9040, 0x9140,
   3.360 -	0x9240, 0x9340, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   3.361 -	0x3A70, 0x3B70, 0x3C70, 0x3D70, 0x3E70, 0x3F70, 0x4050, 0x4150,
   3.362 -	0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   3.363 -	0x4A70, 0x4B70, 0x4C70, 0x4D70, 0x4E70, 0x4F70, 0x5050, 0x5150,
   3.364 -	0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   3.365 -	0x5A70, 0x5B70, 0x5C70, 0x5D70, 0x5E70, 0x5F70, 0x6050, 0x6150,
   3.366 -	0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   3.367 -	0x6A70, 0x6B70, 0x6C70, 0x6D70, 0x6E70, 0x6F70, 0x7050, 0x7150,
   3.368 -	0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   3.369 -	0x7A70, 0x7B70, 0x7C70, 0x7D70, 0x7E70, 0x7F70, 0x8050, 0x8150,
   3.370 -	0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   3.371 -	0x8A70, 0x8B70, 0x8C70, 0x8D70, 0x8E70, 0x8F70, 0x9050, 0x9150,
   3.372 -	0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   3.373 -	0x9A70, 0x9B70, 0x9C70, 0x9D70, 0x9E70, 0x9F70, 0xA050, 0xA150,
   3.374 -	0xA250, 0xA350, 0xA450, 0xA550, 0xA650, 0xA750, 0xA850, 0xA950,
   3.375 -	0xAA70, 0xAB70, 0xAC70, 0xAD70, 0xAE70, 0xAF70, 0xB050, 0xB150,
   3.376 -	0xB250, 0xB350, 0xB450, 0xB550, 0xB650, 0xB750, 0xB850, 0xB950,
   3.377 -	0xBA70, 0xBB70, 0xBC70, 0xBD70, 0xBE70, 0xBF70, 0xC050, 0xC150,
   3.378 -	0xC250, 0xC350, 0xC450, 0xC550, 0xC650, 0xC750, 0xC850, 0xC950,
   3.379 -	0xCA70, 0xCB70, 0xCC70, 0xCD70, 0xCE70, 0xCF70, 0xD050, 0xD150,
   3.380 -	0xD250, 0xD350, 0xD450, 0xD550, 0xD650, 0xD750, 0xD850, 0xD950,
   3.381 -	0xDA70, 0xDB70, 0xDC70, 0xDD70, 0xDE70, 0xDF70, 0xE050, 0xE150,
   3.382 -	0xE250, 0xE350, 0xE450, 0xE550, 0xE650, 0xE750, 0xE850, 0xE950,
   3.383 -	0xEA70, 0xEB70, 0xEC70, 0xED70, 0xEE70, 0xEF70, 0xF050, 0xF150,
   3.384 -	0xF250, 0xF350, 0xF450, 0xF550, 0xF650, 0xF750, 0xF850, 0xF950,
   3.385 -	0xFA70, 0xFB70, 0xFC70, 0xFD70, 0xFE70, 0xFF70, 0x00D0, 0x0150,
   3.386 -	0x0250, 0x0350, 0x0450, 0x0550, 0x0650, 0x0750, 0x0850, 0x0950,
   3.387 -	0x0A70, 0x0B70, 0x0C70, 0x0D70, 0x0E70, 0x0F70, 0x1050, 0x1150,
   3.388 -	0x1250, 0x1350, 0x1450, 0x1550, 0x1650, 0x1750, 0x1850, 0x1950,
   3.389 -	0x1A70, 0x1B70, 0x1C70, 0x1D70, 0x1E70, 0x1F70, 0x2050, 0x2150,
   3.390 -	0x2250, 0x2350, 0x2450, 0x2550, 0x2650, 0x2750, 0x2850, 0x2950,
   3.391 -	0x2A70, 0x2B70, 0x2C70, 0x2D70, 0x2E70, 0x2F70, 0x3050, 0x3150,
   3.392 -	0x3250, 0x3350, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   3.393 -	0x3A70, 0x3B70, 0x3C70, 0x3D70, 0x3E70, 0x3F70, 0x4050, 0x4150,
   3.394 -	0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   3.395 -	0x4A70, 0x4B70, 0x4C70, 0x4D70, 0x4E70, 0x4F70, 0x5050, 0x5150,
   3.396 -	0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   3.397 -	0x5A70, 0x5B70, 0x5C70, 0x5D70, 0x5E70, 0x5F70, 0x6050, 0x6150,
   3.398 -	0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   3.399 -	0x6A70, 0x6B70, 0x6C70, 0x6D70, 0x6E70, 0x6F70, 0x7050, 0x7150,
   3.400 -	0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   3.401 -	0x7A70, 0x7B70, 0x7C70, 0x7D70, 0x7E70, 0x7F70, 0x8050, 0x8150,
   3.402 -	0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   3.403 -	0x8A70, 0x8B70, 0x8C70, 0x8D70, 0x8E70, 0x8F70, 0x9050, 0x9150,
   3.404 -	0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   3.405 -};
   3.406 +  {
   3.407 +    0x0080, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700,
   3.408 +    0x0800, 0x0900, 0x1020, 0x1120, 0x1220, 0x1320, 0x1420, 0x1520,
   3.409 +    0x1000, 0x1100, 0x1200, 0x1300, 0x1400, 0x1500, 0x1600, 0x1700,
   3.410 +    0x1800, 0x1900, 0x2020, 0x2120, 0x2220, 0x2320, 0x2420, 0x2520,
   3.411 +    0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x2600, 0x2700,
   3.412 +    0x2800, 0x2900, 0x3020, 0x3120, 0x3220, 0x3320, 0x3420, 0x3520,
   3.413 +    0x3000, 0x3100, 0x3200, 0x3300, 0x3400, 0x3500, 0x3600, 0x3700,
   3.414 +    0x3800, 0x3900, 0x4020, 0x4120, 0x4220, 0x4320, 0x4420, 0x4520,
   3.415 +    0x4000, 0x4100, 0x4200, 0x4300, 0x4400, 0x4500, 0x4600, 0x4700,
   3.416 +    0x4800, 0x4900, 0x5020, 0x5120, 0x5220, 0x5320, 0x5420, 0x5520,
   3.417 +    0x5000, 0x5100, 0x5200, 0x5300, 0x5400, 0x5500, 0x5600, 0x5700,
   3.418 +    0x5800, 0x5900, 0x6020, 0x6120, 0x6220, 0x6320, 0x6420, 0x6520,
   3.419 +    0x6000, 0x6100, 0x6200, 0x6300, 0x6400, 0x6500, 0x6600, 0x6700,
   3.420 +    0x6800, 0x6900, 0x7020, 0x7120, 0x7220, 0x7320, 0x7420, 0x7520,
   3.421 +    0x7000, 0x7100, 0x7200, 0x7300, 0x7400, 0x7500, 0x7600, 0x7700,
   3.422 +    0x7800, 0x7900, 0x8020, 0x8120, 0x8220, 0x8320, 0x8420, 0x8520,
   3.423 +    0x8000, 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700,
   3.424 +    0x8800, 0x8900, 0x9020, 0x9120, 0x9220, 0x9320, 0x9420, 0x9520,
   3.425 +    0x9000, 0x9100, 0x9200, 0x9300, 0x9400, 0x9500, 0x9600, 0x9700,
   3.426 +    0x9800, 0x9900, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   3.427 +    0x0090, 0x0110, 0x0210, 0x0310, 0x0410, 0x0510, 0x0610, 0x0710,
   3.428 +    0x0810, 0x0910, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   3.429 +    0x1010, 0x1110, 0x1210, 0x1310, 0x1410, 0x1510, 0x1610, 0x1710,
   3.430 +    0x1810, 0x1910, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   3.431 +    0x2010, 0x2110, 0x2210, 0x2310, 0x2410, 0x2510, 0x2610, 0x2710,
   3.432 +    0x2810, 0x2910, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   3.433 +    0x3010, 0x3110, 0x3210, 0x3310, 0x3410, 0x3510, 0x3610, 0x3710,
   3.434 +    0x3810, 0x3910, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   3.435 +    0x4010, 0x4110, 0x4210, 0x4310, 0x4410, 0x4510, 0x4610, 0x4710,
   3.436 +    0x4810, 0x4910, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   3.437 +    0x5010, 0x5110, 0x5210, 0x5310, 0x5410, 0x5510, 0x5610, 0x5710,
   3.438 +    0x5810, 0x5910, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   3.439 +    0x6010, 0x6110, 0x6210, 0x6310, 0x6410, 0x6510, 0x6610, 0x6710,
   3.440 +    0x6810, 0x6910, 0x7030, 0x7130, 0x7230, 0x7330, 0x7430, 0x7530,
   3.441 +    0x7010, 0x7110, 0x7210, 0x7310, 0x7410, 0x7510, 0x7610, 0x7710,
   3.442 +    0x7810, 0x7910, 0x8030, 0x8130, 0x8230, 0x8330, 0x8430, 0x8530,
   3.443 +    0x8010, 0x8110, 0x8210, 0x8310, 0x8410, 0x8510, 0x8610, 0x8710,
   3.444 +    0x8810, 0x8910, 0x9030, 0x9130, 0x9230, 0x9330, 0x9430, 0x9530,
   3.445 +    0x9010, 0x9110, 0x9210, 0x9310, 0x9410, 0x9510, 0x9610, 0x9710,
   3.446 +    0x9810, 0x9910, 0xA030, 0xA130, 0xA230, 0xA330, 0xA430, 0xA530,
   3.447 +    0xA010, 0xA110, 0xA210, 0xA310, 0xA410, 0xA510, 0xA610, 0xA710,
   3.448 +    0xA810, 0xA910, 0xB030, 0xB130, 0xB230, 0xB330, 0xB430, 0xB530,
   3.449 +    0xB010, 0xB110, 0xB210, 0xB310, 0xB410, 0xB510, 0xB610, 0xB710,
   3.450 +    0xB810, 0xB910, 0xC030, 0xC130, 0xC230, 0xC330, 0xC430, 0xC530,
   3.451 +    0xC010, 0xC110, 0xC210, 0xC310, 0xC410, 0xC510, 0xC610, 0xC710,
   3.452 +    0xC810, 0xC910, 0xD030, 0xD130, 0xD230, 0xD330, 0xD430, 0xD530,
   3.453 +    0xD010, 0xD110, 0xD210, 0xD310, 0xD410, 0xD510, 0xD610, 0xD710,
   3.454 +    0xD810, 0xD910, 0xE030, 0xE130, 0xE230, 0xE330, 0xE430, 0xE530,
   3.455 +    0xE010, 0xE110, 0xE210, 0xE310, 0xE410, 0xE510, 0xE610, 0xE710,
   3.456 +    0xE810, 0xE910, 0xF030, 0xF130, 0xF230, 0xF330, 0xF430, 0xF530,
   3.457 +    0xF010, 0xF110, 0xF210, 0xF310, 0xF410, 0xF510, 0xF610, 0xF710,
   3.458 +    0xF810, 0xF910, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   3.459 +    0x0090, 0x0110, 0x0210, 0x0310, 0x0410, 0x0510, 0x0610, 0x0710,
   3.460 +    0x0810, 0x0910, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   3.461 +    0x1010, 0x1110, 0x1210, 0x1310, 0x1410, 0x1510, 0x1610, 0x1710,
   3.462 +    0x1810, 0x1910, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   3.463 +    0x2010, 0x2110, 0x2210, 0x2310, 0x2410, 0x2510, 0x2610, 0x2710,
   3.464 +    0x2810, 0x2910, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   3.465 +    0x3010, 0x3110, 0x3210, 0x3310, 0x3410, 0x3510, 0x3610, 0x3710,
   3.466 +    0x3810, 0x3910, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   3.467 +    0x4010, 0x4110, 0x4210, 0x4310, 0x4410, 0x4510, 0x4610, 0x4710,
   3.468 +    0x4810, 0x4910, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   3.469 +    0x5010, 0x5110, 0x5210, 0x5310, 0x5410, 0x5510, 0x5610, 0x5710,
   3.470 +    0x5810, 0x5910, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   3.471 +    0x0600, 0x0700, 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00,
   3.472 +    0x0E00, 0x0F00, 0x1020, 0x1120, 0x1220, 0x1320, 0x1420, 0x1520,
   3.473 +    0x1600, 0x1700, 0x1800, 0x1900, 0x1A00, 0x1B00, 0x1C00, 0x1D00,
   3.474 +    0x1E00, 0x1F00, 0x2020, 0x2120, 0x2220, 0x2320, 0x2420, 0x2520,
   3.475 +    0x2600, 0x2700, 0x2800, 0x2900, 0x2A00, 0x2B00, 0x2C00, 0x2D00,
   3.476 +    0x2E00, 0x2F00, 0x3020, 0x3120, 0x3220, 0x3320, 0x3420, 0x3520,
   3.477 +    0x3600, 0x3700, 0x3800, 0x3900, 0x3A00, 0x3B00, 0x3C00, 0x3D00,
   3.478 +    0x3E00, 0x3F00, 0x4020, 0x4120, 0x4220, 0x4320, 0x4420, 0x4520,
   3.479 +    0x4600, 0x4700, 0x4800, 0x4900, 0x4A00, 0x4B00, 0x4C00, 0x4D00,
   3.480 +    0x4E00, 0x4F00, 0x5020, 0x5120, 0x5220, 0x5320, 0x5420, 0x5520,
   3.481 +    0x5600, 0x5700, 0x5800, 0x5900, 0x5A00, 0x5B00, 0x5C00, 0x5D00,
   3.482 +    0x5E00, 0x5F00, 0x6020, 0x6120, 0x6220, 0x6320, 0x6420, 0x6520,
   3.483 +    0x6600, 0x6700, 0x6800, 0x6900, 0x6A00, 0x6B00, 0x6C00, 0x6D00,
   3.484 +    0x6E00, 0x6F00, 0x7020, 0x7120, 0x7220, 0x7320, 0x7420, 0x7520,
   3.485 +    0x7600, 0x7700, 0x7800, 0x7900, 0x7A00, 0x7B00, 0x7C00, 0x7D00,
   3.486 +    0x7E00, 0x7F00, 0x8020, 0x8120, 0x8220, 0x8320, 0x8420, 0x8520,
   3.487 +    0x8600, 0x8700, 0x8800, 0x8900, 0x8A00, 0x8B00, 0x8C00, 0x8D00,
   3.488 +    0x8E00, 0x8F00, 0x9020, 0x9120, 0x9220, 0x9320, 0x9420, 0x9520,
   3.489 +    0x9600, 0x9700, 0x9800, 0x9900, 0x9A00, 0x9B00, 0x9C00, 0x9D00,
   3.490 +    0x9E00, 0x9F00, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   3.491 +    0x0610, 0x0710, 0x0810, 0x0910, 0x0A10, 0x0B10, 0x0C10, 0x0D10,
   3.492 +    0x0E10, 0x0F10, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   3.493 +    0x1610, 0x1710, 0x1810, 0x1910, 0x1A10, 0x1B10, 0x1C10, 0x1D10,
   3.494 +    0x1E10, 0x1F10, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   3.495 +    0x2610, 0x2710, 0x2810, 0x2910, 0x2A10, 0x2B10, 0x2C10, 0x2D10,
   3.496 +    0x2E10, 0x2F10, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   3.497 +    0x3610, 0x3710, 0x3810, 0x3910, 0x3A10, 0x3B10, 0x3C10, 0x3D10,
   3.498 +    0x3E10, 0x3F10, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   3.499 +    0x4610, 0x4710, 0x4810, 0x4910, 0x4A10, 0x4B10, 0x4C10, 0x4D10,
   3.500 +    0x4E10, 0x4F10, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   3.501 +    0x5610, 0x5710, 0x5810, 0x5910, 0x5A10, 0x5B10, 0x5C10, 0x5D10,
   3.502 +    0x5E10, 0x5F10, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   3.503 +    0x6610, 0x6710, 0x6810, 0x6910, 0x6A10, 0x6B10, 0x6C10, 0x6D10,
   3.504 +    0x6E10, 0x6F10, 0x7030, 0x7130, 0x7230, 0x7330, 0x7430, 0x7530,
   3.505 +    0x7610, 0x7710, 0x7810, 0x7910, 0x7A10, 0x7B10, 0x7C10, 0x7D10,
   3.506 +    0x7E10, 0x7F10, 0x8030, 0x8130, 0x8230, 0x8330, 0x8430, 0x8530,
   3.507 +    0x8610, 0x8710, 0x8810, 0x8910, 0x8A10, 0x8B10, 0x8C10, 0x8D10,
   3.508 +    0x8E10, 0x8F10, 0x9030, 0x9130, 0x9230, 0x9330, 0x9430, 0x9530,
   3.509 +    0x9610, 0x9710, 0x9810, 0x9910, 0x9A10, 0x9B10, 0x9C10, 0x9D10,
   3.510 +    0x9E10, 0x9F10, 0xA030, 0xA130, 0xA230, 0xA330, 0xA430, 0xA530,
   3.511 +    0xA610, 0xA710, 0xA810, 0xA910, 0xAA10, 0xAB10, 0xAC10, 0xAD10,
   3.512 +    0xAE10, 0xAF10, 0xB030, 0xB130, 0xB230, 0xB330, 0xB430, 0xB530,
   3.513 +    0xB610, 0xB710, 0xB810, 0xB910, 0xBA10, 0xBB10, 0xBC10, 0xBD10,
   3.514 +    0xBE10, 0xBF10, 0xC030, 0xC130, 0xC230, 0xC330, 0xC430, 0xC530,
   3.515 +    0xC610, 0xC710, 0xC810, 0xC910, 0xCA10, 0xCB10, 0xCC10, 0xCD10,
   3.516 +    0xCE10, 0xCF10, 0xD030, 0xD130, 0xD230, 0xD330, 0xD430, 0xD530,
   3.517 +    0xD610, 0xD710, 0xD810, 0xD910, 0xDA10, 0xDB10, 0xDC10, 0xDD10,
   3.518 +    0xDE10, 0xDF10, 0xE030, 0xE130, 0xE230, 0xE330, 0xE430, 0xE530,
   3.519 +    0xE610, 0xE710, 0xE810, 0xE910, 0xEA10, 0xEB10, 0xEC10, 0xED10,
   3.520 +    0xEE10, 0xEF10, 0xF030, 0xF130, 0xF230, 0xF330, 0xF430, 0xF530,
   3.521 +    0xF610, 0xF710, 0xF810, 0xF910, 0xFA10, 0xFB10, 0xFC10, 0xFD10,
   3.522 +    0xFE10, 0xFF10, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   3.523 +    0x0610, 0x0710, 0x0810, 0x0910, 0x0A10, 0x0B10, 0x0C10, 0x0D10,
   3.524 +    0x0E10, 0x0F10, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   3.525 +    0x1610, 0x1710, 0x1810, 0x1910, 0x1A10, 0x1B10, 0x1C10, 0x1D10,
   3.526 +    0x1E10, 0x1F10, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   3.527 +    0x2610, 0x2710, 0x2810, 0x2910, 0x2A10, 0x2B10, 0x2C10, 0x2D10,
   3.528 +    0x2E10, 0x2F10, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   3.529 +    0x3610, 0x3710, 0x3810, 0x3910, 0x3A10, 0x3B10, 0x3C10, 0x3D10,
   3.530 +    0x3E10, 0x3F10, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   3.531 +    0x4610, 0x4710, 0x4810, 0x4910, 0x4A10, 0x4B10, 0x4C10, 0x4D10,
   3.532 +    0x4E10, 0x4F10, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   3.533 +    0x5610, 0x5710, 0x5810, 0x5910, 0x5A10, 0x5B10, 0x5C10, 0x5D10,
   3.534 +    0x5E10, 0x5F10, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   3.535 +    0x00C0, 0x0140, 0x0240, 0x0340, 0x0440, 0x0540, 0x0640, 0x0740,
   3.536 +    0x0840, 0x0940, 0x0440, 0x0540, 0x0640, 0x0740, 0x0840, 0x0940,
   3.537 +    0x1040, 0x1140, 0x1240, 0x1340, 0x1440, 0x1540, 0x1640, 0x1740,
   3.538 +    0x1840, 0x1940, 0x1440, 0x1540, 0x1640, 0x1740, 0x1840, 0x1940,
   3.539 +    0x2040, 0x2140, 0x2240, 0x2340, 0x2440, 0x2540, 0x2640, 0x2740,
   3.540 +    0x2840, 0x2940, 0x2440, 0x2540, 0x2640, 0x2740, 0x2840, 0x2940,
   3.541 +    0x3040, 0x3140, 0x3240, 0x3340, 0x3440, 0x3540, 0x3640, 0x3740,
   3.542 +    0x3840, 0x3940, 0x3440, 0x3540, 0x3640, 0x3740, 0x3840, 0x3940,
   3.543 +    0x4040, 0x4140, 0x4240, 0x4340, 0x4440, 0x4540, 0x4640, 0x4740,
   3.544 +    0x4840, 0x4940, 0x4440, 0x4540, 0x4640, 0x4740, 0x4840, 0x4940,
   3.545 +    0x5040, 0x5140, 0x5240, 0x5340, 0x5440, 0x5540, 0x5640, 0x5740,
   3.546 +    0x5840, 0x5940, 0x5440, 0x5540, 0x5640, 0x5740, 0x5840, 0x5940,
   3.547 +    0x6040, 0x6140, 0x6240, 0x6340, 0x6440, 0x6540, 0x6640, 0x6740,
   3.548 +    0x6840, 0x6940, 0x6440, 0x6540, 0x6640, 0x6740, 0x6840, 0x6940,
   3.549 +    0x7040, 0x7140, 0x7240, 0x7340, 0x7440, 0x7540, 0x7640, 0x7740,
   3.550 +    0x7840, 0x7940, 0x7440, 0x7540, 0x7640, 0x7740, 0x7840, 0x7940,
   3.551 +    0x8040, 0x8140, 0x8240, 0x8340, 0x8440, 0x8540, 0x8640, 0x8740,
   3.552 +    0x8840, 0x8940, 0x8440, 0x8540, 0x8640, 0x8740, 0x8840, 0x8940,
   3.553 +    0x9040, 0x9140, 0x9240, 0x9340, 0x9440, 0x9540, 0x9640, 0x9740,
   3.554 +    0x9840, 0x9940, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   3.555 +    0x4050, 0x4150, 0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750,
   3.556 +    0x4850, 0x4950, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   3.557 +    0x5050, 0x5150, 0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750,
   3.558 +    0x5850, 0x5950, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   3.559 +    0x6050, 0x6150, 0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750,
   3.560 +    0x6850, 0x6950, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   3.561 +    0x7050, 0x7150, 0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750,
   3.562 +    0x7850, 0x7950, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   3.563 +    0x8050, 0x8150, 0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750,
   3.564 +    0x8850, 0x8950, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   3.565 +    0x9050, 0x9150, 0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750,
   3.566 +    0x9850, 0x9950, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   3.567 +    0xA050, 0xA150, 0xA250, 0xA350, 0xA450, 0xA550, 0xA650, 0xA750,
   3.568 +    0xA850, 0xA950, 0xA450, 0xA550, 0xA650, 0xA750, 0xA850, 0xA950,
   3.569 +    0xB050, 0xB150, 0xB250, 0xB350, 0xB450, 0xB550, 0xB650, 0xB750,
   3.570 +    0xB850, 0xB950, 0xB450, 0xB550, 0xB650, 0xB750, 0xB850, 0xB950,
   3.571 +    0xC050, 0xC150, 0xC250, 0xC350, 0xC450, 0xC550, 0xC650, 0xC750,
   3.572 +    0xC850, 0xC950, 0xC450, 0xC550, 0xC650, 0xC750, 0xC850, 0xC950,
   3.573 +    0xD050, 0xD150, 0xD250, 0xD350, 0xD450, 0xD550, 0xD650, 0xD750,
   3.574 +    0xD850, 0xD950, 0xD450, 0xD550, 0xD650, 0xD750, 0xD850, 0xD950,
   3.575 +    0xE050, 0xE150, 0xE250, 0xE350, 0xE450, 0xE550, 0xE650, 0xE750,
   3.576 +    0xE850, 0xE950, 0xE450, 0xE550, 0xE650, 0xE750, 0xE850, 0xE950,
   3.577 +    0xF050, 0xF150, 0xF250, 0xF350, 0xF450, 0xF550, 0xF650, 0xF750,
   3.578 +    0xF850, 0xF950, 0xF450, 0xF550, 0xF650, 0xF750, 0xF850, 0xF950,
   3.579 +    0x00D0, 0x0150, 0x0250, 0x0350, 0x0450, 0x0550, 0x0650, 0x0750,
   3.580 +    0x0850, 0x0950, 0x0450, 0x0550, 0x0650, 0x0750, 0x0850, 0x0950,
   3.581 +    0x1050, 0x1150, 0x1250, 0x1350, 0x1450, 0x1550, 0x1650, 0x1750,
   3.582 +    0x1850, 0x1950, 0x1450, 0x1550, 0x1650, 0x1750, 0x1850, 0x1950,
   3.583 +    0x2050, 0x2150, 0x2250, 0x2350, 0x2450, 0x2550, 0x2650, 0x2750,
   3.584 +    0x2850, 0x2950, 0x2450, 0x2550, 0x2650, 0x2750, 0x2850, 0x2950,
   3.585 +    0x3050, 0x3150, 0x3250, 0x3350, 0x3450, 0x3550, 0x3650, 0x3750,
   3.586 +    0x3850, 0x3950, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   3.587 +    0x4050, 0x4150, 0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750,
   3.588 +    0x4850, 0x4950, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   3.589 +    0x5050, 0x5150, 0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750,
   3.590 +    0x5850, 0x5950, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   3.591 +    0x6050, 0x6150, 0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750,
   3.592 +    0x6850, 0x6950, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   3.593 +    0x7050, 0x7150, 0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750,
   3.594 +    0x7850, 0x7950, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   3.595 +    0x8050, 0x8150, 0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750,
   3.596 +    0x8850, 0x8950, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   3.597 +    0x9050, 0x9150, 0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750,
   3.598 +    0x9850, 0x9950, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   3.599 +    0xFA60, 0xFB60, 0xFC60, 0xFD60, 0xFE60, 0xFF60, 0x00C0, 0x0140,
   3.600 +    0x0240, 0x0340, 0x0440, 0x0540, 0x0640, 0x0740, 0x0840, 0x0940,
   3.601 +    0x0A60, 0x0B60, 0x0C60, 0x0D60, 0x0E60, 0x0F60, 0x1040, 0x1140,
   3.602 +    0x1240, 0x1340, 0x1440, 0x1540, 0x1640, 0x1740, 0x1840, 0x1940,
   3.603 +    0x1A60, 0x1B60, 0x1C60, 0x1D60, 0x1E60, 0x1F60, 0x2040, 0x2140,
   3.604 +    0x2240, 0x2340, 0x2440, 0x2540, 0x2640, 0x2740, 0x2840, 0x2940,
   3.605 +    0x2A60, 0x2B60, 0x2C60, 0x2D60, 0x2E60, 0x2F60, 0x3040, 0x3140,
   3.606 +    0x3240, 0x3340, 0x3440, 0x3540, 0x3640, 0x3740, 0x3840, 0x3940,
   3.607 +    0x3A60, 0x3B60, 0x3C60, 0x3D60, 0x3E60, 0x3F60, 0x4040, 0x4140,
   3.608 +    0x4240, 0x4340, 0x4440, 0x4540, 0x4640, 0x4740, 0x4840, 0x4940,
   3.609 +    0x4A60, 0x4B60, 0x4C60, 0x4D60, 0x4E60, 0x4F60, 0x5040, 0x5140,
   3.610 +    0x5240, 0x5340, 0x5440, 0x5540, 0x5640, 0x5740, 0x5840, 0x5940,
   3.611 +    0x5A60, 0x5B60, 0x5C60, 0x5D60, 0x5E60, 0x5F60, 0x6040, 0x6140,
   3.612 +    0x6240, 0x6340, 0x6440, 0x6540, 0x6640, 0x6740, 0x6840, 0x6940,
   3.613 +    0x6A60, 0x6B60, 0x6C60, 0x6D60, 0x6E60, 0x6F60, 0x7040, 0x7140,
   3.614 +    0x7240, 0x7340, 0x7440, 0x7540, 0x7640, 0x7740, 0x7840, 0x7940,
   3.615 +    0x7A60, 0x7B60, 0x7C60, 0x7D60, 0x7E60, 0x7F60, 0x8040, 0x8140,
   3.616 +    0x8240, 0x8340, 0x8440, 0x8540, 0x8640, 0x8740, 0x8840, 0x8940,
   3.617 +    0x8A60, 0x8B60, 0x8C60, 0x8D60, 0x8E60, 0x8F60, 0x9040, 0x9140,
   3.618 +    0x9240, 0x9340, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   3.619 +    0x3A70, 0x3B70, 0x3C70, 0x3D70, 0x3E70, 0x3F70, 0x4050, 0x4150,
   3.620 +    0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   3.621 +    0x4A70, 0x4B70, 0x4C70, 0x4D70, 0x4E70, 0x4F70, 0x5050, 0x5150,
   3.622 +    0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   3.623 +    0x5A70, 0x5B70, 0x5C70, 0x5D70, 0x5E70, 0x5F70, 0x6050, 0x6150,
   3.624 +    0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   3.625 +    0x6A70, 0x6B70, 0x6C70, 0x6D70, 0x6E70, 0x6F70, 0x7050, 0x7150,
   3.626 +    0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   3.627 +    0x7A70, 0x7B70, 0x7C70, 0x7D70, 0x7E70, 0x7F70, 0x8050, 0x8150,
   3.628 +    0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   3.629 +    0x8A70, 0x8B70, 0x8C70, 0x8D70, 0x8E70, 0x8F70, 0x9050, 0x9150,
   3.630 +    0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   3.631 +    0x9A70, 0x9B70, 0x9C70, 0x9D70, 0x9E70, 0x9F70, 0xA050, 0xA150,
   3.632 +    0xA250, 0xA350, 0xA450, 0xA550, 0xA650, 0xA750, 0xA850, 0xA950,
   3.633 +    0xAA70, 0xAB70, 0xAC70, 0xAD70, 0xAE70, 0xAF70, 0xB050, 0xB150,
   3.634 +    0xB250, 0xB350, 0xB450, 0xB550, 0xB650, 0xB750, 0xB850, 0xB950,
   3.635 +    0xBA70, 0xBB70, 0xBC70, 0xBD70, 0xBE70, 0xBF70, 0xC050, 0xC150,
   3.636 +    0xC250, 0xC350, 0xC450, 0xC550, 0xC650, 0xC750, 0xC850, 0xC950,
   3.637 +    0xCA70, 0xCB70, 0xCC70, 0xCD70, 0xCE70, 0xCF70, 0xD050, 0xD150,
   3.638 +    0xD250, 0xD350, 0xD450, 0xD550, 0xD650, 0xD750, 0xD850, 0xD950,
   3.639 +    0xDA70, 0xDB70, 0xDC70, 0xDD70, 0xDE70, 0xDF70, 0xE050, 0xE150,
   3.640 +    0xE250, 0xE350, 0xE450, 0xE550, 0xE650, 0xE750, 0xE850, 0xE950,
   3.641 +    0xEA70, 0xEB70, 0xEC70, 0xED70, 0xEE70, 0xEF70, 0xF050, 0xF150,
   3.642 +    0xF250, 0xF350, 0xF450, 0xF550, 0xF650, 0xF750, 0xF850, 0xF950,
   3.643 +    0xFA70, 0xFB70, 0xFC70, 0xFD70, 0xFE70, 0xFF70, 0x00D0, 0x0150,
   3.644 +    0x0250, 0x0350, 0x0450, 0x0550, 0x0650, 0x0750, 0x0850, 0x0950,
   3.645 +    0x0A70, 0x0B70, 0x0C70, 0x0D70, 0x0E70, 0x0F70, 0x1050, 0x1150,
   3.646 +    0x1250, 0x1350, 0x1450, 0x1550, 0x1650, 0x1750, 0x1850, 0x1950,
   3.647 +    0x1A70, 0x1B70, 0x1C70, 0x1D70, 0x1E70, 0x1F70, 0x2050, 0x2150,
   3.648 +    0x2250, 0x2350, 0x2450, 0x2550, 0x2650, 0x2750, 0x2850, 0x2950,
   3.649 +    0x2A70, 0x2B70, 0x2C70, 0x2D70, 0x2E70, 0x2F70, 0x3050, 0x3150,
   3.650 +    0x3250, 0x3350, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   3.651 +    0x3A70, 0x3B70, 0x3C70, 0x3D70, 0x3E70, 0x3F70, 0x4050, 0x4150,
   3.652 +    0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   3.653 +    0x4A70, 0x4B70, 0x4C70, 0x4D70, 0x4E70, 0x4F70, 0x5050, 0x5150,
   3.654 +    0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   3.655 +    0x5A70, 0x5B70, 0x5C70, 0x5D70, 0x5E70, 0x5F70, 0x6050, 0x6150,
   3.656 +    0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   3.657 +    0x6A70, 0x6B70, 0x6C70, 0x6D70, 0x6E70, 0x6F70, 0x7050, 0x7150,
   3.658 +    0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   3.659 +    0x7A70, 0x7B70, 0x7C70, 0x7D70, 0x7E70, 0x7F70, 0x8050, 0x8150,
   3.660 +    0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   3.661 +    0x8A70, 0x8B70, 0x8C70, 0x8D70, 0x8E70, 0x8F70, 0x9050, 0x9150,
   3.662 +    0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   3.663 +  };
   3.664  
   3.665  u8 ZeroTable[] =
   3.666 -{
   3.667 -	0x80, 0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.668 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.669 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.670 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.671 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.672 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.673 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.674 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.675 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.676 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.677 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.678 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.679 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.680 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.681 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.682 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0
   3.683 -};
   3.684 +  {
   3.685 +    0x80, 0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.686 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.687 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.688 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.689 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.690 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.691 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.692 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.693 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.694 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.695 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.696 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.697 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.698 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.699 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   3.700 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0
   3.701 +  };
   3.702  
   3.703  #define GBSAVE_GAME_VERSION_1 1
   3.704  #define GBSAVE_GAME_VERSION_2 2
   3.705 @@ -536,81 +536,81 @@
   3.706  
   3.707  int inline gbGetValue(int min, int max, int v)
   3.708  {
   3.709 -	return (int)(min + (float)(max - min) * (2.0 * (v / 31.0) - (v / 31.0) * (v / 31.0)));
   3.710 +  return (int)(min + (float)(max - min) * (2.0 * (v / 31.0) - (v / 31.0) * (v / 31.0)));
   3.711  }
   3.712  
   3.713  void gbGenFilter()
   3.714  {
   3.715 -	for (int r = 0; r < 32; r++)
   3.716 +  for (int r = 0; r < 32; r++)
   3.717 +    {
   3.718 +      for (int g = 0; g < 32; g++)
   3.719  	{
   3.720 -		for (int g = 0; g < 32; g++)
   3.721 -		{
   3.722 -			for (int b = 0; b < 32; b++)
   3.723 -			{
   3.724 -				int nr = gbGetValue(gbGetValue(4, 14, g),
   3.725 -				                    gbGetValue(24, 29, g), r) - 4;
   3.726 -				int ng = gbGetValue(gbGetValue(4 + gbGetValue(0, 5, r),
   3.727 -				                               14 + gbGetValue(0, 3, r), b),
   3.728 -				                    gbGetValue(24 + gbGetValue(0, 3, r),
   3.729 -				                               29 + gbGetValue(0, 1, r), b), g) - 4;
   3.730 -				int nb = gbGetValue(gbGetValue(4 + gbGetValue(0, 5, r),
   3.731 -				                               14 + gbGetValue(0, 3, r), g),
   3.732 -				                    gbGetValue(24 + gbGetValue(0, 3, r),
   3.733 -				                               29 + gbGetValue(0, 1, r), g), b) - 4;
   3.734 -				gbColorFilter[(b << 10) | (g << 5) | r] = (nb << 10) | (ng << 5) | nr;
   3.735 -			}
   3.736 -		}
   3.737 +	  for (int b = 0; b < 32; b++)
   3.738 +	    {
   3.739 +	      int nr = gbGetValue(gbGetValue(4, 14, g),
   3.740 +				  gbGetValue(24, 29, g), r) - 4;
   3.741 +	      int ng = gbGetValue(gbGetValue(4 + gbGetValue(0, 5, r),
   3.742 +					     14 + gbGetValue(0, 3, r), b),
   3.743 +				  gbGetValue(24 + gbGetValue(0, 3, r),
   3.744 +					     29 + gbGetValue(0, 1, r), b), g) - 4;
   3.745 +	      int nb = gbGetValue(gbGetValue(4 + gbGetValue(0, 5, r),
   3.746 +					     14 + gbGetValue(0, 3, r), g),
   3.747 +				  gbGetValue(24 + gbGetValue(0, 3, r),
   3.748 +					     29 + gbGetValue(0, 1, r), g), b) - 4;
   3.749 +	      gbColorFilter[(b << 10) | (g << 5) | r] = (nb << 10) | (ng << 5) | nr;
   3.750 +	    }
   3.751  	}
   3.752 +    }
   3.753  }
   3.754  
   3.755  void gbCopyMemory(u16 d, u16 s, int count)
   3.756  {
   3.757 -	while (count)
   3.758 -	{
   3.759 -		gbWriteMemoryQuick(d, gbReadMemoryQuick(s));
   3.760 -		s++;
   3.761 -		d++;
   3.762 -		count--;
   3.763 -	}
   3.764 +  while (count)
   3.765 +    {
   3.766 +      gbWriteMemoryQuick(d, gbReadMemoryQuick(s));
   3.767 +      s++;
   3.768 +      d++;
   3.769 +      count--;
   3.770 +    }
   3.771  }
   3.772  
   3.773  void gbDoHdma()
   3.774  {
   3.775 -	gbCopyMemory(gbHdmaDestination, gbHdmaSource, 0x10);
   3.776 -
   3.777 -	gbHdmaDestination += 0x10;
   3.778 -	gbHdmaSource	  += 0x10;
   3.779 -
   3.780 -	register_HDMA2 = (register_HDMA2 + 0x10) & 0xFF;
   3.781 -	if (register_HDMA2 == 0x00)
   3.782 -		register_HDMA1++;
   3.783 -
   3.784 -	register_HDMA4 = (register_HDMA4 + 0x10) & 0xFF;
   3.785 -	if (register_HDMA4 == 0x00)
   3.786 -		register_HDMA3++;
   3.787 -
   3.788 -	if (gbHdmaDestination == 0x96b0)
   3.789 -		gbHdmaBytes = gbHdmaBytes;
   3.790 -	gbHdmaBytes -= 0x10;
   3.791 -	register_HDMA5--;
   3.792 -	if (register_HDMA5 == 0xff)
   3.793 -		gbHdmaOn = 0;
   3.794 +  gbCopyMemory(gbHdmaDestination, gbHdmaSource, 0x10);
   3.795 +
   3.796 +  gbHdmaDestination += 0x10;
   3.797 +  gbHdmaSource	  += 0x10;
   3.798 +
   3.799 +  register_HDMA2 = (register_HDMA2 + 0x10) & 0xFF;
   3.800 +  if (register_HDMA2 == 0x00)
   3.801 +    register_HDMA1++;
   3.802 +
   3.803 +  register_HDMA4 = (register_HDMA4 + 0x10) & 0xFF;
   3.804 +  if (register_HDMA4 == 0x00)
   3.805 +    register_HDMA3++;
   3.806 +
   3.807 +  if (gbHdmaDestination == 0x96b0)
   3.808 +    gbHdmaBytes = gbHdmaBytes;
   3.809 +  gbHdmaBytes -= 0x10;
   3.810 +  register_HDMA5--;
   3.811 +  if (register_HDMA5 == 0xff)
   3.812 +    gbHdmaOn = 0;
   3.813  }
   3.814  
   3.815  // fix for Harley and Lego Racers
   3.816  void gbCompareLYToLYC()
   3.817  {
   3.818 -	if (register_LY == register_LYC)
   3.819 -	{
   3.820 -		// mark that we have a match
   3.821 -		register_STAT |= 4;
   3.822 -
   3.823 -		// check if we need an interrupt
   3.824 -		if ((register_STAT & 0x40) && (register_IE & 2))
   3.825 -			gbInterrupt |= 2;
   3.826 -	}
   3.827 -	else   // no match
   3.828 -		register_STAT &= 0xfb;
   3.829 +  if (register_LY == register_LYC)
   3.830 +    {
   3.831 +      // mark that we have a match
   3.832 +      register_STAT |= 4;
   3.833 +
   3.834 +      // check if we need an interrupt
   3.835 +      if ((register_STAT & 0x40) && (register_IE & 2))
   3.836 +	gbInterrupt |= 2;
   3.837 +    }
   3.838 +  else   // no match
   3.839 +    register_STAT &= 0xfb;
   3.840  }
   3.841  
   3.842  // FIXME: horrible kludge to workaround the frame timing bug
   3.843 @@ -618,1971 +618,1971 @@
   3.844  
   3.845  void gbWriteMemoryWrapped(register u16 address, register u8 value)
   3.846  {
   3.847 -	if (address < 0x8000)
   3.848 +  if (address < 0x8000)
   3.849 +    {
   3.850 +#ifndef FINAL_VERSION
   3.851 +      if (memorydebug && (address > 0x3fff || address < 0x2000))
   3.852  	{
   3.853 +	  log("Memory register write %04x=%02x PC=%04x\n",
   3.854 +	      address,
   3.855 +	      value,
   3.856 +	      PC.W);
   3.857 +	}
   3.858 +#endif
   3.859 +      if (mapper)
   3.860 +	(*mapper)(address, value);
   3.861 +      return;
   3.862 +    }
   3.863 +
   3.864 +  if (address < 0xa000)
   3.865 +    {
   3.866 +      gbWriteMemoryQuick(address, value);
   3.867 +      return;
   3.868 +    }
   3.869 +
   3.870 +  if (address < 0xc000)
   3.871 +    {
   3.872  #ifndef FINAL_VERSION
   3.873 -		if (memorydebug && (address > 0x3fff || address < 0x2000))
   3.874 -		{
   3.875 -			log("Memory register write %04x=%02x PC=%04x\n",
   3.876 -			    address,
   3.877 -			    value,
   3.878 -			    PC.W);
   3.879 -		}
   3.880 +      if (memorydebug)
   3.881 +	{
   3.882 +	  log("Memory register write %04x=%02x PC=%04x\n",
   3.883 +	      address,
   3.884 +	      value,
   3.885 +	      PC.W);
   3.886 +	}
   3.887  #endif
   3.888 -		if (mapper)
   3.889 -			(*mapper)(address, value);
   3.890 -		return;
   3.891 +
   3.892 +      if (mapper)
   3.893 +	(*mapperRAM)(address, value);
   3.894 +      return;
   3.895 +    }
   3.896 +
   3.897 +  if (address < 0xfe00)
   3.898 +    {
   3.899 +      gbWriteMemoryQuick(address, value);
   3.900 +      return;
   3.901 +    }
   3.902 +
   3.903 +  if (address < 0xff00)
   3.904 +    {
   3.905 +      gbMemory[address] = value;
   3.906 +      return;
   3.907 +    }
   3.908 +
   3.909 +  switch (address & 0x00ff)
   3.910 +    {
   3.911 +    case 0x00:
   3.912 +      {
   3.913 +	gbMemory[0xff00] = ((gbMemory[0xff00] & 0xcf) |
   3.914 +			    (value & 0x30));
   3.915 +	if (gbSgbMode)
   3.916 +	  {
   3.917 +	    gbSgbDoBitTransfer(value);
   3.918 +	  }
   3.919 +
   3.920 +	return;
   3.921 +      }
   3.922 +
   3.923 +    case 0x01:
   3.924 +      {
   3.925 +	gbMemory[0xff01] = value;
   3.926 +	return;
   3.927 +      }
   3.928 +
   3.929 +      // serial control
   3.930 +    case 0x02:
   3.931 +      {
   3.932 +	gbSerialOn		 = (value & 0x80);
   3.933 +	gbMemory[0xff02] = value;
   3.934 +	if (gbSerialOn)
   3.935 +	  {
   3.936 +	    gbSerialTicks = GBSERIAL_CLOCK_TICKS;
   3.937 +#ifdef LINK_EMULATION
   3.938 +	    if (linkConnected)
   3.939 +	      {
   3.940 +		if (value & 1)
   3.941 +		  {
   3.942 +		    linkSendByte(0x100 | gbMemory[0xFF01]);
   3.943 +		    Sleep(5);
   3.944 +		  }
   3.945 +	      }
   3.946 +#endif
   3.947 +	  }
   3.948 +
   3.949 +	gbSerialBits = 0;
   3.950 +	return;
   3.951 +      }
   3.952 +
   3.953 +      // DIV register resets on any write
   3.954 +    case 0x04:
   3.955 +      {
   3.956 +	register_DIV = 0;
   3.957 +	return;
   3.958 +      }
   3.959 +    case 0x05:
   3.960 +      register_TIMA = value;
   3.961 +      return;
   3.962 +
   3.963 +    case 0x06:
   3.964 +      register_TMA = value;
   3.965 +      return;
   3.966 +
   3.967 +      // TIMER control
   3.968 +    case 0x07:
   3.969 +      {
   3.970 +	register_TAC = value;
   3.971 +
   3.972 +	gbTimerOn	= (value & 4);
   3.973 +	gbTimerMode = value & 3;
   3.974 +	//    register_TIMA = register_TMA;
   3.975 +	switch (gbTimerMode)
   3.976 +	  {
   3.977 +	  case 0:
   3.978 +	    gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_0_CLOCK_TICKS;
   3.979 +	    break;
   3.980 +	  case 1:
   3.981 +	    gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_1_CLOCK_TICKS;
   3.982 +	    break;
   3.983 +	  case 2:
   3.984 +	    gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_2_CLOCK_TICKS;
   3.985 +	    break;
   3.986 +	  case 3:
   3.987 +	    gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_3_CLOCK_TICKS;
   3.988 +	    break;
   3.989 +	  }
   3.990 +	return;
   3.991 +      }
   3.992 +
   3.993 +    case 0x0f:
   3.994 +      {
   3.995 +	register_IF = value;
   3.996 +	gbInterrupt = value;
   3.997 +	return;
   3.998 +      }
   3.999 +
  3.1000 +    case 0x10:
  3.1001 +    case 0x11:
  3.1002 +    case 0x12:
  3.1003 +    case 0x13:
  3.1004 +    case 0x14:
  3.1005 +    case 0x15:
  3.1006 +    case 0x16:
  3.1007 +    case 0x17:
  3.1008 +    case 0x18:
  3.1009 +    case 0x19:
  3.1010 +    case 0x1a:
  3.1011 +    case 0x1b:
  3.1012 +    case 0x1c:
  3.1013 +    case 0x1d:
  3.1014 +    case 0x1e:
  3.1015 +    case 0x1f:
  3.1016 +    case 0x20:
  3.1017 +    case 0x21:
  3.1018 +    case 0x22:
  3.1019 +    case 0x23:
  3.1020 +    case 0x24:
  3.1021 +    case 0x25:
  3.1022 +    case 0x26:
  3.1023 +      {
  3.1024 +	SOUND_EVENT(address, value);
  3.1025 +	return;
  3.1026 +      }
  3.1027 +    case 0x40:
  3.1028 +      {
  3.1029 +	int lcdChange = (register_LCDC & 0x80) ^ (value & 0x80);
  3.1030 +
  3.1031 +	if (lcdChange)
  3.1032 +	  {
  3.1033 +	    if (value & 0x80)
  3.1034 +	      {
  3.1035 +		gbLcdTicks	   = GBLCD_MODE_1_CLOCK_TICKS;
  3.1036 +		gbLcdMode	   = 0;
  3.1037 +		register_STAT &= 0xfc;
  3.1038 +		register_LY	   = 0x00;
  3.1039 +		// FIXME: horrible workaround
  3.1040 +		if (gbNullInputHackTempEnabled && !useOldFrameTiming)
  3.1041 +		  memcpy(gbJoymask, s_gbJoymask, sizeof(gbJoymask));
  3.1042 +	      }
  3.1043 +	    else
  3.1044 +	      {
  3.1045 +		gbLcdTicks	   = 0;
  3.1046 +		gbLcdMode	   = 0;
  3.1047 +		register_STAT &= 0xfc;
  3.1048 +		register_LY	   = 0x00;
  3.1049 +		// FIXME: horrible workaround
  3.1050 +		memcpy(s_gbJoymask, gbJoymask, sizeof(gbJoymask));
  3.1051 +		if (gbNullInputHackTempEnabled && !useOldFrameTiming)
  3.1052 +		  memset(gbJoymask, 0, sizeof(gbJoymask));
  3.1053 +	      }
  3.1054 +	    //      compareLYToLYC();
  3.1055 +	  }
  3.1056 +	// don't draw the window if it was not enabled and not being drawn before
  3.1057 +	if (!(register_LCDC & 0x20) && (value & 0x20) && gbWindowLine == -1 &&
  3.1058 +	    register_LY > register_WY)
  3.1059 +	  gbWindowLine = 144;
  3.1060 +
  3.1061 +	register_LCDC = value;
  3.1062 +
  3.1063 +	return;
  3.1064 +      }
  3.1065 +
  3.1066 +      // STAT
  3.1067 +    case 0x41:
  3.1068 +      {
  3.1069 +	//register_STAT = (register_STAT & 0x87) |
  3.1070 +	//      (value & 0x7c);
  3.1071 +	register_STAT = (value & 0xf8) | (register_STAT & 0x07);     // fix ?
  3.1072 +	// GB bug from Devrs FAQ
  3.1073 +	if (!gbCgbMode && (register_LCDC & 0x80) && gbLcdMode < 2)
  3.1074 +	  gbInterrupt |= 2;
  3.1075 +	return;
  3.1076 +      }
  3.1077 +
  3.1078 +      // SCY
  3.1079 +    case 0x42:
  3.1080 +      {
  3.1081 +	register_SCY = value;
  3.1082 +	return;
  3.1083 +      }
  3.1084 +
  3.1085 +      // SCX
  3.1086 +    case 0x43:
  3.1087 +      {
  3.1088 +	register_SCX = value;
  3.1089 +	return;
  3.1090 +      }
  3.1091 +
  3.1092 +      // LY
  3.1093 +    case 0x44:
  3.1094 +      {
  3.1095 +	// read only
  3.1096 +	return;
  3.1097 +      }
  3.1098 +
  3.1099 +      // LYC
  3.1100 +    case 0x45:
  3.1101 +      {
  3.1102 +	register_LYC = value;
  3.1103 +	if ((register_LCDC & 0x80))
  3.1104 +	  {
  3.1105 +	    gbCompareLYToLYC();
  3.1106 +	  }
  3.1107 +	return;
  3.1108 +      }
  3.1109 +
  3.1110 +      // DMA!
  3.1111 +    case 0x46:
  3.1112 +      {
  3.1113 +	int source = value * 0x0100;
  3.1114 +
  3.1115 +	gbCopyMemory(0xfe00,
  3.1116 +		     source,
  3.1117 +		     0xa0);
  3.1118 +	register_DMA = value;
  3.1119 +	return;
  3.1120 +      }
  3.1121 +
  3.1122 +      // BGP
  3.1123 +    case 0x47:
  3.1124 +      {
  3.1125 +	gbBgp[0] = value & 0x03;
  3.1126 +	gbBgp[1] = (value & 0x0c) >> 2;
  3.1127 +	gbBgp[2] = (value & 0x30) >> 4;
  3.1128 +	gbBgp[3] = (value & 0xc0) >> 6;
  3.1129 +	break;
  3.1130 +      }
  3.1131 +
  3.1132 +      // OBP0
  3.1133 +    case 0x48:
  3.1134 +      {
  3.1135 +	gbObp0[0] = value & 0x03;
  3.1136 +	gbObp0[1] = (value & 0x0c) >> 2;
  3.1137 +	gbObp0[2] = (value & 0x30) >> 4;
  3.1138 +	gbObp0[3] = (value & 0xc0) >> 6;
  3.1139 +	break;
  3.1140 +      }
  3.1141 +
  3.1142 +      // OBP1
  3.1143 +    case 0x49:
  3.1144 +      {
  3.1145 +	gbObp1[0] = value & 0x03;
  3.1146 +	gbObp1[1] = (value & 0x0c) >> 2;
  3.1147 +	gbObp1[2] = (value & 0x30) >> 4;
  3.1148 +	gbObp1[3] = (value & 0xc0) >> 6;
  3.1149 +	break;
  3.1150 +      }
  3.1151 +
  3.1152 +    case 0x4a:
  3.1153 +      register_WY = value;
  3.1154 +      return;
  3.1155 +
  3.1156 +    case 0x4b:
  3.1157 +      register_WX = value;
  3.1158 +      return;
  3.1159 +
  3.1160 +      // KEY1
  3.1161 +    case 0x4d:
  3.1162 +      {
  3.1163 +	if (gbCgbMode)
  3.1164 +	  {
  3.1165 +	    gbMemory[0xff4d] = (gbMemory[0xff4d] & 0x80) | (value & 1);
  3.1166 +	    return;
  3.1167 +	  }
  3.1168 +	break;
  3.1169 +      }
  3.1170 +
  3.1171 +      // VBK
  3.1172 +    case 0x4f:
  3.1173 +      {
  3.1174 +	if (gbCgbMode)
  3.1175 +	  {
  3.1176 +	    value = value & 1;
  3.1177 +	    if (value == gbVramBank)
  3.1178 +	      return;
  3.1179 +
  3.1180 +	    int vramAddress = value * 0x2000;
  3.1181 +	    gbMemoryMap[0x08] = &gbVram[vramAddress];
  3.1182 +	    gbMemoryMap[0x09] = &gbVram[vramAddress + 0x1000];
  3.1183 +
  3.1184 +	    gbVramBank	 = value;
  3.1185 +	    register_VBK = value;
  3.1186 +	  }
  3.1187 +	return;
  3.1188 +	break;
  3.1189 +      }
  3.1190 +
  3.1191 +      // HDMA1
  3.1192 +    case 0x51:
  3.1193 +      {
  3.1194 +	if (gbCgbMode)
  3.1195 +	  {
  3.1196 +	    if (value > 0x7f && value < 0xa0)
  3.1197 +	      value = 0;
  3.1198 +
  3.1199 +	    gbHdmaSource = (value << 8) | (register_HDMA2 & 0xf0);
  3.1200 +
  3.1201 +	    register_HDMA1 = value;
  3.1202 +	    return;
  3.1203 +	  }
  3.1204 +	break;
  3.1205 +      }
  3.1206 +
  3.1207 +      // HDMA2
  3.1208 +    case 0x52:
  3.1209 +      {
  3.1210 +	if (gbCgbMode)
  3.1211 +	  {
  3.1212 +	    value = value & 0xf0;
  3.1213 +
  3.1214 +	    gbHdmaSource = (register_HDMA1 << 8) | (value);
  3.1215 +
  3.1216 +	    register_HDMA2 = value;
  3.1217 +	    return;
  3.1218 +	  }
  3.1219 +	break;
  3.1220 +      }
  3.1221 +
  3.1222 +      // HDMA3
  3.1223 +    case 0x53:
  3.1224 +      {
  3.1225 +	if (gbCgbMode)
  3.1226 +	  {
  3.1227 +	    value = value & 0x1f;
  3.1228 +	    gbHdmaDestination  = (value << 8) | (register_HDMA4 & 0xf0);
  3.1229 +	    gbHdmaDestination += 0x8000;
  3.1230 +	    register_HDMA3	   = value;
  3.1231 +	    return;
  3.1232 +	  }
  3.1233 +	break;
  3.1234 +      }
  3.1235 +
  3.1236 +      // HDMA4
  3.1237 +    case 0x54:
  3.1238 +      {
  3.1239 +	if (gbCgbMode)
  3.1240 +	  {
  3.1241 +	    value = value & 0xf0;
  3.1242 +	    gbHdmaDestination  = ((register_HDMA3 & 0x1f) << 8) | value;
  3.1243 +	    gbHdmaDestination += 0x8000;
  3.1244 +	    register_HDMA4	   = value;
  3.1245 +	    return;
  3.1246 +	  }
  3.1247 +	break;
  3.1248 +      }
  3.1249 +
  3.1250 +      // HDMA5
  3.1251 +    case 0x55:
  3.1252 +      {
  3.1253 +	if (gbCgbMode)
  3.1254 +	  {
  3.1255 +	    gbHdmaBytes = 16 + (value & 0x7f) * 16;
  3.1256 +	    if (gbHdmaOn)
  3.1257 +	      {
  3.1258 +		if (value & 0x80)
  3.1259 +		  {
  3.1260 +		    register_HDMA5 = (value & 0x7f);
  3.1261 +		  }
  3.1262 +		else
  3.1263 +		  {
  3.1264 +		    register_HDMA5 = 0xff;
  3.1265 +		    gbHdmaOn	   = 0;
  3.1266 +		  }
  3.1267 +	      }
  3.1268 +	    else
  3.1269 +	      {
  3.1270 +		if (value & 0x80)
  3.1271 +		  {
  3.1272 +		    gbHdmaOn	   = 1;
  3.1273 +		    register_HDMA5 = value & 0x7f;
  3.1274 +		    if (gbLcdMode == 0)
  3.1275 +		      gbDoHdma();
  3.1276 +		  }
  3.1277 +		else
  3.1278 +		  {
  3.1279 +		    // we need to take the time it takes to complete the transfer into
  3.1280 +		    // account... according to GB DEV FAQs, the setup time is the same
  3.1281 +		    // for single and double speed, but the actual transfer takes the
  3.1282 +		    // same time // (is that a typo?)
  3.1283 +		    switch (gbDMASpeedVersion)
  3.1284 +		      {
  3.1285 +		      case 1:     // I believe this is more correct
  3.1286 +			// the lower 7 bits of FF55 specify the Transfer Length (divided by 16, minus 1)
  3.1287 +			// and we make gbDmaTicks twice as many cycles at double speed to make the transfer take the same time
  3.1288 +			if (gbSpeed)
  3.1289 +			  gbDmaTicks = 16 * ((value & 0x7f) + 1);
  3.1290 +			else
  3.1291 +			  gbDmaTicks = 8 * ((value & 0x7f) + 1);
  3.1292 +			break;
  3.1293 +		      case 0:     // here for backward compatibility
  3.1294 +			// I think this was a guess that approximates the above in most but not all games
  3.1295 +			if (gbSpeed)
  3.1296 +			  gbDmaTicks = 231 + 16 * (value & 0x7f);
  3.1297 +			else
  3.1298 +			  gbDmaTicks = 231 + 8 * (value & 0x7f);
  3.1299 +			break;
  3.1300 +		      default:     // shouldn't happen
  3.1301 +			//assert(0);
  3.1302 +			break;
  3.1303 +		      }
  3.1304 +		    gbCopyMemory(gbHdmaDestination, gbHdmaSource, gbHdmaBytes);
  3.1305 +		    gbHdmaDestination += gbHdmaBytes;
  3.1306 +		    gbHdmaSource	  += gbHdmaBytes;
  3.1307 +
  3.1308 +		    register_HDMA3 = ((gbHdmaDestination - 0x8000) >> 8) & 0x1f;
  3.1309 +		    register_HDMA4 = gbHdmaDestination & 0xf0;
  3.1310 +		    register_HDMA1 = (gbHdmaSource >> 8) & 0xff;
  3.1311 +		    register_HDMA2 = gbHdmaSource & 0xf0;
  3.1312 +		  }
  3.1313 +	      }
  3.1314 +	    return;
  3.1315 +	  }
  3.1316 +	break;
  3.1317 +      }
  3.1318 +
  3.1319 +      // BCPS
  3.1320 +    case 0x68:
  3.1321 +      {
  3.1322 +	if (gbCgbMode)
  3.1323 +	  {
  3.1324 +	    int paletteIndex = (value & 0x3f) >> 1;
  3.1325 +	    int paletteHiLo	 = (value & 0x01);
  3.1326 +
  3.1327 +	    gbMemory[0xff68] = value;
  3.1328 +	    gbMemory[0xff69] = (paletteHiLo ?
  3.1329 +				(gbPalette[paletteIndex] >> 8) :
  3.1330 +				(gbPalette[paletteIndex] & 0x00ff));
  3.1331 +	    return;
  3.1332 +	  }
  3.1333 +	break;
  3.1334 +      }
  3.1335 +
  3.1336 +      // BCPD
  3.1337 +    case 0x69:
  3.1338 +      {
  3.1339 +	if (gbCgbMode)
  3.1340 +	  {
  3.1341 +	    int v = gbMemory[0xff68];
  3.1342 +	    int paletteIndex = (v & 0x3f) >> 1;
  3.1343 +	    int paletteHiLo	 = (v & 0x01);
  3.1344 +	    gbMemory[0xff69]		= value;
  3.1345 +	    gbPalette[paletteIndex] = (paletteHiLo ?
  3.1346 +				       ((value << 8) | (gbPalette[paletteIndex] & 0xff)) :
  3.1347 +				       ((gbPalette[paletteIndex] & 0xff00) | (value))) & 0x7fff;
  3.1348 +
  3.1349 +	    if (gbMemory[0xff68] & 0x80)
  3.1350 +	      {
  3.1351 +		int index = ((gbMemory[0xff68] & 0x3f) + 1) & 0x3f;
  3.1352 +
  3.1353 +		gbMemory[0xff68] = (gbMemory[0xff68] & 0x80) | index;
  3.1354 +
  3.1355 +		gbMemory[0xff69] = (index & 1 ?
  3.1356 +				    (gbPalette[index >> 1] >> 8) :
  3.1357 +				    (gbPalette[index >> 1] & 0x00ff));
  3.1358 +	      }
  3.1359 +	    return;
  3.1360 +	  }
  3.1361 +	break;
  3.1362 +      }
  3.1363 +
  3.1364 +      // OCPS
  3.1365 +    case 0x6a:
  3.1366 +      {
  3.1367 +	if (gbCgbMode)
  3.1368 +	  {
  3.1369 +	    int paletteIndex = (value & 0x3f) >> 1;
  3.1370 +	    int paletteHiLo	 = (value & 0x01);
  3.1371 +
  3.1372 +	    paletteIndex += 32;
  3.1373 +
  3.1374 +	    gbMemory[0xff6a] = value;
  3.1375 +	    gbMemory[0xff6b] = (paletteHiLo ?
  3.1376 +				(gbPalette[paletteIndex] >> 8) :
  3.1377 +				(gbPalette[paletteIndex] & 0x00ff));
  3.1378 +	    return;
  3.1379 +	  }
  3.1380 +	break;
  3.1381 +      }
  3.1382 +
  3.1383 +      // OCPD
  3.1384 +    case 0x6b:
  3.1385 +      {
  3.1386 +	if (gbCgbMode)
  3.1387 +	  {
  3.1388 +	    int v = gbMemory[0xff6a];
  3.1389 +	    int paletteIndex = (v & 0x3f) >> 1;
  3.1390 +	    int paletteHiLo	 = (v & 0x01);
  3.1391 +
  3.1392 +	    paletteIndex += 32;
  3.1393 +
  3.1394 +	    gbMemory[0xff6b]		= value;
  3.1395 +	    gbPalette[paletteIndex] = (paletteHiLo ?
  3.1396 +				       ((value << 8) | (gbPalette[paletteIndex] & 0xff)) :
  3.1397 +				       ((gbPalette[paletteIndex] & 0xff00) | (value))) & 0x7fff;
  3.1398 +	    if (gbMemory[0xff6a] & 0x80)
  3.1399 +	      {
  3.1400 +		int index = ((gbMemory[0xff6a] & 0x3f) + 1) & 0x3f;
  3.1401 +
  3.1402 +		gbMemory[0xff6a] = (gbMemory[0xff6a] & 0x80) | index;
  3.1403 +
  3.1404 +		gbMemory[0xff6b] = (index & 1 ?
  3.1405 +				    (gbPalette[(index >> 1) + 32] >> 8) :
  3.1406 +				    (gbPalette[(index >> 1) + 32] & 0x00ff));
  3.1407 +	      }
  3.1408 +	    return;
  3.1409 +	  }
  3.1410 +	break;
  3.1411 +      }
  3.1412 +
  3.1413 +      // SVBK
  3.1414 +    case 0x70:
  3.1415 +      {
  3.1416 +	if (gbCgbMode)
  3.1417 +	  {
  3.1418 +	    value = value & 7;
  3.1419 +
  3.1420 +	    int bank = value;
  3.1421 +	    if (value == 0)
  3.1422 +	      bank = 1;
  3.1423 +
  3.1424 +	    if (bank == gbWramBank)
  3.1425 +	      return;
  3.1426 +
  3.1427 +	    int wramAddress = bank * 0x1000;
  3.1428 +	    gbMemoryMap[0x0d] = &gbWram[wramAddress];
  3.1429 +
  3.1430 +	    gbWramBank	  = bank;
  3.1431 +	    register_SVBK = value;
  3.1432 +	    return;
  3.1433 +	  }
  3.1434 +	break;
  3.1435 +      }
  3.1436 +
  3.1437 +    case 0xff:
  3.1438 +      {
  3.1439 +	register_IE	 = value;
  3.1440 +	register_IF &= value;
  3.1441 +	return;
  3.1442 +      }
  3.1443 +    }
  3.1444 +
  3.1445 +  gbWriteMemoryQuick(address, value);
  3.1446 +}
  3.1447 +
  3.1448 +u8 gbReadOpcode(register u16 address)
  3.1449 +{
  3.1450 +  if (gbCheatMap[address])
  3.1451 +    return gbCheatRead(address);
  3.1452 +
  3.1453 +  // the following fix does more than Echo RAM fix, anyway...
  3.1454 +  switch (gbEchoRAMFixOn ? (address >> 12) & 0x000f : address & 0xf000)
  3.1455 +    {
  3.1456 +    case 0x0a:
  3.1457 +    case 0x0b:
  3.1458 +      if (mapperReadRAM)
  3.1459 +	return mapperReadRAM(address);
  3.1460 +      break;
  3.1461 +    case 0x0f:
  3.1462 +      if (address > 0xff00)
  3.1463 +	{
  3.1464 +	  switch (address & 0x00ff)
  3.1465 +	    {
  3.1466 +	    case 0x04:
  3.1467 +	      return register_DIV;
  3.1468 +	    case 0x05:
  3.1469 +	      return register_TIMA;
  3.1470 +	    case 0x06:
  3.1471 +	      return register_TMA;
  3.1472 +	    case 0x07:
  3.1473 +	      return (0xf8 | register_TAC);
  3.1474 +	    case 0x0f:
  3.1475 +	      return (0xe0 | register_IF);
  3.1476 +	    case 0x40:
  3.1477 +	      return register_LCDC;
  3.1478 +	    case 0x41:
  3.1479 +	      return (0x80 | register_STAT);
  3.1480 +	    case 0x42:
  3.1481 +	      return register_SCY;
  3.1482 +	    case 0x43:
  3.1483 +	      return register_SCX;
  3.1484 +	    case 0x44:
  3.1485 +	      return register_LY;
  3.1486 +	    case 0x45:
  3.1487 +	      return register_LYC;
  3.1488 +	    case 0x46:
  3.1489 +	      return register_DMA;
  3.1490 +	    case 0x4a:
  3.1491 +	      return register_WY;
  3.1492 +	    case 0x4b:
  3.1493 +	      return register_WX;
  3.1494 +	    case 0x4f:
  3.1495 +	      return (0xfe | register_VBK);
  3.1496 +	    case 0x51:
  3.1497 +	      return register_HDMA1;
  3.1498 +	    case 0x52:
  3.1499 +	      return register_HDMA2;
  3.1500 +	    case 0x53:
  3.1501 +	      return register_HDMA3;
  3.1502 +	    case 0x54:
  3.1503 +	      return register_HDMA4;
  3.1504 +	    case 0x55:
  3.1505 +	      return register_HDMA5;
  3.1506 +	    case 0x70:
  3.1507 +	      return (0xf8 | register_SVBK);
  3.1508 +	    case 0xff:
  3.1509 +	      return register_IE;
  3.1510 +	    }
  3.1511  	}
  3.1512 -
  3.1513 -	if (address < 0xa000)
  3.1514 +      break;
  3.1515 +    }
  3.1516 +  return gbReadMemoryQuick(address);
  3.1517 +}
  3.1518 +
  3.1519 +void gbWriteMemory(register u16 address, register u8 value)
  3.1520 +{
  3.1521 +  gbWriteMemoryWrapped(address, value);
  3.1522 +  CallRegisteredLuaMemHook(address, 1, value, LUAMEMHOOK_WRITE);
  3.1523 +}
  3.1524 +
  3.1525 +u8 gbReadMemory(register u16 address)
  3.1526 +{
  3.1527 +  if (gbCheatMap[address])
  3.1528 +    return gbCheatRead(address);
  3.1529 +
  3.1530 +  if (address < 0xa000)
  3.1531 +    return gbReadMemoryQuick(address);
  3.1532 +
  3.1533 +  if (address < 0xc000)
  3.1534 +    {
  3.1535 +#ifndef FINAL_VERSION
  3.1536 +      if (memorydebug)
  3.1537  	{
  3.1538 -		gbWriteMemoryQuick(address, value);
  3.1539 -		return;
  3.1540 +	  log("Memory register read %04x PC=%04x\n",
  3.1541 +	      address,
  3.1542 +	      PC.W);
  3.1543  	}
  3.1544 -
  3.1545 -	if (address < 0xc000)
  3.1546 -	{
  3.1547 -#ifndef FINAL_VERSION
  3.1548 -		if (memorydebug)
  3.1549 -		{
  3.1550 -			log("Memory register write %04x=%02x PC=%04x\n",
  3.1551 -			    address,
  3.1552 -			    value,
  3.1553 -			    PC.W);
  3.1554 -		}
  3.1555  #endif
  3.1556  
  3.1557 -		if (mapper)
  3.1558 -			(*mapperRAM)(address, value);
  3.1559 -		return;
  3.1560 -	}
  3.1561 -
  3.1562 -	if (address < 0xfe00)
  3.1563 -	{
  3.1564 -		gbWriteMemoryQuick(address, value);
  3.1565 -		return;
  3.1566 -	}
  3.1567 -
  3.1568 -	if (address < 0xff00)
  3.1569 -	{
  3.1570 -		gbMemory[address] = value;
  3.1571 -		return;
  3.1572 -	}
  3.1573 -
  3.1574 -	switch (address & 0x00ff)
  3.1575 +      if (mapperReadRAM)
  3.1576 +	return mapperReadRAM(address);
  3.1577 +      return gbReadMemoryQuick(address);
  3.1578 +    }
  3.1579 +
  3.1580 +  if (address >= 0xff00)
  3.1581 +    {
  3.1582 +      switch (address & 0x00ff)
  3.1583  	{
  3.1584  	case 0x00:
  3.1585 -	{
  3.1586 -		gbMemory[0xff00] = ((gbMemory[0xff00] & 0xcf) |
  3.1587 -		                    (value & 0x30));
  3.1588 -		if (gbSgbMode)
  3.1589 -		{
  3.1590 -			gbSgbDoBitTransfer(value);
  3.1591 -		}
  3.1592 -
  3.1593 -		return;
  3.1594 +	  {
  3.1595 +	    if (gbSgbMode)
  3.1596 +	      {
  3.1597 +		gbSgbReadingController |= 4;
  3.1598 +		gbSgbResetPacketState();
  3.1599 +	      }
  3.1600 +
  3.1601 +	    int b = gbMemory[0xff00];
  3.1602 +
  3.1603 +	    if ((b & 0x30) == 0x20)
  3.1604 +	      {
  3.1605 +		b &= 0xf0;
  3.1606 +
  3.1607 +		int joy = 0;
  3.1608 +		if (gbSgbMode && gbSgbMultiplayer)
  3.1609 +		  {
  3.1610 +		    switch (gbSgbNextController)
  3.1611 +		      {
  3.1612 +		      case 0x0f:
  3.1613 +			joy = 0;
  3.1614 +			break;
  3.1615 +		      case 0x0e:
  3.1616 +			joy = 1;
  3.1617 +			break;
  3.1618 +		      case 0x0d:
  3.1619 +			joy = 2;
  3.1620 +			break;
  3.1621 +		      case 0x0c:
  3.1622 +			joy = 3;
  3.1623 +			break;
  3.1624 +		      default:
  3.1625 +			joy = 0;
  3.1626 +		      }
  3.1627 +		  }
  3.1628 +		int joystate = gbJoymask[joy];
  3.1629 +		if (!(joystate & 128))
  3.1630 +		  b |= 0x08;
  3.1631 +		if (!(joystate & 64))
  3.1632 +		  b |= 0x04;
  3.1633 +		if (!(joystate & 32))
  3.1634 +		  b |= 0x02;
  3.1635 +		if (!(joystate & 16))
  3.1636 +		  b |= 0x01;
  3.1637 +
  3.1638 +		gbMemory[0xff00] = b;
  3.1639 +	      }
  3.1640 +	    else if ((b & 0x30) == 0x10)
  3.1641 +	      {
  3.1642 +		b &= 0xf0;
  3.1643 +
  3.1644 +		int joy = 0;
  3.1645 +		if (gbSgbMode && gbSgbMultiplayer)
  3.1646 +		  {
  3.1647 +		    switch (gbSgbNextController)
  3.1648 +		      {
  3.1649 +		      case 0x0f:
  3.1650 +			joy = 0;
  3.1651 +			break;
  3.1652 +		      case 0x0e:
  3.1653 +			joy = 1;
  3.1654 +			break;
  3.1655 +		      case 0x0d:
  3.1656 +			joy = 2;
  3.1657 +			break;
  3.1658 +		      case 0x0c:
  3.1659 +			joy = 3;
  3.1660 +			break;
  3.1661 +		      default:
  3.1662 +			joy = 0;
  3.1663 +		      }
  3.1664 +		  }
  3.1665 +		int joystate = gbJoymask[joy];
  3.1666 +		if (!(joystate & 8))
  3.1667 +		  b |= 0x08;
  3.1668 +		if (!(joystate & 4))
  3.1669 +		  b |= 0x04;
  3.1670 +		if (!(joystate & 2))
  3.1671 +		  b |= 0x02;
  3.1672 +		if (!(joystate & 1))
  3.1673 +		  b |= 0x01;
  3.1674 +
  3.1675 +		gbMemory[0xff00] = b;
  3.1676 +	      }
  3.1677 +	    else
  3.1678 +	      {
  3.1679 +		if (gbSgbMode && gbSgbMultiplayer)
  3.1680 +		  {
  3.1681 +		    gbMemory[0xff00] = 0xf0 | gbSgbNextController;
  3.1682 +		  }
  3.1683 +		else
  3.1684 +		  {
  3.1685 +		    gbMemory[0xff00] = 0xff;
  3.1686 +		  }
  3.1687 +	      }
  3.1688 +	  }
  3.1689 +	  GBSystemCounters.lagged = false;
  3.1690 +	  return gbMemory[0xff00];
  3.1691 +	  break;
  3.1692 +	case 0x01:
  3.1693 +	  return gbMemory[0xff01];
  3.1694 +	case 0x04:
  3.1695 +	  return register_DIV;
  3.1696 +	case 0x05:
  3.1697 +	  return register_TIMA;
  3.1698 +	case 0x06:
  3.1699 +	  return register_TMA;
  3.1700 +	case 0x07:
  3.1701 +	  return (0xf8 | register_TAC);
  3.1702 +	case 0x0f:
  3.1703 +	  return (0xe0 | register_IF);
  3.1704 +	case 0x40:
  3.1705 +	  return register_LCDC;
  3.1706 +	case 0x41:
  3.1707 +	  return (0x80 | register_STAT);
  3.1708 +	case 0x42:
  3.1709 +	  return register_SCY;
  3.1710 +	case 0x43:
  3.1711 +	  return register_SCX;
  3.1712 +	case 0x44:
  3.1713 +	  return register_LY;
  3.1714 +	case 0x45:
  3.1715 +	  return register_LYC;
  3.1716 +	case 0x46:
  3.1717 +	  return register_DMA;
  3.1718 +	case 0x4a:
  3.1719 +	  return register_WY;
  3.1720 +	case 0x4b:
  3.1721 +	  return register_WX;
  3.1722 +	case 0x4f:
  3.1723 +	  return (0xfe | register_VBK);
  3.1724 +	case 0x51:
  3.1725 +	  return register_HDMA1;
  3.1726 +	case 0x52:
  3.1727 +	  return register_HDMA2;
  3.1728 +	case 0x53:
  3.1729 +	  return register_HDMA3;
  3.1730 +	case 0x54:
  3.1731 +	  return register_HDMA4;
  3.1732 +	case 0x55:
  3.1733 +	  return register_HDMA5;
  3.1734 +	case 0x70:
  3.1735 +	  return (0xf8 | register_SVBK);
  3.1736 +	case 0xff:
  3.1737 +	  return register_IE;
  3.1738  	}
  3.1739 -
  3.1740 -	case 0x01:
  3.1741 -	{
  3.1742 -		gbMemory[0xff01] = value;
  3.1743 -		return;
  3.1744 -	}
  3.1745 -
  3.1746 -	// serial control
  3.1747 -	case 0x02:
  3.1748 -	{
  3.1749 -		gbSerialOn		 = (value & 0x80);
  3.1750 -		gbMemory[0xff02] = value;
  3.1751 -		if (gbSerialOn)
  3.1752 -		{
  3.1753 -			gbSerialTicks = GBSERIAL_CLOCK_TICKS;
  3.1754 -#ifdef LINK_EMULATION
  3.1755 -			if (linkConnected)
  3.1756 -			{
  3.1757 -				if (value & 1)
  3.1758 -				{
  3.1759 -					linkSendByte(0x100 | gbMemory[0xFF01]);
  3.1760 -					Sleep(5);
  3.1761 -				}
  3.1762 -			}
  3.1763 -#endif
  3.1764 -		}
  3.1765 -
  3.1766 -		gbSerialBits = 0;
  3.1767 -		return;
  3.1768 -	}
  3.1769 -
  3.1770 -	// DIV register resets on any write
  3.1771 -	case 0x04:
  3.1772 -	{
  3.1773 -		register_DIV = 0;
  3.1774 -		return;
  3.1775 -	}
  3.1776 -	case 0x05:
  3.1777 -		register_TIMA = value;
  3.1778 -		return;
  3.1779 -
  3.1780 -	case 0x06:
  3.1781 -		register_TMA = value;
  3.1782 -		return;
  3.1783 -
  3.1784 -	// TIMER control
  3.1785 -	case 0x07:
  3.1786 -	{
  3.1787 -		register_TAC = value;
  3.1788 -
  3.1789 -		gbTimerOn	= (value & 4);
  3.1790 -		gbTimerMode = value & 3;
  3.1791 -		//    register_TIMA = register_TMA;
  3.1792 -		switch (gbTimerMode)
  3.1793 -		{
  3.1794 -		case 0:
  3.1795 -			gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_0_CLOCK_TICKS;
  3.1796 -			break;
  3.1797 -		case 1:
  3.1798 -			gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_1_CLOCK_TICKS;
  3.1799 -			break;
  3.1800 -		case 2:
  3.1801 -			gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_2_CLOCK_TICKS;
  3.1802 -			break;
  3.1803 -		case 3:
  3.1804 -			gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_3_CLOCK_TICKS;
  3.1805 -			break;
  3.1806 -		}
  3.1807 -		return;
  3.1808 -	}
  3.1809 -
  3.1810 -	case 0x0f:
  3.1811 -	{
  3.1812 -		register_IF = value;
  3.1813 -		gbInterrupt = value;
  3.1814 -		return;
  3.1815 -	}
  3.1816 -
  3.1817 -	case 0x10:
  3.1818 -	case 0x11:
  3.1819 -	case 0x12:
  3.1820 -	case 0x13:
  3.1821 -	case 0x14:
  3.1822 -	case 0x15:
  3.1823 -	case 0x16:
  3.1824 -	case 0x17:
  3.1825 -	case 0x18:
  3.1826 -	case 0x19:
  3.1827 -	case 0x1a:
  3.1828 -	case 0x1b:
  3.1829 -	case 0x1c:
  3.1830 -	case 0x1d:
  3.1831 -	case 0x1e:
  3.1832 -	case 0x1f:
  3.1833 -	case 0x20:
  3.1834 -	case 0x21:
  3.1835 -	case 0x22:
  3.1836 -	case 0x23:
  3.1837 -	case 0x24:
  3.1838 -	case 0x25:
  3.1839 -	case 0x26:
  3.1840 -	{
  3.1841 -		SOUND_EVENT(address, value);
  3.1842 -		return;
  3.1843 -	}
  3.1844 -	case 0x40:
  3.1845 -	{
  3.1846 -		int lcdChange = (register_LCDC & 0x80) ^ (value & 0x80);
  3.1847 -
  3.1848 -		if (lcdChange)
  3.1849 -		{
  3.1850 -			if (value & 0x80)
  3.1851 -			{
  3.1852 -				gbLcdTicks	   = GBLCD_MODE_1_CLOCK_TICKS;
  3.1853 -				gbLcdMode	   = 0;
  3.1854 -				register_STAT &= 0xfc;
  3.1855 -				register_LY	   = 0x00;
  3.1856 -				// FIXME: horrible workaround
  3.1857 -				if (gbNullInputHackTempEnabled && !useOldFrameTiming)
  3.1858 -					memcpy(gbJoymask, s_gbJoymask, sizeof(gbJoymask));
  3.1859 -			}
  3.1860 -			else
  3.1861 -			{
  3.1862 -				gbLcdTicks	   = 0;
  3.1863 -				gbLcdMode	   = 0;
  3.1864 -				register_STAT &= 0xfc;
  3.1865 -				register_LY	   = 0x00;
  3.1866 -				// FIXME: horrible workaround
  3.1867 -				memcpy(s_gbJoymask, gbJoymask, sizeof(gbJoymask));
  3.1868 -				if (gbNullInputHackTempEnabled && !useOldFrameTiming)
  3.1869 -					memset(gbJoymask, 0, sizeof(gbJoymask));
  3.1870 -			}
  3.1871 -			//      compareLYToLYC();
  3.1872 -		}
  3.1873 -		// don't draw the window if it was not enabled and not being drawn before
  3.1874 -		if (!(register_LCDC & 0x20) && (value & 0x20) && gbWindowLine == -1 &&
  3.1875 -		    register_LY > register_WY)
  3.1876 -			gbWindowLine = 144;
  3.1877 -
  3.1878 -		register_LCDC = value;
  3.1879 -
  3.1880 -		return;
  3.1881 -	}
  3.1882 -
  3.1883 -	// STAT
  3.1884 -	case 0x41:
  3.1885 -	{
  3.1886 -		//register_STAT = (register_STAT & 0x87) |
  3.1887 -		//      (value & 0x7c);
  3.1888 -		register_STAT = (value & 0xf8) | (register_STAT & 0x07);     // fix ?
  3.1889 -		// GB bug from Devrs FAQ
  3.1890 -		if (!gbCgbMode && (register_LCDC & 0x80) && gbLcdMode < 2)
  3.1891 -			gbInterrupt |= 2;
  3.1892 -		return;
  3.1893 -	}
  3.1894 -
  3.1895 -	// SCY
  3.1896 -	case 0x42:
  3.1897 -	{
  3.1898 -		register_SCY = value;
  3.1899 -		return;
  3.1900 -	}
  3.1901 -
  3.1902 -	// SCX
  3.1903 -	case 0x43:
  3.1904 -	{
  3.1905 -		register_SCX = value;
  3.1906 -		return;
  3.1907 -	}
  3.1908 -
  3.1909 -	// LY
  3.1910 -	case 0x44:
  3.1911 -	{
  3.1912 -		// read only
  3.1913 -		return;
  3.1914 -	}
  3.1915 -
  3.1916 -	// LYC
  3.1917 -	case 0x45:
  3.1918 -	{
  3.1919 -		register_LYC = value;
  3.1920 -		if ((register_LCDC & 0x80))
  3.1921 -		{
  3.1922 -			gbCompareLYToLYC();
  3.1923 -		}
  3.1924 -		return;
  3.1925 -	}
  3.1926 -
  3.1927 -	// DMA!
  3.1928 -	case 0x46:
  3.1929 -	{
  3.1930 -		int source = value * 0x0100;
  3.1931 -
  3.1932 -		gbCopyMemory(0xfe00,
  3.1933 -		             source,
  3.1934 -		             0xa0);
  3.1935 -		register_DMA = value;
  3.1936 -		return;
  3.1937 -	}
  3.1938 -
  3.1939 -	// BGP
  3.1940 -	case 0x47:
  3.1941 -	{
  3.1942 -		gbBgp[0] = value & 0x03;
  3.1943 -		gbBgp[1] = (value & 0x0c) >> 2;
  3.1944 -		gbBgp[2] = (value & 0x30) >> 4;
  3.1945 -		gbBgp[3] = (value & 0xc0) >> 6;
  3.1946 -		break;
  3.1947 -	}
  3.1948 -
  3.1949 -	// OBP0
  3.1950 -	case 0x48:
  3.1951 -	{
  3.1952 -		gbObp0[0] = value & 0x03;
  3.1953 -		gbObp0[1] = (value & 0x0c) >> 2;
  3.1954 -		gbObp0[2] = (value & 0x30) >> 4;
  3.1955 -		gbObp0[3] = (value & 0xc0) >> 6;
  3.1956 -		break;
  3.1957 -	}
  3.1958 -
  3.1959 -	// OBP1
  3.1960 -	case 0x49:
  3.1961 -	{
  3.1962 -		gbObp1[0] = value & 0x03;
  3.1963 -		gbObp1[1] = (value & 0x0c) >> 2;
  3.1964 -		gbObp1[2] = (value & 0x30) >> 4;
  3.1965 -		gbObp1[3] = (value & 0xc0) >> 6;
  3.1966 -		break;
  3.1967 -	}
  3.1968 -
  3.1969 -	case 0x4a:
  3.1970 -		register_WY = value;
  3.1971 -		return;
  3.1972 -
  3.1973 -	case 0x4b:
  3.1974 -		register_WX = value;
  3.1975 -		return;
  3.1976 -
  3.1977 -	// KEY1
  3.1978 -	case 0x4d:
  3.1979 -	{
  3.1980 -		if (gbCgbMode)
  3.1981 -		{
  3.1982 -			gbMemory[0xff4d] = (gbMemory[0xff4d] & 0x80) | (value & 1);
  3.1983 -			return;
  3.1984 -		}
  3.1985 -		break;
  3.1986 -	}
  3.1987 -
  3.1988 -	// VBK
  3.1989 -	case 0x4f:
  3.1990 -	{
  3.1991 -		if (gbCgbMode)
  3.1992 -		{
  3.1993 -			value = value & 1;
  3.1994 -			if (value == gbVramBank)
  3.1995 -				return;
  3.1996 -
  3.1997 -			int vramAddress = value * 0x2000;
  3.1998 -			gbMemoryMap[0x08] = &gbVram[vramAddress];
  3.1999 -			gbMemoryMap[0x09] = &gbVram[vramAddress + 0x1000];
  3.2000 -
  3.2001 -			gbVramBank	 = value;
  3.2002 -			register_VBK = value;
  3.2003 -		}
  3.2004 -		return;
  3.2005 -		break;
  3.2006 -	}
  3.2007 -
  3.2008 -	// HDMA1
  3.2009 -	case 0x51:
  3.2010 -	{
  3.2011 -		if (gbCgbMode)
  3.2012 -		{
  3.2013 -			if (value > 0x7f && value < 0xa0)
  3.2014 -				value = 0;
  3.2015 -
  3.2016 -			gbHdmaSource = (value << 8) | (register_HDMA2 & 0xf0);
  3.2017 -
  3.2018 -			register_HDMA1 = value;
  3.2019 -			return;
  3.2020 -		}
  3.2021 -		break;
  3.2022 -	}
  3.2023 -
  3.2024 -	// HDMA2
  3.2025 -	case 0x52:
  3.2026 -	{
  3.2027 -		if (gbCgbMode)
  3.2028 -		{
  3.2029 -			value = value & 0xf0;
  3.2030 -
  3.2031 -			gbHdmaSource = (register_HDMA1 << 8) | (value);
  3.2032 -
  3.2033 -			register_HDMA2 = value;
  3.2034 -			return;
  3.2035 -		}
  3.2036 -		break;
  3.2037 -	}
  3.2038 -
  3.2039 -	// HDMA3
  3.2040 -	case 0x53:
  3.2041 -	{
  3.2042 -		if (gbCgbMode)
  3.2043 -		{
  3.2044 -			value = value & 0x1f;
  3.2045 -			gbHdmaDestination  = (value << 8) | (register_HDMA4 & 0xf0);
  3.2046 -			gbHdmaDestination += 0x8000;
  3.2047 -			register_HDMA3	   = value;
  3.2048 -			return;
  3.2049 -		}
  3.2050 -		break;
  3.2051 -	}
  3.2052 -
  3.2053 -	// HDMA4
  3.2054 -	case 0x54:
  3.2055 -	{
  3.2056 -		if (gbCgbMode)
  3.2057 -		{
  3.2058 -			value = value & 0xf0;
  3.2059 -			gbHdmaDestination  = ((register_HDMA3 & 0x1f) << 8) | value;
  3.2060 -			gbHdmaDestination += 0x8000;
  3.2061 -			register_HDMA4	   = value;
  3.2062 -			return;
  3.2063 -		}
  3.2064 -		break;
  3.2065 -	}
  3.2066 -
  3.2067 -	// HDMA5
  3.2068 -	case 0x55:
  3.2069 -	{
  3.2070 -		if (gbCgbMode)
  3.2071 -		{
  3.2072 -			gbHdmaBytes = 16 + (value & 0x7f) * 16;
  3.2073 -			if (gbHdmaOn)
  3.2074 -			{
  3.2075 -				if (value & 0x80)
  3.2076 -				{
  3.2077 -					register_HDMA5 = (value & 0x7f);
  3.2078 -				}
  3.2079 -				else
  3.2080 -				{
  3.2081 -					register_HDMA5 = 0xff;
  3.2082 -					gbHdmaOn	   = 0;
  3.2083 -				}
  3.2084 -			}
  3.2085 -			else
  3.2086 -			{
  3.2087 -				if (value & 0x80)
  3.2088 -				{
  3.2089 -					gbHdmaOn	   = 1;
  3.2090 -					register_HDMA5 = value & 0x7f;
  3.2091 -					if (gbLcdMode == 0)
  3.2092 -						gbDoHdma();
  3.2093 -				}
  3.2094 -				else
  3.2095 -				{
  3.2096 -					// we need to take the time it takes to complete the transfer into
  3.2097 -					// account... according to GB DEV FAQs, the setup time is the same
  3.2098 -					// for single and double speed, but the actual transfer takes the
  3.2099 -					// same time // (is that a typo?)
  3.2100 -					switch (gbDMASpeedVersion)
  3.2101 -					{
  3.2102 -					case 1:     // I believe this is more correct
  3.2103 -						// the lower 7 bits of FF55 specify the Transfer Length (divided by 16, minus 1)
  3.2104 -						// and we make gbDmaTicks twice as many cycles at double speed to make the transfer take the same time
  3.2105 -						if (gbSpeed)
  3.2106 -							gbDmaTicks = 16 * ((value & 0x7f) + 1);
  3.2107 -						else
  3.2108 -							gbDmaTicks = 8 * ((value & 0x7f) + 1);
  3.2109 -						break;
  3.2110 -					case 0:     // here for backward compatibility
  3.2111 -						// I think this was a guess that approximates the above in most but not all games
  3.2112 -						if (gbSpeed)
  3.2113 -							gbDmaTicks = 231 + 16 * (value & 0x7f);
  3.2114 -						else
  3.2115 -							gbDmaTicks = 231 + 8 * (value & 0x7f);
  3.2116 -						break;
  3.2117 -					default:     // shouldn't happen
  3.2118 -						//assert(0);
  3.2119 -						break;
  3.2120 -					}
  3.2121 -					gbCopyMemory(gbHdmaDestination, gbHdmaSource, gbHdmaBytes);
  3.2122 -					gbHdmaDestination += gbHdmaBytes;
  3.2123 -					gbHdmaSource	  += gbHdmaBytes;
  3.2124 -
  3.2125 -					register_HDMA3 = ((gbHdmaDestination - 0x8000) >> 8) & 0x1f;
  3.2126 -					register_HDMA4 = gbHdmaDestination & 0xf0;
  3.2127 -					register_HDMA1 = (gbHdmaSource >> 8) & 0xff;
  3.2128 -					register_HDMA2 = gbHdmaSource & 0xf0;
  3.2129 -				}
  3.2130 -			}
  3.2131 -			return;
  3.2132 -		}
  3.2133 -		break;
  3.2134 -	}
  3.2135 -
  3.2136 -	// BCPS
  3.2137 -	case 0x68:
  3.2138 -	{
  3.2139 -		if (gbCgbMode)
  3.2140 -		{
  3.2141 -			int paletteIndex = (value & 0x3f) >> 1;
  3.2142 -			int paletteHiLo	 = (value & 0x01);
  3.2143 -
  3.2144 -			gbMemory[0xff68] = value;
  3.2145 -			gbMemory[0xff69] = (paletteHiLo ?
  3.2146 -			                    (gbPalette[paletteIndex] >> 8) :
  3.2147 -			                    (gbPalette[paletteIndex] & 0x00ff));
  3.2148 -			return;
  3.2149 -		}
  3.2150 -		break;
  3.2151 -	}
  3.2152 -
  3.2153 -	// BCPD
  3.2154 -	case 0x69:
  3.2155 -	{
  3.2156 -		if (gbCgbMode)
  3.2157 -		{
  3.2158 -			int v = gbMemory[0xff68];
  3.2159 -			int paletteIndex = (v & 0x3f) >> 1;
  3.2160 -			int paletteHiLo	 = (v & 0x01);
  3.2161 -			gbMemory[0xff69]		= value;
  3.2162 -			gbPalette[paletteIndex] = (paletteHiLo ?
  3.2163 -			                           ((value << 8) | (gbPalette[paletteIndex] & 0xff)) :
  3.2164 -			                           ((gbPalette[paletteIndex] & 0xff00) | (value))) & 0x7fff;
  3.2165 -
  3.2166 -			if (gbMemory[0xff68] & 0x80)
  3.2167 -			{
  3.2168 -				int index = ((gbMemory[0xff68] & 0x3f) + 1) & 0x3f;
  3.2169 -
  3.2170 -				gbMemory[0xff68] = (gbMemory[0xff68] & 0x80) | index;
  3.2171 -
  3.2172 -				gbMemory[0xff69] = (index & 1 ?
  3.2173 -				                    (gbPalette[index >> 1] >> 8) :
  3.2174 -				                    (gbPalette[index >> 1] & 0x00ff));
  3.2175 -			}
  3.2176 -			return;
  3.2177 -		}
  3.2178 -		break;
  3.2179 -	}
  3.2180 -
  3.2181 -	// OCPS
  3.2182 -	case 0x6a:
  3.2183 -	{
  3.2184 -		if (gbCgbMode)
  3.2185 -		{
  3.2186 -			int paletteIndex = (value & 0x3f) >> 1;
  3.2187 -			int paletteHiLo	 = (value & 0x01);
  3.2188 -
  3.2189 -			paletteIndex += 32;
  3.2190 -
  3.2191 -			gbMemory[0xff6a] = value;
  3.2192 -			gbMemory[0xff6b] = (paletteHiLo ?
  3.2193 -			                    (gbPalette[paletteIndex] >> 8) :
  3.2194 -			                    (gbPalette[paletteIndex] & 0x00ff));
  3.2195 -			return;
  3.2196 -		}
  3.2197 -		break;
  3.2198 -	}
  3.2199 -
  3.2200 -	// OCPD
  3.2201 -	case 0x6b:
  3.2202 -	{
  3.2203 -		if (gbCgbMode)
  3.2204 -		{
  3.2205 -			int v = gbMemory[0xff6a];
  3.2206 -			int paletteIndex = (v & 0x3f) >> 1;
  3.2207 -			int paletteHiLo	 = (v & 0x01);
  3.2208 -
  3.2209 -			paletteIndex += 32;
  3.2210 -
  3.2211 -			gbMemory[0xff6b]		= value;
  3.2212 -			gbPalette[paletteIndex] = (paletteHiLo ?
  3.2213 -			                           ((value << 8) | (gbPalette[paletteIndex] & 0xff)) :
  3.2214 -			                           ((gbPalette[paletteIndex] & 0xff00) | (value))) & 0x7fff;
  3.2215 -			if (gbMemory[0xff6a] & 0x80)
  3.2216 -			{
  3.2217 -				int index = ((gbMemory[0xff6a] & 0x3f) + 1) & 0x3f;
  3.2218 -
  3.2219 -				gbMemory[0xff6a] = (gbMemory[0xff6a] & 0x80) | index;
  3.2220 -
  3.2221 -				gbMemory[0xff6b] = (index & 1 ?
  3.2222 -				                    (gbPalette[(index >> 1) + 32] >> 8) :
  3.2223 -				                    (gbPalette[(index >> 1) + 32] & 0x00ff));
  3.2224 -			}
  3.2225 -			return;
  3.2226 -		}
  3.2227 -		break;
  3.2228 -	}
  3.2229 -
  3.2230 -	// SVBK
  3.2231 -	case 0x70:
  3.2232 -	{
  3.2233 -		if (gbCgbMode)
  3.2234 -		{
  3.2235 -			value = value & 7;
  3.2236 -
  3.2237 -			int bank = value;
  3.2238 -			if (value == 0)
  3.2239 -				bank = 1;
  3.2240 -
  3.2241 -			if (bank == gbWramBank)
  3.2242 -				return;
  3.2243 -
  3.2244 -			int wramAddress = bank * 0x1000;
  3.2245 -			gbMemoryMap[0x0d] = &gbWram[wramAddress];
  3.2246 -
  3.2247 -			gbWramBank	  = bank;
  3.2248 -			register_SVBK = value;
  3.2249 -			return;
  3.2250 -		}
  3.2251 -		break;
  3.2252 -	}
  3.2253 -
  3.2254 -	case 0xff:
  3.2255 -	{
  3.2256 -		register_IE	 = value;
  3.2257 -		register_IF &= value;
  3.2258 -		return;
  3.2259 -	}
  3.2260 -	}
  3.2261 -
  3.2262 -	gbWriteMemoryQuick(address, value);
  3.2263 -}
  3.2264 -
  3.2265 -u8 gbReadOpcode(register u16 address)
  3.2266 -{
  3.2267 -	if (gbCheatMap[address])
  3.2268 -		return gbCheatRead(address);
  3.2269 -
  3.2270 -	// the following fix does more than Echo RAM fix, anyway...
  3.2271 -	switch (gbEchoRAMFixOn ? (address >> 12) & 0x000f : address & 0xf000)
  3.2272 -	{
  3.2273 -	case 0x0a:
  3.2274 -	case 0x0b:
  3.2275 -		if (mapperReadRAM)
  3.2276 -			return mapperReadRAM(address);
  3.2277 -		break;
  3.2278 -	case 0x0f:
  3.2279 -		if (address > 0xff00)
  3.2280 -		{
  3.2281 -			switch (address & 0x00ff)
  3.2282 -			{
  3.2283 -			case 0x04:
  3.2284 -				return register_DIV;
  3.2285 -			case 0x05:
  3.2286 -				return register_TIMA;
  3.2287 -			case 0x06:
  3.2288 -				return register_TMA;
  3.2289 -			case 0x07:
  3.2290 -				return (0xf8 | register_TAC);
  3.2291 -			case 0x0f:
  3.2292 -				return (0xe0 | register_IF);
  3.2293 -			case 0x40:
  3.2294 -				return register_LCDC;
  3.2295 -			case 0x41:
  3.2296 -				return (0x80 | register_STAT);
  3.2297 -			case 0x42:
  3.2298 -				return register_SCY;
  3.2299 -			case 0x43:
  3.2300 -				return register_SCX;
  3.2301 -			case 0x44:
  3.2302 -				return register_LY;
  3.2303 -			case 0x45:
  3.2304 -				return register_LYC;
  3.2305 -			case 0x46:
  3.2306 -				return register_DMA;
  3.2307 -			case 0x4a:
  3.2308 -				return register_WY;
  3.2309 -			case 0x4b:
  3.2310 -				return register_WX;
  3.2311 -			case 0x4f:
  3.2312 -				return (0xfe | register_VBK);
  3.2313 -			case 0x51:
  3.2314 -				return register_HDMA1;
  3.2315 -			case 0x52:
  3.2316 -				return register_HDMA2;
  3.2317 -			case 0x53:
  3.2318 -				return register_HDMA3;
  3.2319 -			case 0x54:
  3.2320 -				return register_HDMA4;
  3.2321 -			case 0x55:
  3.2322 -				return register_HDMA5;
  3.2323 -			case 0x70:
  3.2324 -				return (0xf8 | register_SVBK);
  3.2325 -			case 0xff:
  3.2326 -				return register_IE;
  3.2327 -			}
  3.2328 -		}
  3.2329 -		break;
  3.2330 -	}
  3.2331 -	return gbReadMemoryQuick(address);
  3.2332 -}
  3.2333 -
  3.2334 -void gbWriteMemory(register u16 address, register u8 value)
  3.2335 -{
  3.2336 -	gbWriteMemoryWrapped(address, value);
  3.2337 -	CallRegisteredLuaMemHook(address, 1, value, LUAMEMHOOK_WRITE);
  3.2338 -}
  3.2339 -
  3.2340 -u8 gbReadMemory(register u16 address)
  3.2341 -{
  3.2342 -	if (gbCheatMap[address])
  3.2343 -		return gbCheatRead(address);
  3.2344 -
  3.2345 -	if (address < 0xa000)
  3.2346 -		return gbReadMemoryQuick(address);
  3.2347 -
  3.2348 -	if (address < 0xc000)
  3.2349 -	{
  3.2350 -#ifndef FINAL_VERSION
  3.2351 -		if (memorydebug)
  3.2352 -		{
  3.2353 -			log("Memory register read %04x PC=%04x\n",
  3.2354 -			    address,
  3.2355 -			    PC.W);
  3.2356 -		}
  3.2357 -#endif
  3.2358 -
  3.2359 -		if (mapperReadRAM)
  3.2360 -			return mapperReadRAM(address);
  3.2361 -		return gbReadMemoryQuick(address);
  3.2362 -	}
  3.2363 -
  3.2364 -	if (address >= 0xff00)
  3.2365 -	{
  3.2366 -		switch (address & 0x00ff)
  3.2367 -		{
  3.2368 -		case 0x00:
  3.2369 -		{
  3.2370 -			if (gbSgbMode)
  3.2371 -			{
  3.2372 -				gbSgbReadingController |= 4;
  3.2373 -				gbSgbResetPacketState();
  3.2374 -			}
  3.2375 -
  3.2376 -			int b = gbMemory[0xff00];
  3.2377 -
  3.2378 -			if ((b & 0x30) == 0x20)
  3.2379 -			{
  3.2380 -				b &= 0xf0;
  3.2381 -
  3.2382 -				int joy = 0;
  3.2383 -				if (gbSgbMode && gbSgbMultiplayer)
  3.2384 -				{
  3.2385 -					switch (gbSgbNextController)
  3.2386 -					{
  3.2387 -					case 0x0f:
  3.2388 -						joy = 0;
  3.2389 -						break;
  3.2390 -					case 0x0e:
  3.2391 -						joy = 1;
  3.2392 -						break;
  3.2393 -					case 0x0d:
  3.2394 -						joy = 2;
  3.2395 -						break;
  3.2396 -					case 0x0c:
  3.2397 -						joy = 3;
  3.2398 -						break;
  3.2399 -					default:
  3.2400 -						joy = 0;
  3.2401 -					}
  3.2402 -				}
  3.2403 -				int joystate = gbJoymask[joy];
  3.2404 -				if (!(joystate & 128))
  3.2405 -					b |= 0x08;
  3.2406 -				if (!(joystate & 64))
  3.2407 -					b |= 0x04;
  3.2408 -				if (!(joystate & 32))
  3.2409 -					b |= 0x02;
  3.2410 -				if (!(joystate & 16))
  3.2411 -					b |= 0x01;
  3.2412 -
  3.2413 -				gbMemory[0xff00] = b;
  3.2414 -			}
  3.2415 -			else if ((b & 0x30) == 0x10)
  3.2416 -			{
  3.2417 -				b &= 0xf0;
  3.2418 -
  3.2419 -				int joy = 0;
  3.2420 -				if (gbSgbMode && gbSgbMultiplayer)
  3.2421 -				{
  3.2422 -					switch (gbSgbNextController)
  3.2423 -					{
  3.2424 -					case 0x0f:
  3.2425 -						joy = 0;
  3.2426 -						break;
  3.2427 -					case 0x0e:
  3.2428 -						joy = 1;
  3.2429 -						break;
  3.2430 -					case 0x0d:
  3.2431 -						joy = 2;
  3.2432 -						break;
  3.2433 -					case 0x0c:
  3.2434 -						joy = 3;
  3.2435 -						break;
  3.2436 -					default:
  3.2437 -						joy = 0;
  3.2438 -					}
  3.2439 -				}
  3.2440 -				int joystate = gbJoymask[joy];
  3.2441 -				if (!(joystate & 8))
  3.2442 -					b |= 0x08;
  3.2443 -				if (!(joystate & 4))
  3.2444 -					b |= 0x04;
  3.2445 -				if (!(joystate & 2))
  3.2446 -					b |= 0x02;
  3.2447 -				if (!(joystate & 1))
  3.2448 -					b |= 0x01;
  3.2449 -
  3.2450 -				gbMemory[0xff00] = b;
  3.2451 -			}
  3.2452 -			else
  3.2453 -			{
  3.2454 -				if (gbSgbMode && gbSgbMultiplayer)
  3.2455 -				{
  3.2456 -					gbMemory[0xff00] = 0xf0 | gbSgbNextController;
  3.2457 -				}
  3.2458 -				else
  3.2459 -				{
  3.2460 -					gbMemory[0xff00] = 0xff;
  3.2461 -				}
  3.2462 -			}
  3.2463 -		}
  3.2464 -			GBSystemCounters.lagged = false;
  3.2465 -			return gbMemory[0xff00];
  3.2466 -			break;
  3.2467 -		case 0x01:
  3.2468 -			return gbMemory[0xff01];
  3.2469 -		case 0x04:
  3.2470 -			return register_DIV;
  3.2471 -		case 0x05:
  3.2472 -			return register_TIMA;
  3.2473 -		case 0x06:
  3.2474 -			return register_TMA;
  3.2475 -		case 0x07:
  3.2476 -			return (0xf8 | register_TAC);
  3.2477 -		case 0x0f:
  3.2478 -			return (0xe0 | register_IF);
  3.2479 -		case 0x40:
  3.2480 -			return register_LCDC;
  3.2481 -		case 0x41:
  3.2482 -			return (0x80 | register_STAT);
  3.2483 -		case 0x42:
  3.2484 -			return register_SCY;
  3.2485 -		case 0x43:
  3.2486 -			return register_SCX;
  3.2487 -		case 0x44:
  3.2488 -			return register_LY;
  3.2489 -		case 0x45:
  3.2490 -			return register_LYC;
  3.2491 -		case 0x46:
  3.2492 -			return register_DMA;
  3.2493 -		case 0x4a:
  3.2494 -			return register_WY;
  3.2495 -		case 0x4b:
  3.2496 -			return register_WX;
  3.2497 -		case 0x4f:
  3.2498 -			return (0xfe | register_VBK);
  3.2499 -		case 0x51:
  3.2500 -			return register_HDMA1;
  3.2501 -		case 0x52:
  3.2502 -			return register_HDMA2;
  3.2503 -		case 0x53:
  3.2504 -			return register_HDMA3;
  3.2505 -		case 0x54:
  3.2506 -			return register_HDMA4;
  3.2507 -		case 0x55:
  3.2508 -			return register_HDMA5;
  3.2509 -		case 0x70:
  3.2510 -			return (0xf8 | register_SVBK);
  3.2511 -		case 0xff:
  3.2512 -			return register_IE;
  3.2513 -		}
  3.2514 -	}
  3.2515 -
  3.2516 -	return gbReadMemoryQuick(address);
  3.2517 +    }
  3.2518 +
  3.2519 +  return gbReadMemoryQuick(address);
  3.2520  }
  3.2521  
  3.2522  void gbVblank_interrupt()
  3.2523  {
  3.2524 -	if (IFF & 0x80)
  3.2525 -	{
  3.2526 -		PC.W++;
  3.2527 -		IFF &= 0x7f;
  3.2528 -	}
  3.2529 -	gbInterrupt &= 0xfe;
  3.2530 -
  3.2531 -	IFF			&= 0x7e;
  3.2532 -	register_IF &= 0xfe;
  3.2533 -
  3.2534 -	gbWriteMemory(--SP.W, PC.B.B1);
  3.2535 -	gbWriteMemory(--SP.W, PC.B.B0);
  3.2536 -	PC.W = 0x40;
  3.2537 +  if (IFF & 0x80)
  3.2538 +    {
  3.2539 +      PC.W++;
  3.2540 +      IFF &= 0x7f;
  3.2541 +    }
  3.2542 +  gbInterrupt &= 0xfe;
  3.2543 +
  3.2544 +  IFF			&= 0x7e;
  3.2545 +  register_IF &= 0xfe;
  3.2546 +
  3.2547 +  gbWriteMemory(--SP.W, PC.B.B1);
  3.2548 +  gbWriteMemory(--SP.W, PC.B.B0);
  3.2549 +  PC.W = 0x40;
  3.2550  }
  3.2551  
  3.2552  void gbLcd_interrupt()
  3.2553  {
  3.2554 -	if (IFF & 0x80)
  3.2555 -	{
  3.2556 -		PC.W++;
  3.2557 -		IFF &= 0x7f;
  3.2558 -	}
  3.2559 -	gbInterrupt &= 0xfd;
  3.2560 -	IFF			&= 0x7e;
  3.2561 -	register_IF &= 0xfd;
  3.2562 -
  3.2563 -	gbWriteMemory(--SP.W, PC.B.B1);
  3.2564 -	gbWriteMemory(--SP.W, PC.B.B0);
  3.2565 -
  3.2566 -	PC.W = 0x48;
  3.2567 +  if (IFF & 0x80)
  3.2568 +    {
  3.2569 +      PC.W++;
  3.2570 +      IFF &= 0x7f;
  3.2571 +    }
  3.2572 +  gbInterrupt &= 0xfd;
  3.2573 +  IFF			&= 0x7e;
  3.2574 +  register_IF &= 0xfd;
  3.2575 +
  3.2576 +  gbWriteMemory(--SP.W, PC.B.B1);
  3.2577 +  gbWriteMemory(--SP.W, PC.B.B0);
  3.2578 +
  3.2579 +  PC.W = 0x48;
  3.2580  }
  3.2581  
  3.2582  void gbTimer_interrupt()
  3.2583  {
  3.2584 -	if (IFF & 0x80)
  3.2585 -	{
  3.2586 -		PC.W++;
  3.2587 -		IFF &= 0x7f;
  3.2588 -	}
  3.2589 -	IFF			&= 0x7e;
  3.2590 -	gbInterrupt &= 0xfb;
  3.2591 -	register_IF &= 0xfb;
  3.2592 -
  3.2593 -	gbWriteMemory(--SP.W, PC.B.B1);
  3.2594 -	gbWriteMemory(--SP.W, PC.B.B0);
  3.2595 -
  3.2596 -	PC.W = 0x50;
  3.2597 +  if (IFF & 0x80)
  3.2598 +    {
  3.2599 +      PC.W++;
  3.2600 +      IFF &= 0x7f;
  3.2601 +    }
  3.2602 +  IFF			&= 0x7e;
  3.2603 +  gbInterrupt &= 0xfb;
  3.2604 +  register_IF &= 0xfb;
  3.2605 +
  3.2606 +  gbWriteMemory(--SP.W, PC.B.B1);
  3.2607 +  gbWriteMemory(--SP.W, PC.B.B0);
  3.2608 +
  3.2609 +  PC.W = 0x50;
  3.2610  }
  3.2611  
  3.2612  void gbSerial_interrupt()
  3.2613  {
  3.2614 -	if (IFF & 0x80)
  3.2615 -	{
  3.2616 -		PC.W++;
  3.2617 -		IFF &= 0x7f;
  3.2618 -	}
  3.2619 -	IFF			&= 0x7e;
  3.2620 -	gbInterrupt &= 0xf7;
  3.2621 -	register_IF &= 0xf7;
  3.2622 -
  3.2623 -	gbWriteMemory(--SP.W, PC.B.B1);
  3.2624 -	gbWriteMemory(--SP.W, PC.B.B0);
  3.2625 -
  3.2626 -	PC.W = 0x58;
  3.2627 +  if (IFF & 0x80)
  3.2628 +    {
  3.2629 +      PC.W++;
  3.2630 +      IFF &= 0x7f;
  3.2631 +    }
  3.2632 +  IFF			&= 0x7e;
  3.2633 +  gbInterrupt &= 0xf7;
  3.2634 +  register_IF &= 0xf7;
  3.2635 +
  3.2636 +  gbWriteMemory(--SP.W, PC.B.B1);
  3.2637 +  gbWriteMemory(--SP.W, PC.B.B0);
  3.2638 +
  3.2639 +  PC.W = 0x58;
  3.2640  }
  3.2641  
  3.2642  void gbJoypad_interrupt()
  3.2643  {
  3.2644 -	if (IFF & 0x80)
  3.2645 -	{
  3.2646 -		PC.W++;
  3.2647 -		IFF &= 0x7f;
  3.2648 -	}
  3.2649 -	IFF			&= 0x7e;
  3.2650 -	gbInterrupt &= 0xef;
  3.2651 -	register_IF &= 0xef;
  3.2652 -
  3.2653 -	gbWriteMemory(--SP.W, PC.B.B1);
  3.2654 -	gbWriteMemory(--SP.W, PC.B.B0);
  3.2655 -
  3.2656 -	PC.W = 0x60;
  3.2657 +  if (IFF & 0x80)
  3.2658 +    {
  3.2659 +      PC.W++;
  3.2660 +      IFF &= 0x7f;
  3.2661 +    }
  3.2662 +  IFF			&= 0x7e;
  3.2663 +  gbInterrupt &= 0xef;
  3.2664 +  register_IF &= 0xef;
  3.2665 +
  3.2666 +  gbWriteMemory(--SP.W, PC.B.B1);
  3.2667 +  gbWriteMemory(--SP.W, PC.B.B0);
  3.2668 +
  3.2669 +  PC.W = 0x60;
  3.2670  }
  3.2671  
  3.2672  void gbSpeedSwitch()
  3.2673  {
  3.2674 -	if (gbSpeed == 0)
  3.2675 -	{
  3.2676 -		gbSpeed = 1;
  3.2677 -		GBLCD_MODE_0_CLOCK_TICKS   = 51 * 2; //127; //51 * 2;
  3.2678 -		GBLCD_MODE_1_CLOCK_TICKS   = 1140 * 2;
  3.2679 -		GBLCD_MODE_2_CLOCK_TICKS   = 20 * 2; //52; //20 * 2;
  3.2680 -		GBLCD_MODE_3_CLOCK_TICKS   = 43 * 2; //99; //43 * 2;
  3.2681 -		GBDIV_CLOCK_TICKS		   = 64 * 2;
  3.2682 -		GBLY_INCREMENT_CLOCK_TICKS = 114 * 2;
  3.2683 -		GBTIMER_MODE_0_CLOCK_TICKS = 256; //256*2;
  3.2684 -		GBTIMER_MODE_1_CLOCK_TICKS = 4; //4*2;
  3.2685 -		GBTIMER_MODE_2_CLOCK_TICKS = 16; //16*2;
  3.2686 -		GBTIMER_MODE_3_CLOCK_TICKS = 64; //64*2;
  3.2687 -		GBSERIAL_CLOCK_TICKS	   = 128 * 2;
  3.2688 -		gbDivTicks *= 2;
  3.2689 -		gbLcdTicks *= 2;
  3.2690 -		gbLcdLYIncrementTicks *= 2;
  3.2691 -		//    timerTicks *= 2;
  3.2692 -		//    timerClockTicks *= 2;
  3.2693 -		gbSerialTicks	 *= 2;
  3.2694 -		SOUND_CLOCK_TICKS = soundQuality * GB_USE_TICKS_AS * 2;
  3.2695 -		soundTicks		 *= 2;
  3.2696 -		//    synchronizeTicks *= 2;
  3.2697 -		//    SYNCHRONIZE_CLOCK_TICKS *= 2;
  3.2698 -	}
  3.2699 -	else
  3.2700 -	{
  3.2701 -		gbSpeed = 0;
  3.2702 -		GBLCD_MODE_0_CLOCK_TICKS   = 51;
  3.2703 -		GBLCD_MODE_1_CLOCK_TICKS   = 1140;
  3.2704 -		GBLCD_MODE_2_CLOCK_TICKS   = 20;
  3.2705 -		GBLCD_MODE_3_CLOCK_TICKS   = 43;
  3.2706 -		GBDIV_CLOCK_TICKS		   = 64;
  3.2707 -		GBLY_INCREMENT_CLOCK_TICKS = 114;
  3.2708 -		GBTIMER_MODE_0_CLOCK_TICKS = 256;
  3.2709 -		GBTIMER_MODE_1_CLOCK_TICKS = 4;
  3.2710 -		GBTIMER_MODE_2_CLOCK_TICKS = 16;
  3.2711 -		GBTIMER_MODE_3_CLOCK_TICKS = 64;
  3.2712 -		GBSERIAL_CLOCK_TICKS	   = 128;
  3.2713 -		gbDivTicks /= 2;
  3.2714 -		gbLcdTicks /= 2;
  3.2715 -		gbLcdLYIncrementTicks /= 2;
  3.2716 -		//    timerTicks /= 2;
  3.2717 -		//    timerClockTicks /= 2;
  3.2718 -		gbSerialTicks	 /= 2;
  3.2719 -		SOUND_CLOCK_TICKS = soundQuality * GB_USE_TICKS_AS;
  3.2720 -		soundTicks		 /= 2;
  3.2721 -		//    synchronizeTicks /= 2;
  3.2722 -		//    SYNCHRONIZE_CLOCK_TICKS /= 2;
  3.2723 -	}
  3.2724 +  if (gbSpeed == 0)
  3.2725 +    {
  3.2726 +      gbSpeed = 1;
  3.2727 +      GBLCD_MODE_0_CLOCK_TICKS   = 51 * 2; //127; //51 * 2;
  3.2728 +      GBLCD_MODE_1_CLOCK_TICKS   = 1140 * 2;
  3.2729 +      GBLCD_MODE_2_CLOCK_TICKS   = 20 * 2; //52; //20 * 2;
  3.2730 +      GBLCD_MODE_3_CLOCK_TICKS   = 43 * 2; //99; //43 * 2;
  3.2731 +      GBDIV_CLOCK_TICKS		   = 64 * 2;
  3.2732 +      GBLY_INCREMENT_CLOCK_TICKS = 114 * 2;
  3.2733 +      GBTIMER_MODE_0_CLOCK_TICKS = 256; //256*2;
  3.2734 +      GBTIMER_MODE_1_CLOCK_TICKS = 4; //4*2;
  3.2735 +      GBTIMER_MODE_2_CLOCK_TICKS = 16; //16*2;
  3.2736 +      GBTIMER_MODE_3_CLOCK_TICKS = 64; //64*2;
  3.2737 +      GBSERIAL_CLOCK_TICKS	   = 128 * 2;
  3.2738 +      gbDivTicks *= 2;
  3.2739 +      gbLcdTicks *= 2;
  3.2740 +      gbLcdLYIncrementTicks *= 2;
  3.2741 +      //    timerTicks *= 2;
  3.2742 +      //    timerClockTicks *= 2;
  3.2743 +      gbSerialTicks	 *= 2;
  3.2744 +      SOUND_CLOCK_TICKS = soundQuality * GB_USE_TICKS_AS * 2;
  3.2745 +      soundTicks		 *= 2;
  3.2746 +      //    synchronizeTicks *= 2;
  3.2747 +      //    SYNCHRONIZE_CLOCK_TICKS *= 2;
  3.2748 +    }
  3.2749 +  else
  3.2750 +    {
  3.2751 +      gbSpeed = 0;
  3.2752 +      GBLCD_MODE_0_CLOCK_TICKS   = 51;
  3.2753 +      GBLCD_MODE_1_CLOCK_TICKS   = 1140;
  3.2754 +      GBLCD_MODE_2_CLOCK_TICKS   = 20;
  3.2755 +      GBLCD_MODE_3_CLOCK_TICKS   = 43;
  3.2756 +      GBDIV_CLOCK_TICKS		   = 64;
  3.2757 +      GBLY_INCREMENT_CLOCK_TICKS = 114;
  3.2758 +      GBTIMER_MODE_0_CLOCK_TICKS = 256;
  3.2759 +      GBTIMER_MODE_1_CLOCK_TICKS = 4;
  3.2760 +      GBTIMER_MODE_2_CLOCK_TICKS = 16;
  3.2761 +      GBTIMER_MODE_3_CLOCK_TICKS = 64;
  3.2762 +      GBSERIAL_CLOCK_TICKS	   = 128;
  3.2763 +      gbDivTicks /= 2;
  3.2764 +      gbLcdTicks /= 2;
  3.2765 +      gbLcdLYIncrementTicks /= 2;
  3.2766 +      //    timerTicks /= 2;
  3.2767 +      //    timerClockTicks /= 2;
  3.2768 +      gbSerialTicks	 /= 2;
  3.2769 +      SOUND_CLOCK_TICKS = soundQuality * GB_USE_TICKS_AS;
  3.2770 +      soundTicks		 /= 2;
  3.2771 +      //    synchronizeTicks /= 2;
  3.2772 +      //    SYNCHRONIZE_CLOCK_TICKS /= 2;
  3.2773 +    }
  3.2774  }
  3.2775  
  3.2776  void gbGetHardwareType()
  3.2777  {
  3.2778 -	gbCgbMode = 0;
  3.2779 -	if (gbRom[0x143] & 0x80)
  3.2780 +  gbCgbMode = 0;
  3.2781 +  if (gbRom[0x143] & 0x80)
  3.2782 +    {
  3.2783 +      if (gbEmulatorType == 0 ||
  3.2784 +	  gbEmulatorType == 1 ||
  3.2785 +	  gbEmulatorType == 4 ||
  3.2786 +	  gbEmulatorType == 5 ||
  3.2787 +	  (gbRom[0x146] != 0x03 && (gbEmulatorType == 2)))
  3.2788  	{
  3.2789 -		if (gbEmulatorType == 0 ||
  3.2790 -		    gbEmulatorType == 1 ||
  3.2791 -		    gbEmulatorType == 4 ||
  3.2792 -		    gbEmulatorType == 5 ||
  3.2793 -		    (gbRom[0x146] != 0x03 && (gbEmulatorType == 2)))
  3.2794 -		{
  3.2795 -			gbCgbMode = 1;
  3.2796 -		}
  3.2797 +	  gbCgbMode = 1;
  3.2798  	}
  3.2799 -
  3.2800 -	if (gbSgbMode == 2)
  3.2801 -	{
  3.2802 -		gbSgbMode = 0;
  3.2803 -		return;
  3.2804 -	}
  3.2805 -
  3.2806 -	gbSgbMode = 0;
  3.2807 -	if (gbRom[0x146] == 0x03)
  3.2808 -	{
  3.2809 -		if (gbEmulatorType == 0 ||
  3.2810 -		    gbEmulatorType == 2 ||
  3.2811 -		    gbEmulatorType == 5 ||
  3.2812 -		    (!(gbRom[0x143] & 0x80) && (gbEmulatorType == 1 || gbEmulatorType == 4)))
  3.2813 -			gbSgbMode = 1;
  3.2814 -	}
  3.2815 +    }
  3.2816 +
  3.2817 +  if (gbSgbMode == 2)
  3.2818 +    {
  3.2819 +      gbSgbMode = 0;
  3.2820 +      return;
  3.2821 +    }
  3.2822 +
  3.2823 +  gbSgbMode = 0;
  3.2824 +  if (gbRom[0x146] == 0x03)
  3.2825 +    {
  3.2826 +      if (gbEmulatorType == 0 ||
  3.2827 +	  gbEmulatorType == 2 ||
  3.2828 +	  gbEmulatorType == 5 ||
  3.2829 +	  (!(gbRom[0x143] & 0x80) && (gbEmulatorType == 1 || gbEmulatorType == 4)))
  3.2830 +	gbSgbMode = 1;
  3.2831 +    }
  3.2832  }
  3.2833  
  3.2834  void gbReset(bool userReset)
  3.2835  {
  3.2836 -	// movie must be closed while opening/creating a movie
  3.2837 -	if (userReset && VBAMovieRecording())
  3.2838 +  // movie must be closed while opening/creating a movie
  3.2839 +  if (userReset && VBAMovieRecording())
  3.2840 +    {
  3.2841 +      VBAMovieSignalReset();
  3.2842 +      return;
  3.2843 +    }
  3.2844 +
  3.2845 +  if (!VBAMovieActive())
  3.2846 +    {
  3.2847 +      GBSystemCounters.frameCount = 0;
  3.2848 +      GBSystemCounters.lagCount	= 0;
  3.2849 +      GBSystemCounters.extraCount = 0;
  3.2850 +      GBSystemCounters.lagged		= true;
  3.2851 +      GBSystemCounters.laggedLast = true;
  3.2852 +    }
  3.2853 +
  3.2854 +  SP.W = 0xfffe;
  3.2855 +  AF.W = 0x01b0;
  3.2856 +  BC.W = 0x0013;
  3.2857 +  DE.W = 0x00d8;
  3.2858 +  HL.W = 0x014d;
  3.2859 +  PC.W = 0x0100;
  3.2860 +  IFF	 = 0;
  3.2861 +  gbInterrupt		= 1;
  3.2862 +  gbInterruptWait = 0;
  3.2863 +
  3.2864 +  register_DIV   = 0;
  3.2865 +  register_TIMA  = 0;
  3.2866 +  register_TMA   = 0;
  3.2867 +  register_TAC   = 0;
  3.2868 +  register_IF	   = 1;
  3.2869 +  register_LCDC  = 0x91;
  3.2870 +  register_STAT  = 0;
  3.2871 +  register_SCY   = 0;
  3.2872 +  register_SCX   = 0;
  3.2873 +  register_LY	   = 0;
  3.2874 +  register_LYC   = 0;
  3.2875 +  register_DMA   = 0;
  3.2876 +  register_WY	   = 0;
  3.2877 +  register_WX	   = 0;
  3.2878 +  register_VBK   = 0;
  3.2879 +  register_HDMA1 = 0;
  3.2880 +  register_HDMA2 = 0;
  3.2881 +  register_HDMA3 = 0;
  3.2882 +  register_HDMA4 = 0;
  3.2883 +  register_HDMA5 = 0;
  3.2884 +  register_SVBK  = 0;
  3.2885 +  register_IE	   = 0;
  3.2886 +
  3.2887 +  gbGetHardwareType();
  3.2888 +  if (gbCgbMode)
  3.2889 +    {
  3.2890 +      if (!gbVram)
  3.2891 +	gbVram = (u8 *)malloc(0x4000 + 4);
  3.2892 +      if (!gbWram)
  3.2893 +	gbWram = (u8 *)malloc(0x8000 + 4);
  3.2894 +      memset(gbVram, 0, 0x4000 + 4);
  3.2895 +      memset(gbWram, 0, 0x8000 + 4);
  3.2896 +    }
  3.2897 +  else
  3.2898 +    {
  3.2899 +      if (gbVram)
  3.2900  	{
  3.2901 -		VBAMovieSignalReset();
  3.2902 -		return;
  3.2903 +	  free(gbVram);
  3.2904 +	  gbVram = NULL;
  3.2905  	}
  3.2906 -
  3.2907 -	if (!VBAMovieActive())
  3.2908 +      if (gbWram)
  3.2909  	{
  3.2910 -		GBSystemCounters.frameCount = 0;
  3.2911 -		GBSystemCounters.lagCount	= 0;
  3.2912 -		GBSystemCounters.extraCount = 0;
  3.2913 -		GBSystemCounters.lagged		= true;
  3.2914 -		GBSystemCounters.laggedLast = true;
  3.2915 +	  free(gbWram);
  3.2916 +	  gbWram = NULL;
  3.2917  	}
  3.2918 -
  3.2919 -	SP.W = 0xfffe;
  3.2920 -	AF.W = 0x01b0;
  3.2921 -	BC.W = 0x0013;
  3.2922 -	DE.W = 0x00d8;
  3.2923 -	HL.W = 0x014d;
  3.2924 -	PC.W = 0x0100;
  3.2925 -	IFF	 = 0;
  3.2926 -	gbInterrupt		= 1;
  3.2927 -	gbInterruptWait = 0;
  3.2928 -
  3.2929 -	register_DIV   = 0;
  3.2930 -	register_TIMA  = 0;
  3.2931 -	register_TMA   = 0;
  3.2932 -	register_TAC   = 0;
  3.2933 -	register_IF	   = 1;
  3.2934 -	register_LCDC  = 0x91;
  3.2935 -	register_STAT  = 0;
  3.2936 -	register_SCY   = 0;
  3.2937 -	register_SCX   = 0;
  3.2938 -	register_LY	   = 0;
  3.2939 -	register_LYC   = 0;
  3.2940 -	register_DMA   = 0;
  3.2941 -	register_WY	   = 0;
  3.2942 -	register_WX	   = 0;
  3.2943 -	register_VBK   = 0;
  3.2944 -	register_HDMA1 = 0;
  3.2945 -	register_HDMA2 = 0;
  3.2946 -	register_HDMA3 = 0;
  3.2947 -	register_HDMA4 = 0;
  3.2948 -	register_HDMA5 = 0;
  3.2949 -	register_SVBK  = 0;
  3.2950 -	register_IE	   = 0;
  3.2951 -
  3.2952 -	gbGetHardwareType();
  3.2953 -	if (gbCgbMode)
  3.2954 +    }
  3.2955 +
  3.2956 +  // clean LineBuffer
  3.2957 +  if (gbLineBuffer)
  3.2958 +    memset(gbLineBuffer, 0, 160 * sizeof(u16));
  3.2959 +  // clean Pix
  3.2960 +  if (pix)
  3.2961 +    memset(pix, 0, 4 * 257 * 226);
  3.2962 +
  3.2963 +  if (gbCgbMode)
  3.2964 +    {
  3.2965 +      if (gbSgbMode)
  3.2966  	{
  3.2967 -		if (!gbVram)
  3.2968 -			gbVram = (u8 *)malloc(0x4000 + 4);
  3.2969 -		if (!gbWram)
  3.2970 -			gbWram = (u8 *)malloc(0x8000 + 4);
  3.2971 -		memset(gbVram, 0, 0x4000 + 4);
  3.2972 -		memset(gbWram, 0, 0x8000 + 4);
  3.2973 +	  if (gbEmulatorType == 5)
  3.2974 +	    AF.W = 0xffb0;
  3.2975 +	  else
  3.2976 +	    AF.W = 0x01b0;
  3.2977 +	  BC.W = 0x0013;
  3.2978 +	  DE.W = 0x00d8;
  3.2979 +	  HL.W = 0x014d;
  3.2980  	}
  3.2981 -	else
  3.2982 +      else
  3.2983  	{
  3.2984 -		if (gbVram)
  3.2985 -		{
  3.2986 -			free(gbVram);
  3.2987 -			gbVram = NULL;
  3.2988 -		}
  3.2989 -		if (gbWram)
  3.2990 -		{
  3.2991 -			free(gbWram);
  3.2992 -			gbWram = NULL;
  3.2993 -		}
  3.2994 +	  AF.W = 0x11b0;
  3.2995 +	  BC.W = 0x0000;
  3.2996 +	  DE.W = 0xff56;
  3.2997 +	  HL.W = 0x000d;
  3.2998  	}
  3.2999 -
  3.3000 -	// clean LineBuffer
  3.3001 -	if (gbLineBuffer)
  3.3002 -		memset(gbLineBuffer, 0, 160 * sizeof(u16));
  3.3003 -	// clean Pix
  3.3004 -	if (pix)
  3.3005 -		memset(pix, 0, 4 * 257 * 226);
  3.3006 -
  3.3007 -	if (gbCgbMode)
  3.3008 -	{
  3.3009 -		if (gbSgbMode)
  3.3010 -		{
  3.3011 -			if (gbEmulatorType == 5)
  3.3012 -				AF.W = 0xffb0;
  3.3013 -			else
  3.3014 -				AF.W = 0x01b0;
  3.3015 -			BC.W = 0x0013;
  3.3016 -			DE.W = 0x00d8;
  3.3017 -			HL.W = 0x014d;
  3.3018 -		}
  3.3019 -		else
  3.3020 -		{
  3.3021 -			AF.W = 0x11b0;
  3.3022 -			BC.W = 0x0000;
  3.3023 -			DE.W = 0xff56;
  3.3024 -			HL.W = 0x000d;
  3.3025 -		}
  3.3026 -		if (gbEmulatorType == 4)
  3.3027 -			BC.B.B1 |= 0x01;
  3.3028 -
  3.3029 -		register_HDMA5	 = 0xff;
  3.3030 -		gbMemory[0xff68] = 0xc0;
  3.3031 -		gbMemory[0xff6a] = 0xc0;
  3.3032 -
  3.3033 -		for (int i = 0; i < 64; i++)
  3.3034 -			gbPalette[i] = 0x7fff;
  3.3035 -	}
  3.3036 -	else
  3.3037 -	{
  3.3038 -		for (int i = 0; i < 8; i++)
  3.3039 -			gbPalette[i] = systemGbPalette[gbPaletteOption * 8 + i];
  3.3040 -	}
  3.3041 -
  3.3042 -	if (gbSpeed)
  3.3043 -	{
  3.3044 -		gbSpeedSwitch();
  3.3045 -		gbMemory[0xff4d] = 0;
  3.3046 -	}
  3.3047 -
  3.3048 -	gbDivTicks = GBDIV_CLOCK_TICKS;
  3.3049 -	gbLcdMode  = 2;
  3.3050 -	gbLcdTicks = GBLCD_MODE_2_CLOCK_TICKS;
  3.3051 -	gbLcdLYIncrementTicks = 0;
  3.3052 -	gbTimerTicks		  = 0;
  3.3053 -	gbTimerClockTicks	  = 0;
  3.3054 -	gbSerialTicks		  = 0;
  3.3055 -	gbSerialBits		  = 0;
  3.3056 -	gbSerialOn			  = 0;
  3.3057 -	gbWindowLine		  = -1;
  3.3058 -	gbTimerOn			  = 0;
  3.3059 -	gbTimerMode			  = 0;
  3.3060 -	//  gbSynchronizeTicks = GBSYNCHRONIZE_CLOCK_TICKS;
  3.3061 -	gbSpeed		 = 0;
  3.3062 -	gbJoymask[0] = gbJoymask[1] = gbJoymask[2] = gbJoymask[3] = 0;
  3.3063 -
  3.3064 -	// FIXME: horrible kludge
  3.3065 -	memset(s_gbJoymask, 0, sizeof(s_gbJoymask));
  3.3066 -
  3.3067 -	if (gbCgbMode)
  3.3068 -	{
  3.3069 -		gbSpeed	 = 0;
  3.3070 -		gbHdmaOn = 0;
  3.3071 -		gbHdmaSource	  = 0x0000;
  3.3072 -		gbHdmaDestination = 0x8000;
  3.3073 -		gbVramBank		  = 0;
  3.3074 -		gbWramBank		  = 1;
  3.3075 -		register_LY		  = 0x90;
  3.3076 -		gbLcdMode		  = 1;
  3.3077 -	}
  3.3078 -
  3.3079 -	if (gbSgbMode)
  3.3080 -	{
  3.3081 -		gbSgbReset();
  3.3082 -	}
  3.3083 -
  3.3084 -	for (int i = 0; i < 4; i++)
  3.3085 -		gbBgp[i] = gbObp0[i] = gbObp1[i] = i;
  3.3086 -
  3.3087 -	memset(&gbDataMBC1, 0, sizeof(gbDataMBC1));
  3.3088 -	gbDataMBC1.mapperROMBank = 1;
  3.3089 -
  3.3090 -	gbDataMBC2.mapperRAMEnable = 0;
  3.3091 -	gbDataMBC2.mapperROMBank   = 1;
  3.3092 -
  3.3093 -	memset(&gbDataMBC3, 0, 6 * sizeof(int32));
  3.3094 -	gbDataMBC3.mapperROMBank = 1;
  3.3095 -
  3.3096 -	memset(&gbDataMBC5, 0, sizeof(gbDataMBC5));
  3.3097 -	gbDataMBC5.mapperROMBank = 1;
  3.3098 -	switch (gbRom[0x147])
  3.3099 -	{
  3.3100 -	case 0x1c:
  3.3101 -	case 0x1d:
  3.3102 -	case 0x1e:
  3.3103 -		gbDataMBC5.isRumbleCartridge = 1;
  3.3104 -	}
  3.3105 -
  3.3106 -	memset(&gbDataHuC1, 0, sizeof(gbDataHuC1));
  3.3107 -	gbDataHuC1.mapperROMBank = 1;
  3.3108 -
  3.3109 -	memset(&gbDataHuC3, 0, sizeof(gbDataHuC3));
  3.3110 -	gbDataHuC3.mapperROMBank = 1;
  3.3111 -
  3.3112 -	gbMemoryMap[0x00] = &gbRom[0x0000];
  3.3113 -	gbMemoryMap[0x01] = &gbRom[0x1000];
  3.3114 -	gbMemoryMap[0x02] = &gbRom[0x2000];
  3.3115 -	gbMemoryMap[0x03] = &gbRom[0x3000];
  3.3116 -	gbMemoryMap[0x04] = &gbRom[0x4000];
  3.3117 -	gbMemoryMap[0x05] = &gbRom[0x5000];
  3.3118 -	gbMemoryMap[0x06] = &gbRom[0x6000];
  3.3119 -	gbMemoryMap[0x07] = &gbRom[0x7000];
  3.3120 -	if (gbCgbMode)
  3.3121 -	{
  3.3122 -		gbMemoryMap[0x08] = &gbVram[0x0000];
  3.3123 -		gbMemoryMap[0x09] = &gbVram[0x1000];
  3.3124 -		gbMemoryMap[0x0a] = &gbMemory[0xa000];
  3.3125 -		gbMemoryMap[0x0b] = &gbMemory[0xb000];
  3.3126 -		gbMemoryMap[0x0c] = &gbMemory[0xc000];
  3.3127 -		gbMemoryMap[0x0d] = &gbWram[0x1000];
  3.3128 -		gbMemoryMap[0x0e] = &gbMemory[0xe000];
  3.3129 -		gbMemoryMap[0x0f] = &gbMemory[0xf000];
  3.3130 -	}
  3.3131 -	else
  3.3132 -	{
  3.3133 -		gbMemoryMap[0x08] = &gbMemory[0x8000];
  3.3134 -		gbMemoryMap[0x09] = &gbMemory[0x9000];
  3.3135 -		gbMemoryMap[0x0a] = &gbMemory[0xa000];
  3.3136 -		gbMemoryMap[0x0b] = &gbMemory[0xb000];
  3.3137 -		gbMemoryMap[0x0c] = &gbMemory[0xc000];
  3.3138 -		gbMemoryMap[0x0d] = &gbMemory[0xd000];
  3.3139 -		gbMemoryMap[0x0e] = &gbMemory[0xe000];
  3.3140 -		gbMemoryMap[0x0f] = &gbMemory[0xf000];
  3.3141 -	}
  3.3142 -
  3.3143 -	if (gbRam)
  3.3144 -	{
  3.3145 -		gbMemoryMap[0x0a] = &gbRam[0x0000];
  3.3146 -		gbMemoryMap[0x0b] = &gbRam[0x1000];
  3.3147 -	}
  3.3148 -
  3.3149 -	gbSoundReset();
  3.3150 -
  3.3151 -	systemResetSensor();
  3.3152 -
  3.3153 -	systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  3.3154 -
  3.3155 -	gbLastTime	 = systemGetClock();
  3.3156 -	gbFrameCount = 0;
  3.3157 -
  3.3158 -	systemRefreshScreen();
  3.3159 +      if (gbEmulatorType == 4)
  3.3160 +	BC.B.B1 |= 0x01;
  3.3161 +
  3.3162 +      register_HDMA5	 = 0xff;
  3.3163 +      gbMemory[0xff68] = 0xc0;
  3.3164 +      gbMemory[0xff6a] = 0xc0;
  3.3165 +
  3.3166 +      for (int i = 0; i < 64; i++)
  3.3167 +	gbPalette[i] = 0x7fff;
  3.3168 +    }
  3.3169 +  else
  3.3170 +    {
  3.3171 +      for (int i = 0; i < 8; i++)
  3.3172 +	gbPalette[i] = systemGbPalette[gbPaletteOption * 8 + i];
  3.3173 +    }
  3.3174 +
  3.3175 +  if (gbSpeed)
  3.3176 +    {
  3.3177 +      gbSpeedSwitch();
  3.3178 +      gbMemory[0xff4d] = 0;
  3.3179 +    }
  3.3180 +
  3.3181 +  gbDivTicks = GBDIV_CLOCK_TICKS;
  3.3182 +  gbLcdMode  = 2;
  3.3183 +  gbLcdTicks = GBLCD_MODE_2_CLOCK_TICKS;
  3.3184 +  gbLcdLYIncrementTicks = 0;
  3.3185 +  gbTimerTicks		  = 0;
  3.3186 +  gbTimerClockTicks	  = 0;
  3.3187 +  gbSerialTicks		  = 0;
  3.3188 +  gbSerialBits		  = 0;
  3.3189 +  gbSerialOn			  = 0;
  3.3190 +  gbWindowLine		  = -1;
  3.3191 +  gbTimerOn			  = 0;
  3.3192 +  gbTimerMode			  = 0;
  3.3193 +  //  gbSynchronizeTicks = GBSYNCHRONIZE_CLOCK_TICKS;
  3.3194 +  gbSpeed		 = 0;
  3.3195 +  gbJoymask[0] = gbJoymask[1] = gbJoymask[2] = gbJoymask[3] = 0;
  3.3196 +
  3.3197 +  // FIXME: horrible kludge
  3.3198 +  memset(s_gbJoymask, 0, sizeof(s_gbJoymask));
  3.3199 +
  3.3200 +  if (gbCgbMode)
  3.3201 +    {
  3.3202 +      gbSpeed	 = 0;
  3.3203 +      gbHdmaOn = 0;
  3.3204 +      gbHdmaSource	  = 0x0000;
  3.3205 +      gbHdmaDestination = 0x8000;
  3.3206 +      gbVramBank		  = 0;
  3.3207 +      gbWramBank		  = 1;
  3.3208 +      register_LY		  = 0x90;
  3.3209 +      gbLcdMode		  = 1;
  3.3210 +    }
  3.3211 +
  3.3212 +  if (gbSgbMode)
  3.3213 +    {
  3.3214 +      gbSgbReset();
  3.3215 +    }
  3.3216 +
  3.3217 +  for (int i = 0; i < 4; i++)
  3.3218 +    gbBgp[i] = gbObp0[i] = gbObp1[i] = i;
  3.3219 +
  3.3220 +  memset(&gbDataMBC1, 0, sizeof(gbDataMBC1));
  3.3221 +  gbDataMBC1.mapperROMBank = 1;
  3.3222 +
  3.3223 +  gbDataMBC2.mapperRAMEnable = 0;
  3.3224 +  gbDataMBC2.mapperROMBank   = 1;
  3.3225 +
  3.3226 +  memset(&gbDataMBC3, 0, 6 * sizeof(int32));
  3.3227 +  gbDataMBC3.mapperROMBank = 1;
  3.3228 +
  3.3229 +  memset(&gbDataMBC5, 0, sizeof(gbDataMBC5));
  3.3230 +  gbDataMBC5.mapperROMBank = 1;
  3.3231 +  switch (gbRom[0x147])
  3.3232 +    {
  3.3233 +    case 0x1c:
  3.3234 +    case 0x1d:
  3.3235 +    case 0x1e:
  3.3236 +      gbDataMBC5.isRumbleCartridge = 1;
  3.3237 +    }
  3.3238 +
  3.3239 +  memset(&gbDataHuC1, 0, sizeof(gbDataHuC1));
  3.3240 +  gbDataHuC1.mapperROMBank = 1;
  3.3241 +
  3.3242 +  memset(&gbDataHuC3, 0, sizeof(gbDataHuC3));
  3.3243 +  gbDataHuC3.mapperROMBank = 1;
  3.3244 +
  3.3245 +  gbMemoryMap[0x00] = &gbRom[0x0000];
  3.3246 +  gbMemoryMap[0x01] = &gbRom[0x1000];
  3.3247 +  gbMemoryMap[0x02] = &gbRom[0x2000];
  3.3248 +  gbMemoryMap[0x03] = &gbRom[0x3000];
  3.3249 +  gbMemoryMap[0x04] = &gbRom[0x4000];
  3.3250 +  gbMemoryMap[0x05] = &gbRom[0x5000];
  3.3251 +  gbMemoryMap[0x06] = &gbRom[0x6000];
  3.3252 +  gbMemoryMap[0x07] = &gbRom[0x7000];
  3.3253 +  if (gbCgbMode)
  3.3254 +    {
  3.3255 +      gbMemoryMap[0x08] = &gbVram[0x0000];
  3.3256 +      gbMemoryMap[0x09] = &gbVram[0x1000];
  3.3257 +      gbMemoryMap[0x0a] = &gbMemory[0xa000];
  3.3258 +      gbMemoryMap[0x0b] = &gbMemory[0xb000];
  3.3259 +      gbMemoryMap[0x0c] = &gbMemory[0xc000];
  3.3260 +      gbMemoryMap[0x0d] = &gbWram[0x1000];
  3.3261 +      gbMemoryMap[0x0e] = &gbMemory[0xe000];
  3.3262 +      gbMemoryMap[0x0f] = &gbMemory[0xf000];
  3.3263 +    }
  3.3264 +  else
  3.3265 +    {
  3.3266 +      gbMemoryMap[0x08] = &gbMemory[0x8000];
  3.3267 +      gbMemoryMap[0x09] = &gbMemory[0x9000];
  3.3268 +      gbMemoryMap[0x0a] = &gbMemory[0xa000];
  3.3269 +      gbMemoryMap[0x0b] = &gbMemory[0xb000];
  3.3270 +      gbMemoryMap[0x0c] = &gbMemory[0xc000];
  3.3271 +      gbMemoryMap[0x0d] = &gbMemory[0xd000];
  3.3272 +      gbMemoryMap[0x0e] = &gbMemory[0xe000];
  3.3273 +      gbMemoryMap[0x0f] = &gbMemory[0xf000];
  3.3274 +    }
  3.3275 +
  3.3276 +  if (gbRam)
  3.3277 +    {
  3.3278 +      gbMemoryMap[0x0a] = &gbRam[0x0000];
  3.3279 +      gbMemoryMap[0x0b] = &gbRam[0x1000];
  3.3280 +    }
  3.3281 +
  3.3282 +  gbSoundReset();
  3.3283 +
  3.3284 +  systemResetSensor();
  3.3285 +
  3.3286 +  systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  3.3287 +
  3.3288 +  gbLastTime	 = systemGetClock();
  3.3289 +  gbFrameCount = 0;
  3.3290 +
  3.3291 +  systemRefreshScreen();
  3.3292  }
  3.3293  
  3.3294  void gbWriteSaveMBC1(const char *name)
  3.3295  {
  3.3296 -	FILE *gzFile = fopen(name, "wb");
  3.3297 -
  3.3298 -	if (gzFile == NULL)
  3.3299 -	{
  3.3300 -		systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  3.3301 -		return;
  3.3302 -	}
  3.3303 -
  3.3304 -	fwrite(gbRam,
  3.3305 -	       1,
  3.3306 -	       gbRamSize,
  3.3307 -	       gzFile);
  3.3308 -
  3.3309 -	fclose(gzFile);
  3.3310 +  FILE *gzFile = fopen(name, "wb");
  3.3311 +
  3.3312 +  if (gzFile == NULL)
  3.3313 +    {
  3.3314 +      systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  3.3315 +      return;
  3.3316 +    }
  3.3317 +
  3.3318 +  fwrite(gbRam,
  3.3319 +	 1,
  3.3320 +	 gbRamSize,
  3.3321 +	 gzFile);
  3.3322 +
  3.3323 +  fclose(gzFile);
  3.3324  }
  3.3325  
  3.3326  void gbWriteSaveMBC2(const char *name)
  3.3327  {
  3.3328 -	FILE *file = fopen(name, "wb");
  3.3329 -
  3.3330 -	if (file == NULL)
  3.3331 -	{
  3.3332 -		systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  3.3333 -		return;
  3.3334 -	}
  3.3335 -
  3.3336 -	fwrite(&gbMemory[0xa000],
  3.3337 -	       1,
  3.3338 -	       256,
  3.3339 -	       file);
  3.3340 -
  3.3341 -	fclose(file);
  3.3342 +  FILE *file = fopen(name, "wb");
  3.3343 +
  3.3344 +  if (file == NULL)
  3.3345 +    {
  3.3346 +      systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  3.3347 +      return;
  3.3348 +    }
  3.3349 +
  3.3350 +  fwrite(&gbMemory[0xa000],
  3.3351 +	 1,
  3.3352 +	 256,
  3.3353 +	 file);
  3.3354 +
  3.3355 +  fclose(file);
  3.3356  }
  3.3357  
  3.3358  void gbWriteSaveMBC3(const char *name, bool extendedSave)
  3.3359  {
  3.3360 -	FILE *gzFile = fopen(name, "wb");
  3.3361 -
  3.3362 -	if (gzFile == NULL)
  3.3363 -	{
  3.3364 -		systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  3.3365 -		return;
  3.3366 -	}
  3.3367 -
  3.3368 -	fwrite(gbRam,
  3.3369 -	       1,
  3.3370 -	       gbRamSize,
  3.3371 -	       gzFile);
  3.3372 -
  3.3373 -	if (extendedSave)
  3.3374 -	{
  3.3375 -		//assert(sizeof(time_t) == 4);
  3.3376 -		fwrite(&gbDataMBC3.mapperSeconds,
  3.3377 -		       1,
  3.3378 -		       10 * sizeof(int32) + /*sizeof(time_t)*/4,
  3.3379 -		       gzFile);
  3.3380 -	}
  3.3381 -
  3.3382 -	fclose(gzFile);
  3.3383 +  FILE *gzFile = fopen(name, "wb");
  3.3384 +
  3.3385 +  if (gzFile == NULL)
  3.3386 +    {
  3.3387 +      systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  3.3388 +      return;
  3.3389 +    }
  3.3390 +
  3.3391 +  fwrite(gbRam,
  3.3392 +	 1,
  3.3393 +	 gbRamSize,
  3.3394 +	 gzFile);
  3.3395 +
  3.3396 +  if (extendedSave)
  3.3397 +    {
  3.3398 +      //assert(sizeof(time_t) == 4);
  3.3399 +      fwrite(&gbDataMBC3.mapperSeconds,
  3.3400 +	     1,
  3.3401 +	     10 * sizeof(int32) + /*sizeof(time_t)*/4,
  3.3402 +	     gzFile);
  3.3403 +    }
  3.3404 +
  3.3405 +  fclose(gzFile);
  3.3406  }
  3.3407  
  3.3408  void gbWriteSaveMBC5(const char *name)
  3.3409  {
  3.3410 -	FILE *gzFile = fopen(name, "wb");
  3.3411 -
  3.3412 -	if (gzFile == NULL)
  3.3413 -	{
  3.3414 -		systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  3.3415 -		return;
  3.3416 -	}
  3.3417 -
  3.3418 -	fwrite(gbRam,
  3.3419 -	       1,
  3.3420 -	       gbRamSize,
  3.3421 -	       gzFile);
  3.3422 -
  3.3423 -	fclose(gzFile);
  3.3424 +  FILE *gzFile = fopen(name, "wb");
  3.3425 +
  3.3426 +  if (gzFile == NULL)
  3.3427 +    {
  3.3428 +      systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  3.3429 +      return;
  3.3430 +    }
  3.3431 +
  3.3432 +  fwrite(gbRam,
  3.3433 +	 1,
  3.3434 +	 gbRamSize,
  3.3435 +	 gzFile);
  3.3436 +
  3.3437 +  fclose(gzFile);
  3.3438  }
  3.3439  
  3.3440  void gbWriteSaveMBC7(const char *name)
  3.3441  {
  3.3442 -	FILE *file = fopen(name, "wb");
  3.3443 -
  3.3444 -	if (file == NULL)
  3.3445 -	{
  3.3446 -		systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  3.3447 -		return;
  3.3448 -	}
  3.3449 -
  3.3450 -	fwrite(&gbMemory[0xa000],
  3.3451 -	       1,
  3.3452 -	       256,
  3.3453 -	       file);
  3.3454 -
  3.3455 -	fclose(file);
  3.3456 +  FILE *file = fopen(name, "wb");
  3.3457 +
  3.3458 +  if (file == NULL)
  3.3459 +    {
  3.3460 +      systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  3.3461 +      return;
  3.3462 +    }
  3.3463 +
  3.3464 +  fwrite(&gbMemory[0xa000],
  3.3465 +	 1,
  3.3466 +	 256,
  3.3467 +	 file);
  3.3468 +
  3.3469 +  fclose(file);
  3.3470  }
  3.3471  
  3.3472  bool gbReadSaveMBC1(const char *name)
  3.3473  {
  3.3474 -	gzFile gzFile = gzopen(name, "rb");
  3.3475 -
  3.3476 -	if (gzFile == NULL)
  3.3477 -	{
  3.3478 -		return false;
  3.3479 -	}
  3.3480 -
  3.3481 -	int read = gzread(gzFile,
  3.3482 -	                  gbRam,
  3.3483 -	                  gbRamSize);
  3.3484 -
  3.3485 -	if (read != gbRamSize)
  3.3486 -	{
  3.3487 -		systemMessage(MSG_FAILED_TO_READ_SGM, N_("Failed to read complete save game %s (%d)"), name, read);
  3.3488 -		gzclose(gzFile);
  3.3489 -		return false;
  3.3490 -	}
  3.3491 -
  3.3492 -	gzclose(gzFile);
  3.3493 -	return true;
  3.3494 +  gzFile gzFile = gzopen(name, "rb");
  3.3495 +
  3.3496 +  if (gzFile == NULL)
  3.3497 +    {
  3.3498 +      return false;
  3.3499 +    }
  3.3500 +
  3.3501 +  int read = gzread(gzFile,
  3.3502 +		    gbRam,
  3.3503 +		    gbRamSize);
  3.3504 +
  3.3505 +  if (read != gbRamSize)
  3.3506 +    {
  3.3507 +      systemMessage(MSG_FAILED_TO_READ_SGM, N_("Failed to read complete save game %s (%d)"), name, read);
  3.3508 +      gzclose(gzFile);
  3.3509 +      return false;
  3.3510 +    }
  3.3511 +
  3.3512 +  gzclose(gzFile);
  3.3513 +  return true;
  3.3514  }
  3.3515  
  3.3516  bool gbReadSaveMBC2(const char *name)
  3.3517  {
  3.3518 -	FILE *file = fopen(name, "rb");
  3.3519 -
  3.3520 -	if (file == NULL)
  3.3521 -	{
  3.3522 -		return false;
  3.3523 -	}
  3.3524 -
  3.3525 -	int read = fread(&gbMemory[0xa000],
  3.3526 -	                 1,
  3.3527 -	                 256,
  3.3528 -	                 file);
  3.3529 -
  3.3530 -	if (read != 256)
  3.3531 -	{
  3.3532 -		systemMessage(MSG_FAILED_TO_READ_SGM,
  3.3533 -		              N_("Failed to read complete save game %s (%d)"), name, read);
  3.3534 -		fclose(file);
  3.3535 -		return false;
  3.3536 -	}
  3.3537 -
  3.3538 -	fclose(file);
  3.3539 -	return true;
  3.3540 +  FILE *file = fopen(name, "rb");
  3.3541 +
  3.3542 +  if (file == NULL)
  3.3543 +    {
  3.3544 +      return false;
  3.3545 +    }
  3.3546 +
  3.3547 +  int read = fread(&gbMemory[0xa000],
  3.3548 +		   1,
  3.3549 +		   256,
  3.3550 +		   file);
  3.3551 +
  3.3552 +  if (read != 256)
  3.3553 +    {
  3.3554 +      systemMessage(MSG_FAILED_TO_READ_SGM,
  3.3555 +		    N_("Failed to read complete save game %s (%d)"), name, read);
  3.3556 +      fclose(file);
  3.3557 +      return false;
  3.3558 +    }
  3.3559 +
  3.3560 +  fclose(file);
  3.3561 +  return true;
  3.3562  }
  3.3563  
  3.3564  bool gbReadSaveMBC3(const char *name)
  3.3565  {
  3.3566 -	gzFile gzFile = gzopen(name, "rb");
  3.3567 -
  3.3568 -	if (gzFile == NULL)
  3.3569 +  gzFile gzFile = gzopen(name, "rb");
  3.3570 +
  3.3571 +  if (gzFile == NULL)
  3.3572 +    {
  3.3573 +      return false;
  3.3574 +    }
  3.3575 +
  3.3576 +  int read = gzread(gzFile,
  3.3577 +		    gbRam,
  3.3578 +		    gbRamSize);
  3.3579 +
  3.3580 +  bool res = true;
  3.3581 +
  3.3582 +  if (read != gbRamSize)
  3.3583 +    {
  3.3584 +      systemMessage(MSG_FAILED_TO_READ_SGM,
  3.3585 +		    N_("Failed to read complete save game %s (%d)"), name, read);
  3.3586 +    }
  3.3587 +  else
  3.3588 +    {
  3.3589 +      //assert(sizeof(time_t) == 4);
  3.3590 +      read = gzread(gzFile,
  3.3591 +		    &gbDataMBC3.mapperSeconds,
  3.3592 +		    sizeof(int32) * 10 + /*sizeof(time_t)*/4);
  3.3593 +
  3.3594 +      if (read != (sizeof(int32) * 10 + /*sizeof(time_t)*/4) && read != 0)
  3.3595  	{
  3.3596 -		return false;
  3.3597 +	  systemMessage(MSG_FAILED_TO_READ_RTC,
  3.3598 +			N_("Failed to read RTC from save game %s (continuing)"),
  3.3599 +			name);
  3.3600 +	  res = false;
  3.3601  	}
  3.3602 -
  3.3603 -	int read = gzread(gzFile,
  3.3604 -	                  gbRam,
  3.3605 -	                  gbRamSize);
  3.3606 -
  3.3607 -	bool res = true;
  3.3608 -
  3.3609 -	if (read != gbRamSize)
  3.3610 -	{
  3.3611 -		systemMessage(MSG_FAILED_TO_READ_SGM,
  3.3612 -		              N_("Failed to read complete save game %s (%d)"), name, read);
  3.3613 -	}
  3.3614 -	else
  3.3615 -	{
  3.3616 -		//assert(sizeof(time_t) == 4);
  3.3617 -		read = gzread(gzFile,
  3.3618 -		              &gbDataMBC3.mapperSeconds,
  3.3619 -		              sizeof(int32) * 10 + /*sizeof(time_t)*/4);
  3.3620 -
  3.3621 -		if (read != (sizeof(int32) * 10 + /*sizeof(time_t)*/4) && read != 0)
  3.3622 -		{
  3.3623 -			systemMessage(MSG_FAILED_TO_READ_RTC,
  3.3624 -			              N_("Failed to read RTC from save game %s (continuing)"),
  3.3625 -			              name);
  3.3626 -			res = false;
  3.3627 -		}
  3.3628 -	}
  3.3629 -
  3.3630 -	gzclose(gzFile);
  3.3631 -	return res;
  3.3632 +    }
  3.3633 +
  3.3634 +  gzclose(gzFile);
  3.3635 +  return res;
  3.3636  }
  3.3637  
  3.3638  bool gbReadSaveMBC5(const char *name)
  3.3639  {
  3.3640 -	gzFile gzFile = gzopen(name, "rb");
  3.3641 -
  3.3642 -	if (gzFile == NULL)
  3.3643 -	{
  3.3644 -		return false;
  3.3645 -	}
  3.3646 -
  3.3647 -	int read = gzread(gzFile,
  3.3648 -	                  gbRam,
  3.3649 -	                  gbRamSize);
  3.3650 -
  3.3651 -	if (read != gbRamSize)
  3.3652 -	{
  3.3653 -		systemMessage(MSG_FAILED_TO_READ_SGM,
  3.3654 -		              N_("Failed to read complete save game %s (%d)"), name, read);
  3.3655 -		gzclose(gzFile);
  3.3656 -		return false;
  3.3657 -	}
  3.3658 -
  3.3659 -	gzclose(gzFile);
  3.3660 -	return true;
  3.3661 +  gzFile gzFile = gzopen(name, "rb");
  3.3662 +
  3.3663 +  if (gzFile == NULL)
  3.3664 +    {
  3.3665 +      return false;
  3.3666 +    }
  3.3667 +
  3.3668 +  int read = gzread(gzFile,
  3.3669 +		    gbRam,
  3.3670 +		    gbRamSize);
  3.3671 +
  3.3672 +  if (read != gbRamSize)
  3.3673 +    {
  3.3674 +      systemMessage(MSG_FAILED_TO_READ_SGM,
  3.3675 +		    N_("Failed to read complete save game %s (%d)"), name, read);
  3.3676 +      gzclose(gzFile);
  3.3677 +      return false;
  3.3678 +    }
  3.3679 +
  3.3680 +  gzclose(gzFile);
  3.3681 +  return true;
  3.3682  }
  3.3683  
  3.3684  bool gbReadSaveMBC7(const char *name)
  3.3685  {
  3.3686 -	FILE *file = fopen(name, "rb");
  3.3687 -
  3.3688 -	if (file == NULL)
  3.3689 -	{
  3.3690 -		return false;
  3.3691 -	}
  3.3692 -
  3.3693 -	int read = fread(&gbMemory[0xa000],
  3.3694 -	                 1,
  3.3695 -	                 256,
  3.3696 -	                 file);
  3.3697 -
  3.3698 -	if (read != 256)
  3.3699 -	{
  3.3700 -		systemMessage(MSG_FAILED_TO_READ_SGM,
  3.3701 -		              N_("Failed to read complete save game %s (%d)"), name, read);
  3.3702 -		fclose(file);
  3.3703 -		return false;
  3.3704 -	}
  3.3705 -
  3.3706 -	fclose(file);
  3.3707 -	return true;
  3.3708 +  FILE *file = fopen(name, "rb");
  3.3709 +
  3.3710 +  if (file == NULL)
  3.3711 +    {
  3.3712 +      return false;
  3.3713 +    }
  3.3714 +
  3.3715 +  int read = fread(&gbMemory[0xa000],
  3.3716 +		   1,
  3.3717 +		   256,
  3.3718 +		   file);
  3.3719 +
  3.3720 +  if (read != 256)
  3.3721 +    {
  3.3722 +      systemMessage(MSG_FAILED_TO_READ_SGM,
  3.3723 +		    N_("Failed to read complete save game %s (%d)"), name, read);
  3.3724 +      fclose(file);
  3.3725 +      return false;
  3.3726 +    }
  3.3727 +
  3.3728 +  fclose(file);
  3.3729 +  return true;
  3.3730  }
  3.3731  
  3.3732  #if 0
  3.3733  bool gbLoadBIOS(const char *biosFileName, bool useBiosFile)
  3.3734  {
  3.3735 -	useBios = false;
  3.3736 -	if (useBiosFile)
  3.3737 +  useBios = false;
  3.3738 +  if (useBiosFile)
  3.3739 +    {
  3.3740 +      useBios = utilLoadBIOS(bios, biosFileName, gbEmulatorType);
  3.3741 +      if (!useBios)
  3.3742  	{
  3.3743 -		useBios = utilLoadBIOS(bios, biosFileName, gbEmulatorType);
  3.3744 -		if (!useBios)
  3.3745 -		{
  3.3746 -			systemMessage(MSG_INVALID_BIOS_FILE_SIZE, N_("Invalid BOOTROM file"));
  3.3747 -		}
  3.3748 +	  systemMessage(MSG_INVALID_BIOS_FILE_SIZE, N_("Invalid BOOTROM file"));
  3.3749  	}
  3.3750 -	return useBios;
  3.3751 +    }
  3.3752 +  return useBios;
  3.3753  }
  3.3754  #endif
  3.3755  
  3.3756  void gbInit()
  3.3757  {
  3.3758 -	gbGenFilter();
  3.3759 -	gbSgbInit();    // calls gbSgbReset()... whatever
  3.3760 -
  3.3761 -	gbMemory = (u8 *)malloc(65536 + 4);
  3.3762 -	memset(gbMemory, 0, 65536 + 4);
  3.3763 -	memset(gbPalette, 0, 2 * 128);
  3.3764 -
  3.3765 -	// HACK: +4 at start to accomodate the 2xSaI filter reading out of bounds of the leftmost pixel
  3.3766 -	origPix = (u8 *)calloc(1, 4 * 257 * 226 + 4);
  3.3767 -	pix		= origPix + 4;
  3.3768 -
  3.3769 -	gbLineBuffer = (u16 *)malloc(160 * sizeof(u16));
  3.3770 +  gbGenFilter();
  3.3771 +  gbSgbInit();    // calls gbSgbReset()... whatever
  3.3772 +
  3.3773 +  gbMemory = (u8 *)malloc(65536 + 4);
  3.3774 +  memset(gbMemory, 0, 65536 + 4);
  3.3775 +  memset(gbPalette, 0, 2 * 128);
  3.3776 +
  3.3777 +  // HACK: +4 at start to accomodate the 2xSaI filter reading out of bounds of the leftmost pixel
  3.3778 +  origPix = (u8 *)calloc(1, 4 * 257 * 226 + 4);
  3.3779 +  pix		= origPix + 4;
  3.3780 +
  3.3781 +  gbLineBuffer = (u16 *)malloc(160 * sizeof(u16));
  3.3782  }
  3.3783  
  3.3784  bool gbWriteBatteryFile(const char *file, bool extendedSave)
  3.3785  {
  3.3786 -	if (gbBattery)
  3.3787 -	{
  3.3788 -		int type = gbRom[0x147];
  3.3789 -
  3.3790 -		switch (type)
  3.3791 -		{
  3.3792 -		case 0x03:
  3.3793 -			gbWriteSaveMBC1(file);
  3.3794 -			break;
  3.3795 -		case 0x06:
  3.3796 -			gbWriteSaveMBC2(file);
  3.3797 -			break;
  3.3798 -		case 0x0f:
  3.3799 -		case 0x10:
  3.3800 -		case 0x13:
  3.3801 -			gbWriteSaveMBC3(file, extendedSave);
  3.3802 -			break;
  3.3803 -		case 0x1b:
  3.3804 -		case 0x1e:
  3.3805 -			gbWriteSaveMBC5(file);
  3.3806 -			break;
  3.3807 -		case 0x22:
  3.3808 -			gbWriteSaveMBC7(file);
  3.3809 -			break;
  3.3810 -		case 0xff:
  3.3811 -			gbWriteSaveMBC1(file);
  3.3812 -			break;
  3.3813 -		}
  3.3814 -	}
  3.3815 -	return true;
  3.3816 -}
  3.3817 -
  3.3818 -bool gbWriteBatteryFile(const char *file)
  3.3819 -{
  3.3820 -	gbWriteBatteryFile(file, true);
  3.3821 -	return true;
  3.3822 -}
  3.3823 -
  3.3824 -bool gbWriteBatteryToStream(gzFile gzfile)
  3.3825 -{
  3.3826 -	// the GB save code is ugly, so rather than convert it all to use gzFiles, just save it to a temp file...
  3.3827 -#define TEMP_SAVE_FNAME ("tempvbawrite.sav")
  3.3828 -	bool retVal = gbWriteBatteryFile(TEMP_SAVE_FNAME, true);
  3.3829 -
  3.3830 -	// ...open the temp file and figure out its size...
  3.3831 -	FILE *fileTemp = fopen(TEMP_SAVE_FNAME, "rb");
  3.3832 -	if (fileTemp == NULL)
  3.3833 -		return false;
  3.3834 -	fseek(fileTemp, 0, SEEK_END);
  3.3835 -	int len = (int) ftell(fileTemp);
  3.3836 -
  3.3837 -	// ...copy over the temp file...
  3.3838 -	char *temp = new char [len];
  3.3839 -	fseek(fileTemp, 0, SEEK_SET);
  3.3840 -	if (fread(temp, len, 1, fileTemp) != 1)
  3.3841 -	{
  3.3842 -		delete [] temp;
  3.3843 -		fclose(fileTemp);
  3.3844 -		return false;
  3.3845 -	}
  3.3846 -	fclose(fileTemp);
  3.3847 -	utilGzWrite(gzfile, temp, len);
  3.3848 -	delete [] temp;
  3.3849 -
  3.3850 -	// ... and delete the temp file
  3.3851 -	remove(TEMP_SAVE_FNAME);
  3.3852 -#undef TEMP_SAVE_FNAME
  3.3853 -
  3.3854 -	return retVal;
  3.3855 -}
  3.3856 -
  3.3857 -bool gbReadBatteryFile(const char *file)
  3.3858 -{
  3.3859 -	bool res = false;
  3.3860 -	if (gbBattery)
  3.3861 -	{
  3.3862 -		int type = gbRom[0x147];
  3.3863 -
  3.3864 -		switch (type)
  3.3865 -		{
  3.3866 -		case 0x03:
  3.3867 -			res = gbReadSaveMBC1(file);
  3.3868 -			break;
  3.3869 -		case 0x06:
  3.3870 -			res = gbReadSaveMBC2(file);
  3.3871 -			break;
  3.3872 -		case 0x0f:
  3.3873 -		case 0x10:
  3.3874 -		case 0x13:
  3.3875 -			if (!gbReadSaveMBC3(file))
  3.3876 -			{
  3.3877 -				struct tm *lt;
  3.3878 -				time_t tmp; //Small kludge to get it working on some systems where time_t has size 8.
  3.3879 -
  3.3880 -				if (VBAMovieActive() || VBAMovieLoading())
  3.3881 -				{
  3.3882 -					gbDataMBC3.mapperLastTime = VBAMovieGetId() + VBAMovieGetFrameCounter() / 60;
  3.3883 -					lt = gmtime(&tmp);
  3.3884 -					gbDataMBC3.mapperLastTime=(u32)tmp;
  3.3885 -				}
  3.3886 -				else
  3.3887 -				{
  3.3888 -					time(&tmp);
  3.3889 -					gbDataMBC3.mapperLastTime=(u32)tmp;
  3.3890 -					lt = localtime(&tmp);
  3.3891 -				}
  3.3892 -				systemScreenMessage(ctime(&tmp), 4);
  3.3893 -				gbDataMBC3.mapperLastTime=(u32)tmp;
  3.3894 -
  3.3895 -				gbDataMBC3.mapperSeconds = lt->tm_sec;
  3.3896 -				gbDataMBC3.mapperMinutes = lt->tm_min;
  3.3897 -				gbDataMBC3.mapperHours	 = lt->tm_hour;
  3.3898 -				gbDataMBC3.mapperDays	 = lt->tm_yday & 255;
  3.3899 -				gbDataMBC3.mapperControl = (gbDataMBC3.mapperControl & 0xfe) |
  3.3900 -				                           (lt->tm_yday > 255 ? 1 : 0);
  3.3901 -				res = false;
  3.3902 -				break;
  3.3903 -			}
  3.3904 -			time_t tmp;
  3.3905 -			systemScreenMessage(ctime(&tmp), 4);
  3.3906 -			gbDataMBC3.mapperLastTime=(u32)tmp;
  3.3907 -			res = true;
  3.3908 -			break;
  3.3909 -		case 0x1b:
  3.3910 -		case 0x1e:
  3.3911 -			res = gbReadSaveMBC5(file);
  3.3912 -			break;
  3.3913 -		case 0x22:
  3.3914 -			res = gbReadSaveMBC7(file);
  3.3915 -		case 0xff:
  3.3916 -			res = gbReadSaveMBC1(file);
  3.3917 -			break;
  3.3918 -		}
  3.3919 -	}
  3.3920 -	systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  3.3921 -	return res;
  3.3922 -}
  3.3923 -
  3.3924 -bool gbReadBatteryFromStream(gzFile gzfile)
  3.3925 -{
  3.3926 -	// the GB save code is ugly, so rather than convert it all to use gzFiles, just copy it to temp RAM...
  3.3927 -#define TEMP_SAVE_FNAME ("tempvbaread.sav")
  3.3928 -	int	  pos	 = gztell(gzfile);
  3.3929 -	int	  buflen = 1024;
  3.3930 -	// ...make a temp file and write it there...
  3.3931 -	FILE *fileTemp = fopen(TEMP_SAVE_FNAME, "wb");
  3.3932 -	if (fileTemp == NULL)
  3.3933 -		return false;
  3.3934 -	int gzDeflated;
  3.3935 -	char *temp	 = new char [buflen];
  3.3936 -	while ((gzDeflated = utilGzRead(gzfile, temp, buflen)) != 0)
  3.3937 -	{
  3.3938 -		if (gzDeflated == -1 || fwrite(temp, gzDeflated, 1, fileTemp) != 1)
  3.3939 -		{
  3.3940 -			delete [] temp;
  3.3941 -			fclose(fileTemp);
  3.3942 -			gzseek(gzfile, pos, SEEK_SET); /// FIXME: leaves pos in gzfile before save instead of after it (everything that
  3.3943 -			                               // calls this right now does a seek afterwards so it doesn't matter for now, but it's
  3.3944 -			                               // still bad)
  3.3945 -			return false;
  3.3946 -		}
  3.3947 -	}
  3.3948 -	gzseek(gzfile, pos, SEEK_SET); /// FIXME: leaves pos in gzfile before save instead of after it (everything that calls this
  3.3949 -	                               // right now does a seek afterwards so it doesn't matter for now, but it's still bad)
  3.3950 -	fclose(fileTemp);
  3.3951 -	delete [] temp;
  3.3952 -
  3.3953 -	// ... load from the temp file...
  3.3954 -	bool retVal = gbReadBatteryFile(TEMP_SAVE_FNAME);
  3.3955 -
  3.3956 -	// ... and delete the temp file
  3.3957 -	remove(TEMP_SAVE_FNAME);
  3.3958 -#undef TEMP_SAVE_FNAME
  3.3959 -
  3.3960 -	return retVal;
  3.3961 -}
  3.3962 -
  3.3963 -bool gbReadGSASnapshot(const char *fileName)
  3.3964 -{
  3.3965 -	FILE *file = fopen(fileName, "rb");
  3.3966 -
  3.3967 -	if (!file)
  3.3968 -	{
  3.3969 -		systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
  3.3970 -		return false;
  3.3971 -	}
  3.3972 -
  3.3973 -	//  long size = ftell(file);
  3.3974 -	fseek(file, 0x4, SEEK_SET);
  3.3975 -	char buffer[16];
  3.3976 -	char buffer2[16];
  3.3977 -	fread(buffer, 1, 15, file);
  3.3978 -	buffer[15] = 0;
  3.3979 -	memcpy(buffer2, &gbRom[0x134], 15);
  3.3980 -	buffer2[15] = 0;
  3.3981 -	if (memcmp(buffer, buffer2, 15))
  3.3982 -	{
  3.3983 -		systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR,
  3.3984 -		              N_("Cannot import snapshot for %s. Current game is %s"),
  3.3985 -		              buffer,
  3.3986 -		              buffer2);
  3.3987 -		fclose(file);
  3.3988 -		return false;
  3.3989 -	}
  3.3990 -	fseek(file, 0x13, SEEK_SET);
  3.3991 -	int read   = 0;
  3.3992 -	int toRead = 0;
  3.3993 -	switch (gbRom[0x147])
  3.3994 +  if (gbBattery)
  3.3995 +    {
  3.3996 +      int type = gbRom[0x147];
  3.3997 +
  3.3998 +      switch (type)
  3.3999  	{
  3.4000  	case 0x03:
  3.4001 +	  gbWriteSaveMBC1(file);
  3.4002 +	  break;
  3.4003 +	case 0x06:
  3.4004 +	  gbWriteSaveMBC2(file);
  3.4005 +	  break;
  3.4006  	case 0x0f:
  3.4007  	case 0x10:
  3.4008  	case 0x13:
  3.4009 +	  gbWriteSaveMBC3(file, extendedSave);
  3.4010 +	  break;
  3.4011  	case 0x1b:
  3.4012  	case 0x1e:
  3.4013 +	  gbWriteSaveMBC5(file);
  3.4014 +	  break;
  3.4015 +	case 0x22:
  3.4016 +	  gbWriteSaveMBC7(file);
  3.4017 +	  break;
  3.4018  	case 0xff:
  3.4019 -		read   = fread(gbRam, 1, gbRamSize, file);
  3.4020 -		toRead = gbRamSize;
  3.4021 -		break;
  3.4022 +	  gbWriteSaveMBC1(file);
  3.4023 +	  break;
  3.4024 +	}
  3.4025 +    }
  3.4026 +  return true;
  3.4027 +}
  3.4028 +
  3.4029 +bool gbWriteBatteryFile(const char *file)
  3.4030 +{
  3.4031 +  gbWriteBatteryFile(file, true);
  3.4032 +  return true;
  3.4033 +}
  3.4034 +
  3.4035 +bool gbWriteBatteryToStream(gzFile gzfile)
  3.4036 +{
  3.4037 +  // the GB save code is ugly, so rather than convert it all to use gzFiles, just save it to a temp file...
  3.4038 +#define TEMP_SAVE_FNAME ("tempvbawrite.sav")
  3.4039 +  bool retVal = gbWriteBatteryFile(TEMP_SAVE_FNAME, true);
  3.4040 +
  3.4041 +  // ...open the temp file and figure out its size...
  3.4042 +  FILE *fileTemp = fopen(TEMP_SAVE_FNAME, "rb");
  3.4043 +  if (fileTemp == NULL)
  3.4044 +    return false;
  3.4045 +  fseek(fileTemp, 0, SEEK_END);
  3.4046 +  int len = (int) ftell(fileTemp);
  3.4047 +
  3.4048 +  // ...copy over the temp file...
  3.4049 +  char *temp = new char [len];
  3.4050 +  fseek(fileTemp, 0, SEEK_SET);
  3.4051 +  if (fread(temp, len, 1, fileTemp) != 1)
  3.4052 +    {
  3.4053 +      delete [] temp;
  3.4054 +      fclose(fileTemp);
  3.4055 +      return false;
  3.4056 +    }
  3.4057 +  fclose(fileTemp);
  3.4058 +  utilGzWrite(gzfile, temp, len);
  3.4059 +  delete [] temp;
  3.4060 +
  3.4061 +  // ... and delete the temp file
  3.4062 +  remove(TEMP_SAVE_FNAME);
  3.4063 +#undef TEMP_SAVE_FNAME
  3.4064 +
  3.4065 +  return retVal;
  3.4066 +}
  3.4067 +
  3.4068 +bool gbReadBatteryFile(const char *file)
  3.4069 +{
  3.4070 +  bool res = false;
  3.4071 +  if (gbBattery)
  3.4072 +    {
  3.4073 +      int type = gbRom[0x147];
  3.4074 +
  3.4075 +      switch (type)
  3.4076 +	{
  3.4077 +	case 0x03:
  3.4078 +	  res = gbReadSaveMBC1(file);
  3.4079 +	  break;
  3.4080  	case 0x06:
  3.4081 +	  res = gbReadSaveMBC2(file);
  3.4082 +	  break;
  3.4083 +	case 0x0f:
  3.4084 +	case 0x10:
  3.4085 +	case 0x13:
  3.4086 +	  if (!gbReadSaveMBC3(file))
  3.4087 +	    {
  3.4088 +	      struct tm *lt;
  3.4089 +	      time_t tmp; //Small kludge to get it working on some systems where time_t has size 8.
  3.4090 +
  3.4091 +	      if (VBAMovieActive() || VBAMovieLoading())
  3.4092 +		{
  3.4093 +		  gbDataMBC3.mapperLastTime = VBAMovieGetId() + VBAMovieGetFrameCounter() / 60;
  3.4094 +		  lt = gmtime(&tmp);
  3.4095 +		  gbDataMBC3.mapperLastTime=(u32)tmp;
  3.4096 +		}
  3.4097 +	      else
  3.4098 +		{
  3.4099 +		  time(&tmp);
  3.4100 +		  gbDataMBC3.mapperLastTime=(u32)tmp;
  3.4101 +		  lt = localtime(&tmp);
  3.4102 +		}
  3.4103 +	      systemScreenMessage(ctime(&tmp), 4);
  3.4104 +	      gbDataMBC3.mapperLastTime=(u32)tmp;
  3.4105 +
  3.4106 +	      gbDataMBC3.mapperSeconds = lt->tm_sec;
  3.4107 +	      gbDataMBC3.mapperMinutes = lt->tm_min;
  3.4108 +	      gbDataMBC3.mapperHours	 = lt->tm_hour;
  3.4109 +	      gbDataMBC3.mapperDays	 = lt->tm_yday & 255;
  3.4110 +	      gbDataMBC3.mapperControl = (gbDataMBC3.mapperControl & 0xfe) |
  3.4111 +		(lt->tm_yday > 255 ? 1 : 0);
  3.4112 +	      res = false;
  3.4113 +	      break;
  3.4114 +	    }
  3.4115 +	  time_t tmp;
  3.4116 +	  systemScreenMessage(ctime(&tmp), 4);
  3.4117 +	  gbDataMBC3.mapperLastTime=(u32)tmp;
  3.4118 +	  res = true;
  3.4119 +	  break;
  3.4120 +	case 0x1b:
  3.4121 +	case 0x1e:
  3.4122 +	  res = gbReadSaveMBC5(file);
  3.4123 +	  break;
  3.4124  	case 0x22:
  3.4125 -		read   = fread(&gbMemory[0xa000], 1, 256, file);
  3.4126 -		toRead = 256;
  3.4127 -		break;
  3.4128 -	default:
  3.4129 -		systemMessage(MSG_UNSUPPORTED_SNAPSHOT_FILE,
  3.4130 -		              N_("Unsupported snapshot file %s"),
  3.4131 -		              fileName);
  3.4132 -		fclose(file);
  3.4133 -		return false;
  3.4134 +	  res = gbReadSaveMBC7(file);
  3.4135 +	case 0xff:
  3.4136 +	  res = gbReadSaveMBC1(file);
  3.4137 +	  break;
  3.4138  	}
  3.4139 -	fclose(file);
  3.4140 -	gbReset();
  3.4141 -	return true;
  3.4142 +    }
  3.4143 +  systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  3.4144 +  return res;
  3.4145  }
  3.4146  
  3.4147 +bool gbReadBatteryFromStream(gzFile gzfile)
  3.4148 +{
  3.4149 +  // the GB save code is ugly, so rather than convert it all to use gzFiles, just copy it to temp RAM...
  3.4150 +#define TEMP_SAVE_FNAME ("tempvbaread.sav")
  3.4151 +  int	  pos	 = gztell(gzfile);
  3.4152 +  int	  buflen = 1024;
  3.4153 +  // ...make a temp file and write it there...
  3.4154 +  FILE *fileTemp = fopen(TEMP_SAVE_FNAME, "wb");
  3.4155 +  if (fileTemp == NULL)
  3.4156 +    return false;
  3.4157 +  int gzDeflated;
  3.4158 +  char *temp	 = new char [buflen];
  3.4159 +  while ((gzDeflated = utilGzRead(gzfile, temp, buflen)) != 0)
  3.4160 +    {
  3.4161 +      if (gzDeflated == -1 || fwrite(temp, gzDeflated, 1, fileTemp) != 1)
  3.4162 +	{
  3.4163 +	  delete [] temp;
  3.4164 +	  fclose(fileTemp);
  3.4165 +	  gzseek(gzfile, pos, SEEK_SET); /// FIXME: leaves pos in gzfile before save instead of after it (everything that
  3.4166 +	  // calls this right now does a seek afterwards so it doesn't matter for now, but it's
  3.4167 +	  // still bad)
  3.4168 +	  return false;
  3.4169 +	}
  3.4170 +    }
  3.4171 +  gzseek(gzfile, pos, SEEK_SET); /// FIXME: leaves pos in gzfile before save instead of after it (everything that calls this
  3.4172 +  // right now does a seek afterwards so it doesn't matter for now, but it's still bad)
  3.4173 +  fclose(fileTemp);
  3.4174 +  delete [] temp;
  3.4175 +
  3.4176 +  // ... load from the temp file...
  3.4177 +  bool retVal = gbReadBatteryFile(TEMP_SAVE_FNAME);
  3.4178 +
  3.4179 +  // ... and delete the temp file
  3.4180 +  remove(TEMP_SAVE_FNAME);
  3.4181 +#undef TEMP_SAVE_FNAME
  3.4182 +
  3.4183 +  return retVal;
  3.4184 +}
  3.4185 +
  3.4186 +bool gbReadGSASnapshot(const char *fileName)
  3.4187 +{
  3.4188 +  FILE *file = fopen(fileName, "rb");
  3.4189 +
  3.4190 +  if (!file)
  3.4191 +    {
  3.4192 +      systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
  3.4193 +      return false;
  3.4194 +    }
  3.4195 +
  3.4196 +  //  long size = ftell(file);
  3.4197 +  fseek(file, 0x4, SEEK_SET);
  3.4198 +  char buffer[16];
  3.4199 +  char buffer2[16];
  3.4200 +  fread(buffer, 1, 15, file);
  3.4201 +  buffer[15] = 0;
  3.4202 +  memcpy(buffer2, &gbRom[0x134], 15);
  3.4203 +  buffer2[15] = 0;
  3.4204 +  if (memcmp(buffer, buffer2, 15))
  3.4205 +    {
  3.4206 +      systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR,
  3.4207 +		    N_("Cannot import snapshot for %s. Current game is %s"),
  3.4208 +		    buffer,
  3.4209 +		    buffer2);
  3.4210 +      fclose(file);
  3.4211 +      return false;
  3.4212 +    }
  3.4213 +  fseek(file, 0x13, SEEK_SET);
  3.4214 +  int read   = 0;
  3.4215 +  int toRead = 0;
  3.4216 +  switch (gbRom[0x147])
  3.4217 +    {
  3.4218 +    case 0x03:
  3.4219 +    case 0x0f:
  3.4220 +    case 0x10:
  3.4221 +    case 0x13:
  3.4222 +    case 0x1b:
  3.4223 +    case 0x1e:
  3.4224 +    case 0xff:
  3.4225 +      read   = fread(gbRam, 1, gbRamSize, file);
  3.4226 +      toRead = gbRamSize;
  3.4227 +      break;
  3.4228 +    case 0x06:
  3.4229 +    case 0x22:
  3.4230 +      read   = fread(&gbMemory[0xa000], 1, 256, file);
  3.4231 +      toRead = 256;
  3.4232 +      break;
  3.4233 +    default:
  3.4234 +      systemMessage(MSG_UNSUPPORTED_SNAPSHOT_FILE,
  3.4235 +		    N_("Unsupported snapshot file %s"),
  3.4236 +		    fileName);
  3.4237 +      fclose(file);
  3.4238 +      return false;
  3.4239 +    }
  3.4240 +  fclose(file);
  3.4241 +  gbReset();
  3.4242 +  return true;
  3.4243 +}
  3.4244 +
  3.4245  variable_desc gbSaveGameStruct[] =
  3.4246 -{
  3.4247 -	{ &PC.W,					   sizeof(u16)						 },
  3.4248 -	{ &SP.W,					   sizeof(u16)						 },
  3.4249 -	{ &AF.W,					   sizeof(u16)						 },
  3.4250 -	{ &BC.W,					   sizeof(u16)						 },
  3.4251 -	{ &DE.W,					   sizeof(u16)						 },
  3.4252 -	{ &HL.W,					   sizeof(u16)						 },
  3.4253 -	{ &IFF,						   sizeof(u8)						 },
  3.4254 -	{ &GBLCD_MODE_0_CLOCK_TICKS,   sizeof(int32)					 },
  3.4255 -	{ &GBLCD_MODE_1_CLOCK_TICKS,   sizeof(int32)					 },
  3.4256 -	{ &GBLCD_MODE_2_CLOCK_TICKS,   sizeof(int32)					 },
  3.4257 -	{ &GBLCD_MODE_3_CLOCK_TICKS,   sizeof(int32)					 },
  3.4258 -	{ &GBDIV_CLOCK_TICKS,		   sizeof(int32)					 },
  3.4259 -	{ &GBLY_INCREMENT_CLOCK_TICKS, sizeof(int32)					 },
  3.4260 -	{ &GBTIMER_MODE_0_CLOCK_TICKS, sizeof(int32)					 },
  3.4261 -	{ &GBTIMER_MODE_1_CLOCK_TICKS, sizeof(int32)					 },
  3.4262 -	{ &GBTIMER_MODE_2_CLOCK_TICKS, sizeof(int32)					 },
  3.4263 -	{ &GBTIMER_MODE_3_CLOCK_TICKS, sizeof(int32)					 },
  3.4264 -	{ &GBSERIAL_CLOCK_TICKS,	   sizeof(int32)					 },
  3.4265 -	{ &GBSYNCHRONIZE_CLOCK_TICKS,  sizeof(int32)					 },
  3.4266 -	{ &gbDivTicks,				   sizeof(int32)					 },
  3.4267 -	{ &gbLcdMode,				   sizeof(int32)					 },
  3.4268 -	{ &gbLcdTicks,				   sizeof(int32)					 },
  3.4269 -	{ &gbLcdLYIncrementTicks,	   sizeof(int32)					 },
  3.4270 -	{ &gbTimerTicks,			   sizeof(int32)					 },
  3.4271 -	{ &gbTimerClockTicks,		   sizeof(int32)					 },
  3.4272 -	{ &gbSerialTicks,			   sizeof(int32)					 },
  3.4273 -	{ &gbSerialBits,			   sizeof(int32)					 },
  3.4274 -	{ &gbInterrupt,				   sizeof(int32)					 },
  3.4275 -	{ &gbInterruptWait,			   sizeof(int32)					 },
  3.4276 -	{ &gbSynchronizeTicks,		   sizeof(int32)					 },
  3.4277 -	{ &gbTimerOn,				   sizeof(int32)					 },
  3.4278 -	{ &gbTimerMode,				   sizeof(int32)					 },
  3.4279 -	{ &gbSerialOn,				   sizeof(int32)					 },
  3.4280 -	{ &gbWindowLine,			   sizeof(int32)					 },
  3.4281 -	{ &gbCgbMode,				   sizeof(int32)					 },
  3.4282 -	{ &gbVramBank,				   sizeof(int32)					 },
  3.4283 -	{ &gbWramBank,				   sizeof(int32)					 },
  3.4284 -	{ &gbHdmaSource,			   sizeof(int32)					 },
  3.4285 -	{ &gbHdmaDestination,		   sizeof(int32)					 },
  3.4286 -	{ &gbHdmaBytes,				   sizeof(int32)					 },
  3.4287 -	{ &gbHdmaOn,				   sizeof(int32)					 },
  3.4288 -	{ &gbSpeed,					   sizeof(int32)					 },
  3.4289 -	{ &gbSgbMode,				   sizeof(int32)					 },
  3.4290 -	{ &register_DIV,			   sizeof(u8)						 },
  3.4291 -	{ &register_TIMA,			   sizeof(u8)						 },
  3.4292 -	{ &register_TMA,			   sizeof(u8)						 },
  3.4293 -	{ &register_TAC,			   sizeof(u8)						 },
  3.4294 -	{ &register_IF,				   sizeof(u8)						 },
  3.4295 -	{ &register_LCDC,			   sizeof(u8)						 },
  3.4296 -	{ &register_STAT,			   sizeof(u8)						 },
  3.4297 -	{ &register_SCY,			   sizeof(u8)						 },
  3.4298 -	{ &register_SCX,			   sizeof(u8)						 },
  3.4299 -	{ &register_LY,				   sizeof(u8)						 },
  3.4300 -	{ &register_LYC,			   sizeof(u8)						 },
  3.4301 -	{ &register_DMA,			   sizeof(u8)						 },
  3.4302 -	{ &register_WY,				   sizeof(u8)						 },
  3.4303 -	{ &register_WX,				   sizeof(u8)						 },
  3.4304 -	{ &register_VBK,			   sizeof(u8)						 },
  3.4305 -	{ &register_HDMA1,			   sizeof(u8)						 },
  3.4306 -	{ &register_HDMA2,			   sizeof(u8)						 },
  3.4307 -	{ &register_HDMA3,			   sizeof(u8)						 },
  3.4308 -	{ &register_HDMA4,			   sizeof(u8)						 },
  3.4309 -	{ &register_HDMA5,			   sizeof(u8)						 },
  3.4310 -	{ &register_SVBK,			   sizeof(u8)						 },
  3.4311 -	{ &register_IE,				   sizeof(u8)						 },
  3.4312 -	{ &gbBgp[0],				   sizeof(u8)						 },
  3.4313 -	{ &gbBgp[1],				   sizeof(u8)						 },
  3.4314 -	{ &gbBgp[2],				   sizeof(u8)						 },
  3.4315 -	{ &gbBgp[3],				   sizeof(u8)						 },
  3.4316 -	{ &gbObp0[0],				   sizeof(u8)						 },
  3.4317 -	{ &gbObp0[1],				   sizeof(u8)						 },
  3.4318 -	{ &gbObp0[2],				   sizeof(u8)						 },
  3.4319 -	{ &gbObp0[3],				   sizeof(u8)						 },
  3.4320 -	{ &gbObp1[0],				   sizeof(u8)						 },
  3.4321 -	{ &gbObp1[1],				   sizeof(u8)						 },
  3.4322 -	{ &gbObp1[2],				   sizeof(u8)						 },
  3.4323 -	{ &gbObp1[3],				   sizeof(u8)						 },
  3.4324 -	{ NULL,						   0								 }
  3.4325 -};
  3.4326 +  {
  3.4327 +    { &PC.W,					   sizeof(u16)						 },
  3.4328 +    { &SP.W,					   sizeof(u16)						 },
  3.4329 +    { &AF.W,					   sizeof(u16)						 },
  3.4330 +    { &BC.W,					   sizeof(u16)						 },
  3.4331 +    { &DE.W,					   sizeof(u16)						 },
  3.4332 +    { &HL.W,					   sizeof(u16)						 },
  3.4333 +    { &IFF,						   sizeof(u8)						 },
  3.4334 +    { &GBLCD_MODE_0_CLOCK_TICKS,   sizeof(int32)					 },
  3.4335 +    { &GBLCD_MODE_1_CLOCK_TICKS,   sizeof(int32)					 },
  3.4336 +    { &GBLCD_MODE_2_CLOCK_TICKS,   sizeof(int32)					 },
  3.4337 +    { &GBLCD_MODE_3_CLOCK_TICKS,   sizeof(int32)					 },
  3.4338 +    { &GBDIV_CLOCK_TICKS,		   sizeof(int32)					 },
  3.4339 +    { &GBLY_INCREMENT_CLOCK_TICKS, sizeof(int32)					 },
  3.4340 +    { &GBTIMER_MODE_0_CLOCK_TICKS, sizeof(int32)					 },
  3.4341 +    { &GBTIMER_MODE_1_CLOCK_TICKS, sizeof(int32)					 },
  3.4342 +    { &GBTIMER_MODE_2_CLOCK_TICKS, sizeof(int32)					 },
  3.4343 +    { &GBTIMER_MODE_3_CLOCK_TICKS, sizeof(int32)					 },
  3.4344 +    { &GBSERIAL_CLOCK_TICKS,	   sizeof(int32)					 },
  3.4345 +    { &GBSYNCHRONIZE_CLOCK_TICKS,  sizeof(int32)					 },
  3.4346 +    { &gbDivTicks,				   sizeof(int32)					 },
  3.4347 +    { &gbLcdMode,				   sizeof(int32)					 },
  3.4348 +    { &gbLcdTicks,				   sizeof(int32)					 },
  3.4349 +    { &gbLcdLYIncrementTicks,	   sizeof(int32)					 },
  3.4350 +    { &gbTimerTicks,			   sizeof(int32)					 },
  3.4351 +    { &gbTimerClockTicks,		   sizeof(int32)					 },
  3.4352 +    { &gbSerialTicks,			   sizeof(int32)					 },
  3.4353 +    { &gbSerialBits,			   sizeof(int32)					 },
  3.4354 +    { &gbInterrupt,				   sizeof(int32)					 },
  3.4355 +    { &gbInterruptWait,			   sizeof(int32)					 },
  3.4356 +    { &gbSynchronizeTicks,		   sizeof(int32)					 },
  3.4357 +    { &gbTimerOn,				   sizeof(int32)					 },
  3.4358 +    { &gbTimerMode,				   sizeof(int32)					 },
  3.4359 +    { &gbSerialOn,				   sizeof(int32)					 },
  3.4360 +    { &gbWindowLine,			   sizeof(int32)					 },
  3.4361 +    { &gbCgbMode,				   sizeof(int32)					 },
  3.4362 +    { &gbVramBank,				   sizeof(int32)					 },
  3.4363 +    { &gbWramBank,				   sizeof(int32)					 },
  3.4364 +    { &gbHdmaSource,			   sizeof(int32)					 },
  3.4365 +    { &gbHdmaDestination,		   sizeof(int32)					 },
  3.4366 +    { &gbHdmaBytes,				   sizeof(int32)					 },
  3.4367 +    { &gbHdmaOn,				   sizeof(int32)					 },
  3.4368 +    { &gbSpeed,					   sizeof(int32)					 },
  3.4369 +    { &gbSgbMode,				   sizeof(int32)					 },
  3.4370 +    { &register_DIV,			   sizeof(u8)						 },
  3.4371 +    { &register_TIMA,			   sizeof(u8)						 },
  3.4372 +    { &register_TMA,			   sizeof(u8)						 },
  3.4373 +    { &register_TAC,			   sizeof(u8)						 },
  3.4374 +    { &register_IF,				   sizeof(u8)						 },
  3.4375 +    { &register_LCDC,			   sizeof(u8)						 },
  3.4376 +    { &register_STAT,			   sizeof(u8)						 },
  3.4377 +    { &register_SCY,			   sizeof(u8)						 },
  3.4378 +    { &register_SCX,			   sizeof(u8)						 },
  3.4379 +    { &register_LY,				   sizeof(u8)						 },
  3.4380 +    { &register_LYC,			   sizeof(u8)						 },
  3.4381 +    { &register_DMA,			   sizeof(u8)						 },
  3.4382 +    { &register_WY,				   sizeof(u8)						 },
  3.4383 +    { &register_WX,				   sizeof(u8)						 },
  3.4384 +    { &register_VBK,			   sizeof(u8)						 },
  3.4385 +    { &register_HDMA1,			   sizeof(u8)						 },
  3.4386 +    { &register_HDMA2,			   sizeof(u8)						 },
  3.4387 +    { &register_HDMA3,			   sizeof(u8)						 },
  3.4388 +    { &register_HDMA4,			   sizeof(u8)						 },
  3.4389 +    { &register_HDMA5,			   sizeof(u8)						 },
  3.4390 +    { &register_SVBK,			   sizeof(u8)						 },
  3.4391 +    { &register_IE,				   sizeof(u8)						 },
  3.4392 +    { &gbBgp[0],				   sizeof(u8)						 },
  3.4393 +    { &gbBgp[1],				   sizeof(u8)						 },
  3.4394 +    { &gbBgp[2],				   sizeof(u8)						 },
  3.4395 +    { &gbBgp[3],				   sizeof(u8)						 },
  3.4396 +    { &gbObp0[0],				   sizeof(u8)						 },
  3.4397 +    { &gbObp0[1],				   sizeof(u8)						 },
  3.4398 +    { &gbObp0[2],				   sizeof(u8)						 },
  3.4399 +    { &gbObp0[3],				   sizeof(u8)						 },
  3.4400 +    { &gbObp1[0],				   sizeof(u8)						 },
  3.4401 +    { &gbObp1[1],				   sizeof(u8)						 },
  3.4402 +    { &gbObp1[2],				   sizeof(u8)						 },
  3.4403 +    { &gbObp1[3],				   sizeof(u8)						 },
  3.4404 +    { NULL,						   0								 }
  3.4405 +  };
  3.4406  
  3.4407  bool gbWriteSaveStateToStream(gzFile gzFile)
  3.4408  {
  3.4409 -	utilWriteInt(gzFile, GBSAVE_GAME_VERSION);
  3.4410 -
  3.4411 -	utilGzWrite(gzFile, &gbRom[0x134], 15);
  3.4412 -
  3.4413 -	utilWriteData(gzFile, gbSaveGameStruct);
  3.4414 -
  3.4415 -	utilGzWrite(gzFile, &IFF, 2);
  3.4416 -
  3.4417 -	if (gbSgbMode)
  3.4418 -	{
  3.4419 -		gbSgbSaveGame(gzFile);
  3.4420 -	}
  3.4421 -
  3.4422 -	utilGzWrite(gzFile, &gbDataMBC1, sizeof(gbDataMBC1));
  3.4423 -	utilGzWrite(gzFile, &gbDataMBC2, sizeof(gbDataMBC2));
  3.4424 -	//assert(sizeof(time_t) == 4);
  3.4425 -	utilGzWrite(gzFile, &gbDataMBC3, sizeof(gbDataMBC3));
  3.4426 -	utilGzWrite(gzFile, &gbDataMBC5, sizeof(gbDataMBC5));
  3.4427 -	utilGzWrite(gzFile, &gbDataHuC1, sizeof(gbDataHuC1));
  3.4428 -	utilGzWrite(gzFile, &gbDataHuC3, sizeof(gbDataHuC3));
  3.4429 -
  3.4430 -	// yes, this definitely needs to be saved, or loading paused games will show a black screen
  3.4431 -	// this is also necessary to be consistent with what the GBA saving does
  3.4432 -	utilGzWrite(gzFile, pix, 4 * 257 * 226);
  3.4433 -
  3.4434 -	utilGzWrite(gzFile, gbPalette, 128 * sizeof(u16));
  3.4435 -	// todo: remove
  3.4436 -	utilGzWrite(gzFile, gbPalette, 128 * sizeof(u16));
  3.4437 -
  3.4438 -	utilGzWrite(gzFile, &gbMemory[0x8000], 0x8000);
  3.4439 -
  3.4440 -	if (gbRamSize && gbRam)
  3.4441 -	{
  3.4442 -		utilGzWrite(gzFile, gbRam, gbRamSize);
  3.4443 -	}
  3.4444 -
  3.4445 -	if (gbCgbMode)
  3.4446 -	{
  3.4447 -		utilGzWrite(gzFile, gbVram, 0x4000);
  3.4448 -		utilGzWrite(gzFile, gbWram, 0x8000);
  3.4449 -	}
  3.4450 -
  3.4451 -	gbSoundSaveGame(gzFile);
  3.4452 -
  3.4453 -	gbCheatsSaveGame(gzFile);
  3.4454 -
  3.4455 -	// new to re-recording version:
  3.4456 -	{
  3.4457 -		extern int32 sensorX, sensorY;
  3.4458 -		utilGzWrite(gzFile, &sensorX, sizeof(sensorX));
  3.4459 -		utilGzWrite(gzFile, &sensorY, sizeof(sensorY));
  3.4460 -		utilGzWrite(gzFile, gbJoymask, 4 * sizeof(*gbJoymask)); // this has to be saved or old input will incorrectly get
  3.4461 -		                                                        // carried
  3.4462 -		                                                        // back on loading a snapshot!
  3.4463 -
  3.4464 -		bool8 movieActive = VBAMovieActive();
  3.4465 -		utilGzWrite(gzFile, &movieActive, sizeof(movieActive));
  3.4466 -		if (movieActive)
  3.4467 -		{
  3.4468 -			uint8 *movie_freeze_buf	 = NULL;
  3.4469 -			uint32 movie_freeze_size = 0;
  3.4470 -
  3.4471 -			VBAMovieFreeze(&movie_freeze_buf, &movie_freeze_size);
  3.4472 -			if (movie_freeze_buf)
  3.4473 -			{
  3.4474 -				utilGzWrite(gzFile, &movie_freeze_size, sizeof(movie_freeze_size));
  3.4475 -				utilGzWrite(gzFile, movie_freeze_buf, movie_freeze_size);
  3.4476 -				delete [] movie_freeze_buf;
  3.4477 -			}
  3.4478 -			else
  3.4479 -			{
  3.4480 -				systemMessage(0, N_("Failed to save movie snapshot."));
  3.4481 -				return false;
  3.4482 -			}
  3.4483 -		}
  3.4484 -		utilGzWrite(gzFile, &GBSystemCounters.frameCount, sizeof(GBSystemCounters.frameCount));
  3.4485 -	}
  3.4486 -
  3.4487 -	// new to rerecording 19.4 wip (svn r22+):
  3.4488 -	{
  3.4489 -		utilGzWrite(gzFile, &GBSystemCounters.lagCount, sizeof(GBSystemCounters.lagCount));
  3.4490 -		utilGzWrite(gzFile, &GBSystemCounters.lagged, sizeof(GBSystemCounters.lagged));
  3.4491 -		utilGzWrite(gzFile, &GBSystemCounters.laggedLast, sizeof(GBSystemCounters.laggedLast));
  3.4492 -	}
  3.4493 -
  3.4494 -	return true;
  3.4495 +  utilWriteInt(gzFile, GBSAVE_GAME_VERSION);
  3.4496 +
  3.4497 +  utilGzWrite(gzFile, &gbRom[0x134], 15);
  3.4498 +
  3.4499 +  utilWriteData(gzFile, gbSaveGameStruct);
  3.4500 +
  3.4501 +  utilGzWrite(gzFile, &IFF, 2);
  3.4502 +
  3.4503 +  if (gbSgbMode)
  3.4504 +    {
  3.4505 +      gbSgbSaveGame(gzFile);
  3.4506 +    }
  3.4507 +
  3.4508 +  utilGzWrite(gzFile, &gbDataMBC1, sizeof(gbDataMBC1));
  3.4509 +  utilGzWrite(gzFile, &gbDataMBC2, sizeof(gbDataMBC2));
  3.4510 +  //assert(sizeof(time_t) == 4);
  3.4511 +  utilGzWrite(gzFile, &gbDataMBC3, sizeof(gbDataMBC3));
  3.4512 +  utilGzWrite(gzFile, &gbDataMBC5, sizeof(gbDataMBC5));
  3.4513 +  utilGzWrite(gzFile, &gbDataHuC1, sizeof(gbDataHuC1));
  3.4514 +  utilGzWrite(gzFile, &gbDataHuC3, sizeof(gbDataHuC3));
  3.4515 +
  3.4516 +  // yes, this definitely needs to be saved, or loading paused games will show a black screen
  3.4517 +  // this is also necessary to be consistent with what the GBA saving does
  3.4518 +  utilGzWrite(gzFile, pix, 4 * 257 * 226);
  3.4519 +
  3.4520 +  utilGzWrite(gzFile, gbPalette, 128 * sizeof(u16));
  3.4521 +  // todo: remove
  3.4522 +  utilGzWrite(gzFile, gbPalette, 128 * sizeof(u16));
  3.4523 +
  3.4524 +  utilGzWrite(gzFile, &gbMemory[0x8000], 0x8000);
  3.4525 +
  3.4526 +  if (gbRamSize && gbRam)
  3.4527 +    {
  3.4528 +      utilGzWrite(gzFile, gbRam, gbRamSize);
  3.4529 +    }
  3.4530 +
  3.4531 +  if (gbCgbMode)
  3.4532 +    {
  3.4533 +      utilGzWrite(gzFile, gbVram, 0x4000);
  3.4534 +      utilGzWrite(gzFile, gbWram, 0x8000);
  3.4535 +    }
  3.4536 +
  3.4537 +  gbSoundSaveGame(gzFile);
  3.4538 +
  3.4539 +  gbCheatsSaveGame(gzFile);
  3.4540 +
  3.4541 +  // new to re-recording version:
  3.4542 +  {
  3.4543 +    extern int32 sensorX, sensorY;
  3.4544 +    utilGzWrite(gzFile, &sensorX, sizeof(sensorX));
  3.4545 +    utilGzWrite(gzFile, &sensorY, sizeof(sensorY));
  3.4546 +    utilGzWrite(gzFile, gbJoymask, 4 * sizeof(*gbJoymask)); // this has to be saved or old input will incorrectly get
  3.4547 +    // carried
  3.4548 +    // back on loading a snapshot!
  3.4549 +
  3.4550 +    bool8 movieActive = VBAMovieActive();
  3.4551 +    utilGzWrite(gzFile, &movieActive, sizeof(movieActive));
  3.4552 +    if (movieActive)
  3.4553 +      {
  3.4554 +	uint8 *movie_freeze_buf	 = NULL;
  3.4555 +	uint32 movie_freeze_size = 0;
  3.4556 +
  3.4557 +	VBAMovieFreeze(&movie_freeze_buf, &movie_freeze_size);
  3.4558 +	if (movie_freeze_buf)
  3.4559 +	  {
  3.4560 +	    utilGzWrite(gzFile, &movie_freeze_size, sizeof(movie_freeze_size));
  3.4561 +	    utilGzWrite(gzFile, movie_freeze_buf, movie_freeze_size);
  3.4562 +	    delete [] movie_freeze_buf;
  3.4563 +	  }
  3.4564 +	else
  3.4565 +	  {
  3.4566 +	    systemMessage(0, N_("Failed to save movie snapshot."));
  3.4567 +	    return false;
  3.4568 +	  }
  3.4569 +      }
  3.4570 +    utilGzWrite(gzFile, &GBSystemCounters.frameCount, sizeof(GBSystemCounters.frameCount));
  3.4571 +  }
  3.4572 +
  3.4573 +  // new to rerecording 19.4 wip (svn r22+):
  3.4574 +  {
  3.4575 +    utilGzWrite(gzFile, &GBSystemCounters.lagCount, sizeof(GBSystemCounters.lagCount));
  3.4576 +    utilGzWrite(gzFile, &GBSystemCounters.lagged, sizeof(GBSystemCounters.lagged));
  3.4577 +    utilGzWrite(gzFile, &GBSystemCounters.laggedLast, sizeof(GBSystemCounters.laggedLast));
  3.4578 +  }
  3.4579 +
  3.4580 +  return true;
  3.4581  }
  3.4582  
  3.4583  bool gbWriteMemSaveState(char *memory, int available)
  3.4584  {
  3.4585 -	gzFile gzFile = utilMemGzOpen(memory, available, "w");
  3.4586 -
  3.4587 -	if (gzFile == NULL)
  3.4588 -	{
  3.4589 -		return false;
  3.4590 -	}
  3.4591 -
  3.4592 -	bool res = gbWriteSaveStateToStream(gzFile);
  3.4593 -
  3.4594 -	long pos = utilGzTell(gzFile) + 8;
  3.4595 -
  3.4596 -	if (pos >= (available))
  3.4597 -		res = false;
  3.4598 -
  3.4599 -	utilGzClose(gzFile);
  3.4600 -
  3.4601 -	return res;
  3.4602 +  gzFile gzFile = utilMemGzOpen(memory, available, "w");
  3.4603 +
  3.4604 +  if (gzFile == NULL)
  3.4605 +    {
  3.4606 +      return false;
  3.4607 +    }
  3.4608 +
  3.4609 +  bool res = gbWriteSaveStateToStream(gzFile);
  3.4610 +
  3.4611 +  long pos = utilGzTell(gzFile) + 8;
  3.4612 +
  3.4613 +  if (pos >= (available))
  3.4614 +    res = false;
  3.4615 +
  3.4616 +  utilGzClose(gzFile);
  3.4617 +
  3.4618 +  return res;
  3.4619  }
  3.4620  
  3.4621  bool gbWriteSaveState(const char *name)
  3.4622  {
  3.4623 -	gzFile gzFile = utilGzOpen(name, "wb");
  3.4624 -
  3.4625 -	if (gzFile == NULL)
  3.4626 -		return false;
  3.4627 -
  3.4628 -	bool res = gbWriteSaveStateToStream(gzFile);
  3.4629 -
  3.4630 -	utilGzClose(gzFile);
  3.4631 -	return res;
  3.4632 +  gzFile gzFile = utilGzOpen(name, "wb");
  3.4633 +
  3.4634 +  if (gzFile == NULL)
  3.4635 +    return false;
  3.4636 +
  3.4637 +  bool res = gbWriteSaveStateToStream(gzFile);
  3.4638 +
  3.4639 +  utilGzClose(gzFile);
  3.4640 +  return res;
  3.4641  }
  3.4642  
  3.4643  static int	tempStateID	  = 0;
  3.4644 @@ -2591,1328 +2591,1331 @@
  3.4645  
  3.4646  bool gbReadSaveStateFromStream(gzFile gzFile)
  3.4647  {
  3.4648 -	int	 type;
  3.4649 -	char tempBackupName [128];
  3.4650 -	if (backupSafe)
  3.4651 +  int	 type;
  3.4652 +  char tempBackupName [128];
  3.4653 +  if (backupSafe)
  3.4654 +    {
  3.4655 +      sprintf(tempBackupName, "gbatempsave%d.sav", tempStateID++);
  3.4656 +      gbWriteSaveState(tempBackupName);
  3.4657 +    }
  3.4658 +
  3.4659 +  int version = utilReadInt(gzFile);
  3.4660 +
  3.4661 +  if (version > GBSAVE_GAME_VERSION || version < 0)
  3.4662 +    {
  3.4663 +      systemMessage(MSG_UNSUPPORTED_VB_SGM,
  3.4664 +		    N_("Unsupported VisualBoy save game version %d"), version);
  3.4665 +      goto failedLoadGB;
  3.4666 +    }
  3.4667 +
  3.4668 +  u8 romname[20];
  3.4669 +
  3.4670 +  utilGzRead(gzFile, romname, 15);
  3.4671 +
  3.4672 +  if (memcmp(&gbRom[0x134], romname, 15) != 0)
  3.4673 +    {
  3.4674 +      systemMessage(MSG_CANNOT_LOAD_SGM_FOR,
  3.4675 +		    N_("Cannot load save game for %s. Playing %s"),
  3.4676 +		    romname, &gbRom[0x134]);
  3.4677 +      goto failedLoadGB;
  3.4678 +    }
  3.4679 +
  3.4680 +  utilReadData(gzFile, gbSaveGameStruct);
  3.4681 +
  3.4682 +  if (version >= GBSAVE_GAME_VERSION_7)
  3.4683 +    {
  3.4684 +      utilGzRead(gzFile, &IFF, 2);
  3.4685 +    }
  3.4686 +
  3.4687 +  if (gbSgbMode)
  3.4688 +    {
  3.4689 +      gbSgbReadGame(gzFile, version);
  3.4690 +    }
  3.4691 +  else
  3.4692 +    {
  3.4693 +      gbSgbMask = 0; // loading a game at the wrong time causes no display
  3.4694 +    }
  3.4695 +
  3.4696 +  utilGzRead(gzFile, &gbDataMBC1, sizeof(gbDataMBC1));
  3.4697 +  utilGzRead(gzFile, &gbDataMBC2, sizeof(gbDataMBC2));
  3.4698 +  if (version < GBSAVE_GAME_VERSION_4)
  3.4699 +    // prior to version 4, there was no adjustment for the time the game
  3.4700 +    // was last played, so we have less to read. This needs update if the
  3.4701 +    // structure changes again.
  3.4702 +    utilGzRead(gzFile, &gbDataMBC3, sizeof(int32) * 10);
  3.4703 +  else
  3.4704 +    {
  3.4705 +      //assert(sizeof(time_t) == 4);
  3.4706 +      utilGzRead(gzFile, &gbDataMBC3, sizeof(gbDataMBC3));
  3.4707 +    }
  3.4708 +  utilGzRead(gzFile, &gbDataMBC5, sizeof(gbDataMBC5));
  3.4709 +  utilGzRead(gzFile, &gbDataHuC1, sizeof(gbDataHuC1));
  3.4710 +  utilGzRead(gzFile, &gbDataHuC3, sizeof(gbDataHuC3));
  3.4711 +
  3.4712 +  if (version >= GBSAVE_GAME_VERSION_12)
  3.4713 +    {
  3.4714 +      utilGzRead(gzFile, pix, 4 * 257 * 226);
  3.4715 +    }
  3.4716 +  else
  3.4717 +    {
  3.4718 +      memset(pix, 0, 257 * 226 * sizeof(u32));
  3.4719 +      //		if(version < GBSAVE_GAME_VERSION_5)
  3.4720 +      //			utilGzRead(gzFile, pix, 256*224*sizeof(u16));
  3.4721 +    }
  3.4722 +
  3.4723 +  if (version < GBSAVE_GAME_VERSION_6)
  3.4724 +    {
  3.4725 +      utilGzRead(gzFile, gbPalette, 64 * sizeof(u16));
  3.4726 +    }
  3.4727 +  else
  3.4728 +    utilGzRead(gzFile, gbPalette, 128 * sizeof(u16));
  3.4729 +
  3.4730 +  // todo: remove
  3.4731 +  utilGzRead(gzFile, gbPalette, 128 * sizeof(u16));
  3.4732 +
  3.4733 +  if (version < GBSAVE_GAME_VERSION_10)
  3.4734 +    {
  3.4735 +      if (!gbCgbMode && !gbSgbMode)
  3.4736  	{
  3.4737 -		sprintf(tempBackupName, "gbatempsave%d.sav", tempStateID++);
  3.4738 -		gbWriteSaveState(tempBackupName);
  3.4739 +	  for (int i = 0; i < 8; i++)
  3.4740 +	    gbPalette[i] = systemGbPalette[gbPaletteOption * 8 + i];
  3.4741  	}
  3.4742 -
  3.4743 -	int version = utilReadInt(gzFile);
  3.4744 -
  3.4745 -	if (version > GBSAVE_GAME_VERSION || version < 0)
  3.4746 +    }
  3.4747 +
  3.4748 +  utilGzRead(gzFile, &gbMemory[0x8000], 0x8000);
  3.4749 +
  3.4750 +  if (gbRamSize && gbRam)
  3.4751 +    {
  3.4752 +      utilGzRead(gzFile, gbRam, gbRamSize);
  3.4753 +    }
  3.4754 +
  3.4755 +  gbMemoryMap[0x00] = &gbRom[0x0000];
  3.4756 +  gbMemoryMap[0x01] = &gbRom[0x1000];
  3.4757 +  gbMemoryMap[0x02] = &gbRom[0x2000];
  3.4758 +  gbMemoryMap[0x03] = &gbRom[0x3000];
  3.4759 +  gbMemoryMap[0x04] = &gbRom[0x4000];
  3.4760 +  gbMemoryMap[0x05] = &gbRom[0x5000];
  3.4761 +  gbMemoryMap[0x06] = &gbRom[0x6000];
  3.4762 +  gbMemoryMap[0x07] = &gbRom[0x7000];
  3.4763 +  gbMemoryMap[0x08] = &gbMemory[0x8000];
  3.4764 +  gbMemoryMap[0x09] = &gbMemory[0x9000];
  3.4765 +  gbMemoryMap[0x0a] = &gbMemory[0xa000];
  3.4766 +  gbMemoryMap[0x0b] = &gbMemory[0xb000];
  3.4767 +  gbMemoryMap[0x0c] = &gbMemory[0xc000];
  3.4768 +  gbMemoryMap[0x0d] = &gbMemory[0xd000];
  3.4769 +  gbMemoryMap[0x0e] = &gbMemory[0xe000];
  3.4770 +  gbMemoryMap[0x0f] = &gbMemory[0xf000];
  3.4771 +
  3.4772 +  type = gbRom[0x147];
  3.4773 +
  3.4774 +  switch (type)
  3.4775 +    {
  3.4776 +    case 0x00:
  3.4777 +    case 0x01:
  3.4778 +    case 0x02:
  3.4779 +    case 0x03:
  3.4780 +      // MBC 1
  3.4781 +      memoryUpdateMapMBC1();
  3.4782 +      break;
  3.4783 +    case 0x05:
  3.4784 +    case 0x06:
  3.4785 +      // MBC2
  3.4786 +      memoryUpdateMapMBC2();
  3.4787 +      break;
  3.4788 +    case 0x0f:
  3.4789 +    case 0x10:
  3.4790 +    case 0x11:
  3.4791 +    case 0x12:
  3.4792 +    case 0x13:
  3.4793 +      // MBC 3
  3.4794 +      memoryUpdateMapMBC3();
  3.4795 +      break;
  3.4796 +    case 0x19:
  3.4797 +    case 0x1a:
  3.4798 +    case 0x1b:
  3.4799 +      // MBC5
  3.4800 +      memoryUpdateMapMBC5();
  3.4801 +      break;
  3.4802 +    case 0x1c:
  3.4803 +    case 0x1d:
  3.4804 +    case 0x1e:
  3.4805 +      // MBC 5 Rumble
  3.4806 +      memoryUpdateMapMBC5();
  3.4807 +      break;
  3.4808 +    case 0x22:
  3.4809 +      // MBC 7
  3.4810 +      memoryUpdateMapMBC7();
  3.4811 +      break;
  3.4812 +    case 0xfe:
  3.4813 +      // HuC3
  3.4814 +      memoryUpdateMapHuC3();
  3.4815 +      break;
  3.4816 +    case 0xff:
  3.4817 +      // HuC1
  3.4818 +      memoryUpdateMapHuC1();
  3.4819 +      break;
  3.4820 +    }
  3.4821 +
  3.4822 +  if (gbCgbMode)
  3.4823 +    {
  3.4824 +      if (!gbVram)
  3.4825 +	gbVram = (u8 *)malloc(0x4000 + 4);
  3.4826 +      if (!gbWram)
  3.4827 +	gbWram = (u8 *)malloc(0x8000 + 4);
  3.4828 +      utilGzRead(gzFile, gbVram, 0x4000);
  3.4829 +      utilGzRead(gzFile, gbWram, 0x8000);
  3.4830 +
  3.4831 +      int value = register_SVBK;
  3.4832 +      if (value == 0)
  3.4833 +	value = 1;
  3.4834 +
  3.4835 +      gbMemoryMap[0x08] = &gbVram[register_VBK * 0x2000];
  3.4836 +      gbMemoryMap[0x09] = &gbVram[register_VBK * 0x2000 + 0x1000];
  3.4837 +      gbMemoryMap[0x0d] = &gbWram[value * 0x1000];
  3.4838 +    }
  3.4839 +  else
  3.4840 +    {
  3.4841 +      if (gbVram)
  3.4842  	{
  3.4843 -		systemMessage(MSG_UNSUPPORTED_VB_SGM,
  3.4844 -		              N_("Unsupported VisualBoy save game version %d"), version);
  3.4845 -		goto failedLoadGB;
  3.4846 +	  free(gbVram);
  3.4847 +	  gbVram = NULL;
  3.4848  	}
  3.4849 -
  3.4850 -	u8 romname[20];
  3.4851 -
  3.4852 -	utilGzRead(gzFile, romname, 15);
  3.4853 -
  3.4854 -	if (memcmp(&gbRom[0x134], romname, 15) != 0)
  3.4855 +      if (gbWram)
  3.4856  	{
  3.4857 -		systemMessage(MSG_CANNOT_LOAD_SGM_FOR,
  3.4858 -		              N_("Cannot load save game for %s. Playing %s"),
  3.4859 -		              romname, &gbRom[0x134]);
  3.4860 -		goto failedLoadGB;
  3.4861 +	  free(gbWram);
  3.4862 +	  gbWram = NULL;
  3.4863  	}
  3.4864 -
  3.4865 -	utilReadData(gzFile, gbSaveGameStruct);
  3.4866 -
  3.4867 -	if (version >= GBSAVE_GAME_VERSION_7)
  3.4868 +    }
  3.4869 +
  3.4870 +  gbSoundReadGame(version, gzFile);
  3.4871 +
  3.4872 +#if 0
  3.4873 +  if (gbBorderOn)
  3.4874 +    {
  3.4875 +      gbSgbRenderBorder();
  3.4876 +    }
  3.4877 +
  3.4878 +  systemRefreshScreen();
  3.4879 +#endif
  3.4880 +
  3.4881 +  if (version > GBSAVE_GAME_VERSION_1)
  3.4882 +    gbCheatsReadGame(gzFile, version);
  3.4883 +
  3.4884 +  systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  3.4885 +
  3.4886 +  if (version >= GBSAVE_GAME_VERSION_11) // new to re-recording version:
  3.4887 +    {
  3.4888 +      extern int32 sensorX, sensorY; // from SDL.cpp
  3.4889 +      utilGzRead(gzFile, &sensorX, sizeof(sensorX));
  3.4890 +      utilGzRead(gzFile, &sensorY, sizeof(sensorY));
  3.4891 +      utilGzRead(gzFile, gbJoymask, 4 * sizeof(*gbJoymask)); // this has to be saved or old input will incorrectly get carried
  3.4892 +      // back on loading a snapshot!
  3.4893 +
  3.4894 +      bool8 movieSnapshot;
  3.4895 +      utilGzRead(gzFile, &movieSnapshot, sizeof(movieSnapshot));
  3.4896 +      if (VBAMovieActive() && !movieSnapshot)
  3.4897  	{
  3.4898 -		utilGzRead(gzFile, &IFF, 2);
  3.4899 +	  systemMessage(0, N_("Can't load a non-movie snapshot while a movie is active."));
  3.4900 +	  goto failedLoadGB;
  3.4901  	}
  3.4902  
  3.4903 -	if (gbSgbMode)
  3.4904 +      if (movieSnapshot) // even if a movie isn't active we still want to parse through this in case other stuff is added
  3.4905 +	// later on in the save format
  3.4906  	{
  3.4907 -		gbSgbReadGame(gzFile, version);
  3.4908 +	  uint32 movieInputDataSize = 0;
  3.4909 +	  utilGzRead(gzFile, &movieInputDataSize, sizeof(movieInputDataSize));
  3.4910 +	  uint8 *local_movie_data = new uint8 [movieInputDataSize];
  3.4911 +	  int	   readBytes		= utilGzRead(gzFile, local_movie_data, movieInputDataSize);
  3.4912 +	  if (readBytes != movieInputDataSize)
  3.4913 +	    {
  3.4914 +	      systemMessage(0, N_("Corrupt movie snapshot."));
  3.4915 +	      if (local_movie_data)
  3.4916 +		delete [] local_movie_data;
  3.4917 +	      goto failedLoadGB;
  3.4918 +	    }
  3.4919 +	  int code = VBAMovieUnfreeze(local_movie_data, movieInputDataSize);
  3.4920 +	  if (local_movie_data)
  3.4921 +	    delete [] local_movie_data;
  3.4922 +	  if (code != MOVIE_SUCCESS && VBAMovieActive())
  3.4923 +	    {
  3.4924 +	      char errStr [1024];
  3.4925 +	      strcpy(errStr, "Failed to load movie snapshot");
  3.4926 +	      switch (code)
  3.4927 +		{
  3.4928 +		case MOVIE_NOT_FROM_THIS_MOVIE:
  3.4929 +		  strcat(errStr, ";\nSnapshot not from this movie"); break;
  3.4930 +		case MOVIE_NOT_FROM_A_MOVIE:
  3.4931 +		  strcat(errStr, ";\nNot a movie snapshot"); break;                    // shouldn't get here...
  3.4932 +		case MOVIE_SNAPSHOT_INCONSISTENT:
  3.4933 +		  strcat(errStr, ";\nSnapshot inconsistent with movie"); break;
  3.4934 +		case MOVIE_WRONG_FORMAT:
  3.4935 +		  strcat(errStr, ";\nWrong format"); break;
  3.4936 +		}
  3.4937 +	      strcat(errStr, ".");
  3.4938 +	      systemMessage(0, N_(errStr));
  3.4939 +	      goto failedLoadGB;
  3.4940 +	    }
  3.4941  	}
  3.4942 -	else
  3.4943 -	{
  3.4944 -		gbSgbMask = 0; // loading a game at the wrong time causes no display
  3.4945 -	}
  3.4946 -
  3.4947 -	utilGzRead(gzFile, &gbDataMBC1, sizeof(gbDataMBC1));
  3.4948 -	utilGzRead(gzFile, &gbDataMBC2, sizeof(gbDataMBC2));
  3.4949 -	if (version < GBSAVE_GAME_VERSION_4)
  3.4950 -		// prior to version 4, there was no adjustment for the time the game
  3.4951 -		// was last played, so we have less to read. This needs update if the
  3.4952 -		// structure changes again.
  3.4953 -		utilGzRead(gzFile, &gbDataMBC3, sizeof(int32) * 10);
  3.4954 -	else
  3.4955 -	{
  3.4956 -		//assert(sizeof(time_t) == 4);
  3.4957 -		utilGzRead(gzFile, &gbDataMBC3, sizeof(gbDataMBC3));
  3.4958 -	}
  3.4959 -	utilGzRead(gzFile, &gbDataMBC5, sizeof(gbDataMBC5));
  3.4960 -	utilGzRead(gzFile, &gbDataHuC1, sizeof(gbDataHuC1));
  3.4961 -	utilGzRead(gzFile, &gbDataHuC3, sizeof(gbDataHuC3));
  3.4962 -
  3.4963 -	if (version >= GBSAVE_GAME_VERSION_12)
  3.4964 -	{
  3.4965 -		utilGzRead(gzFile, pix, 4 * 257 * 226);
  3.4966 -	}
  3.4967 -	else
  3.4968 -	{
  3.4969 -		memset(pix, 0, 257 * 226 * sizeof(u32));
  3.4970 -//		if(version < GBSAVE_GAME_VERSION_5)
  3.4971 -//			utilGzRead(gzFile, pix, 256*224*sizeof(u16));
  3.4972 -	}
  3.4973 -
  3.4974 -	if (version < GBSAVE_GAME_VERSION_6)
  3.4975 -	{
  3.4976 -		utilGzRead(gzFile, gbPalette, 64 * sizeof(u16));
  3.4977 -	}
  3.4978 -	else
  3.4979 -		utilGzRead(gzFile, gbPalette, 128 * sizeof(u16));
  3.4980 -
  3.4981 -	// todo: remove
  3.4982 -	utilGzRead(gzFile, gbPalette, 128 * sizeof(u16));
  3.4983 -
  3.4984 -	if (version < GBSAVE_GAME_VERSION_10)
  3.4985 -	{
  3.4986 -		if (!gbCgbMode && !gbSgbMode)
  3.4987 -		{
  3.4988 -			for (int i = 0; i < 8; i++)
  3.4989 -				gbPalette[i] = systemGbPalette[gbPaletteOption * 8 + i];
  3.4990 -		}
  3.4991 -	}
  3.4992 -
  3.4993 -	utilGzRead(gzFile, &gbMemory[0x8000], 0x8000);
  3.4994 -
  3.4995 -	if (gbRamSize && gbRam)
  3.4996 -	{
  3.4997 -		utilGzRead(gzFile, gbRam, gbRamSize);
  3.4998 -	}
  3.4999 -
  3.5000 -	gbMemoryMap[0x00] = &gbRom[0x0000];
  3.5001 -	gbMemoryMap[0x01] = &gbRom[0x1000];
  3.5002 -	gbMemoryMap[0x02] = &gbRom[0x2000];
  3.5003 -	gbMemoryMap[0x03] = &gbRom[0x3000];
  3.5004 -	gbMemoryMap[0x04] = &gbRom[0x4000];
  3.5005 -	gbMemoryMap[0x05] = &gbRom[0x5000];
  3.5006 -	gbMemoryMap[0x06] = &gbRom[0x6000];
  3.5007 -	gbMemoryMap[0x07] = &gbRom[0x7000];
  3.5008 -	gbMemoryMap[0x08] = &gbMemory[0x8000];
  3.5009 -	gbMemoryMap[0x09] = &gbMemory[0x9000];
  3.5010 -	gbMemoryMap[0x0a] = &gbMemory[0xa000];
  3.5011 -	gbMemoryMap[0x0b] = &gbMemory[0xb000];
  3.5012 -	gbMemoryMap[0x0c] = &gbMemory[0xc000];
  3.5013 -	gbMemoryMap[0x0d] = &gbMemory[0xd000];
  3.5014 -	gbMemoryMap[0x0e] = &gbMemory[0xe000];
  3.5015 -	gbMemoryMap[0x0f] = &gbMemory[0xf000];
  3.5016 -
  3.5017 -	type = gbRom[0x147];
  3.5018 -
  3.5019 -	switch (type)
  3.5020 -	{
  3.5021 -	case 0x00:
  3.5022 -	case 0x01:
  3.5023 -	case 0x02:
  3.5024 -	case 0x03:
  3.5025 -		// MBC 1
  3.5026 -		memoryUpdateMapMBC1();
  3.5027 -		break;
  3.5028 -	case 0x05:
  3.5029 -	case 0x06:
  3.5030 -		// MBC2
  3.5031 -		memoryUpdateMapMBC2();
  3.5032 -		break;
  3.5033 -	case 0x0f:
  3.5034 -	case 0x10:
  3.5035 -	case 0x11:
  3.5036 -	case 0x12:
  3.5037 -	case 0x13:
  3.5038 -		// MBC 3
  3.5039 -		memoryUpdateMapMBC3();
  3.5040 -		break;
  3.5041 -	case 0x19:
  3.5042 -	case 0x1a:
  3.5043 -	case 0x1b:
  3.5044 -		// MBC5
  3.5045 -		memoryUpdateMapMBC5();
  3.5046 -		break;
  3.5047 -	case 0x1c:
  3.5048 -	case 0x1d:
  3.5049 -	case 0x1e:
  3.5050 -		// MBC 5 Rumble
  3.5051 -		memoryUpdateMapMBC5();
  3.5052 -		break;
  3.5053 -	case 0x22:
  3.5054 -		// MBC 7
  3.5055 -		memoryUpdateMapMBC7();
  3.5056 -		break;
  3.5057 -	case 0xfe:
  3.5058 -		// HuC3
  3.5059 -		memoryUpdateMapHuC3();
  3.5060 -		break;
  3.5061 -	case 0xff:
  3.5062 -		// HuC1
  3.5063 -		memoryUpdateMapHuC1();
  3.5064 -		break;
  3.5065 -	}
  3.5066 -
  3.5067 -	if (gbCgbMode)
  3.5068 -	{
  3.5069 -		if (!gbVram)
  3.5070 -			gbVram = (u8 *)malloc(0x4000 + 4);
  3.5071 -		if (!gbWram)
  3.5072 -			gbWram = (u8 *)malloc(0x8000 + 4);
  3.5073 -		utilGzRead(gzFile, gbVram, 0x4000);
  3.5074 -		utilGzRead(gzFile, gbWram, 0x8000);
  3.5075 -
  3.5076 -		int value = register_SVBK;
  3.5077 -		if (value == 0)
  3.5078 -			value = 1;
  3.5079 -
  3.5080 -		gbMemoryMap[0x08] = &gbVram[register_VBK * 0x2000];
  3.5081 -		gbMemoryMap[0x09] = &gbVram[register_VBK * 0x2000 + 0x1000];
  3.5082 -		gbMemoryMap[0x0d] = &gbWram[value * 0x1000];
  3.5083 -	}
  3.5084 -	else
  3.5085 -	{
  3.5086 -		if (gbVram)
  3.5087 -		{
  3.5088 -			free(gbVram);
  3.5089 -			gbVram = NULL;
  3.5090 -		}
  3.5091 -		if (gbWram)
  3.5092 -		{
  3.5093 -			free(gbWram);
  3.5094 -			gbWram = NULL;
  3.5095 -		}
  3.5096 -	}
  3.5097 -
  3.5098 -	gbSoundReadGame(version, gzFile);
  3.5099 -
  3.5100 -#if 0
  3.5101 -	if (gbBorderOn)
  3.5102 -	{
  3.5103 -		gbSgbRenderBorder();
  3.5104 -	}
  3.5105 -
  3.5106 -	systemRefreshScreen();
  3.5107 -#endif
  3.5108 -
  3.5109 -	if (version > GBSAVE_GAME_VERSION_1)
  3.5110 -		gbCheatsReadGame(gzFile, version);
  3.5111 -
  3.5112 -	systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  3.5113 -
  3.5114 -	if (version >= GBSAVE_GAME_VERSION_11) // new to re-recording version:
  3.5115 -	{
  3.5116 -		extern int32 sensorX, sensorY; // from SDL.cpp
  3.5117 -		utilGzRead(gzFile, &sensorX, sizeof(sensorX));
  3.5118 -		utilGzRead(gzFile, &sensorY, sizeof(sensorY));
  3.5119 -		utilGzRead(gzFile, gbJoymask, 4 * sizeof(*gbJoymask)); // this has to be saved or old input will incorrectly get carried
  3.5120 -		                                                       // back on loading a snapshot!
  3.5121 -
  3.5122 -		bool8 movieSnapshot;
  3.5123 -		utilGzRead(gzFile, &movieSnapshot, sizeof(movieSnapshot));
  3.5124 -		if (VBAMovieActive() && !movieSnapshot)
  3.5125 -		{
  3.5126 -			systemMessage(0, N_("Can't load a non-movie snapshot while a movie is active."));
  3.5127 -			goto failedLoadGB;
  3.5128 -		}
  3.5129 -
  3.5130 -		if (movieSnapshot) // even if a movie isn't active we still want to parse through this in case other stuff is added
  3.5131 -		                   // later on in the save format
  3.5132 -		{
  3.5133 -			uint32 movieInputDataSize = 0;
  3.5134 -			utilGzRead(gzFile, &movieInputDataSize, sizeof(movieInputDataSize));
  3.5135 -			uint8 *local_movie_data = new uint8 [movieInputDataSize];
  3.5136 -			int	   readBytes		= utilGzRead(gzFile, local_movie_data, movieInputDataSize);
  3.5137 -			if (readBytes != movieInputDataSize)
  3.5138 -			{
  3.5139 -				systemMessage(0, N_("Corrupt movie snapshot."));
  3.5140 -				if (local_movie_data)
  3.5141 -					delete [] local_movie_data;
  3.5142 -				goto failedLoadGB;
  3.5143 -			}
  3.5144 -			int code = VBAMovieUnfreeze(local_movie_data, movieInputDataSize);
  3.5145 -			if (local_movie_data)
  3.5146 -				delete [] local_movie_data;
  3.5147 -			if (code != MOVIE_SUCCESS && VBAMovieActive())
  3.5148 -			{
  3.5149 -				char errStr [1024];
  3.5150 -				strcpy(errStr, "Failed to load movie snapshot");
  3.5151 -				switch (code)
  3.5152 -				{
  3.5153 -				case MOVIE_NOT_FROM_THIS_MOVIE:
  3.5154 -					strcat(errStr, ";\nSnapshot not from this movie"); break;
  3.5155 -				case MOVIE_NOT_FROM_A_MOVIE:
  3.5156 -					strcat(errStr, ";\nNot a movie snapshot"); break;                    // shouldn't get here...
  3.5157 -				case MOVIE_SNAPSHOT_INCONSISTENT:
  3.5158 -					strcat(errStr, ";\nSnapshot inconsistent with movie"); break;
  3.5159 -				case MOVIE_WRONG_FORMAT:
  3.5160 -					strcat(errStr, ";\nWrong format"); break;
  3.5161 -				}
  3.5162 -				strcat(errStr, ".");
  3.5163 -				systemMessage(0, N_(errStr));
  3.5164 -				goto failedLoadGB;
  3.5165 -			}
  3.5166 -		}
  3.5167 -		utilGzRead(gzFile, &GBSystemCounters.frameCount, sizeof(GBSystemCounters.frameCount));
  3.5168 -	}
  3.5169 -
  3.5170 -	if (version >= GBSAVE_GAME_VERSION_13)   // new to rerecording 19.4 wip (svn r22+):
  3.5171 -	{
  3.5172 -		utilGzRead(gzFile, &GBSystemCounters.lagCount, sizeof(GBSystemCounters.lagCount));
  3.5173 -		utilGzRead(gzFile, &GBSystemCounters.lagged, sizeof(GBSystemCounters.lagged));
  3.5174 -		utilGzRead(gzFile, &GBSystemCounters.laggedLast, sizeof(GBSystemCounters.laggedLast));
  3.5175 -	}
  3.5176 -
  3.5177 -	if (backupSafe)
  3.5178 -	{
  3.5179 -		remove(tempBackupName);
  3.5180 -		tempFailCount = 0;
  3.5181 -	}
  3.5182 -
  3.5183 -	for (int i = 0; i < 4; ++i)
  3.5184 -		systemSetJoypad(i, gbJoymask[i] & 0xFFFF);
  3.5185 -
  3.5186 -	// FIXME: horrible kludge
  3.5187 -	memcpy(s_gbJoymask, gbJoymask, sizeof(gbJoymask));
  3.5188 -
  3.5189 -	VBAUpdateButtonPressDisplay();
  3.5190 -	VBAUpdateFrameCountDisplay();
  3.5191 -	systemRefreshScreen();
  3.5192 -	return true;
  3.5193 -
  3.5194 -failedLoadGB:
  3.5195 -	if (backupSafe)
  3.5196 -	{
  3.5197 -		tempFailCount++;
  3.5198 -		if (tempFailCount < 3) // fail no more than 2 times in a row
  3.5199 -			gbReadSaveState(tempBackupName);
  3.5200 -		remove(tempBackupName);
  3.5201 -	}
  3.5202 -	return false;
  3.5203 +      utilGzRead(gzFile, &GBSystemCounters.frameCount, sizeof(GBSystemCounters.frameCount));
  3.5204 +    }
  3.5205 +
  3.5206 +  if (version >= GBSAVE_GAME_VERSION_13)   // new to rerecording 19.4 wip (svn r22+):
  3.5207 +    {
  3.5208 +      utilGzRead(gzFile, &GBSystemCounters.lagCount, sizeof(GBSystemCounters.lagCount));
  3.5209 +      utilGzRead(gzFile, &GBSystemCounters.lagged, sizeof(GBSystemCounters.lagged));
  3.5210 +      utilGzRead(gzFile, &GBSystemCounters.laggedLast, sizeof(GBSystemCounters.laggedLast));
  3.5211 +    }
  3.5212 +
  3.5213 +  if (backupSafe)
  3.5214 +    {
  3.5215 +      remove(tempBackupName);
  3.5216 +      tempFailCount = 0;
  3.5217 +    }
  3.5218 +
  3.5219 +  for (int i = 0; i < 4; ++i)
  3.5220 +    systemSetJoypad(i, gbJoymask[i] & 0xFFFF);
  3.5221 +
  3.5222 +  // FIXME: horrible kludge
  3.5223 +  memcpy(s_gbJoymask, gbJoymask, sizeof(gbJoymask));
  3.5224 +
  3.5225 +  VBAUpdateButtonPressDisplay();
  3.5226 +  VBAUpdateFrameCountDisplay();
  3.5227 +  systemRefreshScreen();
  3.5228 +  return true;
  3.5229 +
  3.5230 + failedLoadGB:
  3.5231 +  if (backupSafe)
  3.5232 +    {
  3.5233 +      tempFailCount++;
  3.5234 +      if (tempFailCount < 3) // fail no more than 2 times in a row
  3.5235 +	gbReadSaveState(tempBackupName);
  3.5236 +      remove(tempBackupName);
  3.5237 +    }
  3.5238 +  return false;
  3.5239  }
  3.5240  
  3.5241  bool gbReadMemSaveState(char *memory, int available)
  3.5242  {
  3.5243 -	gzFile gzFile = utilMemGzOpen(memory, available, "r");
  3.5244 -
  3.5245 -	backupSafe = false;
  3.5246 -	bool res = gbReadSaveStateFromStream(gzFile);
  3.5247 -	backupSafe = true;
  3.5248 -
  3.5249 -	utilGzClose(gzFile);
  3.5250 -
  3.5251 -	return res;
  3.5252 +  gzFile gzFile = utilMemGzOpen(memory, available, "r");
  3.5253 +
  3.5254 +  backupSafe = false;
  3.5255 +  bool res = gbReadSaveStateFromStream(gzFile);
  3.5256 +  backupSafe = true;
  3.5257 +
  3.5258 +  utilGzClose(gzFile);
  3.5259 +
  3.5260 +  return res;
  3.5261  }
  3.5262  
  3.5263  bool gbReadSaveState(const char *name)
  3.5264  {
  3.5265 -	gzFile gzFile = utilGzOpen(name, "rb");
  3.5266 -
  3.5267 -	if (gzFile == NULL)
  3.5268 -	{
  3.5269 -		return false;
  3.5270 -	}
  3.5271 -
  3.5272 -	bool res = gbReadSaveStateFromStream(gzFile);
  3.5273 -
  3.5274 -	utilGzClose(gzFile);
  3.5275 -
  3.5276 -	return res;
  3.5277 +  gzFile gzFile = utilGzOpen(name, "rb");
  3.5278 +
  3.5279 +  if (gzFile == NULL)
  3.5280 +    {
  3.5281 +      return false;
  3.5282 +    }
  3.5283 +
  3.5284 +  bool res = gbReadSaveStateFromStream(gzFile);
  3.5285 +
  3.5286 +  utilGzClose(gzFile);
  3.5287 +
  3.5288 +  return res;
  3.5289  }
  3.5290  
  3.5291  bool gbWritePNGFile(const char *fileName)
  3.5292  {
  3.5293 -	if (gbBorderOn)
  3.5294 -		return utilWritePNGFile(fileName, 256, 224, pix);
  3.5295 -	return utilWritePNGFile(fileName, 160, 144, pix);
  3.5296 +  if (gbBorderOn)
  3.5297 +    return utilWritePNGFile(fileName, 256, 224, pix);
  3.5298 +  return utilWritePNGFile(fileName, 160, 144, pix);
  3.5299  }
  3.5300  
  3.5301  bool gbWriteBMPFile(const char *fileName)
  3.5302  {
  3.5303 -	if (gbBorderOn)
  3.5304 -		return utilWriteBMPFile(fileName, 256, 224, pix);
  3.5305 -	return utilWriteBMPFile(fileName, 160, 144, pix);
  3.5306 +  if (gbBorderOn)
  3.5307 +    return utilWriteBMPFile(fileName, 256, 224, pix);
  3.5308 +  return utilWriteBMPFile(fileName, 160, 144, pix);
  3.5309  }
  3.5310  
  3.5311  void gbCleanUp()
  3.5312  {
  3.5313 -	newFrame	  = true;
  3.5314 -
  3.5315 -	GBSystemCounters.frameCount = 0;
  3.5316 -	GBSystemCounters.lagCount	= 0;
  3.5317 -	GBSystemCounters.extraCount = 0;
  3.5318 -	GBSystemCounters.lagged		= true;
  3.5319 -	GBSystemCounters.laggedLast = true;
  3.5320 -
  3.5321 -	if (gbRam != NULL)
  3.5322 -	{
  3.5323 -		free(gbRam);
  3.5324 -		gbRam = NULL;
  3.5325 -	}
  3.5326 -
  3.5327 -	if (gbRom != NULL)
  3.5328 -	{
  3.5329 -		free(gbRom);
  3.5330 -		gbRom = NULL;
  3.5331 -	}
  3.5332 -
  3.5333 -	if (gbMemory != NULL)
  3.5334 -	{
  3.5335 -		free(gbMemory);
  3.5336 -		gbMemory = NULL;
  3.5337 -	}
  3.5338 -
  3.5339 -	if (gbLineBuffer != NULL)
  3.5340 -	{
  3.5341 -		free(gbLineBuffer);
  3.5342 -		gbLineBuffer = NULL;
  3.5343 -	}
  3.5344 -
  3.5345 -	if (origPix != NULL)
  3.5346 -	{
  3.5347 -		free(origPix);
  3.5348 -		origPix = NULL;
  3.5349 -	}
  3.5350 -	pix = NULL;
  3.5351 -
  3.5352 -	gbSgbShutdown();
  3.5353 -
  3.5354 -	if (gbVram != NULL)
  3.5355 -	{
  3.5356 -		free(gbVram);
  3.5357 -		gbVram = NULL;
  3.5358 -	}
  3.5359 -
  3.5360 -	if (gbWram != NULL)
  3.5361 -	{
  3.5362 -		free(gbWram);
  3.5363 -		gbWram = NULL;
  3.5364 -	}
  3.5365 -
  3.5366 -	systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  3.5367 -
  3.5368 -	memset(gbJoymask, 0, sizeof(gbJoymask));
  3.5369 -	// FIXME: horrible kludge
  3.5370 -	memset(s_gbJoymask, 0, sizeof(s_gbJoymask));
  3.5371 -
  3.5372 -	systemClearJoypads();
  3.5373 -	systemResetSensor();
  3.5374 -
  3.5375 -//	gbLastTime = gbFrameCount = 0;
  3.5376 -	systemRefreshScreen();
  3.5377 +  newFrame	  = true;
  3.5378 +
  3.5379 +  GBSystemCounters.frameCount = 0;
  3.5380 +  GBSystemCounters.lagCount	= 0;
  3.5381 +  GBSystemCounters.extraCount = 0;
  3.5382 +  GBSystemCounters.lagged		= true;
  3.5383 +  GBSystemCounters.laggedLast = true;
  3.5384 +
  3.5385 +  if (gbRam != NULL)
  3.5386 +    {
  3.5387 +      free(gbRam);
  3.5388 +      gbRam = NULL;
  3.5389 +    }
  3.5390 +
  3.5391 +  if (gbRom != NULL)
  3.5392 +    {
  3.5393 +      free(gbRom);
  3.5394 +      gbRom = NULL;
  3.5395 +    }
  3.5396 +
  3.5397 +  if (gbMemory != NULL)
  3.5398 +    {
  3.5399 +      free(gbMemory);
  3.5400 +      gbMemory = NULL;
  3.5401 +    }
  3.5402 +
  3.5403 +  if (gbLineBuffer != NULL)
  3.5404 +    {
  3.5405 +      free(gbLineBuffer);
  3.5406 +      gbLineBuffer = NULL;
  3.5407 +    }
  3.5408 +
  3.5409 +  if (origPix != NULL)
  3.5410 +    {
  3.5411 +      free(origPix);
  3.5412 +      origPix = NULL;
  3.5413 +    }
  3.5414 +  pix = NULL;
  3.5415 +
  3.5416 +  gbSgbShutdown();
  3.5417 +
  3.5418 +  if (gbVram != NULL)
  3.5419 +    {
  3.5420 +      free(gbVram);
  3.5421 +      gbVram = NULL;
  3.5422 +    }
  3.5423 +
  3.5424 +  if (gbWram != NULL)
  3.5425 +    {
  3.5426 +      free(gbWram);
  3.5427 +      gbWram = NULL;
  3.5428 +    }
  3.5429 +
  3.5430 +  systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  3.5431 +
  3.5432 +  memset(gbJoymask, 0, sizeof(gbJoymask));
  3.5433 +  // FIXME: horrible kludge
  3.5434 +  memset(s_gbJoymask, 0, sizeof(s_gbJoymask));
  3.5435 +
  3.5436 +  systemClearJoypads();
  3.5437 +  systemResetSensor();
  3.5438 +
  3.5439 +  //	gbLastTime = gbFrameCount = 0;
  3.5440 +  systemRefreshScreen();
  3.5441  }
  3.5442  
  3.5443  bool gbLoadRom(const char *szFile)
  3.5444  {
  3.5445 -	int size = 0;
  3.5446 -
  3.5447 -	if (gbRom != NULL)
  3.5448 -	{
  3.5449 -		gbCleanUp();
  3.5450 -	}
  3.5451 -
  3.5452 -	systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  3.5453 -
  3.5454 -	gbRom = utilLoad(szFile,
  3.5455 -	                 utilIsGBImage,
  3.5456 -	                 NULL,
  3.5457 -	                 size);
  3.5458 -	if (!gbRom)
  3.5459 -		return false;
  3.5460 -
  3.5461 -	gbRomSize = size;
  3.5462 -
  3.5463 -	return gbUpdateSizes();
  3.5464 +  int size = 0;
  3.5465 +
  3.5466 +  if (gbRom != NULL)
  3.5467 +    {
  3.5468 +      gbCleanUp();
  3.5469 +    }
  3.5470 +
  3.5471 +  systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  3.5472 +
  3.5473 +  gbRom = utilLoad(szFile,
  3.5474 +		   utilIsGBImage,
  3.5475 +		   NULL,
  3.5476 +		   size);
  3.5477 +  if (!gbRom)
  3.5478 +    return false;
  3.5479 +
  3.5480 +  gbRomSize = size;
  3.5481 +
  3.5482 +  return gbUpdateSizes();
  3.5483  }
  3.5484  
  3.5485  bool gbUpdateSizes()
  3.5486  {
  3.5487 -	if (gbRom[0x148] > 8)
  3.5488 -	{
  3.5489 -		systemMessage(MSG_UNSUPPORTED_ROM_SIZE,
  3.5490 -		              N_("Unsupported rom size %02x"), gbRom[0x148]);
  3.5491 -		return false;
  3.5492 -	}
  3.5493 -
  3.5494 -	if (gbRomSize < gbRomSizes[gbRom[0x148]])
  3.5495 -	{
  3.5496 -		gbRom = (u8 *)realloc(gbRom, gbRomSizes[gbRom[0x148]]);
  3.5497 -	}
  3.5498 -	gbRomSize	  = gbRomSizes[gbRom[0x148]];
  3.5499 -	gbRomSizeMask = gbRomSizesMasks[gbRom[0x148]];
  3.5500 -
  3.5501 -	if (gbRom[0x149] > 5)
  3.5502 -	{
  3.5503 -		systemMessage(MSG_UNSUPPORTED_RAM_SIZE,
  3.5504 -		              N_("Unsupported ram size %02x"), gbRom[0x149]);
  3.5505 -		return false;
  3.5506 -	}
  3.5507 -
  3.5508 -	gbRamSize	  = gbRamSizes[gbRom[0x149]];
  3.5509 -	gbRamSizeMask = gbRamSizesMasks[gbRom[0x149]];
  3.5510 -
  3.5511 -	if (gbRamSize)
  3.5512 -	{
  3.5513 -		gbRam = (u8 *)malloc(gbRamSize + 4);
  3.5514 -		memset(gbRam, 0xFF, gbRamSize + 4);
  3.5515 -	}
  3.5516 -
  3.5517 -	int type = gbRom[0x147];
  3.5518 -
  3.5519 -	mapperReadRAM = NULL;
  3.5520 -
  3.5521 -	switch (type)
  3.5522 -	{
  3.5523 -	case 0x00:
  3.5524 -	case 0x01:
  3.5525 -	case 0x02:
  3.5526 -	case 0x03:
  3.5527 -		// MBC 1
  3.5528 -		mapper	  = mapperMBC1ROM;
  3.5529 -		mapperRAM = mapperMBC1RAM;
  3.5530 -		break;
  3.5531 -	case 0x05:
  3.5532 -	case 0x06:
  3.5533 -		// MBC2
  3.5534 -		mapper		  = mapperMBC2ROM;
  3.5535 -		mapperRAM	  = mapperMBC2RAM;
  3.5536 -		gbRamSize	  = 0x200;
  3.5537 -		gbRamSizeMask = 0x1ff;
  3.5538 -		break;
  3.5539 -	case 0x0f:
  3.5540 -	case 0x10:
  3.5541 -	case 0x11:
  3.5542 -	case 0x12:
  3.5543 -	case 0x13:
  3.5544 -		// MBC 3
  3.5545 -		mapper		  = mapperMBC3ROM;
  3.5546 -		mapperRAM	  = mapperMBC3RAM;
  3.5547 -		mapperReadRAM = mapperMBC3ReadRAM;
  3.5548 -		break;
  3.5549 -	case 0x19:
  3.5550 -	case 0x1a:
  3.5551 -	case 0x1b:
  3.5552 -		// MBC5
  3.5553 -		mapper	  = mapperMBC5ROM;
  3.5554 -		mapperRAM = mapperMBC5RAM;
  3.5555 -		break;
  3.5556 -	case 0x1c:
  3.5557 -	case 0x1d:
  3.5558 -	case 0x1e:
  3.5559 -		// MBC 5 Rumble
  3.5560 -		mapper	  = mapperMBC5ROM;
  3.5561 -		mapperRAM = mapperMBC5RAM;
  3.5562 -		break;
  3.5563 -	case 0x22:
  3.5564 -		// MBC 7
  3.5565 -		mapper		  = mapperMBC7ROM;
  3.5566 -		mapperRAM	  = mapperMBC7RAM;
  3.5567 -		mapperReadRAM = mapperMBC7ReadRAM;
  3.5568 -		break;
  3.5569 -	case 0xfe:
  3.5570 -		// HuC3
  3.5571 -		mapper		  = mapperHuC3ROM;
  3.5572 -		mapperRAM	  = mapperHuC3RAM;
  3.5573 -		mapperReadRAM = mapperHuC3ReadRAM;
  3.5574 -		break;
  3.5575 -	case 0xff:
  3.5576 -		// HuC1
  3.5577 -		mapper	  = mapperHuC1ROM;
  3.5578 -		mapperRAM = mapperHuC1RAM;
  3.5579 -		break;
  3.5580 -	default:
  3.5581 -		systemMessage(MSG_UNKNOWN_CARTRIDGE_TYPE,
  3.5582 -		              N_("Unknown cartridge type %02x"), type);
  3.5583 -		return false;
  3.5584 -	}
  3.5585 -
  3.5586 -	switch (type)
  3.5587 -	{
  3.5588 -	case 0x03:
  3.5589 -	case 0x06:
  3.5590 -	case 0x0f:
  3.5591 -	case 0x10:
  3.5592 -	case 0x13:
  3.5593 -	case 0x1b:
  3.5594 -	case 0x1d:
  3.5595 -	case 0x1e:
  3.5596 -	case 0x22:
  3.5597 -	case 0xff:
  3.5598 -		gbBattery = 1;
  3.5599 -		break;
  3.5600 -	}
  3.5601 -
  3.5602 -	gbInit();
  3.5603 -	gbReset();
  3.5604 -
  3.5605 -	return true;
  3.5606 +  if (gbRom[0x148] > 8)
  3.5607 +    {
  3.5608 +      systemMessage(MSG_UNSUPPORTED_ROM_SIZE,
  3.5609 +		    N_("Unsupported rom size %02x"), gbRom[0x148]);
  3.5610 +      return false;
  3.5611 +    }
  3.5612 +
  3.5613 +  if (gbRomSize < gbRomSizes[gbRom[0x148]])
  3.5614 +    {
  3.5615 +      gbRom = (u8 *)realloc(gbRom, gbRomSizes[gbRom[0x148]]);
  3.5616 +    }
  3.5617 +  gbRomSize	  = gbRomSizes[gbRom[0x148]];
  3.5618 +  gbRomSizeMask = gbRomSizesMasks[gbRom[0x148]];
  3.5619 +
  3.5620 +  if (gbRom[0x149] > 5)
  3.5621 +    {
  3.5622 +      systemMessage(MSG_UNSUPPORTED_RAM_SIZE,
  3.5623 +		    N_("Unsupported ram size %02x"), gbRom[0x149]);
  3.5624 +      return false;
  3.5625 +    }
  3.5626 +
  3.5627 +  gbRamSize	  = gbRamSizes[gbRom[0x149]];
  3.5628 +  gbRamSizeMask = gbRamSizesMasks[gbRom[0x149]];
  3.5629 +
  3.5630 +  if (gbRamSize)
  3.5631 +    {
  3.5632 +      gbRam = (u8 *)malloc(gbRamSize + 4);
  3.5633 +      memset(gbRam, 0xFF, gbRamSize + 4);
  3.5634 +    }
  3.5635 +
  3.5636 +  int type = gbRom[0x147];
  3.5637 +
  3.5638 +  mapperReadRAM = NULL;
  3.5639 +
  3.5640 +  switch (type)
  3.5641 +    {
  3.5642 +    case 0x00:
  3.5643 +    case 0x01:
  3.5644 +    case 0x02:
  3.5645 +    case 0x03:
  3.5646 +      // MBC 1
  3.5647 +      mapper	  = mapperMBC1ROM;
  3.5648 +      mapperRAM = mapperMBC1RAM;
  3.5649 +      break;
  3.5650 +    case 0x05:
  3.5651 +    case 0x06:
  3.5652 +      // MBC2
  3.5653 +      mapper		  = mapperMBC2ROM;
  3.5654 +      mapperRAM	  = mapperMBC2RAM;
  3.5655 +      gbRamSize	  = 0x200;
  3.5656 +      gbRamSizeMask = 0x1ff;
  3.5657 +      break;
  3.5658 +    case 0x0f:
  3.5659 +    case 0x10:
  3.5660 +    case 0x11:
  3.5661 +    case 0x12:
  3.5662 +    case 0x13:
  3.5663 +      // MBC 3
  3.5664 +      mapper		  = mapperMBC3ROM;
  3.5665 +      mapperRAM	  = mapperMBC3RAM;
  3.5666 +      mapperReadRAM = mapperMBC3ReadRAM;
  3.5667 +      break;
  3.5668 +    case 0x19:
  3.5669 +    case 0x1a:
  3.5670 +    case 0x1b:
  3.5671 +      // MBC5
  3.5672 +      mapper	  = mapperMBC5ROM;
  3.5673 +      mapperRAM = mapperMBC5RAM;
  3.5674 +      break;
  3.5675 +    case 0x1c:
  3.5676 +    case 0x1d:
  3.5677 +    case 0x1e:
  3.5678 +      // MBC 5 Rumble
  3.5679 +      mapper	  = mapperMBC5ROM;
  3.5680 +      mapperRAM = mapperMBC5RAM;
  3.5681 +      break;
  3.5682 +    case 0x22:
  3.5683 +      // MBC 7
  3.5684 +      mapper		  = mapperMBC7ROM;
  3.5685 +      mapperRAM	  = mapperMBC7RAM;
  3.5686 +      mapperReadRAM = mapperMBC7ReadRAM;
  3.5687 +      break;
  3.5688 +    case 0xfe:
  3.5689 +      // HuC3
  3.5690 +      mapper		  = mapperHuC3ROM;
  3.5691 +      mapperRAM	  = mapperHuC3RAM;
  3.5692 +      mapperReadRAM = mapperHuC3ReadRAM;
  3.5693 +      break;
  3.5694 +    case 0xff:
  3.5695 +      // HuC1
  3.5696 +      mapper	  = mapperHuC1ROM;
  3.5697 +      mapperRAM = mapperHuC1RAM;
  3.5698 +      break;
  3.5699 +    default:
  3.5700 +      systemMessage(MSG_UNKNOWN_CARTRIDGE_TYPE,
  3.5701 +		    N_("Unknown cartridge type %02x"), type);
  3.5702 +      return false;
  3.5703 +    }
  3.5704 +
  3.5705 +  switch (type)
  3.5706 +    {
  3.5707 +    case 0x03:
  3.5708 +    case 0x06:
  3.5709 +    case 0x0f:
  3.5710 +    case 0x10:
  3.5711 +    case 0x13:
  3.5712 +    case 0x1b:
  3.5713 +    case 0x1d:
  3.5714 +    case 0x1e:
  3.5715 +    case 0x22:
  3.5716 +    case 0xff:
  3.5717 +      gbBattery = 1;
  3.5718 +      break;
  3.5719 +    }
  3.5720 +
  3.5721 +  gbInit();
  3.5722 +  gbReset();
  3.5723 +
  3.5724 +  return true;
  3.5725  }
  3.5726  
  3.5727  void gbEmulate(int ticksToStop)
  3.5728  {
  3.5729 -	gbRegister tempRegister;
  3.5730 -	u8		   tempValue;
  3.5731 -	s8		   offset;
  3.5732 -
  3.5733 -	int clockTicks = 0;
  3.5734 -	gbDmaTicks = 0;
  3.5735 -
  3.5736 -	register int opcode = 0;
  3.5737 -
  3.5738 -	u32 newmask = 0;
  3.5739 -	if (newFrame)
  3.5740 +  printf("RLM: Inside the GB!\n");
  3.5741 +  gbRegister tempRegister;
  3.5742 +  u8		   tempValue;
  3.5743 +  s8		   offset;
  3.5744 +
  3.5745 +  int clockTicks = 0;
  3.5746 +  gbDmaTicks = 0;
  3.5747 +
  3.5748 +  register int opcode = 0;
  3.5749 +
  3.5750 +  u32 newmask = 0;
  3.5751 +  printf("RLM: newframe = %d\n", newFrame);
  3.5752 +  if (newFrame)
  3.5753 +    {
  3.5754 +      extern void VBAOnExitingFrameBoundary();
  3.5755 +      VBAOnExitingFrameBoundary();
  3.5756 +      printf("RLM: exiting frame boundary?\n");
  3.5757 +      // update joystick information
  3.5758 +      systemReadJoypads();
  3.5759 +
  3.5760 +      bool sensor = (gbRom[0x147] == 0x22);
  3.5761 +
  3.5762 +      // read joystick
  3.5763 +      if (gbSgbMode && gbSgbMultiplayer)
  3.5764  	{
  3.5765 -		extern void VBAOnExitingFrameBoundary();
  3.5766 -		VBAOnExitingFrameBoundary();
  3.5767 -
  3.5768 -		// update joystick information
  3.5769 -		systemReadJoypads();
  3.5770 -
  3.5771 -		bool sensor = (gbRom[0x147] == 0x22);
  3.5772 -
  3.5773 -		// read joystick
  3.5774 -		if (gbSgbMode && gbSgbMultiplayer)
  3.5775 +	  if (gbSgbFourPlayers)
  3.5776 +	    {
  3.5777 +	      gbJoymask[0] = systemGetJoypad(0, sensor);
  3.5778 +	      gbJoymask[1] = systemGetJoypad(1, false);
  3.5779 +	      gbJoymask[2] = systemGetJoypad(2, false);
  3.5780 +	      gbJoymask[3] = systemGetJoypad(3, false);
  3.5781 +	    }
  3.5782 +	  else
  3.5783 +	    {
  3.5784 +	      gbJoymask[0] = systemGetJoypad(0, sensor);
  3.5785 +	      gbJoymask[1] = systemGetJoypad(1, false);
  3.5786 +	    }
  3.5787 +	}
  3.5788 +      else
  3.5789 +	{
  3.5790 +	  gbJoymask[0] = systemGetJoypad(0, sensor);
  3.5791 +	}
  3.5792 +
  3.5793 +      // FIXME: horrible kludge
  3.5794 +      memcpy(s_gbJoymask, gbJoymask, sizeof(gbJoymask));
  3.5795 +
  3.5796 +      //		if (sensor)
  3.5797 +      //			systemUpdateMotionSensor(0);
  3.5798 +
  3.5799 +      newmask = gbJoymask[0];
  3.5800 +      if (newmask & 0xFF)
  3.5801 +	{
  3.5802 +	  gbInterrupt |= 16;
  3.5803 +	}
  3.5804 +
  3.5805 +      extButtons = (newmask >> 18);
  3.5806 +      speedup	   = (extButtons & 1) != 0;
  3.5807 +
  3.5808 +      VBAMovieResetIfRequested();
  3.5809 +      printf("RLM: before Lua functions\n");
  3.5810 +      //CallRegisteredLuaFunctions(LUACALL_BEFOREEMULATION);
  3.5811 +      printf("RLM: after Lua functions\n");
  3.5812 +      newFrame = false;
  3.5813 +    }
  3.5814 +
  3.5815 +
  3.5816 +  for (;; )
  3.5817 +    {
  3.5818 +#ifndef FINAL_VERSION
  3.5819 +      if (systemDebug)
  3.5820 +	{
  3.5821 +	  if (!(IFF & 0x80))
  3.5822 +	    {
  3.5823 +	      if (systemDebug > 1)
  3.5824  		{
  3.5825 -			if (gbSgbFourPlayers)
  3.5826 +		  sprintf(gbBuffer, "PC=%04x AF=%04x BC=%04x DE=%04x HL=%04x SP=%04x I=%04x\n",
  3.5827 +			  PC.W, AF.W, BC.W, DE.W, HL.W, SP.W, IFF);
  3.5828 +		}
  3.5829 +	      else
  3.5830 +		{
  3.5831 +		  sprintf(gbBuffer, "PC=%04x I=%02x\n", PC.W, IFF);
  3.5832 +		}
  3.5833 +	      log(gbBuffer);
  3.5834 +	    }
  3.5835 +	}
  3.5836 +#endif
  3.5837 +      if (IFF & 0x80)
  3.5838 +	{
  3.5839 +	  if (register_LCDC & 0x80)
  3.5840 +	    {
  3.5841 +	      clockTicks = gbLcdTicks;
  3.5842 +	    }
  3.5843 +	  else
  3.5844 +	    clockTicks = 100;
  3.5845 +
  3.5846 +	  if (gbLcdMode == 1 && (gbLcdLYIncrementTicks < clockTicks))
  3.5847 +	    clockTicks = gbLcdLYIncrementTicks;
  3.5848 +
  3.5849 +	  if (gbSerialOn && (gbSerialTicks < clockTicks))
  3.5850 +	    clockTicks = gbSerialTicks;
  3.5851 +
  3.5852 +	  if (gbTimerOn && (gbTimerTicks < clockTicks))
  3.5853 +	    clockTicks = gbTimerTicks;
  3.5854 +
  3.5855 +	  if (soundTicks && (soundTicks < clockTicks))
  3.5856 +	    clockTicks = soundTicks;
  3.5857 +	}
  3.5858 +      else
  3.5859 +	{
  3.5860 +	  opcode = gbReadOpcode(PC.W);
  3.5861 +	  CallRegisteredLuaMemHook(PC.W, 1, opcode, LUAMEMHOOK_EXEC);
  3.5862 +	  PC.W++;
  3.5863 +
  3.5864 +	  if (IFF & 0x100)
  3.5865 +	    {
  3.5866 +	      IFF &= 0xff;
  3.5867 +	      PC.W--;
  3.5868 +	    }
  3.5869 +
  3.5870 +	  clockTicks = gbCycles[opcode];
  3.5871 +
  3.5872 +	  switch (opcode)
  3.5873 +	    {
  3.5874 +	    case 0xCB:
  3.5875 +	      // extended opcode
  3.5876 +	      //CallRegisteredLuaMemHook(PC.W, 1, opcode, LUAMEMHOOK_EXEC);	// is this desired?
  3.5877 +	      opcode	   = gbReadOpcode(PC.W++);
  3.5878 +	      clockTicks = gbCyclesCB[opcode];
  3.5879 +	      switch (opcode)
  3.5880 +		{
  3.5881 +#include "gbCodesCB.h"
  3.5882 +		}
  3.5883 +	      break;
  3.5884 +#include "gbCodes.h"
  3.5885 +	    }
  3.5886 +	}
  3.5887 +
  3.5888 +      if (!emulating)
  3.5889 +	return;
  3.5890 +
  3.5891 +      if (gbDmaTicks)
  3.5892 +	{
  3.5893 +	  clockTicks += gbDmaTicks;
  3.5894 +	  gbDmaTicks	= 0;
  3.5895 +	}
  3.5896 +
  3.5897 +      if (gbSgbMode)
  3.5898 +	{
  3.5899 +	  if (gbSgbPacketTimeout)
  3.5900 +	    {
  3.5901 +	      gbSgbPacketTimeout -= clockTicks;
  3.5902 +
  3.5903 +	      if (gbSgbPacketTimeout <= 0)
  3.5904 +		gbSgbResetPacketState();
  3.5905 +	    }
  3.5906 +	}
  3.5907 +
  3.5908 +      ticksToStop -= clockTicks;
  3.5909 +
  3.5910 +      // DIV register emulation
  3.5911 +      gbDivTicks -= clockTicks;
  3.5912 +      while (gbDivTicks <= 0)
  3.5913 +	{
  3.5914 +	  register_DIV++;
  3.5915 +	  gbDivTicks += GBDIV_CLOCK_TICKS;
  3.5916 +	}
  3.5917 +
  3.5918 +      if (register_LCDC & 0x80)
  3.5919 +	{
  3.5920 +	  // LCD stuff
  3.5921 +	  gbLcdTicks -= clockTicks;
  3.5922 +	  if (gbLcdMode == 1)
  3.5923 +	    {
  3.5924 +	      // during V-BLANK,we need to increment LY at the same rate!
  3.5925 +	      gbLcdLYIncrementTicks -= clockTicks;
  3.5926 +	      while (gbLcdLYIncrementTicks <= 0)
  3.5927 +		{
  3.5928 +		  gbLcdLYIncrementTicks += GBLY_INCREMENT_CLOCK_TICKS;
  3.5929 +
  3.5930 +		  if (register_LY < 153)
  3.5931 +		    {
  3.5932 +		      register_LY++;
  3.5933 +
  3.5934 +		      gbCompareLYToLYC();
  3.5935 +
  3.5936 +		      if (register_LY >= 153)
  3.5937 +			gbLcdLYIncrementTicks = 6;
  3.5938 +		    }
  3.5939 +		  else
  3.5940 +		    {
  3.5941 +		      register_LY = 0x00;
  3.5942 +		      // reset the window line
  3.5943 +		      gbWindowLine = -1;
  3.5944 +		      gbLcdLYIncrementTicks = GBLY_INCREMENT_CLOCK_TICKS * 2;
  3.5945 +		      gbCompareLYToLYC();
  3.5946 +		    }
  3.5947 +		}
  3.5948 +	    }
  3.5949 +
  3.5950 +	  // our counter is off, see what we need to do
  3.5951 +	  while (gbLcdTicks <= 0)
  3.5952 +	    {
  3.5953 +	      int framesToSkip = systemFramesToSkip();
  3.5954 +
  3.5955 +	      switch (gbLcdMode)
  3.5956 +		{
  3.5957 +		case 0:
  3.5958 +		  // H-Blank
  3.5959 +		  register_LY++;
  3.5960 +
  3.5961 +		  gbCompareLYToLYC();
  3.5962 +
  3.5963 +		  // check if we reached the V-Blank period
  3.5964 +		  if (register_LY == 144)
  3.5965 +		    {
  3.5966 +		      // Yes, V-Blank
  3.5967 +		      // set the LY increment counter
  3.5968 +		      gbLcdLYIncrementTicks = gbLcdTicks + GBLY_INCREMENT_CLOCK_TICKS;
  3.5969 +		      gbLcdTicks += GBLCD_MODE_1_CLOCK_TICKS;
  3.5970 +		      gbLcdMode	= 1;
  3.5971 +		      if (register_LCDC & 0x80)
  3.5972  			{
  3.5973 -				gbJoymask[0] = systemGetJoypad(0, sensor);
  3.5974 -				gbJoymask[1] = systemGetJoypad(1, false);
  3.5975 -				gbJoymask[2] = systemGetJoypad(2, false);
  3.5976 -				gbJoymask[3] = systemGetJoypad(3, false);
  3.5977 +			  gbInterrupt	   |= 1; // V-Blank interrupt
  3.5978 +			  gbInterruptWait = 6;
  3.5979 +			  if (register_STAT & 0x10)
  3.5980 +			    gbInterrupt |= 2;
  3.5981  			}
  3.5982 -			else
  3.5983 +
  3.5984 +		      systemFrame();
  3.5985 +
  3.5986 +		      ++gbFrameCount;
  3.5987 +		      u32 currentTime = systemGetClock();
  3.5988 +		      if (currentTime - gbLastTime >= 1000)
  3.5989  			{
  3.5990 -				gbJoymask[0] = systemGetJoypad(0, sensor);
  3.5991 -				gbJoymask[1] = systemGetJoypad(1, false);
  3.5992 +			  systemShowSpeed(int(float(gbFrameCount) * 100000 / (float(currentTime - gbLastTime) * 60) + .5f));
  3.5993 +			  gbLastTime	 = currentTime;
  3.5994 +			  gbFrameCount = 0;
  3.5995  			}
  3.5996 +
  3.5997 +		      ++GBSystemCounters.frameCount;
  3.5998 +		      if (GBSystemCounters.lagged)
  3.5999 +			{
  3.6000 +			  ++GBSystemCounters.lagCount;
  3.6001 +			}
  3.6002 +		      GBSystemCounters.laggedLast = GBSystemCounters.lagged;
  3.6003 +		      GBSystemCounters.lagged		= true;
  3.6004 +
  3.6005 +		      extern void VBAOnEnteringFrameBoundary();
  3.6006 +		      VBAOnEnteringFrameBoundary();
  3.6007 +
  3.6008 +		      newFrame = true;
  3.6009 +
  3.6010 +		      pauseAfterFrameAdvance = systemPauseOnFrame();
  3.6011 +
  3.6012 +		      if (gbFrameSkipCount >= framesToSkip || pauseAfterFrameAdvance)
  3.6013 +			{
  3.6014 +			  if (gbBorderOn)
  3.6015 +			    gbSgbRenderBorder();  // clear unnecessary things on border (e.g. in-game text message)
  3.6016 +
  3.6017 +			  systemRenderFrame();
  3.6018 +			  gbFrameSkipCount = 0;
  3.6019 +
  3.6020 +			  bool capturePressed = (extButtons & 2) != 0;
  3.6021 +			  if (capturePressed && !capturePrevious)
  3.6022 +			    {
  3.6023 +			      captureNumber = systemScreenCapture(captureNumber);
  3.6024 +			    }
  3.6025 +			  capturePrevious = capturePressed && !pauseAfterFrameAdvance;
  3.6026 +			}
  3.6027 +		      else
  3.6028 +			{
  3.6029 +			  ++gbFrameSkipCount;
  3.6030 +			}
  3.6031 +
  3.6032 +		      if (pauseAfterFrameAdvance)
  3.6033 +			{
  3.6034 +			  systemSetPause(true);
  3.6035 +			}
  3.6036 +		    }
  3.6037 +		  else
  3.6038 +		    {
  3.6039 +		      // go the the OAM being accessed mode
  3.6040 +		      gbLcdTicks += GBLCD_MODE_2_CLOCK_TICKS;
  3.6041 +		      gbLcdMode	= 2;
  3.6042 +
  3.6043 +		      // only one LCD interrupt per line. may need to generalize...
  3.6044 +		      if (!(register_STAT & 0x40) ||
  3.6045 +			  (register_LY != register_LYC))
  3.6046 +			{
  3.6047 +			  if ((register_STAT & 0x28) == 0x20)
  3.6048 +			    gbInterrupt |= 2;
  3.6049 +			}
  3.6050 +		    }
  3.6051 +
  3.6052 +		  break;
  3.6053 +		case 1:
  3.6054 +		  // V-Blank
  3.6055 +		  // next mode is OAM being accessed mode
  3.6056 +		  gbLcdTicks += GBLCD_MODE_2_CLOCK_TICKS;
  3.6057 +		  gbLcdMode	= 2;
  3.6058 +		  if (!(register_STAT & 0x40) ||
  3.6059 +		      (register_LY != register_LYC))
  3.6060 +		    {
  3.6061 +		      if ((register_STAT & 0x28) == 0x20)
  3.6062 +			gbInterrupt |= 2;
  3.6063 +		    }
  3.6064 +		  break;
  3.6065 +		case 2:
  3.6066 +		  // OAM being accessed mode
  3.6067 +
  3.6068 +		  // next mode is OAM and VRAM in use
  3.6069 +		  gbLcdTicks += GBLCD_MODE_3_CLOCK_TICKS;
  3.6070 +		  gbLcdMode	= 3;
  3.6071 +		  break;
  3.6072 +		case 3:
  3.6073 +		  // OAM and VRAM in use
  3.6074 +		  // next mode is H-Blank
  3.6075 +		  if (register_LY < 144)
  3.6076 +		    {
  3.6077 +		      if (!gbSgbMask)
  3.6078 +			{
  3.6079 +			  if (gbFrameSkipCount >= framesToSkip || pauseAfterFrameAdvance)
  3.6080 +			    {
  3.6081 +			      gbRenderLine();
  3.6082 +			      gbDrawSprites();
  3.6083 +
  3.6084 +			      switch (systemColorDepth)
  3.6085 +				{
  3.6086 +				case 16:
  3.6087 +
  3.6088 +				  {
  3.6089 +				    u16 *dest = (u16 *)pix +
  3.6090 +				      (gbBorderLineSkip + 2) * (register_LY + gbBorderRowSkip + 1)
  3.6091 +				      + gbBorderColumnSkip;
  3.6092 +				    for (int x = 0; x < 160; )
  3.6093 +				      {
  3.6094 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6095 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6096 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6097 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6098 +
  3.6099 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6100 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6101 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6102 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6103 +
  3.6104 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6105 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6106 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6107 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6108 +
  3.6109 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6110 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6111 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6112 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6113 +				      }
  3.6114 +				    if (gbBorderOn)
  3.6115 +				      dest += gbBorderColumnSkip;
  3.6116 +				    *dest++ = 0;     // for filters that read one pixel more
  3.6117 +				    break;
  3.6118 +				  }
  3.6119 +				case 24:
  3.6120 +
  3.6121 +				  {
  3.6122 +				    u8 *dest = (u8 *)pix +
  3.6123 +				      3 * (gbBorderLineSkip * (register_LY + gbBorderRowSkip) +
  3.6124 +					   gbBorderColumnSkip);
  3.6125 +				    for (int x = 0; x < 160; )
  3.6126 +				      {
  3.6127 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6128 +					dest += 3;
  3.6129 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6130 +					dest += 3;
  3.6131 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6132 +					dest += 3;
  3.6133 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6134 +					dest += 3;
  3.6135 +
  3.6136 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6137 +					dest += 3;
  3.6138 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6139 +					dest += 3;
  3.6140 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6141 +					dest += 3;
  3.6142 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6143 +					dest += 3;
  3.6144 +
  3.6145 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6146 +					dest += 3;
  3.6147 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6148 +					dest += 3;
  3.6149 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6150 +					dest += 3;
  3.6151 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6152 +					dest += 3;
  3.6153 +
  3.6154 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6155 +					dest += 3;
  3.6156 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6157 +					dest += 3;
  3.6158 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6159 +					dest += 3;
  3.6160 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6161 +					dest += 3;
  3.6162 +				      }
  3.6163 +				    break;
  3.6164 +				  }
  3.6165 +				case 32:
  3.6166 +
  3.6167 +				  {
  3.6168 +				    u32 *dest = (u32 *)pix +
  3.6169 +				      (gbBorderLineSkip + 1) * (register_LY + gbBorderRowSkip + 1)
  3.6170 +				      + gbBorderColumnSkip;
  3.6171 +				    for (int x = 0; x < 160; )
  3.6172 +				      {
  3.6173 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6174 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6175 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6176 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6177 +
  3.6178 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6179 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6180 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6181 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6182 +
  3.6183 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6184 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6185 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6186 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6187 +
  3.6188 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6189 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6190 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6191 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6192 +				      }
  3.6193 +				    break;
  3.6194 +				  }
  3.6195 +				}
  3.6196 +			    }
  3.6197 +			}
  3.6198 +		    }
  3.6199 +		  gbLcdTicks += GBLCD_MODE_0_CLOCK_TICKS;
  3.6200 +		  gbLcdMode	= 0;
  3.6201 +		  // only one LCD interrupt per line. may need to generalize...
  3.6202 +		  if (!(register_STAT & 0x40) ||
  3.6203 +		      (register_LY != register_LYC))
  3.6204 +		    {
  3.6205 +		      if (register_STAT & 0x08)
  3.6206 +			gbInterrupt |= 2;
  3.6207 +		    }
  3.6208 +		  if (gbHdmaOn)
  3.6209 +		    {
  3.6210 +		      gbDoHdma();
  3.6211 +		    }
  3.6212 +		  break;
  3.6213  		}
  3.6214 -		else
  3.6215 +	      // mark the correct lcd mode on STAT register
  3.6216 +	      register_STAT = (register_STAT & 0xfc) | gbLcdMode;
  3.6217 +	    }
  3.6218 +	}
  3.6219 +
  3.6220 +      // serial emulation
  3.6221 +      if (gbSerialOn)
  3.6222 +	{
  3.6223 +#ifdef LINK_EMULATION
  3.6224 +	  if (linkConnected)
  3.6225 +	    {
  3.6226 +	      gbSerialTicks -= clockTicks;
  3.6227 +
  3.6228 +	      while (gbSerialTicks <= 0)
  3.6229  		{
  3.6230 -			gbJoymask[0] = systemGetJoypad(0, sensor);
  3.6231 +		  // increment number of shifted bits
  3.6232 +		  gbSerialBits++;
  3.6233 +		  linkProc();
  3.6234 +		  if (gbSerialOn && (gbMemory[0xff02] & 1))
  3.6235 +		    {
  3.6236 +		      if (gbSerialBits == 8)
  3.6237 +			{
  3.6238 +			  gbSerialBits	  = 0;
  3.6239 +			  gbMemory[0xff01]  = 0xff;
  3.6240 +			  gbMemory[0xff02] &= 0x7f;
  3.6241 +			  gbSerialOn		  = 0;
  3.6242 +			  gbInterrupt		 |= 8;
  3.6243 +			  gbSerialTicks	  = 0;
  3.6244 +			}
  3.6245 +		    }
  3.6246 +		  gbSerialTicks += GBSERIAL_CLOCK_TICKS;
  3.6247  		}
  3.6248 -
  3.6249 -		// FIXME: horrible kludge
  3.6250 -		memcpy(s_gbJoymask, gbJoymask, sizeof(gbJoymask));
  3.6251 -
  3.6252 -//		if (sensor)
  3.6253 -//			systemUpdateMotionSensor(0);
  3.6254 -
  3.6255 -		newmask = gbJoymask[0];
  3.6256 -		if (newmask & 0xFF)
  3.6257 +	    }
  3.6258 +	  else
  3.6259 +	    {
  3.6260 +#endif
  3.6261 +	      if (gbMemory[0xff02] & 1)
  3.6262  		{
  3.6263 -			gbInterrupt |= 16;
  3.6264 +		  gbSerialTicks -= clockTicks;
  3.6265 +
  3.6266 +		  // overflow
  3.6267 +		  while (gbSerialTicks <= 0)
  3.6268 +		    {
  3.6269 +		      // shift serial byte to right and put a 1 bit in its place
  3.6270 +		      //      gbMemory[0xff01] = 0x80 | (gbMemory[0xff01]>>1);
  3.6271 +		      // increment number of shifted bits
  3.6272 +		      gbSerialBits++;
  3.6273 +		      if (gbSerialBits == 8)
  3.6274 +			{
  3.6275 +			  // end of transmission
  3.6276 +			  if (gbSerialFunction)    // external device
  3.6277 +			    gbMemory[0xff01] = gbSerialFunction(gbMemory[0xff01]);
  3.6278 +			  else
  3.6279 +			    gbMemory[0xff01] = 0xff;
  3.6280 +			  gbSerialTicks	  = 0;
  3.6281 +			  gbMemory[0xff02] &= 0x7f;
  3.6282 +			  gbSerialOn		  = 0;
  3.6283 +			  gbInterrupt		 |= 8;
  3.6284 +			  gbSerialBits	  = 0;
  3.6285 +			}
  3.6286 +		      else
  3.6287 +			gbSerialTicks += GBSERIAL_CLOCK_TICKS;
  3.6288 +		    }
  3.6289  		}
  3.6290 -
  3.6291 -		extButtons = (newmask >> 18);
  3.6292 -		speedup	   = (extButtons & 1) != 0;
  3.6293 -
  3.6294 -		VBAMovieResetIfRequested();
  3.6295 -
  3.6296 -		CallRegisteredLuaFunctions(LUACALL_BEFOREEMULATION);
  3.6297 -
  3.6298 -		newFrame = false;
  3.6299 +#ifdef LINK_EMULATION
  3.6300 +	    }
  3.6301 +#endif
  3.6302  	}
  3.6303  
  3.6304 -	for (;; )
  3.6305 +      // timer emulation
  3.6306 +      if (gbTimerOn)
  3.6307  	{
  3.6308 -#ifndef FINAL_VERSION
  3.6309 -		if (systemDebug)
  3.6310 +	  gbTimerTicks -= clockTicks;
  3.6311 +
  3.6312 +	  while (gbTimerTicks <= 0)
  3.6313 +	    {
  3.6314 +	      register_TIMA++;
  3.6315 +
  3.6316 +	      if (register_TIMA == 0)
  3.6317  		{
  3.6318 -			if (!(IFF & 0x80))
  3.6319 +		  // timer overflow!
  3.6320 +
  3.6321 +		  // reload timer modulo
  3.6322 +		  register_TIMA = register_TMA;
  3.6323 +
  3.6324 +		  // flag interrupt
  3.6325 +		  gbInterrupt |= 4;
  3.6326 +		}
  3.6327 +
  3.6328 +	      gbTimerTicks += gbTimerClockTicks;
  3.6329 +	    }
  3.6330 +	}
  3.6331 +
  3.6332 +      /*
  3.6333 +	if(soundOffFlag)
  3.6334 +	{
  3.6335 +	if(synchronize && !speedup)
  3.6336 +	{
  3.6337 +	synchronizeTicks -= clockTicks;
  3.6338 +
  3.6339 +	while(synchronizeTicks < 0)
  3.6340 +	{
  3.6341 +	synchronizeTicks += SYNCHRONIZE_CLOCK_TICKS;
  3.6342 +
  3.6343 +	DWORD now = timeGetTime();
  3.6344 +	gbElapsedTime += (now - timeNow);
  3.6345 +
  3.6346 +	if(gbElapsedTime < 50)
  3.6347 +	{
  3.6348 +	DWORD diff = 50 - gbElapsedTime;
  3.6349 +	Sleep(diff);
  3.6350 +	timeNow = timeGetTime();
  3.6351 +	elapsedTime = timeNow - now - diff;
  3.6352 +	if((int)elapsedTime < 0)
  3.6353 +	elapsedTime = 0;
  3.6354 +	} else
  3.6355 +	{
  3.6356 +	timeNow = timeGetTime();
  3.6357 +	elapsedTime = 0;
  3.6358 +	}
  3.6359 +	}
  3.6360 +	}
  3.6361 +	}
  3.6362 +      */
  3.6363 +
  3.6364 +      soundTicks -= clockTicks;
  3.6365 +      while (soundTicks < 0) // must be < 1 when soundtick_t is real data type
  3.6366 +	{
  3.6367 +	  soundTicks += SOUND_CLOCK_TICKS;
  3.6368 +
  3.6369 +	  gbSoundTick();
  3.6370 +	}
  3.6371 +
  3.6372 +      register_IF = gbInterrupt;
  3.6373 +
  3.6374 +      if (IFF & 0x20)
  3.6375 +	{
  3.6376 +	  IFF &= 0xdf;
  3.6377 +	  IFF |= 0x01;
  3.6378 +	  gbInterruptWait = 0;
  3.6379 +	}
  3.6380 +      else if (gbInterrupt)
  3.6381 +	{
  3.6382 +	  if (gbInterruptWait == 0)
  3.6383 +	    {
  3.6384 +	      //        gbInterruptWait = 0;
  3.6385 +
  3.6386 +	      if (IFF & 0x01)
  3.6387 +		{
  3.6388 +		  if ((gbInterrupt & 1) && (register_IE & 1))
  3.6389 +		    {
  3.6390 +		      gbVblank_interrupt();
  3.6391 +		      continue;
  3.6392 +		    }
  3.6393 +
  3.6394 +		  if ((gbInterrupt & 2) && (register_IE & 2))
  3.6395 +		    {
  3.6396 +		      gbLcd_interrupt();
  3.6397 +		      continue;
  3.6398 +		    }
  3.6399 +
  3.6400 +		  if ((gbInterrupt & 4) && (register_IE & 4))
  3.6401 +		    {
  3.6402 +		      gbTimer_interrupt();
  3.6403 +		      continue;
  3.6404 +		    }
  3.6405 +
  3.6406 +		  if ((gbInterrupt & 8) && (register_IE & 8))
  3.6407 +		    {
  3.6408 +		      gbSerial_interrupt();
  3.6409 +		      continue;
  3.6410 +		    }
  3.6411 +
  3.6412 +		  if ((gbInterrupt & 16) && (register_IE & 16))
  3.6413 +		    {
  3.6414 +		      gbJoypad_interrupt();
  3.6415 +		      continue;
  3.6416 +		    }
  3.6417 +		}
  3.6418 +	    }
  3.6419 +	  else
  3.6420 +	    {
  3.6421 +	      gbInterruptWait -= clockTicks;
  3.6422 +	      if (gbInterruptWait < 0)
  3.6423 +		gbInterruptWait = 0;
  3.6424 +	    }
  3.6425 +	}
  3.6426 +
  3.6427 +      if (useOldFrameTiming)
  3.6428 +	{
  3.6429 +	  // old timing code
  3.6430 +	  if (ticksToStop > 0)
  3.6431 +	    continue;
  3.6432 +	}
  3.6433 +      else
  3.6434 +	{
  3.6435 +	  if (!newFrame && (register_LCDC & 0x80) != 0)
  3.6436 +	    continue;
  3.6437 +	}
  3.6438 +
  3.6439 +      if (!(register_LCDC & 0x80))
  3.6440 +	{
  3.6441 +	  if (!useOldFrameTiming)
  3.6442 +	    {
  3.6443 +	      // FIXME: since register_LY can be reset to 0 by some games, frame length is variable
  3.6444 +	      // and infinite loops can occurr
  3.6445 +	      // for now, it IS necessary to do something on this condition or games like
  3.6446 +	      // Megaman would freeze upon low-level restart interrupt sequence (Start+Select+A+B).
  3.6447 +	      // the only sensible way to fix this issue is to implement the RIGHT frame timing
  3.6448 +#ifdef WANTS_INCOMPLETE_WORKAROUND
  3.6449 +	      if (systemReadJoypads())
  3.6450 +		{
  3.6451 +		  if (gbSgbMode && gbSgbMultiplayer)
  3.6452 +		    {
  3.6453 +		      if (gbSgbFourPlayers)
  3.6454  			{
  3.6455 -				if (systemDebug > 1)
  3.6456 -				{
  3.6457 -					sprintf(gbBuffer, "PC=%04x AF=%04x BC=%04x DE=%04x HL=%04x SP=%04x I=%04x\n",
  3.6458 -					        PC.W, AF.W, BC.W, DE.W, HL.W, SP.W, IFF);
  3.6459 -				}
  3.6460 -				else
  3.6461 -				{
  3.6462 -					sprintf(gbBuffer, "PC=%04x I=%02x\n", PC.W, IFF);
  3.6463 -				}
  3.6464 -				log(gbBuffer);
  3.6465 +			  gbJoymask[0] = systemGetJoypad(0, false);
  3.6466 +			  gbJoymask[1] = systemGetJoypad(1, false);
  3.6467 +			  gbJoymask[2] = systemGetJoypad(2, false);
  3.6468 +			  gbJoymask[3] = systemGetJoypad(3, false);
  3.6469  			}
  3.6470 +		      else
  3.6471 +			{
  3.6472 +			  gbJoymask[0] = systemGetJoypad(0, false);
  3.6473 +			  gbJoymask[1] = systemGetJoypad(1, false);
  3.6474 +			}
  3.6475 +		    }
  3.6476 +		  else
  3.6477 +		    {
  3.6478 +		      gbJoymask[0] = systemGetJoypad(0, false);
  3.6479 +		    }
  3.6480  		}
  3.6481 -#endif
  3.6482 -		if (IFF & 0x80)
  3.6483 -		{
  3.6484 -			if (register_LCDC & 0x80)
  3.6485 -			{
  3.6486 -				clockTicks = gbLcdTicks;
  3.6487 -			}
  3.6488 -			else
  3.6489 -				clockTicks = 100;
  3.6490 -
  3.6491 -			if (gbLcdMode == 1 && (gbLcdLYIncrementTicks < clockTicks))
  3.6492 -				clockTicks = gbLcdLYIncrementTicks;
  3.6493 -
  3.6494 -			if (gbSerialOn && (gbSerialTicks < clockTicks))
  3.6495 -				clockTicks = gbSerialTicks;
  3.6496 -
  3.6497 -			if (gbTimerOn && (gbTimerTicks < clockTicks))
  3.6498 -				clockTicks = gbTimerTicks;
  3.6499 -
  3.6500 -			if (soundTicks && (soundTicks < clockTicks))
  3.6501 -				clockTicks = soundTicks;
  3.6502 -		}
  3.6503 -		else
  3.6504 -		{
  3.6505 -			opcode = gbReadOpcode(PC.W);
  3.6506 -			CallRegisteredLuaMemHook(PC.W, 1, opcode, LUAMEMHOOK_EXEC);
  3.6507 -			PC.W++;
  3.6508 -
  3.6509 -			if (IFF & 0x100)
  3.6510 -			{
  3.6511 -				IFF &= 0xff;
  3.6512 -				PC.W--;
  3.6513 -			}
  3.6514 -
  3.6515 -			clockTicks = gbCycles[opcode];
  3.6516 -
  3.6517 -			switch (opcode)
  3.6518 -			{
  3.6519 -			case 0xCB:
  3.6520 -				// extended opcode
  3.6521 -				//CallRegisteredLuaMemHook(PC.W, 1, opcode, LUAMEMHOOK_EXEC);	// is this desired?
  3.6522 -				opcode	   = gbReadOpcode(PC.W++);
  3.6523 -				clockTicks = gbCyclesCB[opcode];
  3.6524 -				switch (opcode)
  3.6525 -				{
  3.6526 -#include "gbCodesCB.h"
  3.6527 -				}
  3.6528 -				break;
  3.6529 -#include "gbCodes.h"
  3.6530 -			}
  3.6531 -		}
  3.6532 -
  3.6533 -		if (!emulating)
  3.6534 -			return;
  3.6535 -
  3.6536 -		if (gbDmaTicks)
  3.6537 -		{
  3.6538 -			clockTicks += gbDmaTicks;
  3.6539 -			gbDmaTicks	= 0;
  3.6540 -		}
  3.6541 -
  3.6542 -		if (gbSgbMode)
  3.6543 -		{
  3.6544 -			if (gbSgbPacketTimeout)
  3.6545 -			{
  3.6546 -				gbSgbPacketTimeout -= clockTicks;
  3.6547 -
  3.6548 -				if (gbSgbPacketTimeout <= 0)
  3.6549 -					gbSgbResetPacketState();
  3.6550 -			}
  3.6551 -		}
  3.6552 -
  3.6553 -		ticksToStop -= clockTicks;
  3.6554 -
  3.6555 -		// DIV register emulation
  3.6556 -		gbDivTicks -= clockTicks;
  3.6557 -		while (gbDivTicks <= 0)
  3.6558 -		{
  3.6559 -			register_DIV++;
  3.6560 -			gbDivTicks += GBDIV_CLOCK_TICKS;
  3.6561 -		}
  3.6562 -
  3.6563 -		if (register_LCDC & 0x80)
  3.6564 -		{
  3.6565 -			// LCD stuff
  3.6566 -			gbLcdTicks -= clockTicks;
  3.6567 -			if (gbLcdMode == 1)
  3.6568 -			{
  3.6569 -				// during V-BLANK,we need to increment LY at the same rate!
  3.6570 -				gbLcdLYIncrementTicks -= clockTicks;
  3.6571 -				while (gbLcdLYIncrementTicks <= 0)
  3.6572 -				{
  3.6573 -					gbLcdLYIncrementTicks += GBLY_INCREMENT_CLOCK_TICKS;
  3.6574 -
  3.6575 -					if (register_LY < 153)
  3.6576 -					{
  3.6577 -						register_LY++;
  3.6578 -
  3.6579 -						gbCompareLYToLYC();
  3.6580 -
  3.6581 -						if (register_LY >= 153)
  3.6582 -							gbLcdLYIncrementTicks = 6;
  3.6583 -					}
  3.6584 -					else
  3.6585 -					{
  3.6586 -						register_LY = 0x00;
  3.6587 -						// reset the window line
  3.6588 -						gbWindowLine = -1;
  3.6589 -						gbLcdLYIncrementTicks = GBLY_INCREMENT_CLOCK_TICKS * 2;
  3.6590 -						gbCompareLYToLYC();
  3.6591 -					}
  3.6592 -				}
  3.6593 -			}
  3.6594 -
  3.6595 -			// our counter is off, see what we need to do
  3.6596 -			while (gbLcdTicks <= 0)
  3.6597 -			{
  3.6598 -				int framesToSkip = systemFramesToSkip();
  3.6599 -
  3.6600 -				switch (gbLcdMode)
  3.6601 -				{
  3.6602 -				case 0:
  3.6603 -					// H-Blank
  3.6604 -					register_LY++;
  3.6605 -
  3.6606 -					gbCompareLYToLYC();
  3.6607 -
  3.6608 -					// check if we reached the V-Blank period
  3.6609 -					if (register_LY == 144)
  3.6610 -					{
  3.6611 -						// Yes, V-Blank
  3.6612 -						// set the LY increment counter
  3.6613 -						gbLcdLYIncrementTicks = gbLcdTicks + GBLY_INCREMENT_CLOCK_TICKS;
  3.6614 -						gbLcdTicks += GBLCD_MODE_1_CLOCK_TICKS;
  3.6615 -						gbLcdMode	= 1;
  3.6616 -						if (register_LCDC & 0x80)
  3.6617 -						{
  3.6618 -							gbInterrupt	   |= 1; // V-Blank interrupt
  3.6619 -							gbInterruptWait = 6;
  3.6620 -							if (register_STAT & 0x10)
  3.6621 -								gbInterrupt |= 2;
  3.6622 -						}
  3.6623 -
  3.6624 -						systemFrame();
  3.6625 -
  3.6626 -						++gbFrameCount;
  3.6627 -						u32 currentTime = systemGetClock();
  3.6628 -						if (currentTime - gbLastTime >= 1000)
  3.6629 -						{
  3.6630 -							systemShowSpeed(int(float(gbFrameCount) * 100000 / (float(currentTime - gbLastTime) * 60) + .5f));
  3.6631 -							gbLastTime	 = currentTime;
  3.6632 -							gbFrameCount = 0;
  3.6633 -						}
  3.6634 -
  3.6635 -						++GBSystemCounters.frameCount;
  3.6636 -						if (GBSystemCounters.lagged)
  3.6637 -						{
  3.6638 -							++GBSystemCounters.lagCount;
  3.6639 -						}
  3.6640 -						GBSystemCounters.laggedLast = GBSystemCounters.lagged;
  3.6641 -						GBSystemCounters.lagged		= true;
  3.6642 -
  3.6643 -						extern void VBAOnEnteringFrameBoundary();
  3.6644 -						VBAOnEnteringFrameBoundary();
  3.6645 -
  3.6646 -						newFrame = true;
  3.6647 -
  3.6648 -						pauseAfterFrameAdvance = systemPauseOnFrame();
  3.6649 -
  3.6650 -						if (gbFrameSkipCount >= framesToSkip || pauseAfterFrameAdvance)
  3.6651 -						{
  3.6652 -							if (gbBorderOn)
  3.6653 -								gbSgbRenderBorder();  // clear unnecessary things on border (e.g. in-game text message)
  3.6654 -
  3.6655 -							systemRenderFrame();
  3.6656 -							gbFrameSkipCount = 0;
  3.6657 -
  3.6658 -							bool capturePressed = (extButtons & 2) != 0;
  3.6659 -							if (capturePressed && !capturePrevious)
  3.6660 -							{
  3.6661 -								captureNumber = systemScreenCapture(captureNumber);
  3.6662 -							}
  3.6663 -							capturePrevious = capturePressed && !pauseAfterFrameAdvance;
  3.6664 -						}
  3.6665 -						else
  3.6666 -						{
  3.6667 -							++gbFrameSkipCount;
  3.6668 -						}
  3.6669 -
  3.6670 -						if (pauseAfterFrameAdvance)
  3.6671 -						{
  3.6672 -							systemSetPause(true);
  3.6673 -						}
  3.6674 -					}
  3.6675 -					else
  3.6676 -					{
  3.6677 -						// go the the OAM being accessed mode
  3.6678 -						gbLcdTicks += GBLCD_MODE_2_CLOCK_TICKS;
  3.6679 -						gbLcdMode	= 2;
  3.6680 -
  3.6681 -						// only one LCD interrupt per line. may need to generalize...
  3.6682 -						if (!(register_STAT & 0x40) ||
  3.6683 -						    (register_LY != register_LYC))
  3.6684 -						{
  3.6685 -							if ((register_STAT & 0x28) == 0x20)
  3.6686 -								gbInterrupt |= 2;
  3.6687 -						}
  3.6688 -					}
  3.6689 -
  3.6690 -					break;
  3.6691 -				case 1:
  3.6692 -					// V-Blank
  3.6693 -					// next mode is OAM being accessed mode
  3.6694 -					gbLcdTicks += GBLCD_MODE_2_CLOCK_TICKS;
  3.6695 -					gbLcdMode	= 2;
  3.6696 -					if (!(register_STAT & 0x40) ||
  3.6697 -					    (register_LY != register_LYC))
  3.6698 -					{
  3.6699 -						if ((register_STAT & 0x28) == 0x20)
  3.6700 -							gbInterrupt |= 2;
  3.6701 -					}
  3.6702 -					break;
  3.6703 -				case 2:
  3.6704 -					// OAM being accessed mode
  3.6705 -
  3.6706 -					// next mode is OAM and VRAM in use
  3.6707 -					gbLcdTicks += GBLCD_MODE_3_CLOCK_TICKS;
  3.6708 -					gbLcdMode	= 3;
  3.6709 -					break;
  3.6710 -				case 3:
  3.6711 -					// OAM and VRAM in use
  3.6712 -					// next mode is H-Blank
  3.6713 -					if (register_LY < 144)
  3.6714 -					{
  3.6715 -						if (!gbSgbMask)
  3.6716 -						{
  3.6717 -							if (gbFrameSkipCount >= framesToSkip || pauseAfterFrameAdvance)
  3.6718 -							{
  3.6719 -								gbRenderLine();
  3.6720 -								gbDrawSprites();
  3.6721 -
  3.6722 -								switch (systemColorDepth)
  3.6723 -								{
  3.6724 -								case 16:
  3.6725 -
  3.6726 -								{
  3.6727 -									u16 *dest = (u16 *)pix +
  3.6728 -									            (gbBorderLineSkip + 2) * (register_LY + gbBorderRowSkip + 1)
  3.6729 -									            + gbBorderColumnSkip;
  3.6730 -									for (int x = 0; x < 160; )
  3.6731 -									{
  3.6732 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6733 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6734 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6735 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6736 -
  3.6737 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6738 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6739 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6740 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6741 -
  3.6742 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6743 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6744 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6745 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6746 -
  3.6747 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6748 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6749 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6750 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  3.6751 -									}
  3.6752 -									if (gbBorderOn)
  3.6753 -										dest += gbBorderColumnSkip;
  3.6754 -									*dest++ = 0;     // for filters that read one pixel more
  3.6755 -									break;
  3.6756 -								}
  3.6757 -								case 24:
  3.6758 -
  3.6759 -								{
  3.6760 -									u8 *dest = (u8 *)pix +
  3.6761 -									           3 * (gbBorderLineSkip * (register_LY + gbBorderRowSkip) +
  3.6762 -									                gbBorderColumnSkip);
  3.6763 -									for (int x = 0; x < 160; )
  3.6764 -									{
  3.6765 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6766 -										dest += 3;
  3.6767 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6768 -										dest += 3;
  3.6769 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6770 -										dest += 3;
  3.6771 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6772 -										dest += 3;
  3.6773 -
  3.6774 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6775 -										dest += 3;
  3.6776 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6777 -										dest += 3;
  3.6778 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6779 -										dest += 3;
  3.6780 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6781 -										dest += 3;
  3.6782 -
  3.6783 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6784 -										dest += 3;
  3.6785 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6786 -										dest += 3;
  3.6787 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6788 -										dest += 3;
  3.6789 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6790 -										dest += 3;
  3.6791 -
  3.6792 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6793 -										dest += 3;
  3.6794 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6795 -										dest += 3;
  3.6796 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6797 -										dest += 3;
  3.6798 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  3.6799 -										dest += 3;
  3.6800 -									}
  3.6801 -									break;
  3.6802 -								}
  3.6803 -								case 32:
  3.6804 -
  3.6805 -								{
  3.6806 -									u32 *dest = (u32 *)pix +
  3.6807 -									            (gbBorderLineSkip + 1) * (register_LY + gbBorderRowSkip + 1)
  3.6808 -									            + gbBorderColumnSkip;
  3.6809 -									for (int x = 0; x < 160; )
  3.6810 -									{
  3.6811 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6812 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6813 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6814 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6815 -
  3.6816 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6817 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6818 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6819 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6820 -
  3.6821 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6822 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6823 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6824 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6825 -
  3.6826 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6827 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6828 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6829 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  3.6830 -									}
  3.6831 -									break;
  3.6832 -								}
  3.6833 -								}
  3.6834 -							}
  3.6835 -						}
  3.6836 -					}
  3.6837 -					gbLcdTicks += GBLCD_MODE_0_CLOCK_TICKS;
  3.6838 -					gbLcdMode	= 0;
  3.6839 -					// only one LCD interrupt per line. may need to generalize...
  3.6840 -					if (!(register_STAT & 0x40) ||
  3.6841 -					    (register_LY != register_LYC))
  3.6842 -					{
  3.6843 -						if (register_STAT & 0x08)
  3.6844 -							gbInterrupt |= 2;
  3.6845 -					}
  3.6846 -					if (gbHdmaOn)
  3.6847 -					{
  3.6848 -						gbDoHdma();
  3.6849 -					}
  3.6850 -					break;
  3.6851 -				}
  3.6852 -				// mark the correct lcd mode on STAT register
  3.6853 -				register_STAT = (register_STAT & 0xfc) | gbLcdMode;
  3.6854 -			}
  3.6855 -		}
  3.6856 -
  3.6857 -		// serial emulation
  3.6858 -		if (gbSerialOn)
  3.6859 -		{
  3.6860 -#ifdef LINK_EMULATION
  3.6861 -			if (linkConnected)
  3.6862 -			{
  3.6863 -				gbSerialTicks -= clockTicks;
  3.6864 -
  3.6865 -				while (gbSerialTicks <= 0)
  3.6866 -				{
  3.6867 -					// increment number of shifted bits
  3.6868 -					gbSerialBits++;
  3.6869 -					linkProc();
  3.6870 -					if (gbSerialOn && (gbMemory[0xff02] & 1))
  3.6871 -					{
  3.6872 -						if (gbSerialBits == 8)
  3.6873 -						{
  3.6874 -							gbSerialBits	  = 0;
  3.6875 -							gbMemory[0xff01]  = 0xff;
  3.6876 -							gbMemory[0xff02] &= 0x7f;
  3.6877 -							gbSerialOn		  = 0;
  3.6878 -							gbInterrupt		 |= 8;
  3.6879 -							gbSerialTicks	  = 0;
  3.6880 -						}
  3.6881 -					}
  3.6882 -					gbSerialTicks += GBSERIAL_CLOCK_TICKS;
  3.6883 -				}
  3.6884 -			}
  3.6885 -			else
  3.6886 -			{
  3.6887 -#endif
  3.6888 -			if (gbMemory[0xff02] & 1)
  3.6889 -			{
  3.6890 -				gbSerialTicks -= clockTicks;
  3.6891 -
  3.6892 -				// overflow
  3.6893 -				while (gbSerialTicks <= 0)
  3.6894 -				{
  3.6895 -					// shift serial byte to right and put a 1 bit in its place
  3.6896 -					//      gbMemory[0xff01] = 0x80 | (gbMemory[0xff01]>>1);
  3.6897 -					// increment number of shifted bits
  3.6898 -					gbSerialBits++;
  3.6899 -					if (gbSerialBits == 8)
  3.6900 -					{
  3.6901 -						// end of transmission
  3.6902 -						if (gbSerialFunction)    // external device
  3.6903 -							gbMemory[0xff01] = gbSerialFunction(gbMemory[0xff01]);
  3.6904 -						else
  3.6905 -							gbMemory[0xff01] = 0xff;
  3.6906 -						gbSerialTicks	  = 0;
  3.6907 -						gbMemory[0xff02] &= 0x7f;
  3.6908 -						gbSerialOn		  = 0;
  3.6909 -						gbInterrupt		 |= 8;
  3.6910 -						gbSerialBits	  = 0;
  3.6911 -					}
  3.6912 -					else
  3.6913 -						gbSerialTicks += GBSERIAL_CLOCK_TICKS;
  3.6914 -				}
  3.6915 -			}
  3.6916 -#ifdef LINK_EMULATION
  3.6917 -		}
  3.6918 -#endif
  3.6919 -		}
  3.6920 -
  3.6921 -		// timer emulation
  3.6922 -		if (gbTimerOn)
  3.6923 -		{
  3.6924 -			gbTimerTicks -= clockTicks;
  3.6925 -
  3.6926 -			while (gbTimerTicks <= 0)
  3.6927 -			{
  3.6928 -				register_TIMA++;
  3.6929 -
  3.6930 -				if (register_TIMA == 0)
  3.6931 -				{
  3.6932 -					// timer overflow!
  3.6933 -
  3.6934 -					// reload timer modulo
  3.6935 -					register_TIMA = register_TMA;
  3.6936 -
  3.6937 -					// flag interrupt
  3.6938 -					gbInterrupt |= 4;
  3.6939 -				}
  3.6940 -
  3.6941 -				gbTimerTicks += gbTimerClockTicks;
  3.6942 -			}
  3.6943 -		}
  3.6944 -
  3.6945 -		/*
  3.6946 -		   if(soundOffFlag)
  3.6947 -		   {
  3.6948 -		   if(synchronize && !speedup)
  3.6949 -		   {
  3.6950 -		   synchronizeTicks -= clockTicks;
  3.6951 -
  3.6952 -		   while(synchronizeTicks < 0)
  3.6953 -		   {
  3.6954 -		   synchronizeTicks += SYNCHRONIZE_CLOCK_TICKS;
  3.6955 -
  3.6956 -		   DWORD now = timeGetTime();
  3.6957 -		   gbElapsedTime += (now - timeNow);
  3.6958 -
  3.6959 -		   if(gbElapsedTime < 50)
  3.6960 -		   {
  3.6961 -		   DWORD diff = 50 - gbElapsedTime;
  3.6962 -		   Sleep(diff);
  3.6963 -		   timeNow = timeGetTime();
  3.6964 -		   elapsedTime = timeNow - now - diff;
  3.6965 -		   if((int)elapsedTime < 0)
  3.6966 -		   elapsedTime = 0;
  3.6967 -		   } else
  3.6968 -		   {
  3.6969 -		   timeNow = timeGetTime();
  3.6970 -		   elapsedTime = 0;
  3.6971 -		   }
  3.6972 -		   }
  3.6973 -		   }
  3.6974 -		   }
  3.6975 -		 */
  3.6976 -
  3.6977 -		soundTicks -= clockTicks;
  3.6978 -		while (soundTicks < 0) // must be < 1 when soundtick_t is real data type
  3.6979 -		{
  3.6980 -			soundTicks += SOUND_CLOCK_TICKS;
  3.6981 -
  3.6982 -			gbSoundTick();
  3.6983 -		}
  3.6984 -
  3.6985 -		register_IF = gbInterrupt;
  3.6986 -
  3.6987 -		if (IFF & 0x20)
  3.6988 -		{
  3.6989 -			IFF &= 0xdf;
  3.6990 -			IFF |= 0x01;
  3.6991 -			gbInterruptWait = 0;
  3.6992 -		}
  3.6993 -		else if (gbInterrupt)
  3.6994 -		{
  3.6995 -			if (gbInterruptWait == 0)
  3.6996 -			{
  3.6997 -				//        gbInterruptWait = 0;
  3.6998 -
  3.6999 -				if (IFF & 0x01)
  3.7000 -				{
  3.7001 -					if ((gbInterrupt & 1) && (register_IE & 1))
  3.7002 -					{
  3.7003 -						gbVblank_interrupt();
  3.7004 -						continue;
  3.7005 -					}
  3.7006 -
  3.7007 -					if ((gbInterrupt & 2) && (register_IE & 2))
  3.7008 -					{
  3.7009 -						gbLcd_interrupt();
  3.7010 -						continue;
  3.7011 -					}
  3.7012 -
  3.7013 -					if ((gbInterrupt & 4) && (register_IE & 4))
  3.7014 -					{
  3.7015 -						gbTimer_interrupt();
  3.7016 -						continue;
  3.7017 -					}
  3.7018 -
  3.7019 -					if ((gbInterrupt & 8) && (register_IE & 8))
  3.7020 -					{
  3.7021 -						gbSerial_interrupt();
  3.7022 -						continue;
  3.7023 -					}
  3.7024 -
  3.7025 -					if ((gbInterrupt & 16) && (register_IE & 16))
  3.7026 -					{
  3.7027 -						gbJoypad_interrupt();
  3.7028 -						continue;
  3.7029 -					}
  3.7030 -				}
  3.7031 -			}
  3.7032 -			else
  3.7033 -			{
  3.7034 -				gbInterruptWait -= clockTicks;
  3.7035 -				if (gbInterruptWait < 0)
  3.7036 -					gbInterruptWait = 0;
  3.7037 -			}
  3.7038 -		}
  3.7039 -
  3.7040 -		if (useOldFrameTiming)
  3.7041 -		{
  3.7042 -			// old timing code
  3.7043 -			if (ticksToStop > 0)
  3.7044 -				continue;
  3.7045 -		}
  3.7046 -		else
  3.7047 -		{
  3.7048 -			if (!newFrame && (register_LCDC & 0x80) != 0)
  3.7049 -				continue;
  3.7050 -		}
  3.7051 -
  3.7052 -		if (!(register_LCDC & 0x80))
  3.7053 -		{
  3.7054 -			if (!useOldFrameTiming)
  3.7055 -			{
  3.7056 -				// FIXME: since register_LY can be reset to 0 by some games, frame length is variable
  3.7057 -				// and infinite loops can occurr
  3.7058 -				// for now, it IS necessary to do something on this condition or games like
  3.7059 -				// Megaman would freeze upon low-level restart interrupt sequence (Start+Select+A+B).
  3.7060 -				// the only sensible way to fix this issue is to implement the RIGHT frame timing
  3.7061 -#ifdef WANTS_INCOMPLETE_WORKAROUND
  3.7062 -				if (systemReadJoypads())
  3.7063 -				{
  3.7064 -					if (gbSgbMode && gbSgbMultiplayer)
  3.7065 -					{
  3.7066 -						if (gbSgbFourPlayers)
  3.7067 -						{
  3.7068 -							gbJoymask[0] = systemGetJoypad(0, false);
  3.7069 -							gbJoymask[1] = systemGetJoypad(1, false);
  3.7070 -							gbJoymask[2] = systemGetJoypad(2, false);
  3.7071 -							gbJoymask[3] = systemGetJoypad(3, false);
  3.7072 -						}
  3.7073 -						else
  3.7074 -						{
  3.7075 -							gbJoymask[0] = systemGetJoypad(0, false);
  3.7076 -							gbJoymask[1] = systemGetJoypad(1, false);
  3.7077 -						}
  3.7078 -					}
  3.7079 -					else
  3.7080 -					{
  3.7081 -						gbJoymask[0] = systemGetJoypad(0, false);
  3.7082 -					}
  3.7083 -				}
  3.7084 -				else
  3.7085 -					gbJoymask[0] = gbJoymask[1] = gbJoymask[2] = gbJoymask[3] = 0;
  3.7086 +	      else
  3.7087 +		gbJoymask[0] = gbJoymask[1] = gbJoymask[2] = gbJoymask[3] = 0;
  3.7088  #else
  3.7089  #endif
  3.7090 -			}
  3.7091 -		}
  3.7092 -
  3.7093 -		// makes sure frames are really divided across input sampling boundaries which occur at a constant rate
  3.7094 -		if (newFrame || useOldFrameTiming)
  3.7095 -		{
  3.7096 -///			extern void VBAOnEnteringFrameBoundary();
  3.7097 -///			VBAOnEnteringFrameBoundary();
  3.7098 -
  3.7099 -			break;
  3.7100 -		}
  3.7101 +	    }
  3.7102  	}
  3.7103 +
  3.7104 +      // makes sure frames are really divided across input sampling boundaries which occur at a constant rate
  3.7105 +      if (newFrame || useOldFrameTiming)
  3.7106 +	{
  3.7107 +	  ///			extern void VBAOnEnteringFrameBoundary();
  3.7108 +	  ///			VBAOnEnteringFrameBoundary();
  3.7109 +
  3.7110 +	  break;
  3.7111 +	}
  3.7112 +    }
  3.7113  }
  3.7114  
  3.7115  struct EmulatedSystem GBSystem =
  3.7116 -{
  3.7117 -	// emuMain
  3.7118 -	gbEmulate,
  3.7119 -	// emuReset
  3.7120 -	gbReset,
  3.7121 -	// emuCleanUp
  3.7122 -	gbCleanUp,
  3.7123 -	// emuReadBattery
  3.7124 -	gbReadBatteryFile,
  3.7125 -	// emuWriteBattery
  3.7126 -	gbWriteBatteryFile,
  3.7127 -	// emuReadBatteryFromStream
  3.7128 -	gbReadBatteryFromStream,
  3.7129 -	// emuWriteBatteryToStream
  3.7130 -	gbWriteBatteryToStream,
  3.7131 -	// emuReadState
  3.7132 -	gbReadSaveState,
  3.7133 -	// emuWriteState
  3.7134 -	gbWriteSaveState,
  3.7135 -	// emuReadStateFromStream
  3.7136 -	gbReadSaveStateFromStream,
  3.7137 -	// emuWriteStateToStream
  3.7138 -	gbWriteSaveStateToStream,
  3.7139 -	// emuReadMemState
  3.7140 -	gbReadMemSaveState,
  3.7141 -	// emuWriteMemState
  3.7142 -	gbWriteMemSaveState,
  3.7143 -	// emuWritePNG
  3.7144 -	gbWritePNGFile,
  3.7145 -	// emuWriteBMP
  3.7146 -	gbWriteBMPFile,
  3.7147 -	// emuUpdateCPSR
  3.7148 -	NULL,
  3.7149 -	// emuHasDebugger
  3.7150 -	false,
  3.7151 -	// emuCount
  3.7152 +  {
  3.7153 +    // emuMain
  3.7154 +    gbEmulate,
  3.7155 +    // emuReset
  3.7156 +    gbReset,
  3.7157 +    // emuCleanUp
  3.7158 +    gbCleanUp,
  3.7159 +    // emuReadBattery
  3.7160 +    gbReadBatteryFile,
  3.7161 +    // emuWriteBattery
  3.7162 +    gbWriteBatteryFile,
  3.7163 +    // emuReadBatteryFromStream
  3.7164 +    gbReadBatteryFromStream,
  3.7165 +    // emuWriteBatteryToStream
  3.7166 +    gbWriteBatteryToStream,
  3.7167 +    // emuReadState
  3.7168 +    gbReadSaveState,
  3.7169 +    // emuWriteState
  3.7170 +    gbWriteSaveState,
  3.7171 +    // emuReadStateFromStream
  3.7172 +    gbReadSaveStateFromStream,
  3.7173 +    // emuWriteStateToStream
  3.7174 +    gbWriteSaveStateToStream,
  3.7175 +    // emuReadMemState
  3.7176 +    gbReadMemSaveState,
  3.7177 +    // emuWriteMemState
  3.7178 +    gbWriteMemSaveState,
  3.7179 +    // emuWritePNG
  3.7180 +    gbWritePNGFile,
  3.7181 +    // emuWriteBMP
  3.7182 +    gbWriteBMPFile,
  3.7183 +    // emuUpdateCPSR
  3.7184 +    NULL,
  3.7185 +    // emuHasDebugger
  3.7186 +    false,
  3.7187 +    // emuCount
  3.7188  #ifdef FINAL_VERSION
  3.7189 -	70000 / 4,
  3.7190 +    70000 / 4,
  3.7191  #else
  3.7192 -	1000,
  3.7193 +    1000,
  3.7194  #endif
  3.7195 -};
  3.7196 +  };
  3.7197  
  3.7198  // is there a reason to use more than one set of counters?
  3.7199  EmulatedSystemCounters &GBSystemCounters = systemCounters;
  3.7200  
  3.7201  /*
  3.7202 -   EmulatedSystemCounters GBSystemCounters =
  3.7203 -   {
  3.7204 -    // frameCount
  3.7205 -    0,
  3.7206 -    // lagCount
  3.7207 -    0,
  3.7208 -    // lagged
  3.7209 -    true,
  3.7210 -    // laggedLast
  3.7211 -    true,
  3.7212 -   };
  3.7213 - */
  3.7214 +  EmulatedSystemCounters GBSystemCounters =
  3.7215 +  {
  3.7216 +  // frameCount
  3.7217 +  0,
  3.7218 +  // lagCount
  3.7219 +  0,
  3.7220 +  // lagged
  3.7221 +  true,
  3.7222 +  // laggedLast
  3.7223 +  true,
  3.7224 +  };
  3.7225 +*/
     4.1 --- a/src/lua/loadlib.c	Sun Mar 04 22:44:42 2012 -0600
     4.2 +++ b/src/lua/loadlib.c	Mon Mar 05 01:25:11 2012 -0600
     4.3 @@ -424,7 +424,7 @@
     4.4    funcname = mkfuncname(L, name);
     4.5    if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
     4.6      if (stat != ERRFUNC) loaderror(L, filename);  /* real error */
     4.7 -    lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
     4.8 +        lua_pushfstring(L, "\n\tno module " LUA_QS " in derp " LUA_QS,
     4.9                         name, filename);
    4.10      return 1;  /* function not found */
    4.11    }
     5.1 --- a/src/sdl/SDL.cpp	Sun Mar 04 22:44:42 2012 -0600
     5.2 +++ b/src/sdl/SDL.cpp	Mon Mar 05 01:25:11 2012 -0600
     5.3 @@ -1966,6 +1966,7 @@
     5.4  
     5.5  void file_run()
     5.6  {
     5.7 +  printf("RLM: file_run\n");
     5.8      utilGetBaseName(szFile, filename);
     5.9      char *p = strrchr(filename, '.');
    5.10  
    5.11 @@ -1989,7 +1990,8 @@
    5.12        failed = !gbLoadRom(szFile);
    5.13        if(!failed) {
    5.14          systemCartridgeType = 1;
    5.15 -        theEmulator = GBSystem;
    5.16 +        printf("RLM: choosing GBSystem\n");
    5.17 +	theEmulator = GBSystem;
    5.18          if(sdlAutoIPS) {
    5.19            int size = gbRomSize;
    5.20            utilApplyIPS(ipsname, &gbRom, &size);
    5.21 @@ -2007,7 +2009,7 @@
    5.22          //        if(cpuEnhancedDetection && cpuSaveType == 0) {
    5.23          //          utilGBAFindSave(rom, size);
    5.24          //        }
    5.25 -
    5.26 +	
    5.27          sdlApplyPerImagePreferences();
    5.28          
    5.29          systemCartridgeType = 0;
    5.30 @@ -2183,7 +2185,7 @@
    5.31        
    5.32      case 'r':
    5.33        if(optarg == NULL) {
    5.34 -        fprintf(stderr, "ERROR: --recordMovie ('r') needs movie filename as option\n");
    5.35 +        fprintf(stderr, "ERROR: --recordmovie ('r') needs movie filename as option\n");
    5.36          exit(-1);
    5.37        }
    5.38          strcpy(movieFileName, optarg);
    5.39 @@ -2192,7 +2194,7 @@
    5.40      case 'p': // play without read-only (editable)
    5.41        fprintf (stderr, "-p got called!\n");
    5.42        if(optarg == NULL) {
    5.43 -        fprintf(stderr, "ERROR: --playMovie ('p') needs movie filename as option\n");
    5.44 +        fprintf(stderr, "ERROR: --playmovie ('p') needs movie filename as option\n");
    5.45          exit(-1);
    5.46        }
    5.47          strcpy(movieFileName, optarg);
    5.48 @@ -2201,7 +2203,7 @@
    5.49      case 'w': // play with read-only
    5.50       fprintf (stderr, "-w got called!\n"); 
    5.51        if(optarg == NULL) {
    5.52 -        fprintf(stderr, "ERROR: --watchMovie ('w') needs movie filename as option\n");
    5.53 +        fprintf(stderr, "ERROR: --watchmovie ('w') needs movie filename as option\n");
    5.54          exit(-1);
    5.55        }
    5.56          strcpy(movieFileName, optarg);
    5.57 @@ -2271,6 +2273,8 @@
    5.58      }
    5.59    }
    5.60  
    5.61 +  printf("RLM: derpy loves you!\n");
    5.62 +  printf("RLM: useMovie: %d (1 is record)\n", useMovie);
    5.63    if(sdlPrintUsage) {
    5.64      usage(argv[0]);
    5.65      exit(-1);
    5.66 @@ -2317,6 +2321,7 @@
    5.67    {
    5.68        szFile = argv[optind];
    5.69        file_run();
    5.70 +      printf("RLM: file_run() done\n");
    5.71    }
    5.72     else 
    5.73    {
    5.74 @@ -2336,7 +2341,7 @@
    5.75      
    5.76      //CPUInit(biosFileName, useBios);
    5.77      CPUInit();
    5.78 -    CPUReset();    
    5.79 +    CPUReset();
    5.80    }
    5.81    
    5.82    if(debuggerStub) 
    5.83 @@ -2615,6 +2620,7 @@
    5.84      soundInit();
    5.85  
    5.86    autoFrameSkipLastTime = throttleLastTime = systemGetClock();
    5.87 +  printf("RLM: and now for the movie part!\n");
    5.88  
    5.89    switch(useMovie)
    5.90    {
    5.91 @@ -2635,13 +2641,14 @@
    5.92      	sdlReadBattery();
    5.93    	  break;
    5.94    }
    5.95 +  printf("RLM: still alive after movie switch\n");
    5.96    SDL_WM_SetCaption("VisualBoyAdvance", NULL);
    5.97    
    5.98    char *moviefile = getenv("AUTODEMO");
    5.99 -//  fprintf (stderr, "Checking for AUTODEMO...\n");
   5.100 +  fprintf (stderr, "Checking for AUTODEMO...\n");
   5.101    if (moviefile)
   5.102    {
   5.103 -//    fprintf (stderr, "I got a filename OMG!\nCalling VBAMovieOpen...\n");
   5.104 +    fprintf (stderr, "I got a filename OMG!\nCalling VBAMovieOpen...\n");
   5.105      VBAMovieOpen(moviefile, true);
   5.106    }
   5.107  
   5.108 @@ -2650,7 +2657,9 @@
   5.109        if(debugger && theEmulator.emuHasDebugger)
   5.110          dbgMain();
   5.111        else {
   5.112 -        theEmulator.emuMain(theEmulator.emuCount);
   5.113 +	printf("RLM: emulator main\n");
   5.114 +	theEmulator.emuMain(theEmulator.emuCount);
   5.115 +	printf("RLM: emulator main called\n");
   5.116          if(rewindSaveNeeded && rewindMemory && theEmulator.emuWriteMemState) {
   5.117            rewindCount++;
   5.118            if(rewindCount > 8)
   5.119 @@ -3605,14 +3614,17 @@
   5.120  
   5.121  void VBAOnEnteringFrameBoundary()
   5.122  {
   5.123 -	CallRegisteredLuaFunctions(LUACALL_AFTEREMULATION);
   5.124 -
   5.125 -	if (VBALuaRunning())
   5.126 -	{
   5.127 -		VBALuaFrameBoundary();
   5.128 -	}
   5.129 -
   5.130 -	VBAMovieUpdateState();
   5.131 +  printf("RLM: Entering Frame Boundary\n");
   5.132 +  CallRegisteredLuaFunctions(LUACALL_AFTEREMULATION);
   5.133 +
   5.134 +  if (VBALuaRunning())
   5.135 +  	{
   5.136 +	  VBALuaFrameBoundary();
   5.137 +  	}
   5.138 +
   5.139 +  printf("RLM: Movie state update pending\n");
   5.140 +  VBAMovieUpdateState();
   5.141 +  printf("RLM: Movie state updated\n");
   5.142  }
   5.143  
   5.144  void VBAOnExitingFrameBoundary()