Browse code

update for C++17 compliance, update to latest 2sf, add WINE cross-compile makefiles

Adam Higerd authored on 2021/02/11 15:36:17
Showing 1 changed files
... ...
@@ -115,7 +115,7 @@ void fw_reset_com(memory_chip_t *mc)
115 115
 			// copy User Settings 1 to User Settings 0 area
116 116
 			memcpy(&mc->data[0x3FE00], &mc->data[0x3FF00], 0x100);
117 117
 
118
-			printf("Firmware: save config");
118
+			fprintf(stderr, "Firmware: save config");
119 119
 			FILE *fp = fopen(mc->userfile, "wb");
120 120
 			if (fp)
121 121
 			{
... ...
@@ -124,15 +124,15 @@ void fw_reset_com(memory_chip_t *mc)
124 124
 					if (fwrite(&mc->data[0x0002A], 1, 0x1D6, fp) == 0x1D6) // WiFi Settings
125 125
 					{
126 126
 						if (fwrite(&mc->data[0x3FA00], 1, 0x300, fp) == 0x300)  // WiFi AP Settings
127
-							printf(" - done\n");
127
+							fprintf(stderr, " - done\n");
128 128
 						else
129
-							printf(" - failed\n");
129
+							fprintf(stderr, " - failed\n");
130 130
 					}
131 131
 				}
132 132
 				fclose(fp);
133 133
 			}
134 134
 			else
135
-				printf(" - failed\n");
135
+				fprintf(stderr, " - failed\n");
136 136
 		}
137 137
 
138 138
 		mc->write_enable = false;
... ...
@@ -235,7 +235,7 @@ uint8_t fw_transfer(memory_chip_t *mc, uint8_t data)
235 235
 				break;
236 236
 
237 237
 			default:
238
-				printf("Unhandled FW command: %02X\n", data);
238
+				fprintf(stderr, "Unhandled FW command: %02X\n", data);
239 239
 		}
240 240
 	}
241 241
 
... ...
@@ -468,7 +468,7 @@ bool BackupDevice::load_no_gba(const char *fname)
468 468
 		fseek(fsrc, 0, SEEK_END);
469 469
 		uint32_t fsize = ftell(fsrc);
470 470
 		fseek(fsrc, 0, SEEK_SET);
471
-		//printf("Open %s file (size %i bytes)\n", fname, fsize);
471
+		//fprintf(stderr, "Open %s file (size %i bytes)\n", fname, fsize);
472 472
 
473 473
 		auto in_buf = std::unique_ptr<uint8_t[]>(new uint8_t[fsize]);
474 474
 
... ...
@@ -480,18 +480,18 @@ bool BackupDevice::load_no_gba(const char *fname)
480 480
 			uint32_t size = 0;
481 481
 			if (!no_gba_unpackSAV(&in_buf[0], fsize, &out_buf[0], size))
482 482
 			{
483
-				//printf("New size %i byte(s)\n", size);
483
+				//fprintf(stderr, "New size %i byte(s)\n", size);
484 484
 				size = no_gba_savTrim(&out_buf[0], size);
485
-				//printf("--- new size after trim %i byte(s)\n", size);
485
+				//fprintf(stderr, "--- new size after trim %i byte(s)\n", size);
486 486
 				size = no_gba_fillLeft(size);
487
-				//printf("--- new size after fill %i byte(s)\n", size);
487
+				//fprintf(stderr, "--- new size after fill %i byte(s)\n", size);
488 488
 				raw_applyUserSettings(size);
489 489
 				this->data.resize(size);
490 490
 				for (uint32_t tt = 0; tt < size; ++tt)
491 491
 					this->data[tt] = out_buf[tt];
492 492
 
493 493
 				//dump back out as a dsv, just to keep things sane
494
-				printf("---- Loaded no$GBA save\n");
494
+				fprintf(stderr, "---- Loaded no$GBA save\n");
495 495
 
496 496
 				fclose(fsrc);
497 497
 				return true;
... ...
@@ -516,7 +516,7 @@ void BackupDevice::loadfile()
516 516
 	if (inf->fail())
517 517
 	{
518 518
 		// no dsv found; we need to try auto-importing a file with .sav extension
519
-		printf("DeSmuME .dsv save file not found. Trying to load an old raw .sav file.\n");
519
+		fprintf(stderr, "DeSmuME .dsv save file not found. Trying to load an old raw .sav file.\n");
520 520
 
521 521
 		// change extension to sav
522 522
 		char tmp[MAX_PATH];
... ...
@@ -527,7 +527,7 @@ void BackupDevice::loadfile()
527 527
 		inf.reset(new EMUFILE_FILE(tmp, "rb"));
528 528
 		if (inf->fail())
529 529
 		{
530
-			printf("Missing save file %s\n", this->filename.c_str());
530
+			fprintf(stderr, "Missing save file %s\n", this->filename.c_str());
531 531
 			return;
532 532
 		}
533 533
 
... ...
@@ -545,7 +545,7 @@ void BackupDevice::loadfile()
545 545
 		if (cmp)
546 546
 		{
547 547
 			// maybe it is a misnamed raw save file. try loading it that way
548
-			printf("Not a DeSmuME .dsv save file. Trying to load as raw.\n");
548
+			fprintf(stderr, "Not a DeSmuME .dsv save file. Trying to load as raw.\n");
549 549
 			if (!this->load_no_gba(this->filename.c_str()))
550 550
 				this->load_raw(this->filename.c_str());
551 551
 			return;
... ...
@@ -557,7 +557,7 @@ void BackupDevice::loadfile()
557 557
 		read32le(&version, inf.get());
558 558
 		if (version)
559 559
 		{
560
-			printf("Unknown save file format\n");
560
+			fprintf(stderr, "Unknown save file format\n");
561 561
 			return;
562 562
 		}
563 563
 		inf->fseek(-24, SEEK_CUR);
Browse code

Replaced the Makefile with one that handles things better.

* g++ compiled DLLs seem to not be seen by Winamp when the
-static-libgcc and -static-libstdc++ flags are used.
* clang++ compiled DLLs seem to cause Winamp to crash on exit.

Naram Qashat authored on 2014/09/18 20:02:22
Showing 1 changed files
... ...
@@ -427,8 +427,6 @@ static int no_gba_unpackSAV(const uint8_t *in_buf, uint32_t fsize, uint8_t *out_
427 427
 			for (int t = 0; t < cc; ++t)
428 428
 				dst[dst_pos++] = src[src_pos++];
429 429
 		}
430
-		size = dst_pos;
431
-		return 0;
432 430
 	}
433 431
 	return 200;
434 432
 }
Browse code

Removed a bunch of casts, they seem to be fine without them in most cases.

Naram Qashat authored on 2013/04/18 23:22:54
Showing 1 changed files
... ...
@@ -284,7 +284,7 @@ void BackupDevice::reset()
284 284
 		this->state = RUNNING;
285 285
 		int savetype = save_types[CommonSettings.manualBackupType].media_type;
286 286
 		int savesize = save_types[CommonSettings.manualBackupType].size;
287
-		this->ensure(static_cast<uint32_t>(savesize)); // expand properly if necessary
287
+		this->ensure(savesize); // expand properly if necessary
288 288
 		this->resize(savesize); // truncate if necessary
289 289
 		this->addr_size = this->addr_size_for_old_save_type(savetype);
290 290
 	}
... ...
@@ -356,12 +356,12 @@ void BackupDevice::load_old_state(uint32_t addrSize, uint8_t *Data, uint32_t dat
356 356
 // =======================================================================
357 357
 // =======================================================================
358 358
 
359
-static int no_gba_unpackSAV(void *in_buf, uint32_t fsize, void *out_buf, uint32_t &size)
359
+static int no_gba_unpackSAV(const uint8_t *in_buf, uint32_t fsize, uint8_t *out_buf, uint32_t &size)
360 360
 {
361 361
 	const char no_GBA_HEADER_ID[] = "NocashGbaBackupMediaSavDataFile";
362 362
 	const char no_GBA_HEADER_SRAM_ID[] = "SRAM";
363
-	uint8_t *src = static_cast<uint8_t *>(in_buf);
364
-	uint8_t *dst = static_cast<uint8_t *>(out_buf);
363
+	const uint8_t *src = in_buf;
364
+	uint8_t *dst = out_buf;
365 365
 	uint32_t src_pos = 0;
366 366
 	uint32_t dst_pos = 0;
367 367
 	uint32_t size_unpacked = 0;
... ...
@@ -379,11 +379,11 @@ static int no_gba_unpackSAV(void *in_buf, uint32_t fsize, void *out_buf, uint32_
379 379
 		if (src[i + 0x40] != no_GBA_HEADER_SRAM_ID[i])
380 380
 			return 2;
381 381
 
382
-	compressMethod = *(reinterpret_cast<uint32_t *>(src + 0x44));
382
+	compressMethod = *(reinterpret_cast<const uint32_t *>(src + 0x44));
383 383
 
384 384
 	if (!compressMethod) // unpacked
385 385
 	{
386
-		size_unpacked = *(reinterpret_cast<uint32_t *>(src + 0x48));
386
+		size_unpacked = *(reinterpret_cast<const uint32_t *>(src + 0x48));
387 387
 		src_pos = 0x4C;
388 388
 		for (uint32_t i = 0; i < size_unpacked; ++i)
389 389
 			dst[dst_pos++] = src[src_pos++];
... ...
@@ -393,7 +393,7 @@ static int no_gba_unpackSAV(void *in_buf, uint32_t fsize, void *out_buf, uint32_
393 393
 
394 394
 	if (compressMethod == 1) // packed (method 1)
395 395
 	{
396
-		size_unpacked = *(reinterpret_cast<uint32_t *>(src + 0x4C));
396
+		size_unpacked = *(reinterpret_cast<const uint32_t *>(src + 0x4C));
397 397
 
398 398
 		src_pos = 0x50;
399 399
 		while (true)
... ...
@@ -408,7 +408,7 @@ static int no_gba_unpackSAV(void *in_buf, uint32_t fsize, void *out_buf, uint32_
408 408
 
409 409
 			if (cc == 0x80)
410 410
 			{
411
-				uint16_t tsize = *(reinterpret_cast<uint16_t *>(src + src_pos + 1));
411
+				uint16_t tsize = *(reinterpret_cast<const uint16_t *>(src + src_pos + 1));
412 412
 				for (int t = 0; t < tsize; ++t)
413 413
 					dst[dst_pos++] = src[src_pos];
414 414
 				src_pos += 3;
... ...
@@ -433,11 +433,11 @@ static int no_gba_unpackSAV(void *in_buf, uint32_t fsize, void *out_buf, uint32_
433 433
 	return 200;
434 434
 }
435 435
 
436
-static uint32_t no_gba_savTrim(void *buf, uint32_t size)
436
+static uint32_t no_gba_savTrim(uint8_t *buf, uint32_t size)
437 437
 {
438 438
 	uint32_t rows = size / 16;
439 439
 	uint32_t pos = (size - 16);
440
-	uint8_t *src = static_cast<uint8_t *>(buf);
440
+	uint8_t *src = buf;
441 441
 
442 442
 	for (unsigned i = 0; i < rows; ++i, pos -= 16)
443 443
 	{
... ...
@@ -539,7 +539,7 @@ void BackupDevice::loadfile()
539 539
 	else
540 540
 	{
541 541
 		// scan for desmume save footer
542
-		int32_t cookieLen = static_cast<int32_t>(strlen(kDesmumeSaveCookie));
542
+		int32_t cookieLen = strlen(kDesmumeSaveCookie);
543 543
 		auto sigbuf = std::unique_ptr<char[]>(new char[cookieLen]);
544 544
 		inf->fseek(-cookieLen, SEEK_END);
545 545
 		inf->fread(&sigbuf[0], cookieLen);
... ...
@@ -610,7 +610,7 @@ bool BackupDevice::load_raw(const char *fn, uint32_t force_size)
610 610
 		return false;
611 611
 
612 612
 	fseek(inf, 0, SEEK_END);
613
-	uint32_t size = static_cast<uint32_t>(ftell(inf));
613
+	uint32_t size = ftell(inf);
614 614
 	uint32_t left = 0;
615 615
 
616 616
 	if (force_size > 0)
Browse code

Updating in_2sf to use a newish version of DeSmuME, 0.9.9 from SVN. Somewhat cleaned up as well, but not everything because it's a pain in the ass.

Naram Qashat authored on 2013/04/18 17:22:55
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
 	Copyright (C) 2006 thoduv
3 3
 	Copyright (C) 2006-2007 Theo Berkau
4
-	Copyright (C) 2008-2012 DeSmuME team
4
+	Copyright (C) 2008-2013 DeSmuME team
5 5
 
6 6
 	This file is free software: you can redistribute it and/or modify
7 7
 	it under the terms of the GNU General Public License as published by
... ...
@@ -19,167 +19,90 @@
19 19
 
20 20
 #include <cstdlib>
21 21
 #include <cstring>
22
-
23
-//#include "debug.h"
24 22
 #include "types.h"
25 23
 #include "mc.h"
26
-//#include "movie.h"
27 24
 #include "readwrite.h"
28 25
 #include "NDSSystem.h"
29 26
 
30
-#define FW_CMD_READ             0x03
31
-#define FW_CMD_WRITEDISABLE     0x04
32
-#define FW_CMD_READSTATUS       0x05
33
-#define FW_CMD_WRITEENABLE      0x06
34
-#define FW_CMD_PAGEWRITE        0x0A
35
-#define FW_CMD_READ_ID			0x9F
36
-
37
-#define BM_CMD_AUTODETECT       0xFF
38
-#define BM_CMD_WRITESTATUS      0x01
39
-#define BM_CMD_WRITELOW         0x02
40
-#define BM_CMD_READLOW          0x03
41
-#define BM_CMD_WRITEDISABLE     0x04
42
-#define BM_CMD_READSTATUS       0x05
43
-#define BM_CMD_WRITEENABLE      0x06
44
-#define BM_CMD_WRITEHIGH        0x0A
45
-#define BM_CMD_READHIGH         0x0B
46
-
47
-/* FLASH*/
48
-#define COMM_PAGE_WRITE		0x0A
49
-#define COMM_PAGE_ERASE		0xDB
50
-#define COMM_SECTOR_ERASE	0xD8
51
-#define COMM_CHIP_ERASE		0xC7
52
-#define CARDFLASH_READ_BYTES_FAST	0x0B    /* Not used*/
53
-#define CARDFLASH_DEEP_POWDOWN		0xB9    /* Not used*/
54
-#define CARDFLASH_WAKEUP			0xAB    /* Not used*/
55
-
56
-//since r2203 this was 0x00.
57
-//but baby pals proves finally that it should be 0xFF:
58
-//the game reads its initial sound volumes from uninitialized data, and if it is 0, the game will be silent
59
-//if it is 0xFF then the game starts with its sound and music at max, as presumably it is supposed to.
60
-//so in r3303 I finally changed it (no$ appears definitely to initialized to 0xFF)
27
+static const uint8_t FW_CMD_READ = 0x03;
28
+static const uint8_t FW_CMD_WRITEDISABLE = 0x04;
29
+static const uint8_t FW_CMD_READSTATUS = 0x05;
30
+static const uint8_t FW_CMD_WRITEENABLE = 0x06;
31
+static const uint8_t FW_CMD_PAGEWRITE = 0x0A;
32
+static const uint8_t FW_CMD_READ_ID = 0x9F;
33
+
34
+// since r2203 this was 0x00.
35
+// but baby pals proves finally that it should be 0xFF:
36
+// the game reads its initial sound volumes from uninitialized data, and if it is 0, the game will be silent
37
+// if it is 0xFF then the game starts with its sound and music at max, as presumably it is supposed to.
38
+// so in r3303 I finally changed it (no$ appears definitely to initialized to 0xFF)
61 39
 static const uint8_t kUninitializedSaveDataValue = 0xFF;
62 40
 
63
-static const char* kDesmumeSaveCookie = "|-DESMUME SAVE-|";
64
-
65
-static const uint32_t saveSizes[] = {512,			// 4k
66
-								8*1024,			// 64k
67
-								32*1024,		// 512k
68
-								64*1024,		// 1Mbit
69
-								256*1024,		// 2Mbit
70
-								512*1024,		// 4Mbit
71
-								1024*1024,		// 8Mbit
72
-								2048*1024,		// 16Mbit
73
-								4096*1024,		// 32Mbit
74
-								8192*1024,		// 64Mbit
75
-								16384*1024,		// 128Mbit
76
-								32768*1024,		// 256Mbit
77
-								65536*1024,		// 512Mbit
78
-								0xFFFFFFFF};
79
-static const uint32_t saveSizes_count = ARRAY_SIZE(saveSizes);
41
+static const char *kDesmumeSaveCookie = "|-DESMUME SAVE-|";
80 42
 
81 43
 //the lookup table from user save types to save parameters
82
-const int save_types[][2] = {
83
-        {MC_TYPE_AUTODETECT,1},
84
-        {MC_TYPE_EEPROM1,MC_SIZE_4KBITS},
85
-        {MC_TYPE_EEPROM2,MC_SIZE_64KBITS},
86
-        {MC_TYPE_EEPROM2,MC_SIZE_512KBITS},
87
-        {MC_TYPE_FRAM,MC_SIZE_256KBITS},
88
-        {MC_TYPE_FLASH,MC_SIZE_2MBITS},
89
-		{MC_TYPE_FLASH,MC_SIZE_4MBITS},
90
-		{MC_TYPE_FLASH,MC_SIZE_8MBITS},
91
-		{MC_TYPE_FLASH,MC_SIZE_16MBITS},
92
-		{MC_TYPE_FLASH,MC_SIZE_32MBITS},
93
-		{MC_TYPE_FLASH,MC_SIZE_64MBITS},
94
-		{MC_TYPE_FLASH,MC_SIZE_128MBITS},
95
-		{MC_TYPE_FLASH,MC_SIZE_256MBITS},
96
-		{MC_TYPE_FLASH,MC_SIZE_512MBITS}
44
+const SAVE_TYPE save_types[] =
45
+{
46
+	{"Autodetect", MC_TYPE_AUTODETECT, 1},
47
+	{"EEPROM 4kbit", MC_TYPE_EEPROM1, MC_SIZE_4KBITS},
48
+	{"EEPROM 64kbit", MC_TYPE_EEPROM2, MC_SIZE_64KBITS},
49
+	{"EEPROM 512kbit", MC_TYPE_EEPROM2, MC_SIZE_512KBITS},
50
+	{"FRAM 256kbit", MC_TYPE_FRAM, MC_SIZE_256KBITS},
51
+	{"FLASH 2Mbit", MC_TYPE_FLASH, MC_SIZE_2MBITS},
52
+	{"FLASH 4Mbit", MC_TYPE_FLASH, MC_SIZE_4MBITS},
53
+	{"FLASH 8Mbit", MC_TYPE_FLASH, MC_SIZE_8MBITS},
54
+	{"FLASH 16Mbit", MC_TYPE_FLASH, MC_SIZE_16MBITS},
55
+	{"FLASH 32Mbit", MC_TYPE_FLASH, MC_SIZE_32MBITS},
56
+	{"FLASH 64Mbit", MC_TYPE_FLASH, MC_SIZE_64MBITS},
57
+	{"FLASH 128Mbit", MC_TYPE_FLASH, MC_SIZE_128MBITS},
58
+	{"FLASH 256Mbit", MC_TYPE_FLASH, MC_SIZE_256MBITS},
59
+	{"FLASH 512Mbit", MC_TYPE_FLASH, MC_SIZE_512MBITS}
97 60
 };
98
-
99
-/*const char *save_names[] = {
100
-		"EEPROM 4kbit",
101
-		"EEPROM 64kbit",
102
-		"EEPROM 512kbit",
103
-		"FRAM 256kbit",
104
-		"FLASH 2Mbit",
105
-		"FLASH 4Mbit",
106
-		"FLASH 8Mbit",
107
-		"FLASH 16Mbit",
108
-		"FLASH 32Mbit",
109
-		"FLASH 64Mbit",
110
-		"FLASH 128Mbit",
111
-		"FLASH 256Mbit",
112
-		"FLASH 512Mbit"
113
-};*/
114
-
115
-//forces the currently selected backup type to be current
116
-//(can possibly be used to repair poorly chosen save types discovered late in gameplay i.e. pokemon gamers)
117
-/*void backup_forceManualBackupType()
118
-{
119
-	MMU_new.backupDevice.forceManualBackupType();
120
-}*/
121
-
122
-/*void backup_setManualBackupType(int type)
123
-{
124
-	CommonSettings.manualBackupType = type;
125
-}*/
126
-
127 61
 void mc_init(memory_chip_t *mc, int type)
128 62
 {
129
-        mc->com = 0;
130
-        mc->addr = 0;
131
-        mc->addr_shift = 0;
132
-        mc->data.clear();
133
-        mc->size = 0;
134
-        mc->write_enable = false;
135
-        mc->writeable_buffer = false;
136
-        mc->type = type;
137
-        mc->autodetectsize = 0;
138
-
139
-        switch(mc->type)
140
-        {
141
-           case MC_TYPE_EEPROM1:
142
-              mc->addr_size = 1;
143
-              break;
144
-           case MC_TYPE_EEPROM2:
145
-           case MC_TYPE_FRAM:
146
-              mc->addr_size = 2;
147
-              break;
148
-           case MC_TYPE_FLASH:
149
-              mc->addr_size = 3;
150
-              break;
151
-           default: break;
152
-        }
63
+	mc->com = 0;
64
+	mc->addr = 0;
65
+	mc->addr_shift = 0;
66
+	mc->data.clear();
67
+	mc->size = 0;
68
+	mc->write_enable = false;
69
+	mc->writeable_buffer = false;
70
+	mc->type = type;
71
+	mc->autodetectsize = 0;
72
+
73
+	switch (mc->type)
74
+	{
75
+		case MC_TYPE_EEPROM1:
76
+			mc->addr_size = 1;
77
+			break;
78
+		case MC_TYPE_EEPROM2:
79
+		case MC_TYPE_FRAM:
80
+			mc->addr_size = 2;
81
+			break;
82
+		case MC_TYPE_FLASH:
83
+			mc->addr_size = 3;
84
+	}
153 85
 }
154 86
 
155 87
 uint8_t *mc_alloc(memory_chip_t *mc, uint32_t size)
156 88
 {
157
-	/*uint8_t *buffer;
158
-	buffer = new uint8_t[size];
159
-	memset(buffer,0,size);*/
160
-
161
-	//if (mc->data) delete [] mc->data;
162 89
 	mc->data.clear();
163
-	//mc->data = buffer;
164
-	//if(!buffer) { return NULL; }
165 90
 	mc->data.resize(size, 0);
166 91
 	mc->size = size;
167 92
 	mc->writeable_buffer = true;
168 93
 
169
-	//return buffer;
170
-	return NULL;
94
+	return nullptr;
171 95
 }
172 96
 
173 97
 void mc_free(memory_chip_t *mc)
174 98
 {
175
-    //if(mc->data) delete[] mc->data;
176 99
 	mc->data.clear();
177
-    mc_init(mc, 0);
100
+	mc_init(mc, 0);
178 101
 }
179 102
 
180 103
 void fw_reset_com(memory_chip_t *mc)
181 104
 {
182
-	if(mc->com == FW_CMD_PAGEWRITE)
105
+	if (mc->com == FW_CMD_PAGEWRITE)
183 106
 	{
184 107
 		if (mc->fp)
185 108
 		{
... ...
@@ -196,9 +119,9 @@ void fw_reset_com(memory_chip_t *mc)
196 119
 			FILE *fp = fopen(mc->userfile, "wb");
197 120
 			if (fp)
198 121
 			{
199
-				if (fwrite(&mc->data[0x3FF00], 1, 0x100, fp) == 0x100)		// User Settings
122
+				if (fwrite(&mc->data[0x3FF00], 1, 0x100, fp) == 0x100) // User Settings
200 123
 				{
201
-					if (fwrite(&mc->data[0x0002A], 1, 0x1D6, fp) == 0x1D6)  // WiFi Settings
124
+					if (fwrite(&mc->data[0x0002A], 1, 0x1D6, fp) == 0x1D6) // WiFi Settings
202 125
 					{
203 126
 						if (fwrite(&mc->data[0x3FA00], 1, 0x300, fp) == 0x300)  // WiFi AP Settings
204 127
 							printf(" - done\n");
... ...
@@ -220,478 +143,173 @@ void fw_reset_com(memory_chip_t *mc)
220 143
 
221 144
 uint8_t fw_transfer(memory_chip_t *mc, uint8_t data)
222 145
 {
223
-	if(mc->com == FW_CMD_READ || mc->com == FW_CMD_PAGEWRITE) /* check if we are in a command that needs 3 bytes address */
146
+	if (mc->com == FW_CMD_READ || mc->com == FW_CMD_PAGEWRITE) /* check if we are in a command that needs 3 bytes address */
224 147
 	{
225
-		if(mc->addr_shift > 0)   /* if we got a complete address */
148
+		if (mc->addr_shift > 0) /* if we got a complete address */
226 149
 		{
227
-			mc->addr_shift--;
150
+			--mc->addr_shift;
228 151
 			mc->addr |= data << (mc->addr_shift * 8); /* argument is a byte of address */
229 152
 		}
230
-		else    /* if we have received 3 bytes of address, proceed command */
153
+		else /* if we have received 3 bytes of address, proceed command */
231 154
 		{
232
-			switch(mc->com)
155
+			switch (mc->com)
233 156
 			{
234 157
 				case FW_CMD_READ:
235
-					if(mc->addr < mc->size)  /* check if we can read */
158
+					if (mc->addr < mc->size)  /* check if we can read */
236 159
 					{
237
-						data = mc->data[mc->addr];       /* return byte */
238
-						mc->addr++;      /* then increment address */
160
+						data = mc->data[mc->addr]; /* return byte */
161
+						++mc->addr; /* then increment address */
239 162
 					}
240 163
 					break;
241
-
242 164
 				case FW_CMD_PAGEWRITE:
243
-					if(mc->addr < mc->size)
165
+					if (mc->addr < mc->size)
244 166
 					{
245
-						mc->data[mc->addr] = data;       /* write byte */
246
-						mc->addr++;
167
+						mc->data[mc->addr] = data; /* write byte */
168
+						++mc->addr;
247 169
 					}
248
-					break;
249 170
 			}
250
-
251 171
 		}
252 172
 	}
253
-	else if(mc->com == FW_CMD_READ_ID)
173
+	else if (mc->com == FW_CMD_READ_ID)
254 174
 	{
255
-		switch(mc->addr)
175
+		switch (mc->addr)
256 176
 		{
257
-		//here is an ID string measured from an old ds fat: 62 16 00 (0x62=sanyo)
258
-		//but we chose to use an ST from martin's ds fat string so programs might have a clue as to the firmware size:
259
-		//20 40 12
260
-		case 0:
261
-			data = 0x20;
262
-			mc->addr=1;
263
-			break;
264
-		case 1:
265
-			data = 0x40; //according to gbatek this is the device ID for the flash on someone's ds fat
266
-			mc->addr=2;
267
-			break;
268
-		case 2:
269
-			data = 0x12;
270
-			mc->addr = 0;
271
-			break;
177
+			// here is an ID string measured from an old ds fat: 62 16 00 (0x62=sanyo)
178
+			// but we chose to use an ST from martin's ds fat string so programs might have a clue as to the firmware size:
179
+			// 20 40 12
180
+			case 0:
181
+				data = 0x20;
182
+				mc->addr = 1;
183
+				break;
184
+			case 1:
185
+				data = 0x40; // according to gbatek this is the device ID for the flash on someone's ds fat
186
+				mc->addr = 2;
187
+				break;
188
+			case 2:
189
+				data = 0x12;
190
+				mc->addr = 0;
272 191
 		}
273 192
 	}
274
-	else if(mc->com == FW_CMD_READSTATUS)
275
-	{
193
+	else if (mc->com == FW_CMD_READSTATUS)
276 194
 		return mc->write_enable ? 0x02 : 0x00;
277
-	}
278
-	else	//finally, check if it's a new command
195
+	else // finally, check if it's a new command
279 196
 	{
280
-		switch(data)
197
+		switch (data)
281 198
 		{
282
-			case 0: break;	//nothing
199
+			case 0:
200
+				break; // nothing
283 201
 
284 202
 			case FW_CMD_READ_ID:
285 203
 				mc->addr = 0;
286 204
 				mc->com = FW_CMD_READ_ID;
287 205
 				break;
288 206
 
289
-			case FW_CMD_READ:    //read command
207
+			case FW_CMD_READ: //read command
290 208
 				mc->addr = 0;
291 209
 				mc->addr_shift = 3;
292 210
 				mc->com = FW_CMD_READ;
293 211
 				break;
294 212
 
295
-			case FW_CMD_WRITEENABLE:     //enable writing
296
-				if(mc->writeable_buffer) { mc->write_enable = true; }
213
+			case FW_CMD_WRITEENABLE: //enable writing
214
+				if (mc->writeable_buffer)
215
+					mc->write_enable = true;
297 216
 				break;
298 217
 
299
-			case FW_CMD_WRITEDISABLE:    //disable writing
300
-
218
+			case FW_CMD_WRITEDISABLE: //disable writing
301 219
 				mc->write_enable = false;
302 220
 				break;
303 221
 
304
-			case FW_CMD_PAGEWRITE:       //write command
305
-				if(mc->write_enable)
222
+			case FW_CMD_PAGEWRITE: //write command
223
+				if (mc->write_enable)
306 224
 				{
307 225
 					mc->addr = 0;
308 226
 					mc->addr_shift = 3;
309 227
 					mc->com = FW_CMD_PAGEWRITE;
310 228
 				}
311
-				else { data = 0; }
229
+				else
230
+					data = 0;
312 231
 				break;
313 232
 
314
-			case FW_CMD_READSTATUS:  //status register command
233
+			case FW_CMD_READSTATUS: //status register command
315 234
 				mc->com = FW_CMD_READSTATUS;
316 235
 				break;
317 236
 
318 237
 			default:
319 238
 				printf("Unhandled FW command: %02X\n", data);
320
-				break;
321 239
 		}
322 240
 	}
323 241
 
324 242
 	return data;
325 243
 }
326 244
 
327
-/*bool BackupDevice::save_state(EMUFILE* os)
328
-{
329
-	uint32_t version = 2;
330
-	//v0
331
-	write32le(version,os);
332
-	write32le(write_enable,os);
333
-	write32le(com,os);
334
-	write32le(addr_size,os);
335
-	write32le(addr_counter,os);
336
-	write32le((uint32_t)state,os);
337
-	writebuffer(data,os);
338
-	writebuffer(data_autodetect,os);
339
-	//v1
340
-	write32le(addr,os);
341
-	//v2
342
-	write8le(motionInitState,os);
343
-	write8le(motionFlag,os);
344
-	return true;
345
-}*/
346
-
347
-bool BackupDevice::load_state(EMUFILE* is)
348
-{
349
-	uint32_t version;
350
-	if(read32le(&version,is)!=1) return false;
351
-	//if(version>=0)
352
-	{
353
-		readbool(&write_enable,is);
354
-		read32le(&com,is);
355
-		read32le(&addr_size,is);
356
-		read32le(&addr_counter,is);
357
-		uint32_t temp;
358
-		read32le(&temp,is);
359
-		state = (STATE)temp;
360
-		readbuffer(data,is);
361
-		readbuffer(data_autodetect,is);
362
-	}
363
-	if(version>=1)
364
-		read32le(&addr,is);
365
-	if(version>=2)
366
-	{
367
-		read8le(&motionInitState,is);
368
-		read8le(&motionFlag,is);
369
-	}
370
-
371
-	return true;
372
-}
373
-
374 245
 BackupDevice::BackupDevice()
375 246
 {
376
-	//isMovieMode = false;
377
-	reset();
247
+	this->reset();
378 248
 }
379 249
 
380
-//due to unfortunate shortcomings in the emulator architecture,
381
-//at reset-time, we won't have a filename to the .dsv file.
382
-//so the only difference between load_rom (init) and reset is that
383
-//one of them saves the filename
384
-void BackupDevice::load_rom(const char* fn)
250
+// due to unfortunate shortcomings in the emulator architecture,
251
+// at reset-time, we won't have a filename to the .dsv file.
252
+// so the only difference between load_rom (init) and reset is that
253
+// one of them saves the filename
254
+void BackupDevice::load_rom(const std::string &fn)
385 255
 {
386
-	//isMovieMode = false;
387 256
 	this->filename = fn;
388
-	reset();
257
+	this->reset();
389 258
 }
390 259
 
391
-/*void BackupDevice::movie_mode()
392
-{
393
-	isMovieMode = true;
394
-	reset();
395
-}*/
396
-
397 260
 void BackupDevice::reset_hardware()
398 261
 {
399
-	write_enable = false;
400
-	com = 0;
401
-	addr = addr_counter = 0;
402
-	motionInitState = MOTION_INIT_STATE_IDLE;
403
-	motionFlag = MOTION_FLAG_NONE;
404
-	state = DETECTING;
405
-	flushPending = false;
406
-	lazyFlushPending = false;
262
+	this->write_enable = false;
263
+	this->com = 0;
264
+	this->addr = this->addr_counter = 0;
265
+	this->motionInitState = MOTION_INIT_STATE_IDLE;
266
+	this->motionFlag = MOTION_FLAG_NONE;
267
+	this->state = DETECTING;
268
+	this->flushPending = false;
269
+	this->lazyFlushPending = false;
407 270
 }
408 271
 
409 272
 void BackupDevice::reset()
410 273
 {
411
-	memset(&info, 0, sizeof(info));
412
-	reset_hardware();
413
-	resize(0);
414
-	data_autodetect.resize(0);
415
-	addr_size = 0;
416
-	loadfile();
417
-
418
-	//if the user has requested a manual choice for backup type, and we havent imported a raw save file, then apply it now
419
-	if(state == DETECTING && CommonSettings.manualBackupType != MC_TYPE_AUTODETECT)
420
-	{
421
-		state = RUNNING;
422
-		int savetype = save_types[CommonSettings.manualBackupType][0];
423
-		int savesize = save_types[CommonSettings.manualBackupType][1];
424
-		ensure((uint32_t)savesize); //expand properly if necessary
425
-		resize(savesize); //truncate if necessary
426
-		addr_size = addr_size_for_old_save_type(savetype);
427
-		//flush();
428
-	}
429
-}
430
-
431
-/*void BackupDevice::close_rom()
432
-{
433
-	//flush();
434
-}*/
274
+	memset(&this->info, 0, sizeof(this->info));
275
+	this->reset_hardware();
276
+	this->resize(0);
277
+	this->data_autodetect.resize(0);
278
+	this->addr_size = 0;
279
+	this->loadfile();
435 280
 
436
-/*void BackupDevice::reset_command()
437
-{
438
-	//printf("MC RESET\n");
439
-	//for a performance hack, save files are only flushed after each reset command
440
-	//(hopefully, after each page)
441
-	if(flushPending)
442
-	{
443
-		//flush();
444
-		flushPending = false;
445
-		lazyFlushPending = false;
446
-	}
447
-
448
-	if(state == DETECTING && data_autodetect.size()>0)
281
+	// if the user has requested a manual choice for backup type, and we havent imported a raw save file, then apply it now
282
+	if (this->state == DETECTING && CommonSettings.manualBackupType != MC_TYPE_AUTODETECT)
449 283
 	{
450
-		//we can now safely detect the save address size
451
-		uint32_t autodetect_size = data_autodetect.size();
452
-
453
-		printf("Autodetecting with autodetect_size=%d\n",autodetect_size);
454
-
455
-		const uint8_t sm64_sig[] = {0x01,0x80,0x00,0x00};
456
-		if(autodetect_size == 4 && !memcmp(&data_autodetect[0],sm64_sig,4))
457
-		{
458
-			addr_size = 2;
459
-		}
460
-		else //detect based on rules
461
-			switch(autodetect_size)
462
-			{
463
-			case 0:
464
-			case 1:
465
-				printf("Catastrophic error while autodetecting save type.\nIt will need to be specified manually\n");
466
-				#ifdef _WINDOWS
467
-				MessageBoxA(0,"Catastrophic Error Code: Camel;\nyour save type has not been autodetected correctly;\nplease report to developers",0,0);
468
-				#endif
469
-				addr_size = 1; //choose 1 just to keep the busted savefile from growing too big
470
-				break;
471
-			case 2:
472
-				 //the modern typical case for small eeproms
473
-				addr_size = 1;
474
-				break;
475
-			case 3:
476
-				//another modern typical case..
477
-				//but unfortunately we select this case for spider-man 3, when what it meant to do was
478
-				//present the archaic 1+2 case
479
-				//it seems that over the hedge does this also.
480
-				addr_size = 2;
481
-				break;
482
-			case 4:
483
-				//a modern typical case
484
-				addr_size = 3;
485
-				break;
486
-			default:
487
-				//the archaic case: write the address and then some modulo-4 number of bytes
488
-				//why modulo 4? who knows.
489
-				addr_size = autodetect_size & 3;
490
-				break;
491
-			}
492
-
493
-		state = RUNNING;
494
-		data_autodetect.resize(0);
495
-		//flush();
496
-	}
497
-
498
-	com = 0;
499
-}*/
500
-/*uint8_t BackupDevice::data_command(uint8_t val, int cpu)
501
-{
502
-	//printf("MC CMD: %02X\n",val);
503
-
504
-	//motion: some guessing here... hope it doesn't break anything
505
-	if(com == BM_CMD_READLOW && motionInitState == MOTION_INIT_STATE_RECEIVED_4_B && val == 0)
506
-	{
507
-		motionInitState = MOTION_INIT_STATE_IDLE;
508
-		motionFlag |= MOTION_FLAG_ENABLED;
509
-		//return 0x04; //return 0x04 to enable motion!!!!!
510
-		return 0; //but we return 0 to disable it! since we don't emulate it anyway
511
-	}
512
-
513
-	//if the game firmly believes we have motion support, then ignore all motion commands, since theyre not emulated.
514
-	if(motionFlag & MOTION_FLAG_SENSORMODE)
515
-	{
516
-		return 0;
517
-	}
518
-
519
-	if(com == BM_CMD_READLOW || com == BM_CMD_WRITELOW)
520
-	{
521
-		//handle data or address
522
-		if(state == DETECTING)
523
-		{
524
-			if(com == BM_CMD_WRITELOW)
525
-			{
526
-				printf("Unexpected backup device initialization sequence using writes!\n");
527
-			}
528
-
529
-			//just buffer the data until we're no longer detecting
530
-			data_autodetect.push_back(val);
531
-			val = 0;
532
-		}
533
-		else
534
-		{
535
-			if(addr_counter<addr_size)
536
-			{
537
-				//continue building address
538
-				addr <<= 8;
539
-				addr |= val;
540
-				addr_counter++;
541
-				//if(addr_counter==addr_size) printf("ADR: %08X\n",addr);
542
-			}
543
-			else
544
-			{
545
-				//why does tomb raider underworld access 0x180 and go clear through to 0x280?
546
-				//should this wrap around at 0 or at 0x100?
547
-				if(addr_size == 1) addr &= 0x1FF;
548
-
549
-				//address is complete
550
-				ensure(addr+1);
551
-				if(com == BM_CMD_READLOW)
552
-				{
553
-					//printf("READ ADR: %08X\n",addr);
554
-					val = data[addr];
555
-					//flushPending = true; //is this a good idea? it may slow stuff down, but it is helpful for debugging
556
-					lazyFlushPending = true; //lets do this instead
557
-					//printf("read: %08X\n",addr);
558
-				}
559
-				else
560
-				{
561
-					if(write_enable)
562
-					{
563
-						//printf("WRITE ADR: %08X\n",addr);
564
-						data[addr] = val;
565
-						flushPending = true;
566
-						//printf("writ: %08X\n",addr);
567
-					}
568
-				}
569
-				addr++;
570
-
571
-			}
572
-		}
573
-	}
574
-	else if(com == BM_CMD_READSTATUS)
575
-	{
576
-		//handle request to read status
577
-		//LOG("Backup Memory Read Status: %02X\n", write_enable << 1);
578
-		return (write_enable << 1) | (3<<2);
579
-	}
580
-	else
581
-	{
582
-		//there is no current command. receive one
583
-		switch(val)
584
-		{
585
-			case 0: break; //??
586
-
587
-			case 0xFE:
588
-				if(motionInitState == MOTION_INIT_STATE_IDLE) { motionInitState = MOTION_INIT_STATE_FE; return 0; }
589
-				break;
590
-			case 0xFD:
591
-				if(motionInitState == MOTION_INIT_STATE_FE) { motionInitState = MOTION_INIT_STATE_FD; return 0; }
592
-				break;
593
-			case 0xFB:
594
-				if(motionInitState == MOTION_INIT_STATE_FD) { motionInitState = MOTION_INIT_STATE_FB; return 0; }
595
-				break;
596
-			case 0xF8:
597
-				//enable sensor mode
598
-				if(motionInitState == MOTION_INIT_STATE_FD)
599
-				{
600
-					motionInitState = MOTION_INIT_STATE_IDLE;
601
-					motionFlag |= MOTION_FLAG_SENSORMODE;
602
-					return 0;
603
-				}
604
-				break;
605
-			case 0xF9:
606
-				//disable sensor mode
607
-				if(motionInitState == MOTION_INIT_STATE_FD)
608
-				{
609
-					motionInitState = MOTION_INIT_STATE_IDLE;
610
-					motionFlag &= ~MOTION_FLAG_SENSORMODE;
611
-					return 0;
612
-				}
613
-				break;
614
-
615
-			case 8:
616
-				printf("COMMAND%c: Unverified Backup Memory command: %02X FROM %08X\n",(cpu==ARMCPU_ARM9)?'9':'7',val, (cpu==ARMCPU_ARM9)?NDS_ARM9.instruct_adr:NDS_ARM7.instruct_adr);
617
-				val = 0xAA;
618
-				break;
619
-
620
-			case BM_CMD_WRITEDISABLE:
621
-				switch(motionInitState)
622
-				{
623
-				case MOTION_INIT_STATE_IDLE: motionInitState = MOTION_INIT_STATE_RECEIVED_4; break;
624
-				case MOTION_INIT_STATE_RECEIVED_4: motionInitState = MOTION_INIT_STATE_RECEIVED_4_B; break;
625
-				}
626
-				write_enable = false;
627
-				break;
628
-
629
-			case BM_CMD_READSTATUS:
630
-				com = BM_CMD_READSTATUS;
631
-				val = (write_enable << 1) | (3<<2);
632
-				break;
633
-
634
-			case BM_CMD_WRITEENABLE:
635
-				write_enable = true;
636
-				break;
637
-
638
-			case BM_CMD_WRITELOW:
639
-			case BM_CMD_READLOW:
640
-				//printf("XLO: %08X\n",addr);
641
-				com = val;
642
-				addr_counter = 0;
643
-				addr = 0;
644
-				break;
645
-
646
-			case BM_CMD_WRITEHIGH:
647
-			case BM_CMD_READHIGH:
648
-				//printf("XHI: %08X\n",addr);
649
-				if(val == BM_CMD_WRITEHIGH) val = BM_CMD_WRITELOW;
650
-				if(val == BM_CMD_READHIGH) val = BM_CMD_READLOW;
651
-				com = val;
652
-				addr_counter = 0;
653
-				addr = 0;
654
-				if(addr_size==1) {
655
-					//"write command that's only available on ST M95040-W that I know of"
656
-					//this makes sense, since this device would only have a 256 bytes address space with writelow
657
-					//and writehigh would allow access to the upper 256 bytes
658
-					//but it was detected in pokemon diamond also during the main save process
659
-					addr = 0x1;
660
-				}
661
-				break;
662
-
663
-			default:
664
-				printf("COMMAND%c: Unhandled Backup Memory command: %02X FROM %08X\n",(cpu==ARMCPU_ARM9)?'9':'7',val, (cpu==ARMCPU_ARM9)?NDS_ARM9.instruct_adr:NDS_ARM7.instruct_adr);
665
-				break;
666
-		} //switch(val)
667
-
668
-		//motion control state machine broke, return to ground
669
-		motionInitState = MOTION_INIT_STATE_IDLE;
284
+		this->state = RUNNING;
285
+		int savetype = save_types[CommonSettings.manualBackupType].media_type;
286
+		int savesize = save_types[CommonSettings.manualBackupType].size;
287
+		this->ensure(static_cast<uint32_t>(savesize)); // expand properly if necessary
288
+		this->resize(savesize); // truncate if necessary
289
+		this->addr_size = this->addr_size_for_old_save_type(savetype);
670 290
 	}
671
-	return val;
672
-}*/
291
+}
673 292
 
674
-//guarantees that the data buffer has room enough for the specified number of bytes
293
+// guarantees that the data buffer has room enough for the specified number of bytes
675 294
 void BackupDevice::ensure(uint32_t Addr)
676 295
 {
677
-	uint32_t size = data.size();
678
-	if(size<Addr)
679
-	{
680
-		resize(Addr);
681
-	}
296
+	uint32_t size = this->data.size();
297
+	if (size < Addr)
298
+		this->resize(Addr);
682 299
 }
683 300
 
684 301
 void BackupDevice::resize(uint32_t size)
685 302
 {
686
-	size_t old_size = data.size();
687
-	data.resize(size);
688
-	for(uint32_t i=old_size;i<size;i++)
689
-		data[i] = kUninitializedSaveDataValue;
303
+	size_t old_size = this->data.size();
304
+	this->data.resize(size);
305
+	for (uint32_t i = old_size; i < size; ++i)
306
+		this->data[i] = kUninitializedSaveDataValue;
690 307
 }
691 308
 
692 309
 uint32_t BackupDevice::addr_size_for_old_save_size(int bupmem_size)
693 310
 {
694
-	switch(bupmem_size) {
311
+	switch (bupmem_size)
312
+	{
695 313
 		case MC_SIZE_4KBITS:
696 314
 			return 1;
697 315
 		case MC_SIZE_64KBITS:
... ...
@@ -712,13 +330,13 @@ uint32_t BackupDevice::addr_size_for_old_save_size(int bupmem_size)
712 330
 
713 331
 uint32_t BackupDevice::addr_size_for_old_save_type(int bupmem_type)
714 332
 {
715
-	switch(bupmem_type)
333
+	switch (bupmem_type)
716 334
 	{
717 335
 		case MC_TYPE_EEPROM1:
718 336
 			return 1;
719 337
 		case MC_TYPE_EEPROM2:
720 338
 		case MC_TYPE_FRAM:
721
-              return 2;
339
+			return 2;
722 340
 		case MC_TYPE_FLASH:
723 341
 			return 3;
724 342
 		default:
... ...
@@ -726,72 +344,63 @@ uint32_t BackupDevice::addr_size_for_old_save_type(int bupmem_type)
726 344
 	}
727 345
 }
728 346
 
729
-
730
-void BackupDevice::load_old_state(uint32_t addrSize, uint8_t* Data, uint32_t datasize)
347
+void BackupDevice::load_old_state(uint32_t addrSize, uint8_t *Data, uint32_t datasize)
731 348
 {
732
-	state = RUNNING;
349
+	this->state = RUNNING;
733 350
 	this->addr_size = addrSize;
734
-	resize(datasize);
735
-	memcpy(&this->data[0],Data,datasize);
736
-
737
-	//dump back out as a dsv, just to keep things sane
738
-	//flush();
351
+	this->resize(datasize);
352
+	memcpy(&this->data[0], Data, datasize);
739 353
 }
740 354
 
741
-//======================================================================= no$GBA
742
-//=======================================================================
743
-//=======================================================================
355
+// ======================================================================= no$GBA
356
+// =======================================================================
357
+// =======================================================================
744 358
 
745 359
 static int no_gba_unpackSAV(void *in_buf, uint32_t fsize, void *out_buf, uint32_t &size)
746 360
 {
747 361
 	const char no_GBA_HEADER_ID[] = "NocashGbaBackupMediaSavDataFile";
748 362
 	const char no_GBA_HEADER_SRAM_ID[] = "SRAM";
749
-	uint8_t	*src = (uint8_t *)in_buf;
750
-	uint8_t	*dst = (uint8_t *)out_buf;
363
+	uint8_t *src = static_cast<uint8_t *>(in_buf);
364
+	uint8_t *dst = static_cast<uint8_t *>(out_buf);
751 365
 	uint32_t src_pos = 0;
752 366
 	uint32_t dst_pos = 0;
753
-	uint8_t	cc = 0;
754
-	uint32_t	size_unpacked = 0;
755
-	//uint32_t	size_packed = 0;
756
-	uint32_t	compressMethod = 0;
367
+	uint32_t size_unpacked = 0;
368
+	uint32_t compressMethod = 0;
757 369
 
758
-	if (fsize < 0x50) return 1;
370
+	if (fsize < 0x50)
371
+		return 1;
759 372
 
760
-	for (int i = 0; i < 0x1F; i++)
761
-	{
762
-		if (src[i] != no_GBA_HEADER_ID[i]) return 2;
763
-	}
764
-	if (src[0x1F] != 0x1A) return 2;
765
-	for (int i = 0; i < 0x4; i++)
766
-	{
767
-		if (src[i+0x40] != no_GBA_HEADER_SRAM_ID[i]) return 2;
768
-	}
373
+	for (int i = 0; i < 0x1F; ++i)
374
+		if (src[i] != no_GBA_HEADER_ID[i])
375
+			return 2;
376
+	if (src[0x1F] != 0x1A)
377
+		return 2;
378
+	for (int i = 0; i < 0x4; ++i)
379
+		if (src[i + 0x40] != no_GBA_HEADER_SRAM_ID[i])
380
+			return 2;
769 381
 
770
-	compressMethod = *((uint32_t*)(src+0x44));
382
+	compressMethod = *(reinterpret_cast<uint32_t *>(src + 0x44));
771 383
 
772
-	if (compressMethod == 0)				// unpacked
384
+	if (!compressMethod) // unpacked
773 385
 	{
774
-		size_unpacked = *((uint32_t*)(src+0x48));
386
+		size_unpacked = *(reinterpret_cast<uint32_t *>(src + 0x48));
775 387
 		src_pos = 0x4C;
776
-		for (uint32_t i = 0; i < size_unpacked; i++)
777
-		{
388
+		for (uint32_t i = 0; i < size_unpacked; ++i)
778 389
 			dst[dst_pos++] = src[src_pos++];
779
-		}
780 390
 		size = dst_pos;
781 391
 		return 0;
782 392
 	}
783 393
 
784
-	if (compressMethod == 1)				// packed (method 1)
394
+	if (compressMethod == 1) // packed (method 1)
785 395
 	{
786
-		//size_packed = *((uint32_t*)(src+0x48));
787
-		size_unpacked = *((uint32_t*)(src+0x4C));
396
+		size_unpacked = *(reinterpret_cast<uint32_t *>(src + 0x4C));
788 397
 
789 398
 		src_pos = 0x50;
790 399
 		while (true)
791 400
 		{
792
-			cc = src[src_pos++];
401
+			uint8_t cc = src[src_pos++];
793 402
 
794
-			if (cc == 0)
403
+			if (!cc)
795 404
 			{
796 405
 				size = dst_pos;
797 406
 				return 0;
... ...
@@ -799,23 +408,23 @@ static int no_gba_unpackSAV(void *in_buf, uint32_t fsize, void *out_buf, uint32_
799 408
 
800 409
 			if (cc == 0x80)
801 410
 			{
802
-				uint16_t tsize = *((uint16_t*)(src+src_pos+1));
803
-				for (int t = 0; t < tsize; t++)
411
+				uint16_t tsize = *(reinterpret_cast<uint16_t *>(src + src_pos + 1));
412
+				for (int t = 0; t < tsize; ++t)
804 413
 					dst[dst_pos++] = src[src_pos];
805 414
 				src_pos += 3;
806 415
 				continue;
807 416
 			}
808 417
 
809
-			if (cc > 0x80)		// repeat
418
+			if (cc > 0x80) // repeat
810 419
 			{
811 420
 				cc -= 0x80;
812
-				for (int t = 0; t < cc; t++)
421
+				for (int t = 0; t < cc; ++t)
813 422
 					dst[dst_pos++] = src[src_pos];
814
-				src_pos++;
423
+				++src_pos;
815 424
 				continue;
816 425
 			}
817 426
 			// copy
818
-			for (int t = 0; t < cc; t++)
427
+			for (int t = 0; t < cc; ++t)
819 428
 				dst[dst_pos++] = src[src_pos++];
820 429
 		}
821 430
 		size = dst_pos;
... ...
@@ -828,347 +437,180 @@ static uint32_t no_gba_savTrim(void *buf, uint32_t size)
828 437
 {
829 438
 	uint32_t rows = size / 16;
830 439
 	uint32_t pos = (size - 16);
831
-	uint8_t	*src = (uint8_t*)buf;
440
+	uint8_t *src = static_cast<uint8_t *>(buf);
832 441
 
833
-	for (unsigned int i = 0; i < rows; i++, pos -= 16)
442
+	for (unsigned i = 0; i < rows; ++i, pos -= 16)
834 443
 	{
835 444
 		if (src[pos] == 0xFF)
836 445
 		{
837
-			for (int t = 0; t < 16; t++)
838
-			{
839
-				if (src[pos+t] != 0xFF) return pos+16;
840
-			}
446
+			for (int t = 0; t < 16; ++t)
447
+				if (src[pos + t] != 0xFF)
448
+					return pos + 16;
841 449
 		}
842 450
 		else
843
-		{
844
-			return pos+16;
845
-		}
451
+			return pos + 16;
846 452
 	}
847 453
 	return size;
848 454
 }
849 455
 
850 456
 static uint32_t no_gba_fillLeft(uint32_t size)
851 457
 {
852
-	for (uint32_t i = 1; i < ARRAY_SIZE(save_types); i++)
853
-	{
854
-		if (size <= (uint32_t)save_types[i][1])
855
-			return size + (save_types[i][1] - size);
856
-	}
458
+	for (uint32_t i = 1; i < ARRAY_SIZE(save_types); ++i)
459
+		if (size <= static_cast<uint32_t>(save_types[i].size))
460
+			return size + (save_types[i].size - size);
857 461
 	return size;
858 462
 }
859 463
 
860 464
 bool BackupDevice::load_no_gba(const char *fname)
861 465
 {
862
-	FILE	*fsrc = fopen(fname, "rb");
863
-	uint8_t		*in_buf = NULL;
864
-	uint8_t		*out_buf = NULL;
466
+	FILE *fsrc = fopen(fname, "rb");
865 467
 
866 468
 	if (fsrc)
867 469
 	{
868
-		uint32_t fsize = 0;
869 470
 		fseek(fsrc, 0, SEEK_END);
870
-		fsize = ftell(fsrc);
471
+		uint32_t fsize = ftell(fsrc);
871 472
 		fseek(fsrc, 0, SEEK_SET);
872 473
 		//printf("Open %s file (size %i bytes)\n", fname, fsize);
873 474
 
874
-		in_buf = new uint8_t [fsize];
475
+		auto in_buf = std::unique_ptr<uint8_t[]>(new uint8_t[fsize]);
875 476
 
876
-		if (fread(in_buf, 1, fsize, fsrc) == fsize)
477
+		if (fread(&in_buf[0], 1, fsize, fsrc) == fsize)
877 478
 		{
878
-			out_buf = new uint8_t [8 * 1024 * 1024 / 8];
879
-			uint32_t size = 0;
479
+			auto out_buf = std::unique_ptr<uint8_t[]>(new uint8_t[8 * 1024 * 1024 / 8]);
880 480
 
881
-			memset(out_buf, 0xFF, 8 * 1024 * 1024 / 8);
882
-			if (no_gba_unpackSAV(in_buf, fsize, out_buf, size) == 0)
481
+			memset(&out_buf[0], 0xFF, 8 * 1024 * 1024 / 8);
482
+			uint32_t size = 0;
483
+			if (!no_gba_unpackSAV(&in_buf[0], fsize, &out_buf[0], size))
883 484
 			{
884 485
 				//printf("New size %i byte(s)\n", size);
885
-				size = no_gba_savTrim(out_buf, size);
486
+				size = no_gba_savTrim(&out_buf[0], size);
886 487
 				//printf("--- new size after trim %i byte(s)\n", size);
887 488
 				size = no_gba_fillLeft(size);
888 489
 				//printf("--- new size after fill %i byte(s)\n", size);
889 490
 				raw_applyUserSettings(size);
890
-				data.resize(size);
891
-				for (uint32_t tt = 0; tt < size; tt++)
892
-					data[tt] = out_buf[tt];
491
+				this->data.resize(size);
492
+				for (uint32_t tt = 0; tt < size; ++tt)
493
+					this->data[tt] = out_buf[tt];
893 494
 
894 495
 				//dump back out as a dsv, just to keep things sane
895
-				//flush();
896 496
 				printf("---- Loaded no$GBA save\n");
897 497
 
898
-				if (in_buf) delete [] in_buf;
899
-				if (out_buf) delete [] out_buf;
900 498
 				fclose(fsrc);
901 499
 				return true;
902 500
 			}
903
-			if (out_buf) delete [] out_buf;
904 501
 		}
905
-		if (in_buf) delete [] in_buf;
906 502
 		fclose(fsrc);
907 503
 	}
908 504
 
909 505
 	return false;
910 506
 }
911 507
 
912
-/*bool BackupDevice::save_no_gba(const char* fname)
913
-{
914
-	FILE* outf = fopen(fname,"wb");
915
-	if(!outf) return false;
916
-	uint32_t size = data.size();
917
-	uint32_t padSize = pad_up_size(size);
918
-	if(data.size()>0)
919
-		fwrite(&data[0],1,size,outf);
920
-	for(uint32_t i=size;i<padSize;i++)
921
-		fputc(0xFF,outf);
922
-
923
-	if (padSize < 512 * 1024)
924
-	{
925
-		for(uint32_t i=padSize; i<512 * 1024; i++)
926
-			fputc(0xFF,outf);
927
-	}
928
-	fclose(outf);
929
-	return true;
930
-}*/
931
-//======================================================================= end
932
-//=======================================================================
933
-//======================================================================= no$GBA
934
-
508
+// ======================================================================= end
509
+// =======================================================================
510
+// ======================================================================= no$GBA
935 511
 
936 512
 void BackupDevice::loadfile()
937 513
 {
938
-	//never use save files if we are in movie mode
939
-	//if(isMovieMode) return;
940
-	if(filename.length() ==0) return; //No sense crashing if no filename supplied
514
+	if (this->filename.empty())
515
+		return; // No sense crashing if no filename supplied
941 516
 
942
-	EMUFILE_FILE* inf = new EMUFILE_FILE(filename.c_str(),"rb");
943
-	if(inf->fail())
517
+	auto inf = std::unique_ptr<EMUFILE_FILE>(new EMUFILE_FILE(filename.c_str(), "rb"));
518
+	if (inf->fail())
944 519
 	{
945
-		delete inf;
946
-		//no dsv found; we need to try auto-importing a file with .sav extension
520
+		// no dsv found; we need to try auto-importing a file with .sav extension
947 521
 		printf("DeSmuME .dsv save file not found. Trying to load an old raw .sav file.\n");
948 522
 
949
-		//change extension to sav
523
+		// change extension to sav
950 524
 		char tmp[MAX_PATH];
951
-		strcpy(tmp,filename.c_str());
952
-		tmp[strlen(tmp)-3] = 0;
953
-		strcat(tmp,"sav");
525
+		strcpy(tmp, this->filename.c_str());
526
+		tmp[strlen(tmp) - 3] = 0;
527
+		strcat(tmp, "sav");
954 528
 
955
-		inf = new EMUFILE_FILE(tmp,"rb");
956
-		if(inf->fail())
529
+		inf.reset(new EMUFILE_FILE(tmp, "rb"));
530
+		if (inf->fail())
957 531
 		{
958
-			delete inf;
959
-			printf("Missing save file %s\n",filename.c_str());
532
+			printf("Missing save file %s\n", this->filename.c_str());
960 533
 			return;
961 534
 		}
962
-		delete inf;
963 535
 
964
-		if (!load_no_gba(tmp))
965
-			load_raw(tmp);
536
+		if (!this->load_no_gba(tmp))
537
+			this->load_raw(tmp);
966 538
 	}
967 539
 	else
968 540
 	{
969
-		//scan for desmume save footer
970
-		const int32_t cookieLen = (int32_t)strlen(kDesmumeSaveCookie);
971
-		char *sigbuf = new char[cookieLen];
541
+		// scan for desmume save footer
542
+		int32_t cookieLen = static_cast<int32_t>(strlen(kDesmumeSaveCookie));
543
+		auto sigbuf = std::unique_ptr<char[]>(new char[cookieLen]);
972 544
 		inf->fseek(-cookieLen, SEEK_END);
973
-		inf->fread(sigbuf,cookieLen);
974
-		int cmp = memcmp(sigbuf,kDesmumeSaveCookie,cookieLen);
975
-		delete[] sigbuf;
976
-		if(cmp)
545
+		inf->fread(&sigbuf[0], cookieLen);
546
+		int cmp = memcmp(&sigbuf[0], kDesmumeSaveCookie,cookieLen);
547
+		if (cmp)
977 548
 		{
978
-			//maybe it is a misnamed raw save file. try loading it that way
549
+			// maybe it is a misnamed raw save file. try loading it that way
979 550
 			printf("Not a DeSmuME .dsv save file. Trying to load as raw.\n");
980
-			delete inf;
981
-			if (!load_no_gba(filename.c_str()))
982
-				load_raw(filename.c_str());
551
+			if (!this->load_no_gba(this->filename.c_str()))
552
+				this->load_raw(this->filename.c_str());
983 553
 			return;
984 554
 		}
985
-		//desmume format
555
+		// desmume format
986 556
 		inf->fseek(-cookieLen, SEEK_END);
987 557
 		inf->fseek(-4, SEEK_CUR);
988 558
 		uint32_t version = 0xFFFFFFFF;
989
-		read32le(&version,inf);
990
-		if(version!=0) {
559
+		read32le(&version, inf.get());
560
+		if (version)
561
+		{
991 562
 			printf("Unknown save file format\n");
992 563
 			return;
993 564
 		}
994 565
 		inf->fseek(-24, SEEK_CUR);
995
-		read32le(&info.size,inf);
996
-		read32le(&info.padSize,inf);
997
-		read32le(&info.type,inf);
998
-		read32le(&info.addr_size,inf);
999
-		read32le(&info.mem_size,inf);
1000
-
1001
-		//uint32_t left = 0;
1002
-		/*if (CommonSettings.autodetectBackupMethod == 1)
1003
-		{
1004
-			if (advsc.isLoaded())
1005
-			{
1006
-				info.type = advsc.getSaveType();
1007
-				if (info.type != 0xFF || info.type != 0xFE)
1008
-				{
1009
-					u32 adv_size = save_types[info.type+1][1];
1010
-					if (info.size > adv_size)
1011
-						info.size = adv_size;
1012
-					else
1013
-						if (info.size < adv_size)
1014
-						{
1015
-							left = adv_size - info.size;
1016
-							info.size = adv_size;
1017
-						}
1018
-				}
1019
-			}
1020
-		}*/
1021
-		//establish the save data
1022
-		resize(info.size);
566
+		read32le(&this->info.size, inf.get());
567
+		read32le(&this->info.padSize, inf.get());
568
+		read32le(&this->info.type, inf.get());
569
+		read32le(&this->info.addr_size, inf.get());
570
+		read32le(&this->info.mem_size, inf.get());
571
+
572
+		// establish the save data
573
+		this->resize(this->info.size);
1023 574
 		inf->fseek(0, SEEK_SET);
1024
-		if(info.size>0)
1025
-			inf->fread(&data[0],info.size); //read all the raw data we have
1026
-		state = RUNNING;
1027
-		addr_size = info.addr_size;
1028
-		//none of the other fields are used right now
1029
-
1030
-		/*if (CommonSettings.autodetectBackupMethod != 1 && info.type == 0)
1031
-		{
1032
-			info.type = searchFileSaveType(info.size);
1033
-			if (info.type == 0xFF) info.type = 0;
1034
-		}
1035
-		uint32_t ss = info.size * 8 / 1024;
1036
-		if (ss >= 1024)
1037
-		{
1038
-			ss /= 1024;
1039
-			printf("Backup size: %i Mbit\n", ss);
1040
-		}
1041
-		else
1042
-			printf("Backup size: %i Kbit\n", ss);*/
1043
-
1044
-		delete inf;
575
+		if (this->info.size > 0)
576
+			inf->fread(&this->data[0], this->info.size); // read all the raw data we have
577
+		this->state = RUNNING;
578
+		this->addr_size = this->info.addr_size;
579
+		// none of the other fields are used right now
1045 580
 	}
1046 581
 }
1047 582
 
1048
-/*bool BackupDevice::save_raw(const char* fn)
583
+void BackupDevice::raw_applyUserSettings(uint32_t &size, bool manual)
1049 584
 {
1050
-	FILE* outf = fopen(fn,"wb");
1051
-	if(!outf) return false;
1052
-	uint32_t size = data.size();
1053
-	uint32_t padSize = pad_up_size(size);
1054
-	if(data.size()>0)
1055
-		fwrite(&data[0],1,size,outf);
1056
-	for(uint32_t i=size;i<padSize;i++)
1057
-		fputc(kUninitializedSaveDataValue,outf);
1058
-	fclose(outf);
1059
-	return true;
1060
-}*/
1061
-
1062
-/*uint32_t BackupDevice::pad_up_size(uint32_t startSize)
1063
-{
1064
-	uint32_t size = startSize;
1065
-	uint32_t ctr=0;
1066
-	while(ctr<saveSizes_count && size > saveSizes[ctr]) ctr++;
1067
-	uint32_t padSize = saveSizes[ctr];
1068
-	if(padSize == 0xFFFFFFFF)
1069
-	{
1070
-		printf("PANIC! Couldn't pad up save size. Refusing to pad.\n");
1071
-		padSize = startSize;
1072
-	}
1073
-		return padSize;
1074
-}*/
1075
-
1076
-/*void BackupDevice::lazy_flush()
1077
-{
1078
-	if(flushPending || lazyFlushPending)
585
+	// respect the user's choice of backup memory type
586
+	if (CommonSettings.manualBackupType == MC_TYPE_AUTODETECT && !manual)
1079 587
 	{
1080
-		lazyFlushPending = flushPending = false;
1081
-		//flush();
1082
-	}
1083
-}*/
1084
-
1085
-/*void BackupDevice::flush()
1086
-{
1087
-	//never use save files if we are in movie mode
1088
-	if(isMovieMode) return;
1089
-
1090
-	EMUFILE* outf = new EMUFILE_FILE(filename.c_str(),"wb");
1091
-	if(!outf->fail())
1092
-	{
1093
-		if(data.size()>0)
1094
-			outf->fwrite(&data[0],data.size());
1095
-
1096
-		//write the footer. we use a footer so that we can maximize the chance of the
1097
-		//save file being recognized as a raw save file by other emulators etc.
1098
-
1099
-		//first, pad up to the next largest known save size.
1100
-		uint32_t size = data.size();
1101
-		uint32_t padSize = pad_up_size(size);
1102
-
1103
-		for(uint32_t i=size;i<padSize;i++)
1104
-			outf->fputc(kUninitializedSaveDataValue);
1105
-
1106
-		//this is just for humans to read
1107
-		outf->fprintf("|<--Snip above here to create a raw sav by excluding this DeSmuME savedata footer:");
1108
-
1109
-		//and now the actual footer
1110
-		write32le(size,outf); //the size of data that has actually been written
1111
-		write32le(padSize,outf); //the size we padded it to
1112
-		write32le(0,outf); //save memory type
1113
-		write32le(addr_size,outf);
1114
-		write32le(0,outf); //save memory size
1115
-		write32le(0,outf); //version number
1116
-		outf->fprintf("%s", kDesmumeSaveCookie); //this is what we'll use to recognize the desmume format save
1117
-
1118
-		delete outf;
1119
-	}
1120
-	else
1121
-	{
1122
-		delete outf;
1123
-		printf("Unable to open savefile %s\n",filename.c_str());
1124
-	}
1125
-}*/
1126
-
1127
-void BackupDevice::raw_applyUserSettings(uint32_t& size, bool manual)
1128
-{
1129
-	//respect the user's choice of backup memory type
1130
-	if(CommonSettings.manualBackupType == MC_TYPE_AUTODETECT && !manual)
1131
-	{
1132
-		addr_size = addr_size_for_old_save_size(size);
1133
-		resize(size);
588
+		this->addr_size = this->addr_size_for_old_save_size(size);
589
+		this->resize(size);
1134 590
 	}
1135 591
 	else
1136 592
 	{
1137 593
 		uint32_t type = CommonSettings.manualBackupType;
1138
-		/*if (manual)
1139
-		{
1140
-			uint32_t res = searchFileSaveType(size);
1141
-			if (res != 0xFF) type = (res + 1); // +1 - skip autodetect
1142
-		}*/
1143
-		int savetype = save_types[type][0];
1144
-		int savesize = save_types[type][1];
1145
-		addr_size = addr_size_for_old_save_type(savetype);
1146
-		if((uint32_t)savesize<size) size = savesize;
1147
-		resize(savesize);
594
+		int savetype = save_types[type].media_type;
595
+		int savesize = save_types[type].size;
596
+		this->addr_size = this->addr_size_for_old_save_type(savetype);
597
+		if (static_cast<uint32_t>(savesize) < size)
598
+			size = savesize;
599
+		this->resize(savesize);
1148 600
 	}
1149 601
 
1150
-	state = RUNNING;
602
+	this->state = RUNNING;
1151 603
 }
1152 604
 
1153
-/*uint32_t BackupDevice::get_save_raw_size(const char* fname)
605
+bool BackupDevice::load_raw(const char *fn, uint32_t force_size)
1154 606
 {
1155
-	FILE* inf = fopen(fname,"rb");
1156
-	if (!inf) return 0xFFFFFFFF;
607
+	FILE *inf = fopen(fn,"rb");
1157 608
 
1158
-	fseek(inf, 0, SEEK_END);
1159
-	uint32_t size = (uint32_t)ftell(inf);
1160
-	fclose(inf);
1161
-	return size;
1162
-}*/
1163
-
1164
-bool BackupDevice::load_raw(const char* fn, uint32_t force_size)
1165
-{
1166
-	FILE* inf = fopen(fn,"rb");
1167
-
1168
-	if (!inf) return false;
609
+	if (!inf)
610
+		return false;
1169 611
 
1170 612
 	fseek(inf, 0, SEEK_END);
1171
-	uint32_t size = (uint32_t)ftell(inf);
613
+	uint32_t size = static_cast<uint32_t>(ftell(inf));
1172 614
 	uint32_t left = 0;
1173 615
 
1174 616
 	if (force_size > 0)
... ...
@@ -1184,97 +626,10 @@ bool BackupDevice::load_raw(const char* fn, uint32_t force_size)
1184 626
 
1185 627
 	fseek(inf, 0, SEEK_SET);
1186 628
 
1187
-	raw_applyUserSettings(size, force_size > 0);
629
+	this->raw_applyUserSettings(size, force_size > 0);
1188 630
 
1189
-	fread(&data[0],1,size - left,inf);
631
+	fread(&this->data[0], 1, size - left, inf);
1190 632
 	fclose(inf);
1191 633
 
1192
-	//dump back out as a dsv, just to keep things sane
1193
-	//flush();
1194
-
1195 634
 	return true;
1196 635
 }
1197
-
1198
-
1199
-/*bool BackupDevice::load_duc(const char* fn)
1200
-{
1201
-  uint32_t size;
1202
-   char id[16];
1203
-   FILE* file = fopen(fn, "rb");
1204
-   if(file == NULL)
1205
-      return false;
1206
-
1207
-   fseek(file, 0, SEEK_END);
1208
-   size = (uint32_t)ftell(file) - 500;
1209
-   fseek(file, 0, SEEK_SET);
1210
-
1211
-   // Make sure we really have the right file
1212
-   fread((void *)id, sizeof(char), 16, file);
1213
-
1214
-   if (memcmp(id, "ARDS000000000001", 16) != 0)
1215
-   {
1216
-	   printf("Not recognized as a valid DUC file\n");
1217
-      fclose(file);
1218
-      return false;
1219
-   }
1220
-   // Skip the rest of the header since we don't need it
1221
-   fseek(file, 500, SEEK_SET);
1222
-
1223
-   raw_applyUserSettings(size);
1224
-
1225
-   ensure((uint32_t)size);
1226
-
1227
-   fread(&data[0],1,size,file);
1228
-   fclose(file);
1229
-
1230
-   //choose
1231
-
1232
-   //flush();
1233
-
1234
-   return true;
1235
-
1236
-}*/
1237
-
1238
-/*bool BackupDevice::load_movie(EMUFILE* is) {
1239
-
1240
-	const int32_t cookieLen = (int32_t)strlen(kDesmumeSaveCookie);
1241
-
1242
-	is->fseek(-cookieLen, SEEK_END);
1243
-	is->fseek(-4, SEEK_CUR);
1244
-
1245
-	uint32_t version = 0xFFFFFFFF;
1246
-	is->fread((char*)&version,4);
1247
-	if(version!=0) {
1248
-		printf("Unknown save file format\n");
1249
-		return false;
1250
-	}
1251
-	is->fseek(-24, SEEK_CUR);
1252
-
1253
-	struct{
1254
-		uint32_t size,padSize,type,addr_size,mem_size;
1255
-	}info;
1256
-
1257
-	is->fread((char*)&info.size,4);
1258
-	is->fread((char*)&info.padSize,4);
1259
-	is->fread((char*)&info.type,4);
1260
-	is->fread((char*)&info.addr_size,4);
1261
-	is->fread((char*)&info.mem_size,4);
1262
-
1263
-	//establish the save data
1264
-	data.resize(info.size);
1265
-	is->fseek(0, SEEK_SET);
1266
-	if(info.size>0)
1267
-		is->fread((char*)&data[0],info.size);
1268
-
1269
-	state = RUNNING;
1270
-	addr_size = info.addr_size;
1271
-	//none of the other fields are used right now
1272
-
1273
-	return true;
1274
-}*/
1275
-
1276
-/*void BackupDevice::forceManualBackupType()
1277
-{
1278
-	addr_size = addr_size_for_old_save_size(save_types[CommonSettings.manualBackupType][1]);
1279
-	state = RUNNING;
1280
-}*/
Browse code

Import actual code.

Naram Qashat authored on 2013/03/26 02:41:19
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,1280 @@
1
+/*
2
+	Copyright (C) 2006 thoduv
3
+	Copyright (C) 2006-2007 Theo Berkau
4
+	Copyright (C) 2008-2012 DeSmuME team
5
+
6
+	This file is free software: you can redistribute it and/or modify
7
+	it under the terms of the GNU General Public License as published by
8
+	the Free Software Foundation, either version 2 of the License, or
9
+	(at your option) any later version.
10
+
11
+	This file is distributed in the hope that it will be useful,
12
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+	GNU General Public License for more details.
15
+
16
+	You should have received a copy of the GNU General Public License
17
+	along with the this software.  If not, see <http://www.gnu.org/licenses/>.
18
+*/
19
+
20
+#include <cstdlib>
21
+#include <cstring>
22
+
23
+//#include "debug.h"
24
+#include "types.h"
25
+#include "mc.h"
26
+//#include "movie.h"
27
+#include "readwrite.h"
28
+#include "NDSSystem.h"
29
+
30
+#define FW_CMD_READ             0x03
31
+#define FW_CMD_WRITEDISABLE     0x04
32
+#define FW_CMD_READSTATUS       0x05
33
+#define FW_CMD_WRITEENABLE      0x06
34
+#define FW_CMD_PAGEWRITE        0x0A
35
+#define FW_CMD_READ_ID			0x9F
36
+
37
+#define BM_CMD_AUTODETECT       0xFF
38
+#define BM_CMD_WRITESTATUS      0x01
39
+#define BM_CMD_WRITELOW         0x02
40
+#define BM_CMD_READLOW          0x03
41
+#define BM_CMD_WRITEDISABLE     0x04
42
+#define BM_CMD_READSTATUS       0x05
43
+#define BM_CMD_WRITEENABLE      0x06
44
+#define BM_CMD_WRITEHIGH        0x0A
45
+#define BM_CMD_READHIGH         0x0B
46
+
47
+/* FLASH*/
48
+#define COMM_PAGE_WRITE		0x0A
49
+#define COMM_PAGE_ERASE		0xDB
50
+#define COMM_SECTOR_ERASE	0xD8
51
+#define COMM_CHIP_ERASE		0xC7
52
+#define CARDFLASH_READ_BYTES_FAST	0x0B    /* Not used*/
53
+#define CARDFLASH_DEEP_POWDOWN		0xB9    /* Not used*/
54
+#define CARDFLASH_WAKEUP			0xAB    /* Not used*/
55
+
56
+//since r2203 this was 0x00.
57
+//but baby pals proves finally that it should be 0xFF:
58
+//the game reads its initial sound volumes from uninitialized data, and if it is 0, the game will be silent
59
+//if it is 0xFF then the game starts with its sound and music at max, as presumably it is supposed to.
60
+//so in r3303 I finally changed it (no$ appears definitely to initialized to 0xFF)
61
+static const uint8_t kUninitializedSaveDataValue = 0xFF;
62
+
63
+static const char* kDesmumeSaveCookie = "|-DESMUME SAVE-|";
64
+
65
+static const uint32_t saveSizes[] = {512,			// 4k
66
+								8*1024,			// 64k
67
+								32*1024,		// 512k
68
+								64*1024,		// 1Mbit
69
+								256*1024,		// 2Mbit
70
+								512*1024,		// 4Mbit
71
+								1024*1024,		// 8Mbit
72
+								2048*1024,		// 16Mbit
73
+								4096*1024,		// 32Mbit
74
+								8192*1024,		// 64Mbit
75
+								16384*1024,		// 128Mbit
76
+								32768*1024,		// 256Mbit
77
+								65536*1024,		// 512Mbit
78
+								0xFFFFFFFF};
79
+static const uint32_t saveSizes_count = ARRAY_SIZE(saveSizes);
80
+
81
+//the lookup table from user save types to save parameters
82
+const int save_types[][2] = {
83
+        {MC_TYPE_AUTODETECT,1},
84
+        {MC_TYPE_EEPROM1,MC_SIZE_4KBITS},
85
+        {MC_TYPE_EEPROM2,MC_SIZE_64KBITS},
86
+        {MC_TYPE_EEPROM2,MC_SIZE_512KBITS},
87
+        {MC_TYPE_FRAM,MC_SIZE_256KBITS},
88
+        {MC_TYPE_FLASH,MC_SIZE_2MBITS},
89
+		{MC_TYPE_FLASH,MC_SIZE_4MBITS},
90
+		{MC_TYPE_FLASH,MC_SIZE_8MBITS},
91
+		{MC_TYPE_FLASH,MC_SIZE_16MBITS},
92
+		{MC_TYPE_FLASH,MC_SIZE_32MBITS},
93
+		{MC_TYPE_FLASH,MC_SIZE_64MBITS},
94
+		{MC_TYPE_FLASH,MC_SIZE_128MBITS},
95
+		{MC_TYPE_FLASH,MC_SIZE_256MBITS},
96
+		{MC_TYPE_FLASH,MC_SIZE_512MBITS}
97
+};
98
+
99
+/*const char *save_names[] = {
100
+		"EEPROM 4kbit",
101
+		"EEPROM 64kbit",
102
+		"EEPROM 512kbit",
103
+		"FRAM 256kbit",
104
+		"FLASH 2Mbit",
105
+		"FLASH 4Mbit",
106
+		"FLASH 8Mbit",
107
+		"FLASH 16Mbit",
108
+		"FLASH 32Mbit",
109
+		"FLASH 64Mbit",
110
+		"FLASH 128Mbit",
111
+		"FLASH 256Mbit",
112
+		"FLASH 512Mbit"
113
+};*/
114
+
115
+//forces the currently selected backup type to be current
116
+//(can possibly be used to repair poorly chosen save types discovered late in gameplay i.e. pokemon gamers)
117
+/*void backup_forceManualBackupType()
118
+{
119
+	MMU_new.backupDevice.forceManualBackupType();
120
+}*/
121
+
122
+/*void backup_setManualBackupType(int type)
123
+{
124
+	CommonSettings.manualBackupType = type;
125
+}*/
126
+
127
+void mc_init(memory_chip_t *mc, int type)
128
+{
129
+        mc->com = 0;
130
+        mc->addr = 0;
131
+        mc->addr_shift = 0;
132
+        mc->data.clear();
133
+        mc->size = 0;
134
+        mc->write_enable = false;
135
+        mc->writeable_buffer = false;
136
+        mc->type = type;
137
+        mc->autodetectsize = 0;
138
+
139
+        switch(mc->type)
140
+        {
141
+           case MC_TYPE_EEPROM1:
142
+              mc->addr_size = 1;
143
+              break;
144
+           case MC_TYPE_EEPROM2:
145
+           case MC_TYPE_FRAM:
146
+              mc->addr_size = 2;
147
+              break;
148
+           case MC_TYPE_FLASH:
149
+              mc->addr_size = 3;
150
+              break;
151
+           default: break;
152
+        }
153
+}
154
+
155
+uint8_t *mc_alloc(memory_chip_t *mc, uint32_t size)
156
+{
157
+	/*uint8_t *buffer;
158
+	buffer = new uint8_t[size];
159
+	memset(buffer,0,size);*/
160
+
161
+	//if (mc->data) delete [] mc->data;
162
+	mc->data.clear();
163
+	//mc->data = buffer;
164
+	//if(!buffer) { return NULL; }
165
+	mc->data.resize(size, 0);
166
+	mc->size = size;
167
+	mc->writeable_buffer = true;
168
+
169
+	//return buffer;
170
+	return NULL;
171
+}
172
+
173
+void mc_free(memory_chip_t *mc)
174
+{
175
+    //if(mc->data) delete[] mc->data;
176
+	mc->data.clear();
177
+    mc_init(mc, 0);
178
+}
179
+
180
+void fw_reset_com(memory_chip_t *mc)
181
+{
182
+	if(mc->com == FW_CMD_PAGEWRITE)
183
+	{
184
+		if (mc->fp)
185
+		{
186
+			fseek(mc->fp, 0, SEEK_SET);
187
+			fwrite(&mc->data[0], mc->size, 1, mc->fp);
188
+		}
189
+
190
+		if (mc->isFirmware&&CommonSettings.UseExtFirmware)
191
+		{
192
+			// copy User Settings 1 to User Settings 0 area
193
+			memcpy(&mc->data[0x3FE00], &mc->data[0x3FF00], 0x100);
194
+
195
+			printf("Firmware: save config");
196
+			FILE *fp = fopen(mc->userfile, "wb");
197
+			if (fp)
198
+			{
199
+				if (fwrite(&mc->data[0x3FF00], 1, 0x100, fp) == 0x100)		// User Settings
200
+				{
201
+					if (fwrite(&mc->data[0x0002A], 1, 0x1D6, fp) == 0x1D6)  // WiFi Settings
202
+					{
203
+						if (fwrite(&mc->data[0x3FA00], 1, 0x300, fp) == 0x300)  // WiFi AP Settings
204
+							printf(" - done\n");
205
+						else
206
+							printf(" - failed\n");
207
+					}
208
+				}
209
+				fclose(fp);
210
+			}
211
+			else
212
+				printf(" - failed\n");
213
+		}
214
+
215
+		mc->write_enable = false;
216
+	}
217
+
218
+	mc->com = 0;
219
+}
220
+
221
+uint8_t fw_transfer(memory_chip_t *mc, uint8_t data)
222
+{
223
+	if(mc->com == FW_CMD_READ || mc->com == FW_CMD_PAGEWRITE) /* check if we are in a command that needs 3 bytes address */
224
+	{
225
+		if(mc->addr_shift > 0)   /* if we got a complete address */
226
+		{
227
+			mc->addr_shift--;
228
+			mc->addr |= data << (mc->addr_shift * 8); /* argument is a byte of address */
229
+		}
230
+		else    /* if we have received 3 bytes of address, proceed command */
231
+		{
232
+			switch(mc->com)
233
+			{
234
+				case FW_CMD_READ:
235
+					if(mc->addr < mc->size)  /* check if we can read */
236
+					{
237
+						data = mc->data[mc->addr];       /* return byte */
238
+						mc->addr++;      /* then increment address */
239
+					}
240
+					break;
241
+
242
+				case FW_CMD_PAGEWRITE:
243
+					if(mc->addr < mc->size)
244
+					{
245
+						mc->data[mc->addr] = data;       /* write byte */
246
+						mc->addr++;
247
+					}
248
+					break;
249
+			}
250
+
251
+		}
252
+	}
253
+	else if(mc->com == FW_CMD_READ_ID)
254
+	{
255
+		switch(mc->addr)
256
+		{
257
+		//here is an ID string measured from an old ds fat: 62 16 00 (0x62=sanyo)
258
+		//but we chose to use an ST from martin's ds fat string so programs might have a clue as to the firmware size:
259
+		//20 40 12
260
+		case 0:
261
+			data = 0x20;
262
+			mc->addr=1;
263
+			break;
264
+		case 1:
265
+			data = 0x40; //according to gbatek this is the device ID for the flash on someone's ds fat
266
+			mc->addr=2;
267
+			break;
268
+		case 2:
269
+			data = 0x12;
270
+			mc->addr = 0;
271
+			break;
272
+		}
273
+	}
274
+	else if(mc->com == FW_CMD_READSTATUS)
275
+	{
276
+		return mc->write_enable ? 0x02 : 0x00;
277
+	}
278
+	else	//finally, check if it's a new command
279
+	{
280
+		switch(data)
281
+		{
282
+			case 0: break;	//nothing
283
+
284
+			case FW_CMD_READ_ID:
285
+				mc->addr = 0;
286
+				mc->com = FW_CMD_READ_ID;
287
+				break;
288
+
289
+			case FW_CMD_READ:    //read command
290
+				mc->addr = 0;
291
+				mc->addr_shift = 3;
292
+				mc->com = FW_CMD_READ;
293
+				break;
294
+
295
+			case FW_CMD_WRITEENABLE:     //enable writing
296
+				if(mc->writeable_buffer) { mc->write_enable = true; }
297
+				break;
298
+
299
+			case FW_CMD_WRITEDISABLE:    //disable writing
300
+
301
+				mc->write_enable = false;
302
+				break;
303
+
304
+			case FW_CMD_PAGEWRITE:       //write command
305
+				if(mc->write_enable)
306
+				{
307
+					mc->addr = 0;
308
+					mc->addr_shift = 3;
309
+					mc->com = FW_CMD_PAGEWRITE;
310
+				}
311
+				else { data = 0; }
312
+				break;
313
+
314
+			case FW_CMD_READSTATUS:  //status register command
315
+				mc->com = FW_CMD_READSTATUS;
316
+				break;
317
+
318
+			default:
319
+				printf("Unhandled FW command: %02X\n", data);
320
+				break;
321
+		}
322
+	}
323
+
324
+	return data;
325
+}
326
+
327
+/*bool BackupDevice::save_state(EMUFILE* os)
328
+{
329
+	uint32_t version = 2;
330
+	//v0
331
+	write32le(version,os);
332
+	write32le(write_enable,os);
333
+	write32le(com,os);
334
+	write32le(addr_size,os);
335
+	write32le(addr_counter,os);
336
+	write32le((uint32_t)state,os);
337
+	writebuffer(data,os);
338
+	writebuffer(data_autodetect,os);
339
+	//v1
340
+	write32le(addr,os);
341
+	//v2
342
+	write8le(motionInitState,os);
343
+	write8le(motionFlag,os);
344
+	return true;
345
+}*/
346
+
347
+bool BackupDevice::load_state(EMUFILE* is)
348
+{
349
+	uint32_t version;
350
+	if(read32le(&version,is)!=1) return false;
351
+	//if(version>=0)
352
+	{
353
+		readbool(&write_enable,is);
354
+		read32le(&com,is);
355
+		read32le(&addr_size,is);
356
+		read32le(&addr_counter,is);
357
+		uint32_t temp;
358
+		read32le(&temp,is);
359
+		state = (STATE)temp;
360
+		readbuffer(data,is);
361
+		readbuffer(data_autodetect,is);
362
+	}
363
+	if(version>=1)
364
+		read32le(&addr,is);
365
+	if(version>=2)
366
+	{
367
+		read8le(&motionInitState,is);
368
+		read8le(&motionFlag,is);
369
+	}
370
+
371
+	return true;
372
+}
373
+
374
+BackupDevice::BackupDevice()
375
+{
376
+	//isMovieMode = false;
377
+	reset();
378
+}
379
+
380
+//due to unfortunate shortcomings in the emulator architecture,
381
+//at reset-time, we won't have a filename to the .dsv file.
382
+//so the only difference between load_rom (init) and reset is that
383
+//one of them saves the filename
384
+void BackupDevice::load_rom(const char* fn)
385
+{
386
+	//isMovieMode = false;
387
+	this->filename = fn;
388
+	reset();
389
+}
390
+
391
+/*void BackupDevice::movie_mode()
392
+{
393
+	isMovieMode = true;
394
+	reset();
395
+}*/
396
+
397
+void BackupDevice::reset_hardware()
398
+{
399
+	write_enable = false;
400
+	com = 0;
401
+	addr = addr_counter = 0;
402
+	motionInitState = MOTION_INIT_STATE_IDLE;
403
+	motionFlag = MOTION_FLAG_NONE;
404
+	state = DETECTING;
405
+	flushPending = false;
406
+	lazyFlushPending = false;
407
+}
408
+
409
+void BackupDevice::reset()
410
+{
411
+	memset(&info, 0, sizeof(info));
412
+	reset_hardware();
413
+	resize(0);
414
+	data_autodetect.resize(0);
415
+	addr_size = 0;
416
+	loadfile();
417
+
418
+	//if the user has requested a manual choice for backup type, and we havent imported a raw save file, then apply it now
419
+	if(state == DETECTING && CommonSettings.manualBackupType != MC_TYPE_AUTODETECT)
420
+	{
421
+		state = RUNNING;
422
+		int savetype = save_types[CommonSettings.manualBackupType][0];
423
+		int savesize = save_types[CommonSettings.manualBackupType][1];
424
+		ensure((uint32_t)savesize); //expand properly if necessary
425
+		resize(savesize); //truncate if necessary
426
+		addr_size = addr_size_for_old_save_type(savetype);
427
+		//flush();
428
+	}
429
+}
430
+
431
+/*void BackupDevice::close_rom()
432
+{
433
+	//flush();
434
+}*/
435
+
436
+/*void BackupDevice::reset_command()
437
+{
438
+	//printf("MC RESET\n");
439
+	//for a performance hack, save files are only flushed after each reset command
440
+	//(hopefully, after each page)
441
+	if(flushPending)
442
+	{
443
+		//flush();
444
+		flushPending = false;
445
+		lazyFlushPending = false;
446
+	}
447
+
448
+	if(state == DETECTING && data_autodetect.size()>0)
449
+	{
450
+		//we can now safely detect the save address size
451
+		uint32_t autodetect_size = data_autodetect.size();
452
+
453
+		printf("Autodetecting with autodetect_size=%d\n",autodetect_size);
454
+
455
+		const uint8_t sm64_sig[] = {0x01,0x80,0x00,0x00};
456
+		if(autodetect_size == 4 && !memcmp(&data_autodetect[0],sm64_sig,4))
457
+		{
458
+			addr_size = 2;
459
+		}
460
+		else //detect based on rules
461
+			switch(autodetect_size)
462
+			{
463
+			case 0:
464
+			case 1:
465
+				printf("Catastrophic error while autodetecting save type.\nIt will need to be specified manually\n");
466
+				#ifdef _WINDOWS
467
+				MessageBoxA(0,"Catastrophic Error Code: Camel;\nyour save type has not been autodetected correctly;\nplease report to developers",0,0);
468
+				#endif
469
+				addr_size = 1; //choose 1 just to keep the busted savefile from growing too big
470
+				break;
471
+			case 2:
472
+				 //the modern typical case for small eeproms
473
+				addr_size = 1;
474
+				break;
475
+			case 3:
476
+				//another modern typical case..
477
+				//but unfortunately we select this case for spider-man 3, when what it meant to do was
478
+				//present the archaic 1+2 case
479
+				//it seems that over the hedge does this also.
480
+				addr_size = 2;
481
+				break;
482
+			case 4:
483
+				//a modern typical case
484
+				addr_size = 3;
485
+				break;
486
+			default:
487
+				//the archaic case: write the address and then some modulo-4 number of bytes
488
+				//why modulo 4? who knows.
489
+				addr_size = autodetect_size & 3;
490
+				break;
491
+			}
492
+
493
+		state = RUNNING;
494
+		data_autodetect.resize(0);
495
+		//flush();
496
+	}
497
+
498
+	com = 0;
499
+}*/
500
+/*uint8_t BackupDevice::data_command(uint8_t val, int cpu)
501
+{
502
+	//printf("MC CMD: %02X\n",val);
503
+
504
+	//motion: some guessing here... hope it doesn't break anything
505
+	if(com == BM_CMD_READLOW && motionInitState == MOTION_INIT_STATE_RECEIVED_4_B && val == 0)
506
+	{
507
+		motionInitState = MOTION_INIT_STATE_IDLE;
508
+		motionFlag |= MOTION_FLAG_ENABLED;
509
+		//return 0x04; //return 0x04 to enable motion!!!!!
510
+		return 0; //but we return 0 to disable it! since we don't emulate it anyway
511
+	}
512
+
513
+	//if the game firmly believes we have motion support, then ignore all motion commands, since theyre not emulated.
514
+	if(motionFlag & MOTION_FLAG_SENSORMODE)
515
+	{
516
+		return 0;
517
+	}
518
+
519
+	if(com == BM_CMD_READLOW || com == BM_CMD_WRITELOW)
520
+	{
521
+		//handle data or address
522
+		if(state == DETECTING)
523
+		{
524
+			if(com == BM_CMD_WRITELOW)
525
+			{
526
+				printf("Unexpected backup device initialization sequence using writes!\n");
527
+			}
528
+
529
+			//just buffer the data until we're no longer detecting
530
+			data_autodetect.push_back(val);
531
+			val = 0;
532
+		}
533
+		else
534
+		{
535
+			if(addr_counter<addr_size)
536
+			{
537
+				//continue building address
538
+				addr <<= 8;
539
+				addr |= val;
540
+				addr_counter++;
541
+				//if(addr_counter==addr_size) printf("ADR: %08X\n",addr);
542
+			}
543
+			else
544
+			{
545
+				//why does tomb raider underworld access 0x180 and go clear through to 0x280?
546
+				//should this wrap around at 0 or at 0x100?
547
+				if(addr_size == 1) addr &= 0x1FF;
548
+
549
+				//address is complete
550
+				ensure(addr+1);
551
+				if(com == BM_CMD_READLOW)
552
+				{
553
+					//printf("READ ADR: %08X\n",addr);
554
+					val = data[addr];
555
+					//flushPending = true; //is this a good idea? it may slow stuff down, but it is helpful for debugging
556
+					lazyFlushPending = true; //lets do this instead
557
+					//printf("read: %08X\n",addr);
558
+				}
559
+				else
560
+				{
561
+					if(write_enable)
562
+					{
563
+						//printf("WRITE ADR: %08X\n",addr);
564
+						data[addr] = val;
565
+						flushPending = true;
566
+						//printf("writ: %08X\n",addr);
567
+					}
568
+				}
569
+				addr++;
570
+
571
+			}
572
+		}
573
+	}
574
+	else if(com == BM_CMD_READSTATUS)
575
+	{
576
+		//handle request to read status
577
+		//LOG("Backup Memory Read Status: %02X\n", write_enable << 1);
578
+		return (write_enable << 1) | (3<<2);
579
+	}
580
+	else
581
+	{
582
+		//there is no current command. receive one
583
+		switch(val)
584
+		{
585
+			case 0: break; //??
586
+
587
+			case 0xFE:
588
+				if(motionInitState == MOTION_INIT_STATE_IDLE) { motionInitState = MOTION_INIT_STATE_FE; return 0; }
589
+				break;
590
+			case 0xFD:
591
+				if(motionInitState == MOTION_INIT_STATE_FE) { motionInitState = MOTION_INIT_STATE_FD; return 0; }
592
+				break;
593
+			case 0xFB:
594
+				if(motionInitState == MOTION_INIT_STATE_FD) { motionInitState = MOTION_INIT_STATE_FB; return 0; }
595
+				break;
596
+			case 0xF8:
597
+				//enable sensor mode
598
+				if(motionInitState == MOTION_INIT_STATE_FD)
599
+				{
600
+					motionInitState = MOTION_INIT_STATE_IDLE;
601
+					motionFlag |= MOTION_FLAG_SENSORMODE;
602
+					return 0;
603
+				}
604
+				break;
605
+			case 0xF9:
606
+				//disable sensor mode
607
+				if(motionInitState == MOTION_INIT_STATE_FD)
608
+				{
609
+					motionInitState = MOTION_INIT_STATE_IDLE;
610
+					motionFlag &= ~MOTION_FLAG_SENSORMODE;
611
+					return 0;
612
+				}
613
+				break;
614
+
615
+			case 8:
616
+				printf("COMMAND%c: Unverified Backup Memory command: %02X FROM %08X\n",(cpu==ARMCPU_ARM9)?'9':'7',val, (cpu==ARMCPU_ARM9)?NDS_ARM9.instruct_adr:NDS_ARM7.instruct_adr);
617
+				val = 0xAA;
618
+				break;
619
+
620
+			case BM_CMD_WRITEDISABLE:
621
+				switch(motionInitState)
622
+				{
623
+				case MOTION_INIT_STATE_IDLE: motionInitState = MOTION_INIT_STATE_RECEIVED_4; break;
624
+				case MOTION_INIT_STATE_RECEIVED_4: motionInitState = MOTION_INIT_STATE_RECEIVED_4_B; break;
625
+				}
626
+				write_enable = false;
627
+				break;
628
+
629
+			case BM_CMD_READSTATUS:
630
+				com = BM_CMD_READSTATUS;
631
+				val = (write_enable << 1) | (3<<2);
632
+				break;
633
+
634
+			case BM_CMD_WRITEENABLE:
635
+				write_enable = true;
636
+				break;
637
+
638
+			case BM_CMD_WRITELOW:
639
+			case BM_CMD_READLOW:
640
+				//printf("XLO: %08X\n",addr);
641
+				com = val;
642
+				addr_counter = 0;
643
+				addr = 0;
644
+				break;
645
+
646
+			case BM_CMD_WRITEHIGH:
647
+			case BM_CMD_READHIGH:
648
+				//printf("XHI: %08X\n",addr);
649
+				if(val == BM_CMD_WRITEHIGH) val = BM_CMD_WRITELOW;
650
+				if(val == BM_CMD_READHIGH) val = BM_CMD_READLOW;
651
+				com = val;
652
+				addr_counter = 0;
653
+				addr = 0;
654
+				if(addr_size==1) {
655
+					//"write command that's only available on ST M95040-W that I know of"
656
+					//this makes sense, since this device would only have a 256 bytes address space with writelow
657
+					//and writehigh would allow access to the upper 256 bytes
658
+					//but it was detected in pokemon diamond also during the main save process
659
+					addr = 0x1;
660
+				}
661
+				break;
662
+
663
+			default:
664
+				printf("COMMAND%c: Unhandled Backup Memory command: %02X FROM %08X\n",(cpu==ARMCPU_ARM9)?'9':'7',val, (cpu==ARMCPU_ARM9)?NDS_ARM9.instruct_adr:NDS_ARM7.instruct_adr);
665
+				break;
666
+		} //switch(val)
667
+
668
+		//motion control state machine broke, return to ground
669
+		motionInitState = MOTION_INIT_STATE_IDLE;
670
+	}
671
+	return val;
672
+}*/
673
+
674
+//guarantees that the data buffer has room enough for the specified number of bytes
675
+void BackupDevice::ensure(uint32_t Addr)
676
+{
677
+	uint32_t size = data.size();
678
+	if(size<Addr)
679
+	{
680
+		resize(Addr);
681
+	}
682
+}
683
+
684
+void BackupDevice::resize(uint32_t size)
685
+{
686
+	size_t old_size = data.size();
687
+	data.resize(size);
688
+	for(uint32_t i=old_size;i<size;i++)
689
+		data[i] = kUninitializedSaveDataValue;
690
+}
691
+
692
+uint32_t BackupDevice::addr_size_for_old_save_size(int bupmem_size)
693
+{
694
+	switch(bupmem_size) {
695
+		case MC_SIZE_4KBITS:
696
+			return 1;
697
+		case MC_SIZE_64KBITS:
698
+		case MC_SIZE_256KBITS:
699
+		case MC_SIZE_512KBITS:
700
+			return 2;
701
+		case MC_SIZE_1MBITS:
702
+		case MC_SIZE_2MBITS:
703
+		case MC_SIZE_4MBITS:
704
+		case MC_SIZE_8MBITS:
705
+		case MC_SIZE_16MBITS:
706
+		case MC_SIZE_64MBITS:
707
+			return 3;
708
+		default:
709
+			return 0xFFFFFFFF;
710
+	}
711
+}
712
+
713
+uint32_t BackupDevice::addr_size_for_old_save_type(int bupmem_type)
714
+{
715
+	switch(bupmem_type)
716
+	{
717
+		case MC_TYPE_EEPROM1:
718
+			return 1;
719
+		case MC_TYPE_EEPROM2:
720
+		case MC_TYPE_FRAM:
721
+              return 2;
722
+		case MC_TYPE_FLASH:
723
+			return 3;
724
+		default:
725
+			return 0xFFFFFFFF;
726
+	}
727
+}
728
+
729
+
730
+void BackupDevice::load_old_state(uint32_t addrSize, uint8_t* Data, uint32_t datasize)
731
+{
732
+	state = RUNNING;
733
+	this->addr_size = addrSize;
734
+	resize(datasize);
735
+	memcpy(&this->data[0],Data,datasize);
736
+
737
+	//dump back out as a dsv, just to keep things sane
738
+	//flush();
739
+}
740
+
741
+//======================================================================= no$GBA
742
+//=======================================================================
743
+//=======================================================================
744
+
745
+static int no_gba_unpackSAV(void *in_buf, uint32_t fsize, void *out_buf, uint32_t &size)
746
+{
747
+	const char no_GBA_HEADER_ID[] = "NocashGbaBackupMediaSavDataFile";
748
+	const char no_GBA_HEADER_SRAM_ID[] = "SRAM";
749
+	uint8_t	*src = (uint8_t *)in_buf;
750
+	uint8_t	*dst = (uint8_t *)out_buf;
751
+	uint32_t src_pos = 0;
752
+	uint32_t dst_pos = 0;
753
+	uint8_t	cc = 0;
754
+	uint32_t	size_unpacked = 0;
755
+	//uint32_t	size_packed = 0;
756
+	uint32_t	compressMethod = 0;
757
+
758
+	if (fsize < 0x50) return 1;
759
+
760
+	for (int i = 0; i < 0x1F; i++)
761
+	{
762
+		if (src[i] != no_GBA_HEADER_ID[i]) return 2;
763
+	}
764
+	if (src[0x1F] != 0x1A) return 2;
765
+	for (int i = 0; i < 0x4; i++)
766
+	{
767
+		if (src[i+0x40] != no_GBA_HEADER_SRAM_ID[i]) return 2;
768
+	}
769
+
770
+	compressMethod = *((uint32_t*)(src+0x44));
771
+
772
+	if (compressMethod == 0)				// unpacked
773
+	{
774
+		size_unpacked = *((uint32_t*)(src+0x48));
775
+		src_pos = 0x4C;
776
+		for (uint32_t i = 0; i < size_unpacked; i++)
777
+		{
778
+			dst[dst_pos++] = src[src_pos++];
779
+		}
780
+		size = dst_pos;
781
+		return 0;
782
+	}
783
+
784
+	if (compressMethod == 1)				// packed (method 1)
785
+	{
786
+		//size_packed = *((uint32_t*)(src+0x48));
787
+		size_unpacked = *((uint32_t*)(src+0x4C));
788
+
789
+		src_pos = 0x50;
790
+		while (true)
791
+		{
792
+			cc = src[src_pos++];
793
+
794
+			if (cc == 0)
795
+			{
796
+				size = dst_pos;
797
+				return 0;
798
+			}
799
+
800
+			if (cc == 0x80)
801
+			{
802
+				uint16_t tsize = *((uint16_t*)(src+src_pos+1));
803
+				for (int t = 0; t < tsize; t++)
804
+					dst[dst_pos++] = src[src_pos];
805
+				src_pos += 3;
806
+				continue;
807
+			}
808
+
809
+			if (cc > 0x80)		// repeat
810
+			{
811
+				cc -= 0x80;
812
+				for (int t = 0; t < cc; t++)
813
+					dst[dst_pos++] = src[src_pos];
814
+				src_pos++;
815
+				continue;
816
+			}
817
+			// copy
818
+			for (int t = 0; t < cc; t++)
819
+				dst[dst_pos++] = src[src_pos++];
820
+		}
821
+		size = dst_pos;
822
+		return 0;
823
+	}
824
+	return 200;
825
+}
826
+
827
+static uint32_t no_gba_savTrim(void *buf, uint32_t size)
828
+{
829
+	uint32_t rows = size / 16;
830
+	uint32_t pos = (size - 16);
831
+	uint8_t	*src = (uint8_t*)buf;
832
+
833
+	for (unsigned int i = 0; i < rows; i++, pos -= 16)
834
+	{
835
+		if (src[pos] == 0xFF)
836
+		{
837
+			for (int t = 0; t < 16; t++)
838
+			{
839
+				if (src[pos+t] != 0xFF) return pos+16;
840
+			}
841
+		}
842
+		else
843
+		{
844
+			return pos+16;
845
+		}
846
+	}
847
+	return size;
848
+}
849
+
850
+static uint32_t no_gba_fillLeft(uint32_t size)
851
+{
852
+	for (uint32_t i = 1; i < ARRAY_SIZE(save_types); i++)
853
+	{
854
+		if (size <= (uint32_t)save_types[i][1])
855
+			return size + (save_types[i][1] - size);
856
+	}
857
+	return size;
858
+}
859
+
860
+bool BackupDevice::load_no_gba(const char *fname)
861
+{
862
+	FILE	*fsrc = fopen(fname, "rb");
863
+	uint8_t		*in_buf = NULL;
864
+	uint8_t		*out_buf = NULL;
865
+
866
+	if (fsrc)
867
+	{
868
+		uint32_t fsize = 0;
869
+		fseek(fsrc, 0, SEEK_END);
870
+		fsize = ftell(fsrc);
871
+		fseek(fsrc, 0, SEEK_SET);
872
+		//printf("Open %s file (size %i bytes)\n", fname, fsize);
873
+
874
+		in_buf = new uint8_t [fsize];
875
+
876
+		if (fread(in_buf, 1, fsize, fsrc) == fsize)
877
+		{
878
+			out_buf = new uint8_t [8 * 1024 * 1024 / 8];
879
+			uint32_t size = 0;
880
+
881
+			memset(out_buf, 0xFF, 8 * 1024 * 1024 / 8);
882
+			if (no_gba_unpackSAV(in_buf, fsize, out_buf, size) == 0)
883
+			{
884
+				//printf("New size %i byte(s)\n", size);
885
+				size = no_gba_savTrim(out_buf, size);
886
+				//printf("--- new size after trim %i byte(s)\n", size);
887
+				size = no_gba_fillLeft(size);
888
+				//printf("--- new size after fill %i byte(s)\n", size);
889
+				raw_applyUserSettings(size);
890
+				data.resize(size);
891
+				for (uint32_t tt = 0; tt < size; tt++)
892
+					data[tt] = out_buf[tt];
893
+
894
+				//dump back out as a dsv, just to keep things sane
895
+				//flush();
896
+				printf("---- Loaded no$GBA save\n");
897
+
898
+				if (in_buf) delete [] in_buf;
899
+				if (out_buf) delete [] out_buf;
900
+				fclose(fsrc);
901
+				return true;
902
+			}
903
+			if (out_buf) delete [] out_buf;
904
+		}
905
+		if (in_buf) delete [] in_buf;
906
+		fclose(fsrc);
907
+	}
908
+
909
+	return false;
910
+}
911
+
912
+/*bool BackupDevice::save_no_gba(const char* fname)
913
+{
914
+	FILE* outf = fopen(fname,"wb");
915
+	if(!outf) return false;
916
+	uint32_t size = data.size();
917
+	uint32_t padSize = pad_up_size(size);
918
+	if(data.size()>0)
919
+		fwrite(&data[0],1,size,outf);
920
+	for(uint32_t i=size;i<padSize;i++)
921
+		fputc(0xFF,outf);
922
+
923
+	if (padSize < 512 * 1024)
924
+	{
925
+		for(uint32_t i=padSize; i<512 * 1024; i++)
926
+			fputc(0xFF,outf);
927
+	}
928
+	fclose(outf);
929
+	return true;
930
+}*/
931
+//======================================================================= end
932
+//=======================================================================
933
+//======================================================================= no$GBA
934
+
935
+
936
+void BackupDevice::loadfile()
937
+{
938
+	//never use save files if we are in movie mode
939
+	//if(isMovieMode) return;
940
+	if(filename.length() ==0) return; //No sense crashing if no filename supplied
941
+
942
+	EMUFILE_FILE* inf = new EMUFILE_FILE(filename.c_str(),"rb");
943
+	if(inf->fail())
944
+	{
945
+		delete inf;
946
+		//no dsv found; we need to try auto-importing a file with .sav extension
947
+		printf("DeSmuME .dsv save file not found. Trying to load an old raw .sav file.\n");
948
+
949
+		//change extension to sav
950
+		char tmp[MAX_PATH];
951
+		strcpy(tmp,filename.c_str());
952
+		tmp[strlen(tmp)-3] = 0;
953
+		strcat(tmp,"sav");
954
+
955
+		inf = new EMUFILE_FILE(tmp,"rb");
956
+		if(inf->fail())
957
+		{
958
+			delete inf;
959
+			printf("Missing save file %s\n",filename.c_str());
960
+			return;
961
+		}
962
+		delete inf;
963
+
964
+		if (!load_no_gba(tmp))
965
+			load_raw(tmp);
966
+	}
967
+	else
968
+	{
969
+		//scan for desmume save footer
970
+		const int32_t cookieLen = (int32_t)strlen(kDesmumeSaveCookie);
971
+		char *sigbuf = new char[cookieLen];
972
+		inf->fseek(-cookieLen, SEEK_END);
973
+		inf->fread(sigbuf,cookieLen);
974
+		int cmp = memcmp(sigbuf,kDesmumeSaveCookie,cookieLen);
975
+		delete[] sigbuf;
976
+		if(cmp)
977
+		{
978
+			//maybe it is a misnamed raw save file. try loading it that way
979
+			printf("Not a DeSmuME .dsv save file. Trying to load as raw.\n");
980
+			delete inf;
981
+			if (!load_no_gba(filename.c_str()))
982
+				load_raw(filename.c_str());
983
+			return;
984
+		}
985
+		//desmume format
986
+		inf->fseek(-cookieLen, SEEK_END);
987
+		inf->fseek(-4, SEEK_CUR);
988
+		uint32_t version = 0xFFFFFFFF;
989
+		read32le(&version,inf);
990
+		if(version!=0) {
991
+			printf("Unknown save file format\n");
992
+			return;
993
+		}
994
+		inf->fseek(-24, SEEK_CUR);
995
+		read32le(&info.size,inf);
996
+		read32le(&info.padSize,inf);
997
+		read32le(&info.type,inf);
998
+		read32le(&info.addr_size,inf);
999
+		read32le(&info.mem_size,inf);
1000
+
1001
+		//uint32_t left = 0;
1002
+		/*if (CommonSettings.autodetectBackupMethod == 1)
1003
+		{
1004
+			if (advsc.isLoaded())
1005
+			{
1006
+				info.type = advsc.getSaveType();
1007
+				if (info.type != 0xFF || info.type != 0xFE)
1008
+				{
1009
+					u32 adv_size = save_types[info.type+1][1];
1010
+					if (info.size > adv_size)
1011
+						info.size = adv_size;
1012
+					else
1013
+						if (info.size < adv_size)
1014
+						{
1015
+							left = adv_size - info.size;
1016
+							info.size = adv_size;
1017
+						}
1018
+				}
1019
+			}
1020
+		}*/
1021
+		//establish the save data
1022
+		resize(info.size);
1023
+		inf->fseek(0, SEEK_SET);
1024
+		if(info.size>0)
1025
+			inf->fread(&data[0],info.size); //read all the raw data we have
1026
+		state = RUNNING;
1027
+		addr_size = info.addr_size;
1028
+		//none of the other fields are used right now
1029
+
1030
+		/*if (CommonSettings.autodetectBackupMethod != 1 && info.type == 0)
1031
+		{
1032
+			info.type = searchFileSaveType(info.size);
1033
+			if (info.type == 0xFF) info.type = 0;
1034
+		}
1035
+		uint32_t ss = info.size * 8 / 1024;
1036
+		if (ss >= 1024)
1037
+		{
1038
+			ss /= 1024;
1039
+			printf("Backup size: %i Mbit\n", ss);
1040
+		}
1041
+		else
1042
+			printf("Backup size: %i Kbit\n", ss);*/
1043
+
1044
+		delete inf;
1045
+	}
1046
+}
1047
+
1048
+/*bool BackupDevice::save_raw(const char* fn)
1049
+{
1050
+	FILE* outf = fopen(fn,"wb");
1051
+	if(!outf) return false;
1052
+	uint32_t size = data.size();
1053
+	uint32_t padSize = pad_up_size(size);
1054
+	if(data.size()>0)
1055
+		fwrite(&data[0],1,size,outf);
1056
+	for(uint32_t i=size;i<padSize;i++)
1057
+		fputc(kUninitializedSaveDataValue,outf);
1058
+	fclose(outf);
1059
+	return true;
1060
+}*/
1061
+
1062
+/*uint32_t BackupDevice::pad_up_size(uint32_t startSize)
1063
+{
1064
+	uint32_t size = startSize;
1065
+	uint32_t ctr=0;
1066
+	while(ctr<saveSizes_count && size > saveSizes[ctr]) ctr++;
1067
+	uint32_t padSize = saveSizes[ctr];
1068
+	if(padSize == 0xFFFFFFFF)
1069
+	{
1070
+		printf("PANIC! Couldn't pad up save size. Refusing to pad.\n");
1071
+		padSize = startSize;
1072
+	}
1073
+		return padSize;
1074
+}*/
1075
+
1076
+/*void BackupDevice::lazy_flush()
1077
+{
1078
+	if(flushPending || lazyFlushPending)
1079
+	{
1080
+		lazyFlushPending = flushPending = false;
1081
+		//flush();
1082
+	}
1083
+}*/
1084
+
1085
+/*void BackupDevice::flush()
1086
+{
1087
+	//never use save files if we are in movie mode
1088
+	if(isMovieMode) return;
1089
+
1090
+	EMUFILE* outf = new EMUFILE_FILE(filename.c_str(),"wb");
1091
+	if(!outf->fail())
1092
+	{
1093
+		if(data.size()>0)
1094
+			outf->fwrite(&data[0],data.size());
1095
+
1096
+		//write the footer. we use a footer so that we can maximize the chance of the
1097
+		//save file being recognized as a raw save file by other emulators etc.
1098
+
1099
+		//first, pad up to the next largest known save size.
1100
+		uint32_t size = data.size();
1101
+		uint32_t padSize = pad_up_size(size);
1102
+
1103
+		for(uint32_t i=size;i<padSize;i++)
1104
+			outf->fputc(kUninitializedSaveDataValue);
1105
+
1106
+		//this is just for humans to read
1107
+		outf->fprintf("|<--Snip above here to create a raw sav by excluding this DeSmuME savedata footer:");
1108
+
1109
+		//and now the actual footer
1110
+		write32le(size,outf); //the size of data that has actually been written
1111
+		write32le(padSize,outf); //the size we padded it to
1112
+		write32le(0,outf); //save memory type
1113
+		write32le(addr_size,outf);
1114
+		write32le(0,outf); //save memory size
1115
+		write32le(0,outf); //version number
1116
+		outf->fprintf("%s", kDesmumeSaveCookie); //this is what we'll use to recognize the desmume format save
1117
+
1118
+		delete outf;
1119
+	}
1120
+	else
1121
+	{
1122
+		delete outf;
1123
+		printf("Unable to open savefile %s\n",filename.c_str());
1124
+	}
1125
+}*/
1126
+
1127
+void BackupDevice::raw_applyUserSettings(uint32_t& size, bool manual)
1128
+{
1129
+	//respect the user's choice of backup memory type
1130
+	if(CommonSettings.manualBackupType == MC_TYPE_AUTODETECT && !manual)
1131
+	{
1132
+		addr_size = addr_size_for_old_save_size(size);
1133
+		resize(size);
1134
+	}
1135
+	else
1136
+	{
1137
+		uint32_t type = CommonSettings.manualBackupType;
1138
+		/*if (manual)
1139
+		{
1140
+			uint32_t res = searchFileSaveType(size);
1141
+			if (res != 0xFF) type = (res + 1); // +1 - skip autodetect
1142
+		}*/
1143
+		int savetype = save_types[type][0];
1144
+		int savesize = save_types[type][1];
1145
+		addr_size = addr_size_for_old_save_type(savetype);
1146
+		if((uint32_t)savesize<size) size = savesize;
1147
+		resize(savesize);
1148
+	}
1149
+
1150
+	state = RUNNING;
1151
+}
1152
+
1153
+/*uint32_t BackupDevice::get_save_raw_size(const char* fname)
1154
+{
1155
+	FILE* inf = fopen(fname,"rb");
1156
+	if (!inf) return 0xFFFFFFFF;
1157
+
1158
+	fseek(inf, 0, SEEK_END);
1159
+	uint32_t size = (uint32_t)ftell(inf);
1160
+	fclose(inf);
1161
+	return size;
1162
+}*/
1163
+
1164
+bool BackupDevice::load_raw(const char* fn, uint32_t force_size)
1165
+{
1166
+	FILE* inf = fopen(fn,"rb");
1167
+
1168
+	if (!inf) return false;
1169
+
1170
+	fseek(inf, 0, SEEK_END);
1171
+	uint32_t size = (uint32_t)ftell(inf);
1172
+	uint32_t left = 0;
1173
+
1174
+	if (force_size > 0)
1175
+	{
1176
+		if (size > force_size)
1177
+			size = force_size;
1178
+		else if (size < force_size)
1179
+		{
1180
+			left = force_size - size;
1181
+			size = force_size;
1182
+		}
1183
+	}
1184
+
1185
+	fseek(inf, 0, SEEK_SET);
1186
+
1187
+	raw_applyUserSettings(size, force_size > 0);
1188
+
1189
+	fread(&data[0],1,size - left,inf);
1190
+	fclose(inf);
1191
+
1192
+	//dump back out as a dsv, just to keep things sane
1193
+	//flush();
1194
+
1195
+	return true;
1196
+}
1197
+
1198
+
1199
+/*bool BackupDevice::load_duc(const char* fn)
1200
+{
1201
+  uint32_t size;
1202
+   char id[16];
1203
+   FILE* file = fopen(fn, "rb");
1204
+   if(file == NULL)
1205
+      return false;
1206
+
1207
+   fseek(file, 0, SEEK_END);
1208
+   size = (uint32_t)ftell(file) - 500;
1209
+   fseek(file, 0, SEEK_SET);
1210
+
1211
+   // Make sure we really have the right file
1212
+   fread((void *)id, sizeof(char), 16, file);
1213
+
1214
+   if (memcmp(id, "ARDS000000000001", 16) != 0)
1215
+   {
1216
+	   printf("Not recognized as a valid DUC file\n");
1217
+      fclose(file);
1218
+      return false;
1219
+   }
1220
+   // Skip the rest of the header since we don't need it
1221
+   fseek(file, 500, SEEK_SET);
1222
+
1223
+   raw_applyUserSettings(size);
1224
+
1225
+   ensure((uint32_t)size);
1226
+
1227
+   fread(&data[0],1,size,file);
1228
+   fclose(file);
1229
+
1230
+   //choose
1231
+
1232
+   //flush();
1233
+
1234
+   return true;
1235
+
1236
+}*/
1237
+
1238
+/*bool BackupDevice::load_movie(EMUFILE* is) {
1239
+
1240
+	const int32_t cookieLen = (int32_t)strlen(kDesmumeSaveCookie);
1241
+
1242
+	is->fseek(-cookieLen, SEEK_END);
1243
+	is->fseek(-4, SEEK_CUR);
1244
+
1245
+	uint32_t version = 0xFFFFFFFF;
1246
+	is->fread((char*)&version,4);
1247
+	if(version!=0) {
1248
+		printf("Unknown save file format\n");
1249
+		return false;
1250
+	}
1251
+	is->fseek(-24, SEEK_CUR);
1252
+
1253
+	struct{
1254
+		uint32_t size,padSize,type,addr_size,mem_size;
1255
+	}info;
1256
+
1257
+	is->fread((char*)&info.size,4);
1258
+	is->fread((char*)&info.padSize,4);
1259
+	is->fread((char*)&info.type,4);
1260
+	is->fread((char*)&info.addr_size,4);
1261
+	is->fread((char*)&info.mem_size,4);
1262
+
1263
+	//establish the save data
1264
+	data.resize(info.size);
1265
+	is->fseek(0, SEEK_SET);
1266
+	if(info.size>0)
1267
+		is->fread((char*)&data[0],info.size);
1268
+
1269
+	state = RUNNING;
1270
+	addr_size = info.addr_size;
1271
+	//none of the other fields are used right now
1272
+
1273
+	return true;
1274
+}*/
1275
+
1276
+/*void BackupDevice::forceManualBackupType()
1277
+{
1278
+	addr_size = addr_size_for_old_save_size(save_types[CommonSettings.manualBackupType][1]);
1279
+	state = RUNNING;
1280
+}*/