/*
	Downgrade Launcher R1
	by Davee
	
	Fin-rev 24/01/2011
*/

#include <pspkernel.h>
#include <pspsdk.h>
#include <psputility.h>
#include <pspctrl.h>

#include <pspsysmem_kernel.h>
#include <psploadexec_kernel.h>
#include <psploadcore.h>

#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <malloc.h>

#include "utils.h"
#include "kernel_land.h"
#include "kernel_exploit.h"
#include "rebootex.h"

PSP_MODULE_INFO("6.60/6.39/6.38/6.60 downgrader", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_VFPU);
PSP_HEAP_SIZE_KB(3 << 10);

int main(int argc, char *argv[])
{
	int res;
	SceCtrlData pad_data;
	u32 cur_buttons, prev_buttons = 0;

#ifdef HBL_SUKKIRI
	pspUtilityHtmlViewerParam html_param;
#endif
	
	/* initialise the PSP screen */
	pspDebugScreenInit();
	pspDebugScreenSetTextColor(0x00D05435);
	
	/* display welcome message */
	printf("6.60/6.39/6.38/6.35/6.31 Downgrader\n" "By Davee, ported to 6.38/6.39/6.60 by some1\n\n" "Please wait... ");

#ifdef HBL_SUKKIRI	
	/* Clear html param to 0 */
	memset(&html_param, 0, sizeof(pspUtilityHtmlViewerParam));
	
	/* set enough params in html viewer to get through to module loading */
	html_param.base.size = sizeof(pspUtilityHtmlViewerParam);
	html_param.base.accessThread = 0xF;
	
	/* call sceUtilityHtmlViewerInitStart to load the htmlviewer_utility.prx which imports sceutility/scepower exploit */
	res = sceUtilityHtmlViewerInitStart(&html_param);
	
	/* check error */
	if (res < 0)
	{
		/* this could be an HBL resolving issue... */
		ErrorExit(5000, "Error 0x%08X starting htmlviewer\n", res);
	}
	
	/* wait a second for htmlviewer to get loaded */
	sceKernelDelayThread(1 * 1000 * 1000);
#endif
	
	/* do the kernel exploit */
	doKernelExploit();
	
	/* printf ok message */
	printf("OK\n");
	
	/* set the devkit */
	g_devkit_version = sceKernelDevkitVersion();
	
	/* get the PSP model */
	int model = execKernelFunction(getModel);
	
	printf("Your PSP Model is %02ig.\n", model+1);
	sceKernelDelayThread(5*1000*1000);
	
	if(model == 6 || model == 8)
	{
		model = 3;
	}
	
	/* check for unsupported model */
	if (model != 0 &&			/* PSP PHAT */
		model != 1 &&			/* PSP SLIM */
		model != 2 &&			/* PSP 3000 */
		model != 3 &&			/* PSP 4000 */
		model != 4				/* PSPgo */
	)
	{
		/* unsupported */
		ErrorExit(5000, "PSP %02ig not supported.\n", model+1);
	}
	
	/* check for pspgo */
	if (model == 4)
	{
		printf("\n" "Your PSPgo will require deletion of the [Resume Game] feature. Proceed? (X = Yes, R = No)\n");
		
		while (1)
		{
			sceCtrlPeekBufferPositive(&pad_data, 1);
			
			/* filter out previous buttons */
			cur_buttons = pad_data.Buttons & ~prev_buttons;
			prev_buttons = pad_data.Buttons;
			
			/* check for cross */
			if (cur_buttons & PSP_CTRL_CROSS)
			{
				break;
			}
			
			else if (cur_buttons & PSP_CTRL_RTRIGGER)
			{
				ErrorExit(5000, "Exiting in 5 seconds.\n");
			}
		}
		
		/* delete resume game */
		if (execKernelFunction(delete_resume_game) < 0)
		{
			/* ERROR */
			ErrorExit(5000, "Error deleting [Resume Game]. Exiting for safety reasons.\n");
		}
	}
	
	/* clear screen */
	pspDebugScreenClear();
	
	/* update should be OK, go for it */
	printf("By running this application and launching the SCE updater you accept all responsibility of any damage, temporary or permament, that may occur when using this application. This application has been tested with no loss of functionality or any damage to the system, however  it cannot be guaranteed to be completely safe." "\n" "BY RUNNING THIS APPLICATION YOU ACCEPT ALL THE RISK INVOLVED.\n\n" "Press X to start SCE updater. Press R to exit\n");
	
	while (1)
	{
		sceCtrlPeekBufferPositive(&pad_data, 1);

		/* filter out previous buttons */
		cur_buttons = pad_data.Buttons & ~prev_buttons;
		prev_buttons = pad_data.Buttons;
		
		/* check for cross */
		if (cur_buttons & PSP_CTRL_CROSS)
		{
			break;
		}
		
		else if (cur_buttons & PSP_CTRL_RTRIGGER)
		{
			ErrorExit(5000, "Exiting in 5 seconds.\n");
		}
	}

	printf("OK, good for launch\n");
	
	/* go go go go go */
	res = execKernelFunction(launch_updater);
	
	printf("loading SCE updater failed = 0x%08X\n", res);
	sceKernelDelayThread(5 *1000*1000);
	sceKernelExitGame();
	return 0;
}
