Beispiel #1
0
void populateArgv(int *argc, char *argv[], char *filename) {
	int i = 0;
	Parameters* params = getParameters();
	print_gecko("There are %i parameters\r\n", params->num_params);
	for(i = 0; i < params->num_params; i++) {
		Parameter *param = &params->parameters[i];
		if(param->enable) {
			if(*argc == 0) {
				// Filename first
				argv[0] = filename;
				*argc += 1;
			}
			ParameterValue *arg = &param->arg;
			ParameterValue *val = &param->values[param->currentValueIdx];
			//print_gecko("Arg: (%s) [%s] is enabled with value (%s) [%s]\r\n",
			//	arg->value, arg->name, val->value, val->name);
			char *argvEntry = (char*)malloc((MAX_PARAM_STRING * 2) + 2);
			memset(argvEntry, 0, (MAX_PARAM_STRING * 2) + 2);
			if(!arg->value[0])
				sprintf(argvEntry, "%s", val->value);
			else
				sprintf(argvEntry, "%s=%s", arg->value, val->value);
			print_gecko("Argv entry: [%s]\r\n", argvEntry);
			argv[*argc] = argvEntry;
			*argc+=1;
		}
	}
	print_gecko("Arg count: %i\r\n", *argc);
}
Beispiel #2
0
int CARD_ReadUnaligned(card_file *cardfile, void *buffer, unsigned int length, unsigned int offset, int slot) {
	void *dst = buffer;
	u8 *read_buffer = (u8*)memalign(32,card_sectorsize[slot]);
	int ret = CARD_ERROR_READY;
	print_gecko("Unaligned read dst %08X offset %08X length %i\r\n", dst, offset, length);
	// Unaligned because we're in the middle of a sector, read partial
	ret = CARD_Read(cardfile, read_buffer, card_sectorsize[slot], offset-(offset&0x1ff));
	print_gecko("CARD_Read offset %08X length %i\r\n", offset-(offset&0x1ff), card_sectorsize[slot]);
	if(ret != CARD_ERROR_READY) {
		free(read_buffer);
		return ret;
	}

	int amountRead = card_sectorsize[slot]-(offset&0x1ff);
	int amountToCopy = length > amountRead ? amountRead : length;
	memcpy(dst, read_buffer+(offset&0x1ff), amountToCopy);
	dst += amountToCopy;
	length -= amountToCopy;
	offset += amountToCopy;
	if(length != 0) {
		print_gecko("Unaligned read leftovers offset %08X length %i\r\n", offset, length);
		// At least this will be aligned
		ret = CARD_Read(cardfile, read_buffer, card_sectorsize[slot], offset);
		print_gecko("CARD_Read offset %08X length %i\r\n", offset, card_sectorsize[slot]);
		if(ret != CARD_ERROR_READY) {
			free(read_buffer);
			return ret;
		}
		memcpy(dst, read_buffer, length);
	}

	free(read_buffer);
	return ret;
}
Beispiel #3
0
void scanFiles() {
	freeFiles();
	// Read the directory/device TOC
	if(curDirEntries){ free(curDirEntries); curDirEntries = NULL; }
	print_gecko("Reading directory: %s\r\n",curFile.name);
	curDirEntryCount = devices[DEVICE_CUR]->readDir(&curFile, &curDirEntries, -1);
	memcpy(&curDir, &curFile, sizeof(file_handle));
	sortFiles(curDirEntries, curDirEntryCount);
	print_gecko("Found %i entries\r\n",curDirEntryCount);
}
Beispiel #4
0
void printCheats(void) {
	int i = 0, j = 0;
	print_gecko("There are %i cheats\r\n", _cheats.num_cheats);
	for(i = 0; i < _cheats.num_cheats; i++) {
		CheatEntry *cheat = &_cheats.cheat[i];
		print_gecko("Cheat: (%i codes) %s\r\n", cheat->num_codes, cheat->name);
		for(j = 0; j < cheat->num_codes; j++) {
			print_gecko("%08X %08X\r\n", cheat->codes[j][0], cheat->codes[j][1]);
		}
	}
}
Beispiel #5
0
void printParams(Parameters *params) {
	int i = 0, j = 0;
	print_gecko("There are %i parameters\r\n", params->num_params);
	for(i = 0; i < params->num_params; i++) {
		Parameter *param = &params->parameters[i];
		ParameterValue *arg = &param->arg;
		print_gecko("Argument: (%s) [%s]\r\n", arg->value, arg->name);
		print_gecko("This parameter has %i values\r\n", param->num_values);
		for(j = 0; j < params->parameters[i].num_values; j++) {
			print_gecko("Value: (%s) [%s]\r\n", params->parameters[i].values[j].value, params->parameters[i].values[j].name);
		}
	}
}
Beispiel #6
0
int verify_findMD5Sum(const char * md5orig, int disc_type) {

	print_gecko("Looking for MD5 [%s]\r\n", md5orig);
	char *xmlPointer = (disc_type == IS_NGC_DISC) ? ngcDAT : wiiDAT;
	if(xmlPointer) {
		mxml_node_t *pointer = (disc_type == IS_NGC_DISC)  ? ngcXML : wiiXML;
		
		pointer = mxmlLoadString(NULL, xmlPointer, MXML_TEXT_CALLBACK);
		
		print_gecko("Looking in the %s XML\r\n", pointer == ngcXML ? "GameCube" : "Wii");
		if (pointer) {
			// open the <datafile>
			mxml_node_t *item = mxmlFindElement(pointer, pointer, "datafile", NULL,
					NULL, MXML_DESCEND);
			print_gecko("DataFile Pointer OK\r\n");
			if (item) {
				mxml_index_t *iterator = mxmlIndexNew(item, "game", NULL);
				mxml_node_t *gameElem = NULL;

				//print_gecko("Item Pointer OK\r\n");
				// iterate over all the <game> entries
				while ((gameElem = mxmlIndexEnum(iterator)) != NULL) {
					// get the md5 and compare it
					mxml_node_t *md5Elem = mxmlFindElement(gameElem, gameElem,
							NULL, "md5", NULL, MXML_DESCEND);
					// get the name too
					mxml_node_t *nameElem = mxmlFindElement(gameElem, gameElem,
							NULL, "name", NULL, MXML_DESCEND);

					char md5[64];
					memset(&md5[0], 0, 64);
					strncpy(&md5[0], mxmlElementGetAttr(md5Elem, "md5"), 32);

					//print_gecko("Comparing game [%s] and md5 [%s]\r\n",mxmlElementGetAttr(nameElem, "name"),mxmlElementGetAttr(md5Elem, "md5"));
					if (!strnicmp(&md5[0], md5orig, 32)) {
						snprintf(&gameName[0], 128, "%s", mxmlElementGetAttr(
								nameElem, "name"));
						print_gecko("Found a match!\r\n");
						return 1;
					}
				}
			}
		}
	}
	return 0;
}
Beispiel #7
0
void trySlotB() {
	if (deviceHandler_FAT_init(&initial_SD1)) 	{
		forceSlot = 1;
		print_gecko("Detected SDGecko in Slot B for config\r\n");
	}
	else {
		forceSlot = 0;
	}
}
Beispiel #8
0
s32 deviceHandler_CARD_init(file_handle* file){
	int slot = (!strncmp((const char*)initial_CARDB.name, file->name, 7));
	file->status = initialize_card(slot);
	s32 memSize = 0, sectSize = 0;
	int ret = CARD_ProbeEx(slot,&memSize,&sectSize);
	if(ret==CARD_ERROR_READY) {
		initial_CARD_info.totalSpaceInKB = (memSize<<7);
	} else {
		print_gecko("CARD_ProbeEx failed %i\r\n", ret);
	}
	initial_CARD_info.freeSpaceInKB = 0;
	
	return file->status == CARD_ERROR_READY ? 1 : 0;
}
Beispiel #9
0
// Installs the GeckoOS (kenobiGC) cheats engine and sets up variables/copies cheats
void kenobi_install_engine() {
	int isDebug = swissSettings.wiirdDebug;
	// If high memory is in use, we'll use low, otherwise high.
	u8 *ptr = isDebug ? kenobigc_dbg_bin : kenobigc_bin;
	u32 size = isDebug ? kenobigc_dbg_bin_size : kenobigc_bin_size;
	
	print_gecko("Copying kenobi%s to %08X\r\n", (isDebug?"_dbg":""),(u32)CHEATS_ENGINE);
	memcpy(CHEATS_ENGINE, ptr, size);
	memcpy(CHEATS_GAMEID, (void*)0x80000000, CHEATS_GAMEID_LEN);
	if(!isDebug) {
		CHEATS_ENABLE_CHEATS = CHEATS_TRUE;
	}
	CHEATS_START_PAUSED = isDebug ? CHEATS_TRUE : CHEATS_FALSE;
	memset(CHEATS_LOCATION(size), 0, kenobi_get_maxsize());
	print_gecko("Copying %i bytes of cheats to %08X\r\n", getEnabledCheatsSize(),(u32)CHEATS_LOCATION(size));
	u32 *cheatsLocation = (u32*)CHEATS_LOCATION(size);
	cheatsLocation[0] = 0x00D0C0DE;
	cheatsLocation[1] = 0x00D0C0DE;
	cheatsLocation+=2;
	
	int i = 0, j = 0;
	for(i = 0; i < _cheats.num_cheats; i++) {
		CheatEntry *cheat = &_cheats.cheat[i];
		if(cheat->enabled) {
			for(j = 0; j < cheat->num_codes; j++) {
				// Copy & fix cheats that want to jump to the old cheat engine location 0x800018A8 -> CHEATS_ENGINE+0xA8
				cheatsLocation[0] = cheat->codes[j][0];
				cheatsLocation[1] = cheat->codes[j][1] == 0x800018A8 ? (u32)(CHEATS_ENGINE+0xA8) : cheat->codes[j][1];
				cheatsLocation+=2;
			}
		}
	}
	cheatsLocation[0] = 0xFF000000;
	DCFlushRange((void*)CHEATS_ENGINE, WIIRD_ENGINE_SPACE);
	ICInvalidateRange((void*)CHEATS_ENGINE, WIIRD_ENGINE_SPACE);
}
Beispiel #10
0
// Checks if devices are available, prints name of device being detected for slow init devices
void populateDeviceAvailability() {
	if(PAD_ButtonsHeld(0) & PAD_BUTTON_B) {
		deviceHandler_setAllDevicesAvailable();
		return;
	}
	uiDrawObj_t *msgBox = DrawPublish(DrawProgressBar(true, 0, "Detecting devices ...\nThis can be skipped by holding B next time"));
	int i;
	for(i = 0; i < MAX_DEVICES; i++) {
		if(allDevices[i] != NULL && !deviceHandler_getDeviceAvailable(allDevices[i])) {
			print_gecko("Checking device availability for device %s\r\n", allDevices[i]->deviceName);
			deviceHandler_setDeviceAvailable(allDevices[i], allDevices[i]->test());
		}
		if(PAD_ButtonsHeld(0) & PAD_BUTTON_B) {
			deviceHandler_setAllDevicesAvailable();
			break;
		}
	}
	DrawDispose(msgBox);
}
Beispiel #11
0
s32 deviceHandler_CARD_deleteFile(file_handle* file) {
	int slot = (!strncmp((const char*)initial_CARDB.name, file->name, 7));
	char *filename = getRelativeName(file->name);
	card_dir* cd = (card_dir*)&file->other;
	
	CARD_SetCompany((const char*)cd->company);
	CARD_SetGamecode((const char*)cd->gamecode);
	
	print_gecko("Deleting: %s from slot %i\r\n", filename, slot);
	
	int ret = CARD_DeleteEntry(slot, cd);
	if(ret != CARD_ERROR_READY) {
		uiDrawObj_t *msgBox = DrawMessageBox(D_FAIL,cardError(ret));
		DrawPublish(msgBox);
		wait_press_A();
		DrawDispose(msgBox);
	}
	return ret;
}
Beispiel #12
0
// If there was some new files obtained, return 1, else 0
void verify_download(char *mountPath) {
	if(dontAskAgain) {
		return;
	}
	
	int res = 0;
	// Ask the user if they want to update from the web
	if(verify_initialized) {
		char *line1 = "Redump.org DAT files found";
		char *line2 = "Check for updated DAT files?";
		res = DrawYesNoDialog(line1, line2);
	}
	else {
		char *line1 = "Redump.org DAT files not found";
		char *line2 = "Download them now?";
		res = DrawYesNoDialog(line1, line2);
	}
	
	// If yes, lets download an update
	if(res) {
		// Initialize the network
		if(!net_initialized) {
			char ip[16];
			DrawMessageBox(D_INFO, "Checking for DAT updates\n \nInitializing Network...");
			res = if_config(ip, NULL, NULL, true);
      		if(res >= 0) {
	      		sprintf(txtbuffer, "Checking for DAT updates\nNetwork Initialized!\nIP: %s", ip);
	      		DrawMessageBox(D_INFO, txtbuffer);
				net_initialized = 1;
				print_gecko("Network Initialized!\r\n");
			}
      		else {
	      		DrawMessageBox(D_FAIL, "Checking for DAT updates\nNetwork failed to Initialize!");
	      		sleep(5);
        		net_initialized = 0;
				print_gecko("Network Failed to Initialize!\r\n");
        		return;
      		}
  		}

  		// Download the GC DAT
		char datFilePath[64];
  		sprintf(datFilePath, "%sgc.dat",mountPath);
  		u8 *xmlFile = (u8*)memalign(32, 1*1024*1024);
		if((res = http_request("www.gc-forever.com","/datfile/gc.dat", xmlFile, (1*1024*1024), 0, 0)) > 0) {
			remove(datFilePath);
			FILE *fp = fopen(datFilePath, "wb");
			if(fp) {
				DrawMessageBox(D_INFO, "Checking for updates\nSaving GC DAT...");
				fwrite(xmlFile, 1, res, fp);
				fclose(fp);
				verify_initialized = 0;
				print_gecko("Saved GameCube DAT! %i Bytes\r\n", res);
			}
			else {
				DrawMessageBox(D_FAIL, "Checking for updates\nFailed to save GC DAT...");
				sleep(5);
			}
		}
		else {
			sprintf(txtbuffer, "Error: %i", res);
			print_gecko("Error Saving GC DAT %i\r\n", res);
			DrawMessageBox(D_FAIL, "Checking for updates\nCouldn't find file on gc-forever.com");
			sleep(5);
		}
		// Download the Wii DAT
  		sprintf(datFilePath, "%swii.dat",mountPath);
		if((res = http_request("www.gc-forever.com","/datfile/wii.dat", xmlFile, (1*1024*1024), 0, 0)) > 0) {
			remove(datFilePath);
			FILE *fp = fopen(datFilePath, "wb");
			if(fp) {
				DrawMessageBox(D_INFO, "Checking for updates\nSaving Wii DAT...");
				fwrite(xmlFile, 1, res, fp);
				fclose(fp);
				verify_initialized = 0;
				print_gecko("Saved Wii DAT! %i Bytes\r\n", res);
			}	
			else {
				DrawMessageBox(D_FAIL, "Checking for updates\nFailed to save Wii DAT...");
				sleep(5);
			}					
		}
		else {
			sprintf(txtbuffer, "Error: %i", res);
			print_gecko("Error Saving Wii DAT %i\r\n", res);
			DrawMessageBox(D_FAIL, "Checking for updates\nCouldn't find file on gc-forever.com");
			sleep(5);
		}
		free(xmlFile);
		dontAskAgain = 1;
	}
	else {
		dontAskAgain = 1;
	}
}
Beispiel #13
0
void config_parse(char *configData) {
	// Parse each entry and put it into our array
	char *line, *linectx = NULL;
	int first = 1;
	line = strtok_r( configData, "\r\n", &linectx );
	while( line != NULL ) {
		//print_gecko("Line [%s]\r\n", line);
		if(line[0] != '#') {
			// Is this line a new game entry?
			char *name, *namectx = NULL;
			char *value = NULL;
			name = strtok_r(line, "=", &namectx);
			if(name != NULL)
				value = strtok_r(NULL, "=", &namectx);
			
			if(value != NULL) {
				//print_gecko("Name [%s] Value [%s]\r\n", name, value);

				if(!strcmp("ID", name)) {
					if(!first) {
						configEntriesCount++;
					}
					strncpy(&configEntries[configEntriesCount].game_id[0], value, 4);
					first = 0;
					// Fill this entry with defaults incase some values are missing..
					strcpy(&configEntries[configEntriesCount].comment[0],"No Comment");
					strcpy(&configEntries[configEntriesCount].status[0],"Unknown");
					configEntries[configEntriesCount].gameVMode = 0;
					configEntries[configEntriesCount].softProgressive = 0;
					configEntries[configEntriesCount].muteAudioStreaming = 1;
					configEntries[configEntriesCount].forceWidescreen = 0;
					configEntries[configEntriesCount].forceAnisotropy = 0;
					configEntries[configEntriesCount].forceEncoding = 0;
				}
				else if(!strcmp("Name", name)) {
					strncpy(&configEntries[configEntriesCount].game_name[0], value, 64);
				}
				else if(!strcmp("Comment", name)) {
					strncpy(&configEntries[configEntriesCount].comment[0], value, 128);
				}
				else if(!strcmp("Status", name)) {
					strncpy(&configEntries[configEntriesCount].status[0], value, 32);
				}
				else if(!strcmp("Force Video Mode", name)) {
					if(!strcmp(uiVModeStr[0], value))
						configEntries[configEntriesCount].gameVMode = 0;
					else if(!strcmp(uiVModeStr[1], value))
						configEntries[configEntriesCount].gameVMode = 1;
					else if(!strcmp(uiVModeStr[2], value))
						configEntries[configEntriesCount].gameVMode = 2;
					else if(!strcmp(uiVModeStr[3], value))
						configEntries[configEntriesCount].gameVMode = 3;
					else if(!strcmp(uiVModeStr[4], value))
						configEntries[configEntriesCount].gameVMode = 4;
					else if(!strcmp(uiVModeStr[5], value))
						configEntries[configEntriesCount].gameVMode = 5;
					else if(!strcmp(uiVModeStr[6], value))
						configEntries[configEntriesCount].gameVMode = 6;
				}
				else if(!strcmp("Soft Progressive", name)) {
					if(!strcmp(softProgressiveStr[0], value))
						configEntries[configEntriesCount].softProgressive = 0;
					else if(!strcmp(softProgressiveStr[1], value))
						configEntries[configEntriesCount].softProgressive = 1;
					else if(!strcmp(softProgressiveStr[2], value))
						configEntries[configEntriesCount].softProgressive = 2;
				}
				else if(!strcmp("Mute Audio Streaming", name)) {
					configEntries[configEntriesCount].muteAudioStreaming = !strcmp("Yes", value) ? 1:0;
				}
				else if(!strcmp("Force Widescreen", name)) {
					if(!strcmp(forceWidescreenStr[0], value))
						configEntries[configEntriesCount].forceWidescreen = 0;
					else if(!strcmp(forceWidescreenStr[1], value))
						configEntries[configEntriesCount].forceWidescreen = 1;
					else if(!strcmp(forceWidescreenStr[2], value))
						configEntries[configEntriesCount].forceWidescreen = 2;
				}
				else if(!strcmp("Force Anisotropy", name)) {
					configEntries[configEntriesCount].forceAnisotropy = !strcmp("Yes", value) ? 1:0;
				}
				else if(!strcmp("Force Encoding", name)) {
					if(!strcmp(forceEncodingStr[0], value))
						configEntries[configEntriesCount].forceEncoding = 0;
					else if(!strcmp(forceEncodingStr[1], value))
						configEntries[configEntriesCount].forceEncoding = 1;
					else if(!strcmp(forceEncodingStr[2], value))
						configEntries[configEntriesCount].forceEncoding = 2;
				}
				
				// Swiss settings
				else if(!strcmp("Default Device", name)) {
					configSwissSettings.defaultDevice = !strcmp("Yes", value) ? 1:0;
				}
				else if(!strcmp("SD/IDE Speed", name)) {
					configSwissSettings.exiSpeed = !strcmp("32MHz", value) ? 1:0;
				}
				else if(!strcmp("Enable Debug", name)) {
					configSwissSettings.debugUSB = !strcmp("Yes", value) ? 1:0;
				}
				else if(!strcmp("Force No DVD Drive Mode", name)) {
					configSwissSettings.hasDVDDrive = !strcmp("No", value) ? 1:0;
				}
				else if(!strcmp("Hide Unknown file types", name)) {
					configSwissSettings.hideUnknownFileTypes = !strcmp("Yes", value) ? 1:0;
				}
				else if(!strcmp("Stop DVD Motor on startup", name)) {
					configSwissSettings.stopMotor = !strcmp("Yes", value) ? 1:0;
				}
				else if(!strcmp("Enable WiiRD debug", name)) {
					configSwissSettings.wiirdDebug = !strcmp("Yes", value) ? 1:0;
				}
				else if(!strcmp("Enable File Management", name)) {
					configSwissSettings.enableFileManagement = !strcmp("Yes", value) ? 1:0;
				}
				else if(!strcmp("Swiss Video Mode", name)) {
					if(!strcmp(uiVModeStr[0], value))
						configSwissSettings.uiVMode = 0;
					else if(!strcmp(uiVModeStr[1], value))
						configSwissSettings.uiVMode = 1;
					else if(!strcmp(uiVModeStr[2], value))
						configSwissSettings.uiVMode = 2;
					else if(!strcmp(uiVModeStr[3], value))
						configSwissSettings.uiVMode = 3;
					else if(!strcmp(uiVModeStr[4], value))
						configSwissSettings.uiVMode = 4;
					else if(!strcmp(uiVModeStr[5], value))
						configSwissSettings.uiVMode = 5;
					else if(!strcmp(uiVModeStr[6], value))
						configSwissSettings.uiVMode = 6;
				}
				else if(!strcmp("SMBUserName", name)) {
					strncpy(configSwissSettings.smbUser, value, 20);
				}
				else if(!strcmp("SMBPassword", name)) {
					strncpy(configSwissSettings.smbPassword, value, 16);
				}
				else if(!strcmp("SMBShareName", name)) {
					strncpy(configSwissSettings.smbShare, value, 80);
				}
				else if(!strcmp("SMBHostIP", name)) {
					strncpy(configSwissSettings.smbServerIp, value, 80);
				}
			}
		}
		// And round we go again
		line = strtok_r( NULL, "\r\n", &linectx);
	}

	if(configEntriesCount > 0 || !first)
		configEntriesCount++;
	
	 print_gecko("Found %i entries in the config file\r\n",configEntriesCount);
}
Beispiel #14
0
// This function should always be called for the FULL length cause CARD is lame like that.
s32 deviceHandler_CARD_writeFile(file_handle* file, void* data, u32 length) {
	
	if(gciInfo == NULL) {	// Swiss ID for this
		CARD_SetGameAndCompany();
	} else {	// Game specific
		char company[4], gamecode[8];
		memset(company, 0, 4);
		memset(gamecode, 0, 8);
		memcpy(gamecode, gciInfo->gamecode, 4);
		memcpy(company, gciInfo->company, 2);
		CARD_SetCompany(company);
		CARD_SetGamecode(gamecode);
	}
	
	card_file cardfile;
	unsigned int slot = (!strncmp((const char*)initial_CARDB.name, file->name, 7)), ret = 0;
	unsigned int adj_length = (length % 8192 == 0 ? length : (length + (8192-length%8192)))+8192;
	char *filename = NULL;
	char fname[CARD_FILENAMELEN+1];
	if(gciInfo != NULL) {
		memset(fname, 0, CARD_FILENAMELEN+1);
		memcpy(fname, gciInfo->filename, CARD_FILENAMELEN);
		filename = &fname[0];
		adj_length = gciInfo->filesize8*8192;
	} else {
		filename = getRelativeName(file->name);
	}
	
	// Open the file based on the slot & file name
	ret = CARD_Open(slot,filename, &cardfile);

	print_gecko("Tried to open: [%s] in slot %s got res: %i\r\n",filename, slot ? "B":"A", ret);
	
	if(ret == CARD_ERROR_NOFILE) {
		// If the file doesn't exist, create it.
		ret = CARD_Create(slot, filename,adj_length,&cardfile);
		print_gecko("Tried to create: [%s] in slot %s got res: %i\r\n",filename, slot ? "B":"A", ret);
		if(ret != CARD_ERROR_READY) {
			return ret;
		}
		ret = CARD_Open(slot,filename, &cardfile);
		print_gecko("Tried to open after create: [%s] in slot %s got res: %i\r\n",filename, slot ? "B":"A", ret);
	}
	
	if(ret != CARD_ERROR_READY) {
		// Something went wrong
		return -1;
	}

	// Write the icon, comment, etc.
	time_t gc_time = time (NULL);
	char *tmpBuffer = memalign(32,adj_length);
	memset(tmpBuffer,0,adj_length);
	if(gciInfo == NULL) {
		strcpy(tmpBuffer, filename);
		strcpy(tmpBuffer+0x20, ctime (&gc_time));
		memcpy(tmpBuffer+0x40, gamecube_rgb, sizeof(gamecube_rgb));	// Copy icon
		memcpy(tmpBuffer+0x2000, data, length);	// Copy data
	}
	else {
		data+=sizeof(GCI);
		memcpy(tmpBuffer, data, length);	// Copy data
	}
	
	// The file exists by now, write at offset.
	int amount_written = 0;
	while(amount_written != adj_length) {
		ret = CARD_Write(&cardfile, tmpBuffer+amount_written, card_sectorsize[slot], file->offset);
		file->offset += card_sectorsize[slot];
		amount_written += card_sectorsize[slot];
		print_gecko("Tried to write: [%s] in slot %s got res: %i\r\n",filename, slot ? "B":"A", ret);
		if(ret != CARD_ERROR_READY) break;
	}
	
	card_stat cardstat;
	if(gciInfo == NULL) {	// Swiss
		memset(&cardstat, 0, sizeof(card_stat));
		memcpy(&cardstat.filename, filename, CARD_FILENAMELEN-1);
		cardstat.time = gc_time;
		cardstat.comment_addr = 0;
		cardstat.icon_addr = 0x40;
		cardstat.icon_speed = CARD_SPEED_FAST;
		cardstat.banner_fmt = CARD_BANNER_NONE;
		cardstat.icon_fmt = CARD_ICON_RGB;
	}
	else {	// Info is coming from a GCI
		cardstat.banner_fmt = gciInfo->banner_fmt;
		cardstat.time = gciInfo->time;
		cardstat.icon_addr = gciInfo->icon_addr;
		cardstat.icon_fmt = gciInfo->icon_fmt;
		cardstat.icon_speed = gciInfo->icon_speed;
		cardstat.comment_addr = gciInfo->comment_addr;
	}
	CARD_SetStatus (slot, cardfile.filenum, &cardstat);
	
	free(tmpBuffer);
	CARD_Close(&cardfile);
	return ret == CARD_ERROR_READY ? length : ret;
}
Beispiel #15
0
/****************************************************************************
* Main
****************************************************************************/
int main () 
{
	// Setup defaults (if no config is found)
	memset(&swissSettings, 0 , sizeof(SwissSettings));
	
	void *fb;
	fb = Initialise();
	if(!fb) {
		return -1;
	}

	// Sane defaults
	refreshSRAM();
	swissSettings.debugUSB = 1;
	swissSettings.gameVMode = 0;	// Auto video mode
	swissSettings.exiSpeed = 1;		// 32MHz
	swissSettings.uiVMode = 0; 		// Auto UI mode
	swissSettings.enableFileManagement = 0;

	config_copy_swiss_settings(&swissSettings);
	needsDeviceChange = 1;
	needsRefresh = 1;
	

	//debugging stuff
	if(swissSettings.debugUSB) {
		if(usb_isgeckoalive(1)) {
			usb_flush(1);
		}
		print_gecko("Arena Size: %iKb\r\n",(SYS_GetArena1Hi()-SYS_GetArena1Lo())/1024);
		print_gecko("DVD Drive Present? %s\r\n",swissSettings.hasDVDDrive?"Yes":"No");
		print_gecko("GIT Commit: %s\r\n", GITREVISION);
		print_gecko("GIT Revision: %s\r\n", GITVERSION);
	}
	
	// Detect devices
	populateDeviceAvailability();
	
	curDevice = -1;
	// Are we working with a Wiikey Fusion?
	if(__wkfSpiReadId() != 0 && __wkfSpiReadId() != 0xFFFFFFFF) {
		print_gecko("Detected Wiikey Fusion with SPI Flash ID: %08X\r\n",__wkfSpiReadId());

		// Set real device back
		curDevice = WKF;

		// SlotB hack
		trySlotB();
	}
	else {
		deviceHandler_setStatEnabled(0);
		// Try to init SD cards here and load config
		deviceHandler_initial = &initial_SD0;
		deviceHandler_init		=  deviceHandler_FAT_init;
		deviceHandler_deinit	=  deviceHandler_FAT_deinit;
		if(deviceHandler_init(deviceHandler_initial)) {
			print_gecko("Detected SDGecko in Slot A\r\n");
			load_auto_dol();
			curDevice = SD_CARD;
		}
		else {
			deviceHandler_deinit(deviceHandler_initial);
			deviceHandler_initial = &initial_SD1;
			if(deviceHandler_init(deviceHandler_initial)) {
				print_gecko("Detected SDGecko in Slot B\r\n");
				load_auto_dol();
				curDevice = SD_CARD;
			}
		}
		deviceHandler_setStatEnabled(1);
	}
	
	// If no device has been selected yet to browse ..
	if(curDevice < 0) {
		print_gecko("No default boot device detected, trying DVD!\r\n");
		// Do we have a DVD drive with a ready medium we can perhaps browse then?
		u8 driveReallyExists[8];
		drive_version(&driveReallyExists[0]);
		if(*(u32*)&driveReallyExists[0]) {
			dvd_read_id();
			if(!dvd_get_error()) {
				print_gecko("DVD Medium is up, using it as default device\r\n");
				curDevice = DVD_DISC;
				
				// If we have a GameCube (single image) bootable disc, show the banner screen here
				dvdDiscTypeInt = gettype_disc();
				if(dvdDiscTypeInt == GAMECUBE_DISC) {
					select_device(1);
					// Setup curFile and load it
					memset(&curFile, 0, sizeof(file_handle));
					strcpy(&curFile.name[0], "game.gcm");
					curFile.size = DISC_SIZE;
					curFile.fileAttrib = IS_FILE;
					populate_meta(&curFile);
					load_file();
					curDevice = -1;
					deviceHandler_initial = NULL;
				}
			}
		}
	}
	if(curDevice) {
		needsDeviceChange = 0;
		select_device(1); // to setup deviceHandler_ ptrs
		load_config(forceSlot);
	}

	// Start up the BBA if it exists
	init_network_thread();
	init_httpd_thread();
	
	// DVD Motor off
	if(swissSettings.stopMotor && swissSettings.hasDVDDrive) {
		dvd_motor_off();
	}

	// Swiss video mode force
	GXRModeObj *forcedMode = getModeFromSwissSetting(swissSettings.uiVMode);
	
	if((forcedMode != NULL) && (forcedMode != vmode)) {
		initialise_video(forcedMode);
		vmode = forcedMode;
	}

	while(1) {
		main_loop();
	}
	return 0;
}
Beispiel #16
0
void main_loop()
{ 	
	while(PAD_ButtonsHeld(0) & PAD_BUTTON_A) { VIDEO_WaitVSync (); }
	// We don't care if a subsequent device is "default"
	if(needsDeviceChange) {
		free_files();
		if(deviceHandler_deinit) {
			deviceHandler_deinit(deviceHandler_initial);
		}
		if (forceSlot) {
			deviceHandler_FAT_deinit(&initial_SD1);
		}
		curDevice = -1;
		needsDeviceChange = 0;
		deviceHandler_initial = NULL;
		needsRefresh = 1;
		curMenuLocation = ON_FILLIST;
		select_device(0);
		if (curDevice == WKF)  {
			trySlotB();
		}
		curMenuLocation = ON_OPTIONS;
	}
	
	if(deviceHandler_initial) {
		// If the user selected a device, make sure it's ready before we browse the filesystem
		deviceHandler_deinit( deviceHandler_initial );
		sdgecko_setSpeed(EXI_SPEED32MHZ);
		if(!deviceHandler_init( deviceHandler_initial )) {
			if(((deviceHandler_initial->name[0] == 's')&&(deviceHandler_initial->name[1] == 'd'))||(deviceHandler_initial->name[0] == 'i')) {
				print_gecko("SD/IDE-EXI Device Failed to initialize @ 32MHz!\r\nTrying again once @ 16MHz...\r\n");
				sdgecko_setSpeed(EXI_SPEED16MHZ);
				if(!deviceHandler_init(deviceHandler_initial)) {
				// Try the alternate slot for SDGecko or IDE-EXI
					if(deviceHandler_initial->name[0] == 's')
						deviceHandler_initial = (deviceHandler_initial == &initial_SD0) ?
												&initial_SD1:&initial_SD0;
					else
						deviceHandler_initial = (deviceHandler_initial == &initial_IDE0) ?
												&initial_IDE1:&initial_IDE0;
					memcpy(&curFile, deviceHandler_initial, sizeof(file_handle));
				}
				print_gecko("Trying alternate slot @ 32MHz...\r\n");
				sdgecko_setSpeed(EXI_SPEED32MHZ);
				if(!deviceHandler_init( deviceHandler_initial )) {
					print_gecko("Alternate slot failed once @ 16MHz... \r\n");
					sdgecko_setSpeed(EXI_SPEED16MHZ);
					if(!deviceHandler_init( deviceHandler_initial )) {
						print_gecko("Both slots failed twice\r\n");
						needsDeviceChange = 1;
						return;
					}
				}
			}
		}
		if(curDevice==SD_CARD || curDevice==WKF || curDevice==IDEEXI) { 
			load_config(forceSlot);
		}
	}
	else {
		curMenuLocation=ON_OPTIONS;
	}
	// If a previously undetected device has been successfully init'd, mark it as available from now on
	if(!deviceHandler_getDeviceAvailable(curDevice)) {
		deviceHandler_setDeviceAvailable(curDevice, 1);
	}
  
	while(1) {
		if(deviceHandler_initial && needsRefresh) {
			curMenuLocation=ON_OPTIONS;
			free_files();
			curSelection=0; files=0; curMenuSelection=0;
			// Read the directory/device TOC
			if(allFiles){ free(allFiles); allFiles = NULL; }
			print_gecko("Reading directory: %s\r\n",curFile.name);
			files = deviceHandler_readDir(&curFile, &allFiles, -1);
			memcpy(&curDir, &curFile, sizeof(file_handle));
			sortFiles(allFiles, files);
			print_gecko("Found %i entries\r\n",files);
			if(files<1) { deviceHandler_deinit(deviceHandler_initial); needsDeviceChange=1; break;}
			needsRefresh = 0;
			curMenuLocation=ON_FILLIST;
		}
		while(PAD_ButtonsHeld(0) & PAD_BUTTON_A) { VIDEO_WaitVSync (); }
		drawFiles(&allFiles, files);

		u16 btns = PAD_ButtonsHeld(0);
		if(curMenuLocation==ON_OPTIONS) {
			if(btns & PAD_BUTTON_LEFT){	curMenuSelection = (--curMenuSelection < 0) ? (MENU_MAX-1) : curMenuSelection;}
			else if(btns & PAD_BUTTON_RIGHT){curMenuSelection = (curMenuSelection + 1) % MENU_MAX;	}
		}
		if(deviceHandler_initial && ((btns & PAD_BUTTON_B)||(curMenuLocation==ON_FILLIST)))	{
			while(PAD_ButtonsHeld(0) & PAD_BUTTON_B){ VIDEO_WaitVSync (); }
			curMenuLocation=ON_FILLIST;
			renderFileBrowser(&allFiles, files);
		}
		else if(btns & PAD_BUTTON_A) {
			//handle menu event
			switch(curMenuSelection) {
				case 0:		// Device change
					needsDeviceChange = 1;  //Change from SD->DVD or vice versa
					break;
				case 1:		// Settings
					show_settings(NULL, NULL);
					break;
				case 2:		// Credits
					show_info();
					break;
				case 3:
					if(deviceHandler_initial) {
						memcpy(&curFile, deviceHandler_initial, sizeof(file_handle));
						if(curDevice == WKF) { 
							wkfReinit(); deviceHandler_deinit(deviceHandler_initial);
						}
					}
					needsRefresh=1;
					break;
				case 4:
					__libogc_exit(0);
					break;
			}
			
		}
		while (!(!(PAD_ButtonsHeld(0) & PAD_BUTTON_B) && !(PAD_ButtonsHeld(0) & PAD_BUTTON_A) && !(PAD_ButtonsHeld(0) & PAD_BUTTON_RIGHT) && !(PAD_ButtonsHeld(0) & PAD_BUTTON_LEFT))) {
			VIDEO_WaitVSync();
		}
		if(needsDeviceChange) {
			break;
		}
	}
}
Beispiel #17
0
int patch_gcm(file_handle *file, ExecutableFile *filesToPatch, int numToPatch, int multiDol) {
	int i, num_patched = 0;
	
	// If the current device isn't SD Gecko, init SD Gecko Slot A or B to write patches.
	if(deviceHandler_initial != &initial_SD0 && deviceHandler_initial != &initial_SD1) {
		deviceHandler_setStatEnabled(0);
		if(deviceHandler_FAT_init(&initial_SD0)) {
			savePatchDevice = 0;
		}
		else if(deviceHandler_FAT_init(&initial_SD1)) {
			savePatchDevice = 1;
		}
		deviceHandler_setStatEnabled(1);
	}
	// Already using SD Gecko
	if(deviceHandler_initial == &initial_SD0)
		savePatchDevice = 0;
	else if(deviceHandler_initial == &initial_SD1)
		savePatchDevice = 1;
		
	if(savePatchDevice == -1) {
		DrawFrameStart();
		DrawMessageBox(D_FAIL, "No writable device present\nA SD Gecko must be inserted in\n order to utilise patches for this game.");
		DrawFrameFinish();
		sleep(5);
		return 0;
	}

	char patchFileName[256];
	char patchDirName[256];
	char patchBaseDirName[256];
	char gameID[8];
	memset(&gameID, 0, 8);
	memset(&patchDirName, 0, 256);
	memset(&patchBaseDirName, 0, 256);
	strncpy((char*)&gameID, (char*)&GCMDisk, 4);
	sprintf(&patchDirName[0],"%s:/swiss_patches/%s",(savePatchDevice ? "sdb":"sda"), &gameID[0]);
	sprintf(&patchBaseDirName[0],"%s:/swiss_patches",(savePatchDevice ? "sdb":"sda"));
	print_gecko("Patch dir will be: %s if required\r\n", patchDirName);
	*(u32*)VAR_EXECD_OFFSET = 0xFFFFFFFF;
	// Go through all the possible files we think need patching..
	for(i = 0; i < numToPatch; i++) {
		u32 patched = 0, crc32 = 0;

		sprintf(txtbuffer, "Patching File %i/%i",i+1,numToPatch);
		DrawFrameStart();
		DrawProgressBar((int)(((float)(i+1)/(float)numToPatch)*100), txtbuffer);
		DrawFrameFinish();
			
		// Round up to 32 bytes
		if(filesToPatch[i].size % 0x20) {
			filesToPatch[i].size += (0x20-(filesToPatch[i].size%0x20));
		}
		
		if(filesToPatch[i].size > 8*1024*1024) {
			print_gecko("Skipping %s %iKB too large\r\n", filesToPatch[i].name, filesToPatch[i].size/1024);
			continue;
		}
		print_gecko("Checking %s %iKb\r\n", filesToPatch[i].name, filesToPatch[i].size/1024);
		if(strstr(filesToPatch[i].name, "execD.")) {
			*(u32*)VAR_EXECD_OFFSET = filesToPatch[i].offset;
		}
		if(strstr(filesToPatch[i].name, "iwanagaD.dol") || strstr(filesToPatch[i].name, "switcherD.dol")) {
			continue;	// skip unused PSO files
		}
		int sizeToRead = filesToPatch[i].size;
		u8 *buffer = (u8*)memalign(32, sizeToRead);
		
		deviceHandler_seekFile(file,filesToPatch[i].offset, DEVICE_HANDLER_SEEK_SET);
		if(deviceHandler_readFile(file,buffer,sizeToRead)!= sizeToRead) {
			DrawFrameStart();
			DrawMessageBox(D_FAIL, "Failed to read!");
			DrawFrameFinish();
			sleep(5);
			return 0;
		}
		
		if(curDevice != DVD_DISC) {
			u32 ret = Patch_DVDLowLevelRead(buffer, sizeToRead, filesToPatch[i].type);
			if(READ_PATCHED_ALL != ret)	{
				DrawFrameStart();
				DrawMessageBox(D_FAIL, "Failed to find necessary functions for patching!");
				DrawFrameFinish();
				sleep(5);
			}
			else
				patched += 1;
		}
				
		if(swissSettings.debugUSB && usb_isgeckoalive(1) && !swissSettings.wiirdDebug) {
			patched += Patch_Fwrite(buffer, sizeToRead);
		}
		
		if(swissSettings.wiirdDebug || getEnabledCheatsSize() > 0) {
			Patch_CheatsHook(buffer, sizeToRead, filesToPatch[i].type);
		}
		
		if(curDevice == DVD_DISC && is_gamecube()) {
			patched += Patch_DVDLowLevelReadForDVD(buffer, sizeToRead, filesToPatch[i].type);
			patched += Patch_DVDReset(buffer, sizeToRead);
		}
		
		patched += Patch_VidMode(buffer, sizeToRead, filesToPatch[i].type);
		patched += Patch_FontEnc(buffer, sizeToRead);
		if(swissSettings.forceWidescreen)
			Patch_WideAspect(buffer, sizeToRead, filesToPatch[i].type);
		if(swissSettings.forceAnisotropy)
			Patch_TexFilt(buffer, sizeToRead, filesToPatch[i].type);
		if(patched) {
			// File handle for a patch we might need to write
			FILE *patchFile = 0;
			memset(patchFileName, 0, 256);
		
			// Make a base patches dir if we don't have one already
			if(mkdir(&patchBaseDirName[0], 0777) != 0) {
				if(errno != EEXIST) {
					return -2;
				}
			}
			if(mkdir(&patchDirName[0], 0777) != 0) {
				if(errno != EEXIST) {
					return -2;
				}
			}
			sprintf(patchFileName, "%s/%i",patchDirName, num_patched);

			// Work out the crc32
			crc32 = Crc32_ComputeBuf( 0, buffer, (u32) sizeToRead);

			// See if this file already exists, if it does, match crc
			patchFile = fopen( patchFileName, "rb" );
			if(patchFile) {
				//print_gecko("Old Patch exists\r\n");
				u32 oldCrc32 = 0;
				fseek(patchFile, 0L, SEEK_END);
				u32 file_size = ftell(patchFile);
				fseek(patchFile, file_size-4, SEEK_SET);
				fread(&oldCrc32, 1, 4, patchFile);
				if(oldCrc32 == crc32) {
					num_patched++;
					fclose(patchFile);
					free(buffer);
					print_gecko("CRC matched, no need to patch again\r\n");
					continue;
				}
				else {
					remove(patchFileName);
					fclose(patchFile);
					print_gecko("CRC mismatch, writing patch again\r\n");
				}
			}
			// Otherwise, write a file out for this game with the patched buffer inside.
			print_gecko("Writing patch file: %s %i bytes (disc offset %08X)\r\n", patchFileName, sizeToRead, filesToPatch[i].offset);
			patchFile = fopen(patchFileName, "wb");
			fwrite(buffer, 1, sizeToRead, patchFile);
			u32 magic = SWISS_MAGIC;
			fwrite(&filesToPatch[i].offset, 1, 4, patchFile);
			fwrite(&filesToPatch[i].size, 1, 4, patchFile);
			fwrite(&magic, 1, 4, patchFile);
			fwrite(&crc32, 1, 4, patchFile);
			fclose(patchFile);
			num_patched++;
		}
		free(buffer);
	}

	return num_patched;
}
// This is only called where length = file.size
int deviceHandler_CARD_readFile(file_handle* file, void* buffer, unsigned int length){
	unsigned int slot = file->fileBase>>24, ret = 0, file_no = file->fileBase&0xFFFFFF;
	void *dst = buffer;
	
	// Get the sector size
	u32 SectorSize = 0;
	CARD_GetSectorSize (slot, &SectorSize);
	
	// Create the .gci header
	card_stat CardStat;
	GCI gci;
	CARD_GetStatus(slot,file_no,&CardStat);        
	memset(&gci, 0xFF, sizeof(GCI));
	/*** Populate the GCI ***/
	memcpy(&gci.gamecode, &CardStat.gamecode, 4);
	memcpy(&gci.company, &CardStat.company, 2);
	gci.banner_fmt = CardStat.banner_fmt;
	memcpy(&gci.filename, &CardStat.filename, 0x20);
	gci.time = CardStat.time;
	gci.icon_addr = CardStat.icon_addr;
	gci.icon_fmt = CardStat.icon_fmt;
	gci.icon_speed = CardStat.icon_speed;
	gci.unknown1 = gci.unknown2 = 0;
	gci.index = 32;
	gci.filesize8 = (CardStat.len / 8192);
	gci.comment_addr = CardStat.comment_addr;
	memcpy(dst, &gci, sizeof(GCI));
	dst+= sizeof(GCI);
	
	// Re-init the card with the original file gamecode & company
	char game_code[16];	
	memcpy(&game_code[0],&gci.gamecode, 4);
	game_code[4] = 0;
	CARD_SetGamecode((const char *)&game_code[0]);
	memcpy(&game_code[0],&gci.company, 2);
	game_code[2] = 0;
	CARD_SetCompany((const char *)&game_code[0]);
	
	// Use the original file name
	char file_name[CARD_FILENAMELEN];	
	memset(&file_name[0],0,CARD_FILENAMELEN);
	memcpy(&file_name[0], file->name,strlen(file->name)-4);
	
	print_gecko("Try to open: [%s]\r\n",&file_name[0]);

	// Read the actual file data now
	char *read_buffer = NULL;
	card_file *memcard_file = NULL;
	memcard_file = (card_file*)memalign(32,sizeof(card_file));
	if(!memcard_file) {
		return -2;
	}
	memset(memcard_file, 0, sizeof(card_file));
	
	// Open the Entry
	if((ret = CARD_Open(slot, (const char*)&file_name[0], memcard_file)) != CARD_ERROR_NOFILE){
		/* Allocate the read buffer */
		u32 readSize = ((memcard_file->len % SectorSize) != 0) ? 
						((memcard_file->len/SectorSize)+1) * SectorSize : memcard_file->len;
		read_buffer = memalign(32,SectorSize);
		if(!read_buffer) {
			free(memcard_file);
			return -2;
		}
		
		print_gecko("Reading: [%i] bytes\r\n",readSize);
		
		/* Read the file */
		int i = 0;
		for(i=0;i<(readSize/SectorSize);i++) {
			ret = CARD_Read(memcard_file,read_buffer, SectorSize, i*SectorSize);
			if(!ret) {
				memcpy(dst,read_buffer,(i==(readSize/SectorSize)-1) ? (memcard_file->len % SectorSize):SectorSize);
			}
			dst+=SectorSize;
			print_gecko("Read: [%i] bytes ret [%i]\r\n",SectorSize,ret);
			
		}
	}
	else {
		print_gecko("ret: [%i]\r\n",ret);
		
	}
	CARD_Close(memcard_file);
	free(read_buffer);
	free(memcard_file);      

	return !ret ? length : ret;
}
Beispiel #19
0
// Returns the number of filesToPatch and fills out the filesToPatch array passed in (pre-allocated)
int read_fst(file_handle *file, file_handle** dir, u32 *usedSpace) {

	print_gecko("Read dir for directory: %s\r\n",file->name);
	DiskHeader header;
	char	*FST; 
	char	filename[256];
	int		numFiles = 1, idx = 0;
	int		isRoot = (file->name[0] == '\\');
	
	// Grab disc header
	memset(&header,0,sizeof(DiskHeader));
	DVD_Read(&header,0,sizeof(DiskHeader));
 	// Alloc and read FST
	FST=(char*)memalign(32,header.FSTSize); 
	if(!FST) {
		return -1;
	}
	// Read the FST
 	DVD_Read(FST,header.FSTOffset,header.FSTSize);
	
	// Get the space taken up by this disc
	if(usedSpace) *usedSpace = calc_fst_entries_size(FST);
		
	// Add the disc itself as a "file"
	*dir = malloc( numFiles * sizeof(file_handle) );
	DVD_Read((*dir)[idx].name, 32, 128);
	strcat((*dir)[idx].name, ".gcm");
	(*dir)[idx].fileBase = 0;
	(*dir)[idx].offset = 0;
	(*dir)[idx].size = DISC_SIZE;
	(*dir)[idx].fileAttrib = IS_FILE;
	(*dir)[idx].meta = 0;
	idx++;
	
	u32 entries=*(unsigned int*)&FST[8];
	u32 string_table_offset=FST_ENTRY_SIZE*entries;
		
	int i;
	// Go through the FST and find our DIR (or ROOT)
	int parent_dir_offset = (u32)file->fileBase;
	int dir_end_offset = isRoot ? *(u32*)&FST[8] : 0;
	isRoot = parent_dir_offset==0;
	
	u32 filename_offset=((*(u32*)&FST[parent_dir_offset*0x0C]) & 0x00FFFFFF); 
	memset(&filename[0],0,256);
	memcpy(&filename[0],&FST[string_table_offset+filename_offset],255); 
	dir_end_offset = *(u32*)&FST[(parent_dir_offset*0x0C) + 8];
	
	if(!isRoot) {
		// Add a special ".." dir which will take us back up a dir
		if(idx == numFiles){
			++numFiles;
			*dir = realloc( *dir, numFiles * sizeof(file_handle) ); 
		}
		strcpy((*dir)[idx].name, "..");
		(*dir)[idx].fileBase = *(u32*)&FST[(parent_dir_offset*0x0C)+4];
		(*dir)[idx].offset = 0;
		(*dir)[idx].size = 0;
		(*dir)[idx].fileAttrib = IS_DIR;
		(*dir)[idx].meta = 0;
		idx++;
	}
	//print_gecko("Found DIR [%03i]:%s\r\n",parent_dir_offset,isRoot ? "ROOT":filename);
	
	// Traverse the FST now adding all the files which come under our DIR
	for (i=parent_dir_offset;i<dir_end_offset;i++) {
		if(i==0) continue;
		
		u32 offset=i*0x0c;
		u32 file_offset,size = 0;
		u32 filename_offset=((*(unsigned int*)&FST[offset]) & 0x00FFFFFF); 
		memset(&filename[0],0,256);
		memcpy(&filename[0],&FST[string_table_offset+filename_offset],255); 
		memcpy(&file_offset,&FST[offset+4],4);
		memcpy(&size,&FST[offset+8],4);
		
		// Is this a sub dir of our dir?
		if(FST[offset]) {
			if(file_offset == parent_dir_offset) {
				//print_gecko("Adding: [%03i]%s:%s offset %08X length %08X\r\n",i,!FST[offset] ? "File" : "Dir",filename,file_offset,size);
				if(idx == numFiles){
					++numFiles;
					*dir = realloc( *dir, numFiles * sizeof(file_handle) ); 
				}
				memcpy((*dir)[idx].name, &filename[0], 255);
				(*dir)[idx].fileBase = i;
				(*dir)[idx].offset = 0;
				(*dir)[idx].size = size;
				(*dir)[idx].fileAttrib = IS_DIR;
				(*dir)[idx].meta = 0;
				idx++;
				// Skip the entries that sit in this dir
				i = size-1;
			}
		}
		else {
			// File, add it.
			//print_gecko("Adding: [%03i]%s:%s offset %08X length %08X\r\n",i,!FST[offset] ? "File" : "Dir",filename,file_offset,size);
			if(idx == numFiles){
				++numFiles;
				*dir = realloc( *dir, numFiles * sizeof(file_handle) ); 
			}
			memcpy((*dir)[idx].name, &filename[0], 255);
			(*dir)[idx].fileBase = file_offset;
			(*dir)[idx].offset = 0;
			(*dir)[idx].size = size;
			(*dir)[idx].fileAttrib = IS_FILE;
			(*dir)[idx].meta = 0;
			idx++;
		}
	}
	
	free(FST);

	return numFiles;
}
Beispiel #20
0
s32 deviceHandler_CARD_readFile(file_handle* file, void* buffer, u32 length){
	card_file cardfile;
	void *dst = buffer;
	card_dir* cd = (card_dir*)&file->other;
	char *filename = getRelativeName(file->name);
	unsigned int slot = (!strncmp((const char*)initial_CARDB.name, file->name, 7)), ret = 0;

	if(cd->company[0] == '\0' && cd->gamecode[0] == '\0') {
		// Find the file we don't know about and populate this file_handle if we find it.
		if(!findFile(file)) {
			return CARD_ERROR_NOFILE;
		}
		CARD_SetCompany((const char*)cd->company);
		CARD_SetGamecode((const char*)cd->gamecode);
	} 
	else {
		CARD_SetCompany((const char*)cd->company);
		CARD_SetGamecode((const char*)cd->gamecode);
	}
	int swissFile = !strncmp((const char*)cd->gamecode, "SWIS", 4)
				 && !strncmp((const char*)cd->company, "S0", 2);
	
	// Open the file based on the slot & file name
	ret = CARD_Open(slot,filename, &cardfile);

	print_gecko("Tried to open: [%s] in slot %s got res: %i\r\n",filename, slot ? "B":"A", ret);

	if(ret != CARD_ERROR_READY)	return ret;

	u8 *read_buffer = (u8*)memalign(32,card_sectorsize[slot]);
	if(!read_buffer) {
		return -1;
	}

	/* Read from the file */
	u32 amountRead = 0;
	// If this file was put here by swiss, then skip the first 8192 bytes
	if(swissFile && !isCopyGCIMode) {
		print_gecko("Swiss copied file detected, skipping icon\r\n");
		file->offset += 8192;
	}
	if(isCopyGCIMode) {
		// Write out a .GCI
		card_stat cardstat;
		GCI gci;
		CARD_GetStatus(slot, cardfile.filenum, &cardstat);
		memset(&gci, 0, sizeof(GCI));
		memcpy(&gci.gamecode,cd->gamecode,4);
		memcpy(&gci.company,cd->company,2);
		memcpy(&gci.filename,file->name,CARD_FILENAMELEN);
		gci.reserved01 = 0xFF;
		gci.banner_fmt = cardstat.banner_fmt;
		gci.time = cardstat.time;
		gci.icon_addr = cardstat.icon_addr;
		gci.icon_fmt = cardstat.icon_fmt;
		gci.icon_speed = cardstat.icon_speed;
		gci.unknown1 = cd->permissions;
		gci.filesize8 = cardstat.len / 8192;
		gci.reserved02 = 0xFFFF;
		gci.comment_addr = cardstat.comment_addr;
		memcpy(dst, &gci, sizeof(GCI));
		dst+=sizeof(GCI);
		length-=sizeof(GCI);
		amountRead += sizeof(GCI);
	}
	while(length > 0 && file->offset < file->size) {
		int readsize = length > card_sectorsize[slot] ? card_sectorsize[slot] : length;
		print_gecko("Need to read: [%i] more bytes\r\n", length);
		
		if(file->offset&0x1ff) {
			ret = CARD_ReadUnaligned(&cardfile, read_buffer, card_sectorsize[slot], file->offset, slot);
		}
		else {
			ret = CARD_Read(&cardfile, read_buffer, card_sectorsize[slot], file->offset);
			// Sometimes reads fail the first time stupidly, retry at least once.
			print_gecko("Read: [%i] bytes ret [%i] from offset [%i]\r\n",card_sectorsize[slot],ret, file->offset);
			if(ret == CARD_ERROR_BUSY) {
				print_gecko("Read retry\r\n");
				usleep(2000);
				ret = CARD_Read(&cardfile, read_buffer, card_sectorsize[slot], file->offset);
			}
		}
		
		if(ret == CARD_ERROR_READY)
			memcpy(dst,read_buffer,readsize);
		else 
			return ret;
		dst+=readsize;
		file->offset += readsize;
		length -= readsize;
		amountRead += readsize;
	}
	// For swiss adjusted files, don't trail off the end.
	if(swissFile && length != 0) {
		amountRead+= length;
	}
	DCFlushRange(dst, amountRead);
	CARD_Close(&cardfile);
	free(read_buffer);   

	return amountRead;
}
Beispiel #21
0
/****************************************************************************
* Main
****************************************************************************/
int main () 
{
	// Setup defaults (if no config is found)
	memset(&swissSettings, 0 , sizeof(SwissSettings));

	// Register all devices supported (order matters for boot devices)
	int i = 0;
	for(i = 0; i < MAX_DEVICES; i++)
		allDevices[i] = NULL;
	i = 0;
	allDevices[i++] = &__device_wkf;
	allDevices[i++] = &__device_wode;
	allDevices[i++] = &__device_sd_a;
	allDevices[i++] = &__device_sd_b;
	allDevices[i++] = &__device_card_a;
	allDevices[i++] = &__device_card_b;
	allDevices[i++] = &__device_dvd;
	allDevices[i++] = &__device_ide_a;
	allDevices[i++] = &__device_ide_b;
	allDevices[i++] = &__device_qoob;
	allDevices[i++] = &__device_smb;
	allDevices[i++] = &__device_sys;
	allDevices[i++] = &__device_usbgecko;
	allDevices[i++] = &__device_ftp;
	allDevices[i++] = &__device_fsp;
	allDevices[i++] = NULL;
	
	// Set current devices
	devices[DEVICE_CUR] = NULL;
	devices[DEVICE_DEST] = NULL;
	devices[DEVICE_TEMP] = NULL;
	devices[DEVICE_CONFIG] = NULL;
	devices[DEVICE_PATCHES] = NULL;
	
	Initialise();
	
	// Sane defaults
	refreshSRAM(&swissSettings);
	swissSettings.debugUSB = 0;
	swissSettings.gameVMode = 0;	// Auto video mode
	swissSettings.exiSpeed = 1;		// 32MHz
	swissSettings.uiVMode = 0; 		// Auto UI mode
	swissSettings.aveCompat = 1;
	swissSettings.enableFileManagement = 0;

	needsDeviceChange = 1;
	needsRefresh = 1;
	
	//debugging stuff
	if(swissSettings.debugUSB) {
		if(usb_isgeckoalive(1)) {
			usb_flush(1);
		}
		print_gecko("Arena Size: %iKb\r\n",(SYS_GetArena1Hi()-SYS_GetArena1Lo())/1024);
		print_gecko("DVD Drive Present? %s\r\n",swissSettings.hasDVDDrive?"Yes":"No");
		print_gecko("GIT Commit: %s\r\n", GITREVISION);
		print_gecko("GIT Revision: %s\r\n", GITVERSION);
	}
	
	// Go through all devices with FEAT_BOOT_DEVICE feature and set it as current if one is available
	for(i = 0; i < MAX_DEVICES; i++) {
		if(allDevices[i] != NULL && (allDevices[i]->features & FEAT_BOOT_DEVICE)) {
			print_gecko("Testing device %s\r\n", allDevices[i]->deviceName);
			if(allDevices[i]->test()) {
				deviceHandler_setDeviceAvailable(allDevices[i], true);
				devices[DEVICE_CUR] = allDevices[i];
				break;
			}
		}
	}
	if(devices[DEVICE_CUR] != NULL) {
		print_gecko("Detected %s\r\n", devices[DEVICE_CUR]->deviceName);
		if(devices[DEVICE_CUR]->init(devices[DEVICE_CUR]->initial)) {
			if(devices[DEVICE_CUR]->features & FEAT_AUTOLOAD_DOL) {
				load_auto_dol();
			}
			memcpy(&curFile, devices[DEVICE_CUR]->initial, sizeof(file_handle));
			needsDeviceChange = 0;
		}
	}

	// Scan here since some devices would already be initialised (faster)
	populateDeviceAvailability();

	// If there's no default config device, set it to the first writable device available
	if(swissSettings.configDeviceId == DEVICE_ID_UNK) {
		for(int i = 0; i < MAX_DEVICES; i++) {
			if(allDevices[i] != NULL && (allDevices[i]->features & FEAT_WRITE) && deviceHandler_getDeviceAvailable(allDevices[i])) {
				swissSettings.configDeviceId = allDevices[i]->deviceUniqueId;
				print_gecko("No default config device found, using [%s]\r\n", allDevices[i]->deviceName);
				syssramex* sramex = __SYS_LockSramEx();
				sramex->__padding0 = swissSettings.configDeviceId;
				__SYS_UnlockSramEx(1);
				while(!__SYS_SyncSram());
				break;
			}
		}
	}
	
	// Try to open up the config .ini in case it hasn't been opened already
	if(config_init()) {
		// TODO notification area this
		print_gecko("Loaded %i entries from the config file\r\n",config_get_count());
	}
	
	if(swissSettings.initNetworkAtStart) {
		// Start up the BBA if it exists
		uiDrawObj_t *msgBox = DrawPublish(DrawProgressBar(true, 0, "Initialising Network"));
		init_network();
		init_httpd_thread();
		DrawDispose(msgBox);
	}
	
	// DVD Motor off setting; Always stop the drive if we only started it to read the ID out
	if((swissSettings.stopMotor && swissSettings.hasDVDDrive) || (swissSettings.hasDVDDrive == 2)) {
		dvd_motor_off();
	}

	// Swiss video mode force
	GXRModeObj *forcedMode = getVideoModeFromSwissSetting(swissSettings.uiVMode);
	
	if((forcedMode != NULL) && (forcedMode != getVideoMode())) {
		setVideoMode(forcedMode);
	}

	while(1) {
		menu_loop();
	}
	return 0;
}
Beispiel #22
0
void verify_init(char *mountPath) {
	if (verify_initialized) {
		return;
	}
	
	if(ngcDAT) {
		if(ngcXML) {
			mxmlDelete(ngcXML);
			free(ngcXML);
		}
		free(ngcDAT);
	}
	if(wiiDAT) {
		free(wiiDAT);
		if(wiiXML) {
			mxmlDelete(wiiXML);
			free(wiiXML);
		}
	}

	mxmlSetErrorCallback(print_gecko);
	FILE *fp = NULL;
	// Check for the Gamecube Redump.org DAT and read it
	sprintf(txtbuffer, "%sgc.dat", mountPath);
	fp = fopen(txtbuffer, "rb");
	if (fp) {
		fseek(fp, 0, SEEK_END);
		int size = ftell(fp);
		fseek(fp, 0, SEEK_SET);
		if (size > 0) {
			ngcDAT = (char*) memalign(32, size);
			if (ngcDAT) {
				fread(ngcDAT, 1, size, fp);
			}		
		}
		fclose(fp);
		fp = NULL;
	}

	// Check for the Wii Redump.org DAT and read it
	sprintf(txtbuffer, "%swii.dat", mountPath);
	fp = fopen(txtbuffer, "rb");
	if (fp) {
		fseek(fp, 0L, SEEK_END);
		int size = ftell(fp);
		fseek(fp, 0, SEEK_SET);
		if (size > 0) {
			wiiDAT = (char*) memalign(32, size);
			if (wiiDAT) {
				fread(wiiDAT, 1, size, fp);
			}
		}	
		fclose(fp);
		fp = NULL;
	}
	
	if (ngcDAT) {
		ngcXML = mxmlLoadString(NULL, ngcDAT, MXML_TEXT_CALLBACK);
	}
	if (wiiDAT) {
		wiiXML = mxmlLoadString(NULL, wiiDAT, MXML_TEXT_CALLBACK);
	}

	print_gecko("DAT Files [NGC: %s] [Wii: %s]\r\n", ngcDAT ? "YES":"NO", wiiDAT ? "YES":"NO");
	verify_initialized = ((ngcDAT&&ngcXML) && (wiiDAT&&wiiXML));
}
Beispiel #23
0
int findCheats(bool silent) {
	char trimmedGameId[8], testBuffer[8];
	memset(trimmedGameId, 0, 8);
	memcpy(trimmedGameId, (char*)&GCMDisk, 6);
	file_handle *cheatsFile = memalign(32,sizeof(file_handle));
	memset(cheatsFile, 0, sizeof(file_handle));
	sprintf(cheatsFile->name, "%s/cheats/%s.txt", devices[DEVICE_CUR]->initial->name, trimmedGameId);
	print_gecko("Looking for cheats file @ [%s]\r\n", cheatsFile->name);

	devices[DEVICE_TEMP] = devices[DEVICE_CUR];

	// Check SD in both slots if we're not already running from SD, or if we fail from current device
	if(devices[DEVICE_TEMP]->readFile(cheatsFile, &testBuffer, 8) != 8) {
		// Try SD slots now
		if(devices[DEVICE_CUR] != &__device_sd_a) {
			devices[DEVICE_TEMP] = &__device_sd_a;
		}
		else {
			devices[DEVICE_TEMP] = &__device_sd_b;
		}
		file_handle *slotFile = devices[DEVICE_TEMP]->initial;
		memset(cheatsFile, 0, sizeof(file_handle));
		sprintf(cheatsFile->name, "%s/cheats/%s.txt", slotFile->name, trimmedGameId);
		print_gecko("Looking for cheats file @ [%s]\r\n", cheatsFile->name);

		deviceHandler_setStatEnabled(0);
		devices[DEVICE_TEMP]->init(cheatsFile);
		if(devices[DEVICE_TEMP]->readFile(cheatsFile, &testBuffer, 8) != 8) {
			if(devices[DEVICE_TEMP] == &__device_sd_b) {
				devices[DEVICE_TEMP] = NULL;	// We already tried this & failed.
			}
			else {
				devices[DEVICE_TEMP] = &__device_sd_b;
				slotFile = devices[DEVICE_TEMP]->initial;
				memset(cheatsFile, 0, sizeof(file_handle));
				sprintf(cheatsFile->name, "%s/cheats/%s.txt", slotFile->name, trimmedGameId);
				print_gecko("Looking for cheats file @[%s]\r\n", cheatsFile->name);

				devices[DEVICE_TEMP]->init(cheatsFile);
				if(devices[DEVICE_TEMP]->readFile(cheatsFile, &testBuffer, 8) != 8) {
					devices[DEVICE_TEMP] = NULL;
				}
			}
		}
		deviceHandler_setStatEnabled(1);
	}
	// Still fail?
	if(devices[DEVICE_TEMP] == NULL) {
		if(!silent) {
			while(PAD_ButtonsHeld(0) & PAD_BUTTON_Y);
			uiDrawObj_t *msgBox = DrawMessageBox(D_INFO,"No cheats file found.\nPress A to continue.");
			DrawPublish(msgBox);
			while(!(PAD_ButtonsHeld(0) & PAD_BUTTON_A));
			while(PAD_ButtonsHeld(0) & PAD_BUTTON_A);
			DrawDispose(msgBox);
		}
		free(cheatsFile);
		return 0;
	}
	print_gecko("Cheats file found with size %i\r\n", cheatsFile->size);
	char *cheats_buffer = memalign(32, cheatsFile->size);
	if(cheats_buffer) {
		devices[DEVICE_TEMP]->seekFile(cheatsFile, 0, DEVICE_HANDLER_SEEK_SET);
		devices[DEVICE_TEMP]->readFile(cheatsFile, cheats_buffer, cheatsFile->size);
		parseCheats(cheats_buffer);
		free(cheats_buffer);
		free(cheatsFile);
	}
	return _cheats.num_cheats;
}