PageRenderTime 74ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/WII/uLoader/source/uloader.c

http://codigos-luciferfran.googlecode.com/
C | 2767 lines | 1818 code | 775 blank | 174 comment | 406 complexity | 21254956e8291bf0f67782ad7e049a8d MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, BSD-3-Clause
  1. /* uLoader- Project based in YAL and usbloader by Hermes */
  2. /*
  3. Copyright (C) 2009-2010 Hermes
  4. Copyright (C) 2009 Kwiirk (YAL)
  5. Copyright (C) 2009 Waninkoko (usbloader)
  6. Yet Another Loader. The barely minimum usb loader
  7. Based on SoftChip, which should be based on GeckoOS...
  8. no video, no input, try to load the wbfs passed as argument or return to menu.
  9. This program is free software; you can redistribute it and/or modify
  10. it under the terms of the GNU General Public License as published by
  11. the Free Software Foundation; either version 2 of the License, or
  12. (at your option) any later version.
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. GNU General Public License for more details.
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. // ALTERNATIVE_VERSION
  22. #include <gccore.h>
  23. #include <string.h>
  24. #include <malloc.h>
  25. #include "defs.h"
  26. #include "utils.h"
  27. #include <stdlib.h>
  28. #include <unistd.h>
  29. #include "libpng/pngu/pngu.h"
  30. #include "libwbfs/libwbfs.h"
  31. #include "libwbfs/wiiscrubber.h"
  32. #include "wbfs.h"
  33. #include "usbstorage2.h"
  34. #include <wiiuse/wpad.h>
  35. #include <sdcard/wiisd_io.h>
  36. #include "wdvd.h"
  37. #include "disc.h"
  38. #include <network.h>
  39. #include "remote.h"
  40. #include "global.h"
  41. #include "cheats.h"
  42. #include "sys/dir.h"
  43. #include "fatffs_util.h"
  44. #include "diario.h"
  45. #include "sonido.h"
  46. #include "fatffs_util.h"
  47. #include "dolmenu.h"
  48. char uloader_version[5]="5.1E"; // yes, you can change here the current version of the application
  49. char *str_trace=NULL;
  50. test_t *dolmenubuffer=NULL;
  51. extern u32 dolparameter;
  52. int skip_alternative_dol=0;
  53. u32 INK0= 0xf0000000;
  54. u32 INK1= 0xfff0f0f0;
  55. int in_black=0;
  56. int shadow_mload=0;
  57. // WBFS game configuration datas
  58. // field1: In Use (32 bits), field2: Unused (32 bits)
  59. // NOTE: Remember you field1 is saved in little endian format (the struct use big endian format, so you must reverse bytes)
  60. typedef struct
  61. {
  62. // byte 0
  63. u32 skip_boot :1; // skip boot content in Wiiwares. Old skip ios option
  64. u32 game_locked :1; // parental control
  65. u32 bca_mode :1; // bca mode 0:-> from disc 1-> from data base
  66. u32 pad3 :2;
  67. u32 hook_selected :3; // hooktype option for cheats
  68. // byte 1
  69. u32 pad2 :8;
  70. //u32 shadow_mload :1;
  71. // byte 2
  72. u32 dont_use_diary :1; // if one don't register the game in the diary
  73. u32 pad1 :2;
  74. u32 nand_mode :5; // nand_mode -> bit 0-> use SD, bit 1-> use USB, bit 2-3 -> nand folder , bit 4 -> DLC from x:/nand
  75. // byte 3
  76. u32 language :4; // language: 0-> default 1->japanese...
  77. u32 modevideo :2; // modevideo 0-> auto 1-> PAL 60 2-> NTSC 3-> PAL 50
  78. u32 ios_selected :2; // bit 0-> Use cIOS 224 (old cIOS 249), if bit 0==0 bit 1-> 0= use cIOS 222, 1= use cIOS 223
  79. } cfg_field1;
  80. cfg_field1 *game_cfg_field1=NULL;
  81. /*
  82. uhack_settings0
  83. bit 0 -> 'back in black'
  84. bit 1 -> force IOS 224 instead 222
  85. */
  86. extern u8 uhack_settings0;
  87. extern u8 launch_short;
  88. extern int bootTitle(u64 titleid);
  89. int cios_list[3]={222,223,224};
  90. int global_mount=0;
  91. u32 nand_mode=0;
  92. int frames2=0;
  93. int use_port1=0;
  94. extern float angle_icon; // angle for pointer
  95. int use_icon2=0;
  96. #define MEM_PRINT
  97. int test_mode=0;
  98. int is_fat=0; // working in FAT .ciso Mode
  99. int dvd_only=0; // no WBFS HDD (FAT .ciso, DVD USB, DVD)
  100. int dont_use_diary=0;
  101. u32 load_wip_code(u8 *gameid);
  102. #define CIOS 222
  103. #include <stdarg.h>
  104. #include <stdio.h>
  105. #include "screen.h"
  106. #include "fat.h"
  107. #include <math.h>
  108. #include "gfx.h"
  109. #ifndef ALTERNATIVE_VERSION
  110. #include "resources/defpng.h"
  111. #include "resources/defpng2.h"
  112. #include "resources/button1.h"
  113. #include "resources/button2.h"
  114. #include "resources/button3.h"
  115. #include "resources/icon.h"
  116. #include "resources/sound.h"
  117. #else
  118. #include "resources_alt/defpng.h"
  119. #include "resources_alt/defpng2.h"
  120. #include "resources_alt/button1.h"
  121. #include "resources_alt/button2.h"
  122. #include "resources_alt/button3.h"
  123. #include "resources_alt/icon.h"
  124. #include "resources_alt/sound.h"
  125. #endif
  126. #include "files.h"
  127. #include "mload_modules.h"
  128. extern int home_menu(struct discHdr *header);
  129. extern int call_home_menu(struct discHdr *header, int function);
  130. extern unsigned hiscore;
  131. extern int pintor();
  132. static syswd_t scr_poweroff;
  133. int time_sleep=0;
  134. static void scr_poweroff_handler(syswd_t alarm, void * arg)
  135. {
  136. if(time_sleep>1) time_sleep--;
  137. if(time_sleep==1) SetVideoSleep(1);
  138. }
  139. #define ticks_to_msecs(ticks) ((u32)((ticks)/(TB_TIMER_CLOCK)))
  140. u32 gettick();
  141. int is_16_9=0;
  142. //#include "logmodule.h"
  143. extern void* SYS_AllocArena2MemLo(u32 size,u32 align);
  144. u8 BCA_Data[64] ATTRIBUTE_ALIGN(32);
  145. int BCA_ret=-1;
  146. int show_bca=0;
  147. int force_reload_ios222=0;
  148. int forcevideo=0;
  149. int sd_ok=0;
  150. int ud_ok=0;
  151. #define USE_MODPLAYER 1
  152. #ifdef USE_MODPLAYER
  153. #include "asndlib.h"
  154. #ifdef ALTERNATIVE_VERSION
  155. #include "oggplayer.h"
  156. #include "resources_alt/bg_music.h"
  157. #else
  158. // MOD Player
  159. #include "gcmodplay.h"
  160. MODPlay mod_track;
  161. #include "resources/lotus3_2.h"
  162. #endif
  163. #endif
  164. // parental control flag
  165. int parental_control_on=1;
  166. /*LANGUAGE PATCH - FISHEARS*/
  167. u32 langsel = 0;
  168. char languages[11][22] =
  169. {
  170. {" Default "},
  171. {" Japanese "},
  172. {" English "},
  173. {" German "},
  174. {" French "},
  175. {" Spanish "},
  176. {" Italian "},
  177. {" Dutch "},
  178. {"S. Chinese"},
  179. {"T. Chinese"},
  180. {" Korean "}
  181. };
  182. u32 hook_selected=1;
  183. char hook_type_name[8][16]={
  184. " VBI ",
  185. " KPAD ",
  186. " Joypad ",
  187. " GXDraw ",
  188. " GXFlush ",
  189. "OSSleepThread",
  190. " AXNextFrame ",
  191. " VBI OLD "
  192. };
  193. //---------------------------------------------------------------------------------
  194. /* Global definitions */
  195. //---------------------------------------------------------------------------------
  196. int force_ios249=0;
  197. unsigned char *buff_cheats=NULL;
  198. int len_cheats=0;
  199. extern int cheats_for_wiiware;
  200. int load_cheats(u8 *discid);
  201. int load_disc(u8 *discid);
  202. // to use temporary
  203. u8 *temp_data= NULL;
  204. // to read the game conf datas
  205. u8 *disc_conf= NULL;
  206. // texture of white-noise animation generated here
  207. u32 *game_empty= NULL;
  208. s8 sound_effects[2][2048] ATTRIBUTE_ALIGN(32);
  209. //---------------------------------------------------------------------------------
  210. /* language GUI */
  211. //---------------------------------------------------------------------------------
  212. int idioma=0;
  213. char letrero[2][70][64]=
  214. {
  215. {"Return", "Configure", "Delete Favorite", "Add Favorite", "Load Game", "Add to Favorites", "Favorites", "Page", "Ok" ,"Discard",
  216. " Cheats Codes found !!! ", "Apply Codes ", "Skip Codes ", "Format WBFS", "Selected", "You have one WBFS partition", "Are You Sure You Can Format?",
  217. " Yes ", " No ", "Formatting...","Formatting Disc Successfull","Formatting Disc Failed",
  218. //22
  219. "Return", "Add New Game", "Add PNG Bitmap", "Delete PNG Bitmap", "Fix Parental Control","Return to Wii Menu", "Rename Game", "Delete Game", "Format Disc",
  220. "Alternative .dol","uLoader Update","uLoader Hacks","","",
  221. //36
  222. "Are you sure you want delete this?", "Press A to accept or B to cancel",
  223. // 38
  224. "Insert the game DVD disc...", "ERROR! Aborted", "Press B to Abort","Opening DVD disc...", "ERROR: Not a Wii disc!!",
  225. "ERROR: Game already installed!!!", "Installing game, please wait... ", "Done", "Change the password", "Use this password?","Restore Name",
  226. //49
  227. "Delete Alternative .dol", ".dol Search", "Searching for .dol...","Alternative .dol Selected","Alternative .dol Deleted", "Edit CFG #1", "Edit CFG #2",
  228. // 56
  229. "ehcmodule - Use USB Port 1", "ehcmodule - Use Bulk Reset","ehcmodule - Force GetMaxLun", "ehcmodule - Force SetConfiguration", "ehcmodule - Alternative Timeout",
  230. "No More Snow, Please!!!", "Automatic DVD/SD Mode", "Short Direct Launch (from Channel)", "Back in Black", "Force IOS 224 instead IOS 222", "???"
  231. },
  232. // spanish
  233. {"Retorna", "Configurar", "Borra Favorito", "A?ade Favorito", "Carga juego", "A?ade a Favoritos", "Favoritos", "Página", "Hecho", "Descartar",
  234. " Códigos de Trucos encontrados !!! ","Usa Códigos", "Salta Códigos", "Formatear WBFS", "Seleccionado", "Ya tienes una partición WBFS",
  235. "?Estas seguro que quieres formatear?", " Si ", " No ", "Formateando...", "Exito Formateando el Disco", "Error al Formatear el Disco",
  236. //22
  237. "Retornar", "A?adir Nuevo Juego", "A?adir Bitmap PNG", "Borrar Bitmap PNG", "Fijar Control Parental", "Retorna al Menu de Wii", "Renombrar Juego", "Borrar Juego", "Formatear Disco",
  238. ".dol Alternativo","Actualización de uLoader","uLoader Hacks","","",
  239. //36
  240. "?Estás seguro de que quieres borrar éste?", "Pulsa A para aceptar o B para cancelar",
  241. // 38
  242. "Inserta el DVD del juego ...", "ERROR! Abortado", "Pulsa B para Abortar","Abriendo el disco DVD...", "ERROR: No es un disco de Wii!!",
  243. "ERROR: Juego ya instalado!!!", "Instalando el juego, espera... ", "Terminado", "Cambia la contrase?a", "?Usar esta contrase?a?", "Restaurar Nombre",
  244. //49
  245. "Borrar .dol Alternativo", "Buscar .dol", "Buscando ficheros .dol...","Alternativo .dol Seleccionado","Alternativo .dol Borrado", "Editar CFG #1", "Editar CFG #2",
  246. // 56
  247. "ehcmodule - Usa Puerto USB 1", "ehcmodule - Usa Reset Bulk", "ehcmodule - Fuerza GetMaxLun", "ehcmodule - Fuerza SetConfiguration", "ehcmodule - Timeout Alternativo",
  248. "No Mas Nieve, Por Favor!!!", "Modo DVD/SD Automático", "Lanzamiento Directo Corto (Desde Canal)", "Back in Black", "Fuerza IOS 224 en lugar de IOS 222", "???",
  249. },
  250. };
  251. _config_file config_file ATTRIBUTE_ALIGN(32);
  252. //---------------------------------------------------------------------------------
  253. /* Reset and Power Off */
  254. //---------------------------------------------------------------------------------
  255. int exit_by_reset=0;
  256. int return_reset=2;
  257. void reset_call() {exit_by_reset=return_reset;}
  258. void power_call() {exit_by_reset=3;}
  259. int cios = CIOS;
  260. //---------------------------------------------------------------------------------
  261. /* from Waninkoko usbloader */
  262. //---------------------------------------------------------------------------------
  263. /* Gamelist variables */
  264. struct discHdr *gameList = NULL;
  265. u32 gameCnt = 0;
  266. s32 __Menu_EntryCmp(const void *a, const void *b)
  267. {
  268. struct discHdr *hdr1 = (struct discHdr *)a;
  269. struct discHdr *hdr2 = (struct discHdr *)b;
  270. /* Compare strings */
  271. return strcmp(hdr1->title, hdr2->title);
  272. }
  273. //---------------------------------------------------------------------------------
  274. /* Wiimote's routines */
  275. //---------------------------------------------------------------------------------
  276. unsigned temp_pad=0,new_pad=0,old_pad=0;
  277. WPADData * wmote_datas=NULL;
  278. // wiimote position (temp)
  279. int px=-100,py=-100;
  280. // wiimote position emulated for Guitar
  281. int guitar_pos_x,guitar_pos_y;
  282. static int w_index=-1;
  283. int rumble=0;
  284. void wiimote_rumble(int status)
  285. {
  286. if(config_file.rumble_off) status=0;
  287. //if(status==0) rumble=0;
  288. if(w_index<0)
  289. {
  290. if(status==0)
  291. {
  292. WPAD_Rumble(0, status);
  293. WPAD_Rumble(1, status);
  294. WPAD_Rumble(2, status);
  295. WPAD_Rumble(3, status);
  296. }
  297. return;
  298. }
  299. WPAD_Rumble(w_index, status);
  300. }
  301. void make_rumble_off()
  302. {
  303. int n;
  304. rumble=0;
  305. for(n=0;n<3;n++)
  306. {
  307. usleep(30*1000);
  308. wiimote_rumble(0);
  309. WPAD_Flush(w_index);
  310. WPAD_ScanPads();
  311. }
  312. }
  313. unsigned wiimote_read()
  314. {
  315. int n;
  316. int ret=-1;
  317. unsigned type=0;
  318. unsigned butt=0;
  319. wmote_datas=NULL;
  320. w_index=-1;
  321. for(n=0;n<4;n++) // busca el primer wiimote encendido y usa ese
  322. {
  323. ret=WPAD_Probe(n, &type);
  324. if(ret>=0)
  325. {
  326. butt=WPAD_ButtonsHeld(n);
  327. wmote_datas=WPAD_Data(n);
  328. w_index=n;
  329. break;
  330. }
  331. }
  332. if(n==4) butt=0;
  333. temp_pad=butt;
  334. new_pad=temp_pad & (~old_pad);old_pad=temp_pad;
  335. if(new_pad)
  336. {
  337. time_sleep=TIME_SLEEP_SCR;
  338. SetVideoSleep(0);
  339. }
  340. return butt;
  341. }
  342. void wiimote_ir()
  343. {
  344. px=wmote_datas->ir.x-104*is_16_9;py=wmote_datas->ir.y;
  345. angle_icon=wmote_datas->orient.roll;
  346. time_sleep=TIME_SLEEP_SCR;
  347. SetVideoSleep(0);
  348. SetTexture(NULL);
  349. DrawIcon(px,py,frames2);
  350. }
  351. void wiimote_guitar()
  352. {
  353. angle_icon=0.0f;
  354. if(wmote_datas->exp.gh3.js.pos.x>=wmote_datas->exp.gh3.js.center.x+8)
  355. {guitar_pos_x+=8;if(guitar_pos_x>(SCR_WIDTH+104*is_16_9-16)) guitar_pos_x=(SCR_WIDTH+104*is_16_9-16);}
  356. if(wmote_datas->exp.gh3.js.pos.x<=wmote_datas->exp.gh3.js.center.x-8)
  357. {guitar_pos_x-=8;if(guitar_pos_x<16-104*is_16_9) guitar_pos_x=16-104*is_16_9;}
  358. if(wmote_datas->exp.gh3.js.pos.y>=wmote_datas->exp.gh3.js.center.y+8)
  359. {guitar_pos_y-=8;if(guitar_pos_y<16) guitar_pos_y=16;}
  360. if(wmote_datas->exp.gh3.js.pos.y<=wmote_datas->exp.gh3.js.center.y-8)
  361. {guitar_pos_y+=8;if(guitar_pos_y>(SCR_HEIGHT-16)) guitar_pos_y=(SCR_HEIGHT-16);}
  362. if(guitar_pos_x<-104*is_16_9) guitar_pos_x=104*is_16_9;
  363. if(guitar_pos_x>(SCR_WIDTH-16+104*is_16_9)) guitar_pos_x=(SCR_WIDTH-16+104*is_16_9);
  364. if(guitar_pos_y<0) guitar_pos_y=0;
  365. if(guitar_pos_y>(SCR_HEIGHT-16)) guitar_pos_y=(SCR_HEIGHT-16);
  366. if(px!=guitar_pos_x || py!=guitar_pos_y)
  367. {
  368. time_sleep=TIME_SLEEP_SCR;
  369. SetVideoSleep(0);
  370. }
  371. px=guitar_pos_x; py=guitar_pos_y;
  372. SetTexture(NULL);
  373. DrawIcon(px,py,frames2);
  374. if(new_pad & WPAD_GUITAR_HERO_3_BUTTON_GREEN) new_pad|=WPAD_BUTTON_A;
  375. if(old_pad & WPAD_GUITAR_HERO_3_BUTTON_GREEN) old_pad|=WPAD_BUTTON_A;
  376. if(new_pad & WPAD_GUITAR_HERO_3_BUTTON_RED) new_pad|=WPAD_BUTTON_B;
  377. if(old_pad & WPAD_GUITAR_HERO_3_BUTTON_RED) old_pad|=WPAD_BUTTON_B;
  378. if(new_pad & WPAD_GUITAR_HERO_3_BUTTON_YELLOW) new_pad|=WPAD_BUTTON_1;
  379. if(old_pad & WPAD_GUITAR_HERO_3_BUTTON_YELLOW) old_pad|=WPAD_BUTTON_1;
  380. if(new_pad & WPAD_GUITAR_HERO_3_BUTTON_MINUS) new_pad|=WPAD_BUTTON_MINUS;
  381. if(old_pad & WPAD_GUITAR_HERO_3_BUTTON_MINUS) old_pad|=WPAD_BUTTON_MINUS;
  382. if(new_pad & WPAD_GUITAR_HERO_3_BUTTON_PLUS) new_pad|=WPAD_BUTTON_PLUS;
  383. if(old_pad & WPAD_GUITAR_HERO_3_BUTTON_PLUS) old_pad|=WPAD_BUTTON_PLUS;
  384. }
  385. void wiimote_classic()
  386. {
  387. angle_icon=0.0f;
  388. if(wmote_datas->exp.classic.ljs.pos.x>=wmote_datas->exp.classic.ljs.center.x+8)
  389. {guitar_pos_x+=8;if(guitar_pos_x>(SCR_WIDTH+104*is_16_9-16)) guitar_pos_x=(SCR_WIDTH+104*is_16_9-16);}
  390. if(wmote_datas->exp.classic.ljs.pos.x<=wmote_datas->exp.classic.ljs.center.x-8)
  391. {guitar_pos_x-=8;if(guitar_pos_x<16-104*is_16_9) guitar_pos_x=16-104*is_16_9;}
  392. if(wmote_datas->exp.classic.ljs.pos.y>=wmote_datas->exp.classic.ljs.center.y+8)
  393. {guitar_pos_y-=8;if(guitar_pos_y<16) guitar_pos_y=16;}
  394. if(wmote_datas->exp.classic.ljs.pos.y<=wmote_datas->exp.classic.ljs.center.y-8)
  395. {guitar_pos_y+=8;if(guitar_pos_y>(SCR_HEIGHT-16)) guitar_pos_y=(SCR_HEIGHT-16);}
  396. if(guitar_pos_x<-104*is_16_9) guitar_pos_x=104*is_16_9;
  397. if(guitar_pos_x>(SCR_WIDTH-16+104*is_16_9)) guitar_pos_x=(SCR_WIDTH-16+104*is_16_9);
  398. if(guitar_pos_y<0) guitar_pos_y=0;
  399. if(guitar_pos_y>(SCR_HEIGHT-16)) guitar_pos_y=(SCR_HEIGHT-16);
  400. if(px!=guitar_pos_x || py!=guitar_pos_y)
  401. {
  402. time_sleep=TIME_SLEEP_SCR;
  403. SetVideoSleep(0);
  404. }
  405. px=guitar_pos_x; py=guitar_pos_y;
  406. SetTexture(NULL);
  407. DrawIcon(px,py,frames2);
  408. if(new_pad & WPAD_CLASSIC_BUTTON_UP) new_pad|=WPAD_BUTTON_UP;
  409. if(old_pad & WPAD_CLASSIC_BUTTON_UP) old_pad|=WPAD_BUTTON_UP;
  410. if(new_pad & WPAD_CLASSIC_BUTTON_DOWN) new_pad|=WPAD_BUTTON_DOWN;
  411. if(old_pad & WPAD_CLASSIC_BUTTON_DOWN) old_pad|=WPAD_BUTTON_DOWN;
  412. if(new_pad & WPAD_CLASSIC_BUTTON_LEFT) new_pad|=WPAD_BUTTON_LEFT;
  413. if(old_pad & WPAD_CLASSIC_BUTTON_LEFT) old_pad|=WPAD_BUTTON_LEFT;
  414. if(new_pad & WPAD_CLASSIC_BUTTON_RIGHT) new_pad|=WPAD_BUTTON_RIGHT;
  415. if(old_pad & WPAD_CLASSIC_BUTTON_RIGHT) old_pad|=WPAD_BUTTON_RIGHT;
  416. if(new_pad & WPAD_CLASSIC_BUTTON_A) new_pad|=WPAD_BUTTON_A;
  417. if(old_pad & WPAD_CLASSIC_BUTTON_A) old_pad|=WPAD_BUTTON_A;
  418. if(new_pad & WPAD_CLASSIC_BUTTON_B) new_pad|=WPAD_BUTTON_B;
  419. if(old_pad & WPAD_CLASSIC_BUTTON_B) old_pad|=WPAD_BUTTON_B;
  420. if(new_pad & WPAD_CLASSIC_BUTTON_X) new_pad|=WPAD_BUTTON_1;
  421. if(old_pad & WPAD_CLASSIC_BUTTON_X) old_pad|=WPAD_BUTTON_1;
  422. if(new_pad & WPAD_CLASSIC_BUTTON_Y) new_pad|=WPAD_BUTTON_2;
  423. if(old_pad & WPAD_CLASSIC_BUTTON_Y) old_pad|=WPAD_BUTTON_2;
  424. if(new_pad & WPAD_CLASSIC_BUTTON_HOME) new_pad|=WPAD_BUTTON_HOME;
  425. if(old_pad & WPAD_CLASSIC_BUTTON_HOME) old_pad|=WPAD_BUTTON_HOME;
  426. if(new_pad & WPAD_CLASSIC_BUTTON_PLUS) new_pad|=WPAD_BUTTON_PLUS;
  427. if(old_pad & WPAD_CLASSIC_BUTTON_PLUS) old_pad|=WPAD_BUTTON_PLUS;
  428. if(new_pad & WPAD_CLASSIC_BUTTON_MINUS) new_pad|=WPAD_BUTTON_MINUS;
  429. if(old_pad & WPAD_CLASSIC_BUTTON_MINUS) old_pad|=WPAD_BUTTON_MINUS;
  430. }
  431. //---------------------------------------------------------------------------------
  432. /* Sound effects */
  433. //---------------------------------------------------------------------------------
  434. void snd_fx_tick()
  435. {
  436. #ifdef USE_MODPLAYER
  437. ASND_SetVoice(2, VOICE_MONO_8BIT, 4096*6*2,0, &sound_effects[0][0], 2048/128, 64, 64, NULL);
  438. #endif
  439. }
  440. void snd_fx_yes()
  441. {
  442. #ifdef USE_MODPLAYER
  443. ASND_SetVoice(1, VOICE_MONO_8BIT, 12000,0, &sound_effects[1][0], 2048/4, 63, 63, NULL);
  444. #endif
  445. }
  446. void snd_fx_no()
  447. {
  448. #ifdef USE_MODPLAYER
  449. ASND_SetVoice(1, VOICE_MONO_8BIT, 4096,0, &sound_effects[0][0], 2048/16, 96, 96, NULL);
  450. #endif
  451. }
  452. void snd_fx_scroll()
  453. {
  454. #ifdef USE_MODPLAYER
  455. ASND_SetVoice(2, VOICE_MONO_8BIT, 1024,0, &sound_effects[0][0], 64, 64, 64, NULL);
  456. #endif
  457. }
  458. void snd_fx_fx(int percent)
  459. {
  460. #ifdef USE_MODPLAYER
  461. ASND_SetVoice(2, VOICE_MONO_8BIT, 5000+percent*250,0, &sound_effects[0][0], 128, 64, 64, NULL);
  462. #endif
  463. }
  464. //---------------------------------------------------------------------------------
  465. /* GUI routines and datas*/
  466. //---------------------------------------------------------------------------------
  467. struct _game_datas
  468. {
  469. int ind;
  470. void * png_bmp;
  471. GXTexObj texture;
  472. u32 config;
  473. int is_png;
  474. int pad[3];
  475. } game_datas[32];
  476. struct discHdr png_header;
  477. void create_game_png_texture(int n)
  478. {
  479. PNGUPROP imgProp;
  480. IMGCTX ctx;
  481. char *texture_buff;
  482. s32 ret;
  483. game_datas[n].is_png=0;
  484. game_datas[n].png_bmp=NULL;
  485. if(!(disc_conf[0]=='H' && disc_conf[1]=='D' && disc_conf[2]=='R'))
  486. {game_datas[n].png_bmp=NULL;game_datas[n].config=0;
  487. /*if(is_fat && (png_header.version & 2))
  488. goto is_vc_title;*/
  489. return;
  490. }
  491. game_datas[n].config=disc_conf[4]+(disc_conf[5]<<8)+(disc_conf[6]<<16)+(disc_conf[7]<<24);
  492. if(disc_conf[8]==0 && disc_conf[9]=='C' && disc_conf[10]=='1' && disc_conf[11]=='6')
  493. {
  494. u16 temp_w,temp_h;
  495. game_datas[n].png_bmp=NULL;
  496. memcpy(&temp_w, (void *)&disc_conf[12], 2);
  497. memcpy(&temp_h, (void *)&disc_conf[14], 2);
  498. if(temp_w==0 || temp_w>256) return ;
  499. if(temp_h==0 || temp_h>128) return ;
  500. texture_buff=memalign(32, temp_w * temp_h *2+2048);
  501. if(!texture_buff) {return;}
  502. memcpy(texture_buff, (void *)&disc_conf[16], temp_w * temp_h * 2);
  503. game_datas[n].png_bmp=texture_buff;
  504. game_datas[n].is_png=0;
  505. CreateTexture(&game_datas[n].texture, TILE_RGB5A1, game_datas[n].png_bmp, temp_w, temp_h, 0);
  506. return;
  507. }
  508. if(!(disc_conf[9]=='P' && disc_conf[10]=='N' && disc_conf[11]=='G'))
  509. {game_datas[n].png_bmp=NULL;
  510. // if(is_fat && (png_header.version & 2))
  511. // goto is_vc_title;
  512. return;
  513. }
  514. /* Select PNG data */
  515. ctx = PNGU_SelectImageFromBuffer(disc_conf+8);
  516. if (!ctx)
  517. {game_datas[n].is_png=0;game_datas[n].png_bmp=NULL;return;}
  518. /* Get image properties */
  519. ret = PNGU_GetImageProperties(ctx, &imgProp);
  520. if (ret != PNGU_OK)
  521. {game_datas[n].is_png=0;game_datas[n].png_bmp=NULL;return;}
  522. texture_buff=memalign(32, imgProp.imgWidth * imgProp.imgHeight *4+2048);
  523. if(!texture_buff) {game_datas[n].png_bmp=NULL;game_datas[n].is_png=0;return;}
  524. PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, texture_buff, 255);
  525. PNGU_ReleaseImageContext(ctx);
  526. game_datas[n].png_bmp=texture_buff;
  527. game_datas[n].is_png=1;
  528. DCFlushRange( texture_buff, imgProp.imgWidth * imgProp.imgHeight *4);
  529. GX_InitTexObj(&game_datas[n].texture,texture_buff, imgProp.imgWidth, imgProp.imgHeight, GX_TF_RGBA8, GX_CLAMP , GX_CLAMP , GX_FALSE);
  530. GX_InitTexObjLOD(&game_datas[n].texture, // objeto de textura
  531. GX_LINEAR, // filtro Linear para cerca
  532. GX_LINEAR, // filtro Linear para lejos
  533. 0, 0, 0, 0, 0, GX_ANISO_1);
  534. return;
  535. #if 0
  536. is_vc_title:
  537. {
  538. char filename[256];
  539. void *app;
  540. int size_app;
  541. void *tpl_1;
  542. game_datas[n].png_bmp=NULL;
  543. sprintf(filename, "%s/nand/title/00010001/%02x%02x%02x%02x/content/%08x.app", (png_header.version & 1) ? "sd:" : "ud:",
  544. png_header.id[0], png_header.id[1], png_header.id[2], png_header.id[3], *((u32 *)&png_header.unused2[0]));
  545. void parse_banner_tpl(void *banner, void *tpl_1);
  546. void * tpl_2_rgba(void *tpl);
  547. if(FAT_read_file(filename, &app, &size_app)<0) {return;}
  548. parse_banner_tpl(app, &tpl_1);free(app);
  549. //WBFS_GetBannerTPL(png_header.id, &tpl_1);
  550. if(tpl_1)
  551. {
  552. game_datas[n].png_bmp=tpl_2_rgba(tpl_1);
  553. free(tpl_1);
  554. }
  555. extern u16 tpl_w, tpl_h;
  556. // save fake PNG
  557. if(game_datas[n].png_bmp)
  558. {
  559. /*
  560. disc_conf[0]='H'; disc_conf[1]='D'; disc_conf[2]='R';disc_conf[3]=((tpl_w * tpl_h *2+16+1023)/1024)-1;
  561. // fake PNG
  562. disc_conf[8]=0;
  563. disc_conf[9]= 'C';
  564. disc_conf[10]='1';
  565. disc_conf[11]='6';
  566. memcpy((void *)&disc_conf[12], &tpl_w, 2);
  567. memcpy((void *)&disc_conf[14], &tpl_h, 2);
  568. memcpy((void *)&disc_conf[16], game_datas[n].png_bmp, tpl_w * tpl_h * 2);
  569. global_SetProfileDatas(png_header.id, disc_conf);
  570. */
  571. CreateTexture(&game_datas[n].texture, TILE_RGB5A1, game_datas[n].png_bmp, tpl_w, tpl_h, 0);
  572. }
  573. }
  574. #endif
  575. }
  576. void display_loader_error(int ret)
  577. {
  578. switch(ret)
  579. {
  580. case 1:
  581. s_printf("Error: WDVD_SetUSBMode isn't supported");
  582. break;
  583. case 2:
  584. s_printf("Error: Bad disc ID");
  585. break;
  586. case 3:
  587. s_printf("Error: Bad Partition");
  588. break;
  589. case 4:
  590. s_printf("Fail Opening Partition");
  591. break;
  592. case -10001:
  593. s_printf("Error: Fail reading TMD");
  594. break;
  595. case -10002:
  596. s_printf("Error Creating Shared Content");
  597. break;
  598. case -10003:
  599. s_printf("Error: %08x.app don't exist", ERR_FATFSS_APP);
  600. break;
  601. case -10004:
  602. s_printf("Error: Creating Clone TMD");
  603. break;
  604. case -10005:
  605. s_printf("Error Saving Modified TMD");
  606. break;
  607. case -10006:
  608. s_printf("Error: .dol Not Found");
  609. break;
  610. case 888:
  611. s_printf("Error in ES_Identify()");
  612. break;
  613. case 889:
  614. s_printf("Error: fail loading .dol");
  615. break;
  616. case 890:
  617. s_printf("Error in ES_SetUID()");
  618. break;
  619. case -999:
  620. s_printf("Error: Bad .dol Entry Address");
  621. break;
  622. case 17:
  623. s_printf("Fail Loading FAT FFS Module\n");
  624. break;
  625. case 101:
  626. s_printf("You can't use cIOS 249 with multiple partitions!!!\n");
  627. break;
  628. case -7777:
  629. s_printf("ERROR: You need cIOS 223/ 224 v4-v5 to work!!!\n");
  630. break;
  631. case 666:
  632. s_printf("ERROR FROM THE LOADER: Disc ID is not equal!\n");
  633. break;
  634. default:
  635. s_printf("ERROR FROM THE LOADER: %i\n", ret);
  636. }
  637. }
  638. void usb_test()
  639. {
  640. static int n_sectors=0,errores=0;
  641. static u32 sector=0, sector_size;
  642. static u32 err_time=0,ok_time=0;
  643. static u32 first_time=0, curr_time=0,start_time=0;
  644. static int err=2;
  645. static u32 addr=0,dat,dat2=0,dat3=0,bytes_readed=0,dat4=0, flag=0;
  646. if(err==2)
  647. {
  648. err=0;
  649. start_time=first_time=time(NULL);
  650. }
  651. if(addr==0)
  652. {
  653. // get EHCI base registers
  654. mload_getw((void *) 0x0D040000, &addr);
  655. addr&=0xff;
  656. addr+=0x0D040000;
  657. }
  658. if(n_sectors==0)
  659. n_sectors = USBStorage2_GetCapacity(&sector_size);
  660. dat=0;
  661. mload_getw((void *) (addr+0x44), &dat);
  662. if(dat!=0x1005) dat2=dat;
  663. if(dat2!=0x1805) dat3=dat2;
  664. PY+=32;
  665. s_printf("port: %x %x %x\n", dat,dat2,dat3);
  666. PY-=32;
  667. if(USBStorage2_ReadSectors(sector, 64*512/sector_size, disc_conf)<=0)
  668. {sprintf(cabecera2_str,"ERROR! %i", errores);
  669. errores++;err_time=gettick();if(err==0) curr_time= time(NULL)-first_time;err=1;
  670. }
  671. else
  672. {
  673. if(err)
  674. {first_time=time(NULL);ok_time=gettick();err=0;}
  675. sprintf(cabecera2_str,"OK %i %u Last T: %u Time %u", errores, ticks_to_msecs(ok_time-err_time), curr_time, (u32) (time(NULL)-start_time));
  676. bytes_readed+=64*512;
  677. }
  678. switch((((u32) (time(NULL)-start_time)) % 10))
  679. {
  680. case 0:
  681. if(flag==0)
  682. {dat4=bytes_readed/(10);bytes_readed=0;flag=1;}
  683. break;
  684. default:
  685. flag=0;
  686. break;
  687. }
  688. PY=480-64;
  689. s_printf("sector: %u / %u\n", sector, n_sectors);
  690. PY=480-32;
  691. s_printf("speed: %i bytes/sec\n", dat4);
  692. sector+=64*512/sector_size;
  693. if(sector>(n_sectors-(64*512/sector_size))) sector=0;
  694. if(err) signal_draw_cabecera2=1;
  695. draw_cabecera2();
  696. signal_draw_cabecera2=0;
  697. }
  698. int load_game_routine(u8 *discid, int game_mode);
  699. int load_file_dol(char *name);
  700. #ifdef MEM_PRINT
  701. void save_log()
  702. {
  703. FILE *fp;
  704. int len;
  705. if(!sd_ok) return;
  706. mload_init();
  707. len=mload_get_log();
  708. // mload_seek(0x13750000, SEEK_SET);
  709. if(len>0)
  710. mload_read(temp_data, len);
  711. mload_close();
  712. if(len<=0) return;
  713. if(sd_ok )
  714. {
  715. for(len=0;len<4096;len++)
  716. {
  717. if(temp_data[len]==0) break;
  718. }
  719. fp=fopen("sd:/log_ehc.txt","wb");
  720. if(fp!=0)
  721. {
  722. fwrite(temp_data,1, len ,fp);
  723. fclose(fp);
  724. }
  725. }
  726. }
  727. #endif
  728. int remote_DVD_disc_status=0;
  729. static struct discHdr mydisc_header ATTRIBUTE_ALIGN(32);
  730. int mode_disc=0; // bits 0-1 : 0 -> HDD, 1-> DVD Wii, 2-> USB DVD
  731. int bca_status_read=0;
  732. struct _multi_ciso multi_ciso[8];
  733. int ciso_sel=0;
  734. static u8 disc_buffer[65536] ATTRIBUTE_ALIGN(32);
  735. void remote_DVD_disc()
  736. {
  737. int r;
  738. int ciso=0;
  739. if(remote_DVD_disc_status==3)
  740. {
  741. if(mode_disc & 2)
  742. WDVD_SetUSBMode((u8 *) "_DVD", multi_ciso[ciso_sel].lba);
  743. else
  744. WDVD_SetUSBMode(NULL, multi_ciso[ciso_sel].lba);
  745. bca_status_read=0;BCA_ret=-1;
  746. remote_DVD_disc_status=1;
  747. WDVD_Reset();
  748. r=Disc_Open();
  749. if(r>=0) r=Disc_IsWii();
  750. if(r>=0)
  751. {
  752. if(Disc_ReadHeader(&mydisc_header)==0)
  753. {
  754. memset(BCA_Data,0,64);
  755. bca_status_read=0;BCA_ret=-1;
  756. show_bca=0;
  757. remote_DVD_disc_status=2;
  758. }
  759. else r=-1;
  760. }
  761. }
  762. /*if(mode_disc & 2) WDVD_SetUSBMode((u8 *) "_DVD", 0);
  763. else
  764. WDVD_SetUSBMode(NULL, 0);*/
  765. if(mode_disc & 2) r=Disc_USB_DVD_Wait();
  766. else r=Disc_Wait();
  767. if(r==0)
  768. {
  769. if(remote_DVD_disc_status==0)
  770. {
  771. remote_DVD_disc_status=1;
  772. if(mode_disc & 2) WDVD_SetUSBMode((u8 *) "_DVD", 0);
  773. else
  774. WDVD_SetUSBMode(NULL, 0);
  775. WDVD_Reset();
  776. r=Disc_Open();
  777. if(r>=0)
  778. {
  779. r=Disc_IsWii();
  780. ciso_sel=0;multi_ciso[0].len=multi_ciso[0].lba=0;
  781. // TEST for CISO Disc
  782. if(r==-1 && mode_disc && !(mode_disc & 2))
  783. {
  784. r=WDVD_UnencryptedRead(disc_buffer, 2048, 0);
  785. if(r>=0 && !memcmp((void *) disc_buffer, "CISO",4))
  786. {
  787. int m;
  788. ciso_sel=0;
  789. for(m=0;m<8;m++)
  790. {
  791. multi_ciso[m].len=0;
  792. multi_ciso[m].lba=(m==0); // add one for DVD Wii
  793. }
  794. WDVD_SetUSBMode(NULL, multi_ciso[ciso_sel].lba);
  795. ciso=1;
  796. r=Disc_Open();
  797. if(r>=0) r=Disc_IsWii();
  798. }
  799. else r=-1;
  800. }
  801. // TEST for UDF Disc
  802. if(r==-1 && (mode_disc /*& 2*/))
  803. {
  804. if(mode_disc & 2)
  805. r = USBStorage2_ReadSectors(16, 1, disc_buffer);
  806. else
  807. r=WDVD_UnencryptedRead(disc_buffer, 2048, 16<<11);
  808. if(r>=0 && !memcmp((void *) disc_buffer, "\0BEA01\1\0",8))
  809. {
  810. ciso=1;
  811. if(mode_disc & 2)
  812. r = USBStorage2_ReadSectors(256, 32, disc_buffer);
  813. else
  814. r=WDVD_UnencryptedRead(disc_buffer, 2048*32, 256<<11);
  815. if(r>=0 && !memcmp(disc_buffer, "\2\0\2\0",4))
  816. {
  817. int n,m,p, last_lba=0, curr_lba;;
  818. for(n=1;n<16;n++) if(!memcmp((void *) &disc_buffer[2048*n], "\1\1\2\0",4)) break;
  819. if(n==16) r=-1;
  820. else
  821. {
  822. n*=2048;
  823. p=0;
  824. for(m=0;m<8;m++)
  825. {
  826. if(!memcmp((void *) &disc_buffer[n+p], "\1\1\2\0",4))
  827. {
  828. u8 *punt=&disc_buffer[n+p+0x18];
  829. curr_lba=(punt[0]+(punt[1]<<8)+(punt[2]<<16)+(punt[3]<<24))+1;
  830. if(last_lba<curr_lba) last_lba=curr_lba;
  831. if(!disc_buffer[n+p+0x13] || disc_buffer[n+p+0x12]==0xa) m--;
  832. else
  833. if(disc_buffer[n+p+0x12] & 0x2)
  834. {
  835. // sorry don´t support directories (files must be in root)
  836. break;
  837. }
  838. else
  839. if(curr_lba>32)
  840. {
  841. // sorry LBA is out of the buffer
  842. break;
  843. }
  844. else
  845. {
  846. punt=&disc_buffer[curr_lba*2048+0x40];
  847. multi_ciso[m].len=(punt[0]+(punt[1]<<8)+(punt[2]<<16)+(punt[3]<<24));
  848. memset((void *) multi_ciso[m].name,0,64);
  849. if(disc_buffer[n+p+0x26]==16)
  850. {
  851. int s;
  852. for(s=0;s<63 && s< (disc_buffer[n+p+0x13]/2);s++) multi_ciso[m].name[s]=disc_buffer[n+p+0x28+s*2];
  853. }
  854. else
  855. {
  856. int s;
  857. for(s=0;s<63 && s< (disc_buffer[n+p+0x13]-1);s++) multi_ciso[m].name[s]=disc_buffer[n+p+0x27+s];
  858. }
  859. multi_ciso[m].name[63]=0;
  860. // SKIP if not .ciso file
  861. if(!(strstr((void *) multi_ciso[m].name, ".ciso") || strstr((void *) multi_ciso[m].name, ".CISO")))
  862. {
  863. multi_ciso[m].len=0;
  864. m--;
  865. }
  866. }
  867. p+=(0x26+disc_buffer[n+p+0x13]+3) & ~3;
  868. }
  869. else multi_ciso[m].len=0;
  870. }
  871. if(m<8) // bad UDF format
  872. r=-1;
  873. else
  874. {
  875. last_lba+=257;
  876. for(m=0;m<8;m++)
  877. {
  878. if(!multi_ciso[m].len) break;
  879. multi_ciso[m].lba=last_lba+1*(!(mode_disc & 2)); // add one for DVD Wii
  880. last_lba+=multi_ciso[m].len;
  881. }
  882. ciso_sel=0;
  883. //exit(0);
  884. if(mode_disc & 2)
  885. WDVD_SetUSBMode((u8 *) "_DVD", multi_ciso[ciso_sel].lba);
  886. else
  887. WDVD_SetUSBMode(NULL, multi_ciso[ciso_sel].lba);
  888. WDVD_Reset();
  889. r=Disc_Open();
  890. if(r>=0) r=Disc_IsWii();
  891. }
  892. }
  893. }
  894. else r=-1;
  895. }
  896. else r=-1;
  897. }
  898. // end of TEST for UDF Disc
  899. if(r>=0)
  900. {
  901. if(Disc_ReadHeader(&mydisc_header)==0)
  902. {
  903. memset(BCA_Data,0,64);
  904. if(ciso) bca_status_read=0; else bca_status_read=1;BCA_ret=-1;
  905. show_bca=0;
  906. remote_DVD_disc_status=2;
  907. }
  908. }
  909. else {bca_status_read=0;remote_DVD_disc_status=r;BCA_ret=-1;ciso_sel=0;multi_ciso[0].len=multi_ciso[0].lba=0;}
  910. }
  911. else {remote_DVD_disc_status=r;BCA_ret=-1;bca_status_read=0;ciso_sel=0;multi_ciso[0].len=multi_ciso[0].lba=0;}
  912. }
  913. }
  914. else {remote_DVD_disc_status=0;bca_status_read=0;ciso_sel=0;multi_ciso[0].len=multi_ciso[0].lba=0;}
  915. if(bca_status_read==2)
  916. {
  917. memset(BCA_Data,0,64);
  918. BCA_ret=WDVD_Read_Disc_BCA(BCA_Data);
  919. if(BCA_ret<0) memset(BCA_Data,0,64);
  920. bca_status_read=3;
  921. }
  922. usleep(50*1024);
  923. }
  924. void update_bca(u8 *id, u8 *bca_datas);
  925. int bca_mode=0;
  926. int get_bca(u8 *id, u8 *bca_datas);
  927. /////////////////////////////////////////////////
  928. // main() variables
  929. u8 discid[7];
  930. int direct_launch=0;
  931. int temp_game_cnt;
  932. struct discHdr *temp_buffer = NULL;
  933. /////////////////////////////////////////////////
  934. int menu_main();
  935. char name_button[64];
  936. //---------------------------------------------------------------------------------
  937. int main(int argc, char **argv) {
  938. //---------------------------------------------------------------------------------
  939. int n;
  940. int ret,ret2;
  941. struct timespec tb;
  942. int rel_time;
  943. if (*((u32*)0x80001800) && strncmp("STUBHAXX", (char *)0x80001804, 8) == 0) return_reset=1;
  944. else return_reset=2;
  945. /*
  946. if(argc<1) return_reset=2;
  947. else
  948. if(*((char *) argv[0])=='s') return_reset=2;
  949. */
  950. current_partition=0;
  951. if(argc>1)
  952. if(argv[1])
  953. {
  954. char *t=argv[1];
  955. if(t[0]=='#')
  956. {
  957. t++;
  958. direct_launch=1;
  959. memcpy(discid,t,6);
  960. t+=6;
  961. if(t[0]=='-') current_partition=t[1]-48;
  962. current_partition&=3;
  963. }
  964. }
  965. SYS_SetResetCallback(reset_call); // esto es para que puedas salir al pulsar boton de RESET
  966. SYS_SetPowerCallback(power_call); // esto para apagar con power
  967. LWP_SetThreadPriority(LWP_GetSelf(),40);
  968. SYS_CreateAlarm(&scr_poweroff);
  969. tb.tv_sec = 1;tb.tv_nsec = 0;
  970. SYS_SetPeriodicAlarm(scr_poweroff, &tb, &tb, scr_poweroff_handler, NULL);
  971. discid[6]=0;
  972. ret2=-1;
  973. cios=cios_list[0];
  974. if(uhack_settings0 & 2)
  975. {
  976. n=cios_list[0]; cios_list[0]=cios_list[2]; cios_list[2]=n;
  977. cios=cios_list[0];
  978. ret=IOS_ReloadIOS(cios);
  979. if(ret!=0)
  980. {
  981. uhack_settings0&=~2;
  982. cios=cios_list[2];
  983. ret=IOS_ReloadIOS(cios);
  984. }
  985. }
  986. else
  987. ret=IOS_ReloadIOS(cios);
  988. if(ret!=0)
  989. {
  990. cios=cios_list[1];
  991. ret=IOS_ReloadIOS(cios);
  992. }
  993. if(ret==0)
  994. {
  995. sleep(1);
  996. if((*(volatile u32 *)0x80003140 & 0xffff)<4) ret=-7777;
  997. }
  998. else
  999. {
  1000. #ifndef DONT_USE_IOS249
  1001. force_ios249=1;
  1002. cios=249;
  1003. ret=IOS_ReloadIOS(cios);
  1004. #else
  1005. ret=-1;
  1006. #endif
  1007. sleep(1);
  1008. }
  1009. if(CONF_Init()==0)
  1010. {
  1011. is_16_9=CONF_GetAspectRatio()!=0;
  1012. switch(CONF_GetLanguage())
  1013. {
  1014. case CONF_LANG_SPANISH:
  1015. idioma=1;break;
  1016. default:
  1017. idioma=0;break;
  1018. }
  1019. }
  1020. InitScreen(); // Inicialización del Video
  1021. time_sleep=TIME_SLEEP_SCR;
  1022. remote_init();
  1023. time_t my_time=(time(NULL));
  1024. struct tm *l_time=localtime(&my_time);
  1025. if(l_time)
  1026. {
  1027. l_time->tm_mon++;
  1028. if(!no_more_snow)
  1029. if((l_time->tm_mday>=12 && l_time->tm_mon==12) || l_time->tm_mon<3 || (l_time->tm_mday<=6 && l_time->tm_mon==3)) flag_snow=1;
  1030. }
  1031. //create_png_texture(&text_background, background, 1);
  1032. if(1) // new background
  1033. {
  1034. u32 *t=(void *) SYS_AllocArena2MemLo(128*128*4*3,32);//memalign(32,128*128*4*3);
  1035. memset(t, 0, 128*128*4*3);
  1036. create_background_text(670, 128, 128, t);
  1037. CreateTexture(&text_background[0], TILE_SRGBA8 , t, 128, 128, 1);
  1038. create_background_text(663, 128, 128, t+128*128*1);
  1039. CreateTexture(&text_background[1], TILE_SRGBA8 , t+128*128*1, 128, 128, 1);
  1040. create_background_text(663*2, 128, 128, t+128*128*2);
  1041. CreateTexture(&text_background[2], TILE_SRGBA8 , t+128*128*2, 128, 128, 1);
  1042. GX_InitTexObj(&text_background2, t, 128, 128, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
  1043. GX_InitTexObjLOD(&text_background2, // objeto de textura
  1044. GX_LINEAR, // filtro Linear para cerca
  1045. GX_LINEAR, // filtro Linear para lejos
  1046. 0, 0, 0, 0, 0, GX_ANISO_1);
  1047. }
  1048. bkcolor=0;
  1049. remote_call(splash_scr_send);
  1050. WPAD_Init();
  1051. WPAD_SetIdleTimeout(60*5); // 5 minutes
  1052. WPAD_SetDataFormat(WPAD_CHAN_ALL, WPAD_FMT_BTNS_ACC_IR); // ajusta el formato para acelerometros en todos los wiimotes
  1053. WPAD_SetVRes(WPAD_CHAN_ALL, SCR_WIDTH+is_16_9*208, SCR_HEIGHT);
  1054. sd_ok=0;
  1055. for(n=0;n<5;n++)
  1056. {
  1057. if(__io_wiisd.startup())
  1058. {
  1059. sd_ok = fatMountSimple("sd", &__io_wiisd);
  1060. if(!sd_ok) __io_wiisd.shutdown();
  1061. }
  1062. if(sd_ok) break;
  1063. usleep(50000);
  1064. }
  1065. if(sd_ok) global_mount|=64;
  1066. if(ret!=0)
  1067. {
  1068. remote_call_abort();while(remote_ret()==REMOTE_BUSY) usleep(1000*50);
  1069. splash_scr();
  1070. SelectFontTexture(1); // selecciona la fuente de letra extra
  1071. letter_size(8,32);
  1072. PX=0; PY= SCR_HEIGHT/2+32; color= INK0;
  1073. bkcolor=0;
  1074. autocenter=1;
  1075. SetTexture(NULL);
  1076. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 0xa00000ff);
  1077. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 4, 0xa0000000);
  1078. if(ret==-7777)
  1079. s_printf("ERROR: You need cIOS222 from uLoader 3.0 v4 to work!!!\n");
  1080. else
  1081. #ifndef DONT_USE_IOS249
  1082. s_printf("ERROR: You need cIOS222 and/or cIOS249 to work!!!\n");
  1083. #else
  1084. s_printf("ERROR: You need cIOS222 and/or cIOS223 to work!!!\n");
  1085. #endif
  1086. Screen_flip();
  1087. sleep(2);
  1088. goto error;
  1089. }
  1090. temp_data=memalign(32,256*1024);
  1091. disc_conf=memalign(32,256*1024);
  1092. // texture of white-noise animation generated here
  1093. game_empty=memalign(32,128*64*3*4);
  1094. test_and_patch_for_port1();
  1095. load_ehc_module();
  1096. if(external_ehcmodule)
  1097. {remote_call_abort();while(remote_ret()==REMOTE_BUSY) usleep(1000*50);
  1098. for(n=0;n<20;n++)
  1099. {
  1100. splash_scr();
  1101. SelectFontTexture(1); // selecciona la fuente de letra extra
  1102. letter_size(8,32);
  1103. PX=0; PY= SCR_HEIGHT/2+32; color= INK0;
  1104. bkcolor=0;
  1105. autocenter=1;
  1106. SetTexture(NULL);
  1107. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 0xa000ff00);
  1108. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 4, 0xa0000000);
  1109. s_printf("External ehcmodule.elf loaded\n");
  1110. Screen_flip();
  1111. }
  1112. }
  1113. if(exit_by_reset) {test_mode=1; SYS_SetResetCallback(reset_call);exit_by_reset=0;}
  1114. // sound pattern generator
  1115. for(n=0;n<2;n++)
  1116. {
  1117. int m,l;
  1118. switch(n)
  1119. {
  1120. case 0:
  1121. l=64;
  1122. for(m=0;m<2048;m++)
  1123. {
  1124. sound_effects[0][m]=((m) & l) ? 127 : -128;
  1125. if((m & 255)==0) l>>=1; if(l<16) l=16;
  1126. }
  1127. break;
  1128. case 1:
  1129. l=127;
  1130. for(m=0;m<2048;m++)
  1131. {
  1132. sound_effects[1][m]=((m) & 8) ? l : -l;
  1133. if((m & 7)==0) l--; if(l<0) l=0;
  1134. }
  1135. break;
  1136. }
  1137. }
  1138. remote_call_abort();while(remote_ret()==REMOTE_BUSY) usleep(1000*50);
  1139. ret2=REMOTE_BUSY;
  1140. num_fat_games=0;
  1141. if(sd_ok)
  1142. {
  1143. down_frame=-1;
  1144. down_mess="";//Installing SD Content";
  1145. remote_call(wait_splash_scr);
  1146. FAT_Install(1);
  1147. down_mess="Reading .CISO and WiiWare From SD";
  1148. down_frame=0;
  1149. list_fat("sd:/ciso/");
  1150. if(sd_ok)
  1151. {
  1152. load_cfg(1);
  1153. }
  1154. remote_call_abort();while(remote_ret()==REMOTE_BUSY) usleep(1000*50);
  1155. }
  1156. int ret_flag=0;
  1157. rel_time= time(NULL);
  1158. if(automatic_dvd_mode)
  1159. {
  1160. Disc_Init();
  1161. }
  1162. for(n=0;n<10;n++)
  1163. {
  1164. int r,mod=0;
  1165. while(1)
  1166. {
  1167. WPAD_ScanPads();
  1168. splash_scr();
  1169. SelectFontTexture(1); // selecciona la fuente de letra extra
  1170. letter_size(8,32);
  1171. PX=0; PY= SCR_HEIGHT/2+32; color= INK0;
  1172. bkcolor=0;
  1173. autocenter=1;
  1174. SetTexture(NULL);
  1175. if(mod==0)
  1176. {
  1177. ret_flag=0;
  1178. r=remote_USBStorage2_Init();
  1179. if(r!=REMOTE_BUSY) mod=1;
  1180. }
  1181. if(mod==1)
  1182. {
  1183. r=remote_ret();
  1184. if(r!=REMOTE_BUSY) {mod=0;ret2=r;ret_flag=1;}
  1185. }
  1186. if(ret2==REMOTE_BUSY) ;
  1187. else
  1188. if(ret2==-20001 || ret2==-20002)
  1189. {n=0;
  1190. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 0xa00000ff);
  1191. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 4, 0xa0000000);
  1192. if(ret2==-20001)
  1193. s_printf("ERROR: USB Device Sector Size must be 512 bytes");
  1194. else
  1195. s_printf("ERROR: DVD Device Sector Size must be 2048 bytes");
  1196. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 999, 0xa00000ff);
  1197. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 999, 4, 0xa0000000);
  1198. PY+=80;
  1199. exit_by_reset=return_reset;
  1200. }
  1201. else
  1202. if(ret2==-20000)
  1203. {n=0;
  1204. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 0xa00000ff);
  1205. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 4, 0xa0000000);
  1206. s_printf("ERROR: USB Device is detected as HUB!!!");
  1207. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 999, 0xa00000ff);
  1208. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 999, 4, 0xa0000000);
  1209. PY+=80;
  1210. if(!use_port1)
  1211. s_printf("You need plug one device on USB port 0...");
  1212. else
  1213. s_printf("You need plug one device on USB port 1...");
  1214. }
  1215. else
  1216. if(ret2==-100)
  1217. {
  1218. static int conta=0;
  1219. n=0;
  1220. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 0xa00000ff);
  1221. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 4, 0xa0000000);
  1222. s_printf("ERROR: USB Device Disconnected (try unplug/plug)");
  1223. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 999, 0xa00000ff);
  1224. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 999, 4, 0xa0000000);
  1225. if(automatic_dvd_mode && (time(NULL)-rel_time)>5)
  1226. {
  1227. if(num_fat_games!=0) {dvd_only=1;mode_disc=0;is_fat=1;ret2=0;}
  1228. else
  1229. if(Disc_Wait()==0)
  1230. {
  1231. dvd_only=1;
  1232. mode_disc=1;
  1233. ret2=0;
  1234. }
  1235. }
  1236. PY+=80;
  1237. if(!(conta & 64))
  1238. {
  1239. if(!use_port1)
  1240. s_printf("Maybe you need plug the device on USB port 0...");
  1241. else
  1242. s_printf("Maybe you need plug the device on USB port 1...");
  1243. }
  1244. else
  1245. s_printf("Press < 2 > for DVD Mode");
  1246. conta++;
  1247. if((new_pad & (WPAD_BUTTON_2 | WPAD_CLASSIC_BUTTON_Y | WPAD_GUITAR_HERO_3_BUTTON_RED)) && ret2!=0)
  1248. {
  1249. dvd_only=1;
  1250. if(num_fat_games==0) mode_disc=1; else {mode_disc=0;is_fat=1;}
  1251. ret2=0;
  1252. }
  1253. //if(mode_disc) ret2=0; // mode disc
  1254. }
  1255. else
  1256. if(ret2==-101)
  1257. {n=0;
  1258. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 0xa00000ff);
  1259. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 4, 0xa0000000);
  1260. s_printf("%s","ERROR: USB Device don´t work as USB 2.0 (try unplug/plug)");
  1261. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 999, 0xa00000ff);
  1262. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 999, 4, 0xa0000000);
  1263. PY+=80;
  1264. if(!use_port1)
  1265. s_printf("Maybe you need plug the device on USB port 0...");
  1266. else
  1267. s_printf("Maybe you need plug the device on USB port 1...");
  1268. }
  1269. else
  1270. if(ret2==-122)
  1271. {
  1272. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 0xa00000ff);
  1273. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 4, 0xa0000000);
  1274. s_printf("ERROR: Can't Mount Device");
  1275. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 999, 0xa00000ff);
  1276. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 999, 4, 0xa0000000);
  1277. PY+=80;
  1278. s_printf("... waiting for Storage or DVD media ...");
  1279. }
  1280. else
  1281. if(ret2<0)
  1282. {
  1283. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 0xa00000ff);
  1284. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 4, 0xa0000000);
  1285. s_printf("ERROR: Could not initialize USB subsystem! (ret = %d)", ret2);
  1286. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 999, 0xa00000ff);
  1287. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 999, 4, 0xa0000000);
  1288. PY+=80;
  1289. s_printf("Retries: %i",n);
  1290. }
  1291. if((exit_by_reset || (new_pad & WPAD_BUTTON_HOME)))
  1292. {
  1293. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 0, 0xff0000ff);
  1294. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 0, 4, 0xa0000000);
  1295. letter_size(16,32);PY= SCR_HEIGHT/2+32+80;
  1296. s_printf("Exiting...");
  1297. Screen_flip();
  1298. ret2=-1;n=100;
  1299. break;
  1300. }
  1301. Screen_flip();
  1302. if(ret2<0 && ret2!=-122 && ret2!=-100 && ret2!=-101 && mod<2 && ret2!=REMOTE_BUSY && ret_flag) {ret_flag=0;mod=2;}
  1303. if(!ret2 || ret2==1) break;
  1304. wiimote_read();
  1305. if(mod>1)
  1306. {
  1307. mod++;if(mod>30) {mod=0;break;}
  1308. }
  1309. }
  1310. //if(ret_flag==0) n--;
  1311. if(!ret2 || ret2==1) break;
  1312. }
  1313. if(ret2==1)
  1314. {
  1315. ret2=0;
  1316. dvd_only=1;
  1317. mode_disc=1024+2; // USB DVD MODE
  1318. if(num_fat_games!=0) {is_fat=1;}
  1319. }
  1320. CreatePalette(&palette_icon, TLUT_RGB5A3, 0, icon_palette, icon_palette_colors); // crea paleta 0
  1321. CreateTexture(&text_icon[0], TILE_CI8, icon_sprite_1, icon_sprite_1_sx, icon_sprite_1_sy, 0);
  1322. CreateTexture(&text_icon[1], TILE_CI8, icon_sprite_2, icon_sprite_2_sx, icon_sprite_2_sy, 0);
  1323. CreateTexture(&text_icon[2], TILE_CI8, icon_sprite_3, icon_sprite_3_sx, icon_sprite_3_sy, 0);
  1324. CreateTexture(&text_icon[3], TILE_CI8, icon_sprite_4, icon_sprite_4_sx, icon_sprite_4_sy, 0);
  1325. CreateTexture(&text_icon[4], TILE_CI8, icon_sprite_5, icon_sprite_5_sx, icon_sprite_5_sy, 0);
  1326. CreateTexture(&text_icon[5], TILE_CI8, icon_sprite_6, icon_sprite_6_sx, icon_sprite_6_sy, 0);
  1327. CreateTexture(&text_icon[6], TILE_CI8, icon_sprite_7, icon_sprite_7_sx, icon_sprite_7_sy, 0);
  1328. CreateTexture(&text_icon[7], TILE_CI8, icon_sprite_8, icon_sprite_8_sx, icon_sprite_8_sy, 0);
  1329. CreateTexture(&text_icon[8], TILE_CI8, icon_sprite_9, icon_sprite_9_sx, icon_sprite_9_sy, 0);
  1330. #ifdef MEM_PRINT
  1331. if(test_mode && (mode_disc & 1)==0)
  1332. {
  1333. if(ret2>=0)
  1334. {
  1335. USBStorage2_TestMode(1);
  1336. remote_call(usb_test);
  1337. while(1)
  1338. {
  1339. WPAD_ScanPads();
  1340. wiimote_read();
  1341. if(exit_by_reset || (new_pad & WPAD_BUTTON_HOME)) break;
  1342. usleep(1000*50);
  1343. }
  1344. }
  1345. remote_call_abort();while(remote_ret()==REMOTE_BUSY) usleep(1000*50);
  1346. splash_scr();
  1347. SelectFontTexture(1); // selecciona la fuente de letra extra
  1348. letter_size(8,32);
  1349. PX=0; PY= SCR_HEIGHT/2+32; color= INK0;
  1350. bkcolor=0;
  1351. autocenter=1;
  1352. SetTexture(NULL);
  1353. s_printf("save log");
  1354. Screen_flip();
  1355. save_log();
  1356. splash_scr();
  1357. Screen_flip();
  1358. if(sd_ok)
  1359. {
  1360. fatUnmount("sd");
  1361. __io_wiisd.shutdown();sd_ok=0;
  1362. }
  1363. sleep(2);
  1364. goto error;
  1365. } // end test mode
  1366. #endif
  1367. if(ret2<0) {sleep(2);goto error;}
  1368. remote_call(splash_scr_send);
  1369. if(ret2>=0)
  1370. {
  1371. ret2=WBFS_Init();
  1372. if(mode_disc && ret2<0) {mode_disc|=1024;ret2=0;} // mode disc
  1373. if(ret2>=0) ret2=Disc_Init();
  1374. }
  1375. if(ret2>=0 && (mode_disc & 1026)==0)
  1376. {
  1377. __io_usbstorage2.startup();
  1378. ud_ok = fatMountSimple("ud", &__io_usbstorage2);
  1379. if(ud_ok) global_mount|=128;
  1380. }
  1381. else ud_ok=0;
  1382. if(num_fat_games!=0) ret2=Disc_Init();;
  1383. if(ud_ok)
  1384. {
  1385. remote_call_abort();while(remote_ret()==REMOTE_BUSY) usleep(1000*50);
  1386. down_frame=-1;
  1387. //down_mess="Installing USB Content";
  1388. down_mess="";
  1389. remote_call(wait_splash_scr);
  1390. FAT_Install(0);
  1391. down_mess="Reading .CISO and WiiWare From USB";
  1392. down_frame=0;
  1393. list_fat("ud:/ciso/");
  1394. remote_call_abort();while(remote_ret()==REMOTE_BUSY) usleep(1000*50);
  1395. remote_call(splash_scr_send);
  1396. }
  1397. /*
  1398. // test warning
  1399. if(usb_clusters) usb_clusters=4;
  1400. if(sd_clusters) sd_clusters=4;
  1401. */
  1402. if((sd_clusters && sd_clusters<32) || (usb_clusters && usb_clusters<32))
  1403. {
  1404. remote_call_abort();while(remote_ret()==REMOTE_BUSY) usleep(1000*50);
  1405. cluster_warning();
  1406. remote_call_abort();while(remote_ret()==REMOTE_BUSY) usleep(1000*50);
  1407. remote_call(splash_scr_send);
  1408. }
  1409. if(!direct_launch) sleep(2); //for(n=0;n<120;n++) {splash_scr();Screen_flip();}
  1410. //
  1411. screen_fx=memalign(32, 128*128*4);
  1412. create_png_texture(&text_button[0], button1, 32);
  1413. create_png_texture(&text_button[1], button2, 32);
  1414. create_png_texture(&text_button[2], button3, 32);
  1415. text_button[3]=text_button[1];
  1416. create_png_texture(& default_game_texture, defpng, 32);
  1417. create_png_texture(& default_game_texture2, defpng2, 32);
  1418. if(sd_ok && (uhack_settings0 & 1))
  1419. {
  1420. int len;
  1421. if(FAT_read_file("sd:/background.png", &background_png, &len)<0)
  1422. FAT_read_file("sd:/apps/uloader/background.png", &background_png, &len);
  1423. if(background_png)
  1424. {
  1425. create_png_texture(&text_background[3], background_png, 32);
  1426. free(background_png);background_png= (void *) 0xffffffff; // fake pointer
  1427. }
  1428. }
  1429. if(ud_ok && (uhack_settings0 & 1) && !background_png)
  1430. {
  1431. int len;
  1432. if(FAT_read_file("ud:/background.png", &background_png, &len)<0)
  1433. FAT_read_file("ud:/apps/uloader/background.png", &background_png, &len);
  1434. if(background_png)
  1435. {
  1436. create_png_texture(&text_background[3], background_png, 32);
  1437. free(background_png);background_png= (void *) 0xffffffff; // fake pointer
  1438. }
  1439. }
  1440. for(n=0;n<128*64*3;n++)
  1441. {
  1442. switch((rand()>>3) & 7)
  1443. {
  1444. case 0:
  1445. game_empty[n]=0xfff0f0f0;break;
  1446. case 1:
  1447. game_empty[n]=0xff404040;break;
  1448. case 2:
  1449. game_empty[n]=0xffd0d0d0;break;
  1450. case 3:
  1451. game_empty[n]=0xffc0c0c0;break;
  1452. case 4:
  1453. game_empty[n]=0xffc0a000;break;
  1454. case 5:
  1455. game_empty[n]=0xff404040;break;
  1456. case 6:
  1457. game_empty[n]=0xffd0d0d0;break;
  1458. case 7:
  1459. game_empty[n]=0xffc0c0c0;break;
  1460. }
  1461. }
  1462. CreateTexture(&text_game_empty[0], TILE_SRGBA8, &game_empty[0], 128, 64, 0);
  1463. CreateTexture(&text_game_empty[1], TILE_SRGBA8, &game_empty[128*64], 128, 64, 0);
  1464. CreateTexture(&text_game_empty[2], TILE_SRGBA8, &game_empty[128*64*2], 128, 64, 0);
  1465. text_game_empty[3]=text_game_empty[1];
  1466. remote_call_abort();while(remote_ret()==REMOTE_BUSY) usleep(1000*50);
  1467. splash_scr();
  1468. SelectFontTexture(1); // selecciona la fuente de letra extra
  1469. letter_size(8,32);
  1470. PX=0; PY= SCR_HEIGHT/2+32; color= INK0;
  1471. bkcolor=0;
  1472. autocenter=1;
  1473. SetTexture(NULL);
  1474. if (ret2 < 0) {
  1475. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 0xa00000ff);
  1476. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32, 540, 64, 999, 4, 0xa0000000);
  1477. s_printf("ERROR: Could not initialize WBFS subsystem! (ret = %d)", ret2);
  1478. DrawRoundFillBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 999, 0xa00000ff);
  1479. DrawRoundBox((SCR_WIDTH-540)/2, SCR_HEIGHT/2-16+32+80, 540, 64, 999, 4, 0xa0000000);
  1480. PY+=80;
  1481. if(!use_port1)
  1482. s_printf("Maybe you need plug the device on USB port 0...");
  1483. else
  1484. s_printf("Maybe you need plug the device on USB port 1...");
  1485. Screen_flip();
  1486. sleep(2);
  1487. goto error;
  1488. }
  1489. Screen_flip();
  1490. #if 1
  1491. #ifdef USE_MODPLAYER
  1492. ASND_Init();
  1493. ASND_Pause(0);
  1494. if(l_time)
  1495. {
  1496. if(l_time->tm_mday>=1 && l_time->tm_mday<=6 && l_time->tm_mon==1 && l_time->tm_year>109) happy_new_year(l_time->tm_year);
  1497. }
  1498. remote_call(splash_scr_send);
  1499. // inicializa el modplayer en modo loop infinito
  1500. #ifndef ALTERNATIVE_VERSION
  1501. MODPlay_Init(&mod_track);
  1502. n=-1;
  1503. if(sd_ok)
  1504. {
  1505. FILE *fp;
  1506. fp=fopen("sd:/apps/uloader/music.mod","rb");
  1507. if(fp!=0)
  1508. {
  1509. int size;
  1510. char *p;
  1511. fseek(fp, 0, SEEK_END);
  1512. size = ftell(fp);
  1513. p= malloc(size);
  1514. if(p)
  1515. {
  1516. fseek(fp, 0, SEEK_SET);
  1517. if(fread(p,1, size ,fp)==size)
  1518. {
  1519. n=MODPlay_SetMOD (&mod_track, p);
  1520. }
  1521. else free(p);
  1522. }
  1523. fclose(fp);
  1524. }
  1525. }
  1526. if(n<0) n=MODPlay_SetMOD (&mod_track, lotus3_2 );
  1527. if (n < 0 ) // set the MOD song
  1528. {
  1529. MODPlay_Unload (&mod_track);
  1530. }
  1531. else
  1532. {
  1533. MODPlay_SetVolume( &mod_track, 16, 16); // fix the volume to 16 (max 64)
  1534. MODPlay_Start (&mod_track); // Play the MOD
  1535. }
  1536. #else
  1537. // Ogg
  1538. if(sd_ok)
  1539. {
  1540. FILE *fp;
  1541. int ogg_size;
  1542. void *ogg_file;
  1543. fp=fopen("sd:/apps/uloader/music.ogg","rb"); // abre fichero
  1544. if(fp!=0)
  1545. {
  1546. fseek(fp, 0, SEEK_END); // situa el puntero de lectura al final del fichero
  1547. ogg_size = ftell(fp); // obtiene la posicion del puntero (al estar al final, obtiene el tama?o del fichero ;)
  1548. fseek(fp, 0, SEEK_SET); // situa el puntero de lectura al principio del fichero
  1549. ogg_file=malloc(ogg_size+128); /* asigna memoria suficiente para leer el fichero ogg al completo mas 128 bytes extras de proteccion (seguramente no haga falta, pero por si alguna lectura rebasa un poco) */
  1550. if(ogg_file) // si tenemos memoria asignada, procede
  1551. {
  1552. if(fread(ogg_file,1, ogg_size ,fp)==ogg_size) // lee el fichero al completo, si no falla procede
  1553. {
  1554. PlayOgg(mem_open(ogg_file, ogg_size),0,OGG_INFINITE_TIME); // tocala otra vez, Sam
  1555. }
  1556. }
  1557. fclose(fp); // cierra el fichero
  1558. }
  1559. else PlayOgg(mem_open((void *) bg_music, size_bg_music),0,OGG_INFINITE_TIME);
  1560. }
  1561. else PlayOgg(mem_open((void *) bg_music, size_bg_music),0,OGG_INFINITE_TIME);
  1562. #endif
  1563. #endif
  1564. remote_call_abort();while(remote_ret()==REMOTE_BUSY) usleep(1000*50);
  1565. splash_scr();
  1566. SelectFontTexture(1); // selecciona la fuente de letra extra
  1567. letter_size(16,32);
  1568. PX=0; PY= SCR_HEIGHT/2+32; color= INK0;
  1569. bkcolor=0;
  1570. autocenter=1;
  1571. SetTexture(NULL);
  1572. Screen_flip();
  1573. n=menu_main();
  1574. if(n==1) goto exit_ok;
  1575. if(n==2) goto error_w;
  1576. VIDEO_SetBlack(TRUE);
  1577. VIDEO_Flush();
  1578. VIDEO_WaitVSync();
  1579. exit_ok:
  1580. mload_set_ES_ioctlv_vector(NULL);
  1581. mload_close();
  1582. #ifdef USE_MODPLAYER
  1583. #ifdef ALTERNATIVE_VERSION
  1584. StopOgg();
  1585. #endif
  1586. ASND_End(); // finaliza el sonido
  1587. #endif
  1588. make_rumble_off();
  1589. wiimote_read();
  1590. WPAD_Shutdown();
  1591. USBStorage2_Umount();
  1592. SYS_RemoveAlarm(scr_poweroff);
  1593. Diario_InvalidarDiario();
  1594. sleep(1);
  1595. if(exit_by_reset<2 && !(*((u32*)0x80001800) && strncmp("STUBHAXX", (char *)0x80001804, 8) == 0)) exit_by_reset=2;
  1596. if(exit_by_reset==2)
  1597. SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
  1598. if(exit_by_reset==3)
  1599. SYS_ResetSystem(SYS_POWEROFF_STANDBY, 0, 0);
  1600. return 0;
  1601. error_w:
  1602. mload_set_ES_ioctlv_vector(NULL);
  1603. mload_close();
  1604. #ifdef USE_MODPLAYER
  1605. #ifdef ALTERNATIVE_VERSION
  1606. StopOgg();
  1607. #endif
  1608. ASND_End(); // finaliza el sonido
  1609. #endif
  1610. error:
  1611. make_rumble_off();
  1612. wiimote_read();
  1613. WPAD_Shutdown();
  1614. remote_call_abort();while(remote_ret()==REMOTE_BUSY) usleep(1000*50);
  1615. remote_end();
  1616. SYS_RemoveAlarm(scr_poweroff);
  1617. Diario_InvalidarDiario();
  1618. VIDEO_SetBlack(TRUE);
  1619. VIDEO_Flush();
  1620. VIDEO_WaitVSync();
  1621. sleep(2);
  1622. if(sd_ok)
  1623. {
  1624. fatUnmount("sd");
  1625. __io_wiisd.shutdown();sd_ok=0;
  1626. }
  1627. if(ud_ok)
  1628. {
  1629. fatUnmount("ud");
  1630. __io_usbstorage2.shutdown();ud_ok=0;
  1631. }
  1632. if(exit_by_reset<2 && !(*((u32*)0x80001800) && strncmp("STUBHAXX", (char *)0x80001804, 8) == 0)) exit_by_reset=2;
  1633. if(exit_by_reset==2)
  1634. SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
  1635. if(exit_by_reset==3)
  1636. SYS_ResetSystem(SYS_POWEROFF_STANDBY, 0, 0);
  1637. return 0;
  1638. // return ret;
  1639. }
  1640. static u32 lba_start=0;
  1641. static int init_ciso_table=1;
  1642. int fun_fat_read(void*fp,u32 offset,u32 count,void*iobuf)
  1643. {
  1644. int ret,l;
  1645. static u32 table_lba[2048];
  1646. static u8 mem_index[2048];
  1647. static u8 buff[32768] ATTRIBUTE_ALIGN(32);
  1648. static int ciso_size;
  1649. if(!fp)
  1650. {
  1651. void *temp_ptr;
  1652. int size2;
  1653. size2=(count+31) & ~31;
  1654. temp_ptr=memalign(32, size2);
  1655. if(!temp_ptr) return 0;
  1656. if(WDVD_UnencryptedRead(temp_ptr, size2, ((u64)offset)<<2)<0) count=0;
  1657. if(count)
  1658. {
  1659. memcpy(iobuf, temp_ptr, count);
  1660. }
  1661. free(temp_ptr);
  1662. return (count==0);
  1663. }
  1664. if(init_ciso_table)
  1665. {
  1666. u32 lba_glob=(lba_start<<9)+(16<<9);
  1667. fseek(fp,(lba_start<<11), SEEK_SET);
  1668. ret=fread(buff,1, 32768 ,fp);
  1669. if(ret<=0) {return 1;}
  1670. else
  1671. if(!(buff[0]=='C' && buff[1]=='I' && buff[2]=='S' && buff[3]=='O')) return 1;
  1672. ciso_size=(((u32)buff[4])+(((u32)buff[5])<<8)+(((u32)buff[6])<<16)+(((u32)buff[7])<<24))/4;
  1673. memset(mem_index,0,2048);
  1674. for(l=0;l<16384;l++)
  1675. {
  1676. if((l & 7)==0) table_lba[l>>3]=lba_glob;
  1677. if(buff[(8+l)])
  1678. {
  1679. mem_index[l>>3]|=1<<(l & 7);
  1680. lba_glob+=ciso_size;
  1681. }
  1682. }
  1683. init_ciso_table=0;
  1684. }
  1685. if(!init_ciso_table)
  1686. {
  1687. u32 temp=((u32) offset)/ciso_size;
  1688. u32 read_lba=table_lba[temp>>3];
  1689. for(l=0;l<(temp & 7);l++) if((mem_index[temp>>3]>>l) & 1) read_lba+=ciso_size;
  1690. read_lba<<=2;
  1691. read_lba+=((offset) & (ciso_size-1))<<2;
  1692. fseek(fp, read_lba, SEEK_SET);
  1693. //ret=fread(ptr,1, size ,fp_disc);
  1694. return !(fread(iobuf, 1, count, fp)==count);
  1695. }
  1696. return 1;
  1697. }
  1698. char bannerTitle[84];
  1699. // adapted from Mark R. (USB Loader mrc v9)
  1700. char* FAT_BannerTitle(char *path, SoundInfo *snd ){
  1701. void *banner = NULL;
  1702. int size;
  1703. FILE *fp;
  1704. int indx=0;
  1705. fp=fopen(path, "r");
  1706. if(!fp) goto error;
  1707. init_ciso_table=1;
  1708. lba_start=0;
  1709. size = wbfs_extract_file2(fp, "opening.bnr", &banner, fun_fat_read);
  1710. fclose(fp);
  1711. if (!banner || size <= 0) goto error;
  1712. if(memcmp(((char *) banner)+0x40+indx, "IMET", 4))
  1713. {
  1714. indx+=0x40;
  1715. if(memcmp(((char *) banner)+0x40+indx, "IMET", 4)) goto error;
  1716. }
  1717. int i;
  1718. for(i=0;i<84;i++)
  1719. bannerTitle[i]=((char*)banner)[0xB0+i+indx];
  1720. parse_banner_snd(banner, snd);
  1721. //SAFE_FREE(banner);
  1722. if(banner){
  1723. free(banner);
  1724. banner=NULL;
  1725. }
  1726. return bannerTitle;
  1727. error:
  1728. return NULL;
  1729. }
  1730. s32 __WBFS_ReadDVD(void *fp, u32 lba, u32 len, void *iobuf);
  1731. char* disc_BannerTitle(u32 lba, SoundInfo *snd ){
  1732. void *banner = NULL;
  1733. int size;
  1734. FILE *fp=NULL;
  1735. int indx=0;
  1736. init_ciso_table=1;
  1737. lba_start=lba;
  1738. size = wbfs_extract_file2(fp, "opening.bnr", &banner, __WBFS_ReadDVD/*fun_fat_read*/);
  1739. if (!banner || size <= 0) goto error;
  1740. if(memcmp(((char *) banner)+0x40+indx, "IMET", 4))
  1741. {
  1742. indx+=0x40;
  1743. if(memcmp(((char *) banner)+0x40+indx, "IMET", 4)) goto error;
  1744. }
  1745. int i;
  1746. for(i=0;i<84;i++)
  1747. bannerTitle[i]=((char*)banner)[0xB0+i+indx];
  1748. parse_banner_snd(banner, snd);
  1749. //SAFE_FREE(banner);
  1750. if(banner){
  1751. free(banner);
  1752. banner=NULL;
  1753. }
  1754. return bannerTitle;
  1755. error:
  1756. return NULL;
  1757. }
  1758. char* banner_title=NULL;
  1759. extern void * title_dol;
  1760. extern void * title_banner;
  1761. int load_game_routine(u8 *discid, int game_mode)
  1762. {
  1763. int n, ret,ret2;
  1764. int force_ingame_ios=0;
  1765. int flag_disc=game_mode & 0xa00000;
  1766. static u64 titleid=0;
  1767. make_rumble_off();
  1768. wiimote_read();
  1769. static SoundInfo snd;
  1770. memset(&snd, 0, sizeof(snd));
  1771. titleid=0ULL;
  1772. if(game_mode & 0x400000) // load title
  1773. {
  1774. static u8 str_id[8];
  1775. titleid=0x0001000100000000ULL;
  1776. memcpy(((char *) &titleid)+4, discid, 4);
  1777. game_mode^=0x400000;
  1778. game_cfg_field1= (void *) &game_datas[game_mode-1].config;
  1779. force_ingame_ios= game_cfg_field1->skip_boot;
  1780. cabecera2("Reading The Title ...");
  1781. ret=FAT_get_title(titleid, &title_dol, str_id, force_ingame_ios);
  1782. if(ret<0) return ret;
  1783. //discid=(void *) str_id;
  1784. }
  1785. #if 1
  1786. if(!titleid)
  1787. {
  1788. thread_in_second_plane=1;
  1789. cabecera2("Reading The Banner...");
  1790. if(flag_disc)
  1791. {
  1792. banner_title=disc_BannerTitle(0, &snd);
  1793. }
  1794. else
  1795. if(is_fat)
  1796. {
  1797. char *path;
  1798. get_fat_name_pass=1;
  1799. path=get_fat_name(discid);
  1800. get_fat_name_pass=0;
  1801. if(path)
  1802. banner_title=FAT_BannerTitle(path, &snd);
  1803. else banner_title=NULL;
  1804. }
  1805. else
  1806. {
  1807. banner_title=WBFS_BannerTitle(discid, &snd);
  1808. }
  1809. }
  1810. else
  1811. {
  1812. if(title_banner)
  1813. {
  1814. int indx=0,i;
  1815. banner_title=NULL;
  1816. if(memcmp(((char *) title_banner)+0x40+indx, "IMET", 4))
  1817. {
  1818. indx+=0x40;
  1819. if(memcmp(((char *) title_banner)+0x40+indx, "IMET", 4)) goto title_error;
  1820. }
  1821. for(i=0;i<84;i++)
  1822. bannerTitle[i]=((char*)title_banner)[0xB0+i+indx];
  1823. banner_title=bannerTitle;
  1824. parse_banner_snd(title_banner, &snd);
  1825. title_error:
  1826. if(title_banner){free(title_banner);title_banner=NULL;}
  1827. }
  1828. }
  1829. ASND_StopVoice(0);
  1830. #ifdef USE_MODPLAYER
  1831. #ifdef ALTERNATIVE_VERSION
  1832. StopOgg();
  1833. #else
  1834. //MODPlay_Stop(&mod_track);
  1835. MODPlay_Unload (&mod_track);
  1836. #endif
  1837. //ASND_End(); // finaliza el sonido
  1838. #endif
  1839. if (snd.dsp_data)
  1840. {
  1841. ASND_StopVoice(4);
  1842. int fmt = (snd.channels == 2) ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT;
  1843. if(snd.loop) ASND_SetInfiniteVoice(4, fmt, snd.rate, 0, snd.dsp_data, snd.size, 160,160);
  1844. else ASND_SetVoice(4, fmt, snd.rate, 0, snd.dsp_data, snd.size, 96,96, NULL);
  1845. }
  1846. thread_in_second_plane=0;
  1847. #endif
  1848. //WPAD_Shutdown();
  1849. game_mode &= ~0xa00000;
  1850. add_game_log(discid);
  1851. if(!flag_disc)
  1852. save_cfg(0);
  1853. else
  1854. save_cfg(1);
  1855. game_cfg_field1= (void *) &game_datas[game_mode-1].config;
  1856. #ifndef DONT_USE_IOS249
  1857. if((game_cfg_field1->ios_selected & 1) || force_ios249) cios=249;
  1858. else { if(game_cfg_field1->ios_selected & 2) cios=cios_list[1]; else cios=cios_list[0];}
  1859. #else
  1860. if((game_cfg_field1->ios_selected & 1)) cios=cios_list[2];
  1861. else {if(game_cfg_field1->ios_selected & 2) cios=cios_list[1]; else cios=cios_list[0];}
  1862. // game_datas[game_mode-1].config &=~1;
  1863. #endif
  1864. dont_use_diary= game_cfg_field1->dont_use_diary;
  1865. //shadow_mload= game_cfg_field1->shadow_mload;
  1866. forcevideo= game_cfg_field1->modevideo;//if(forcevideo==3) forcevideo=0;
  1867. langsel= game_cfg_field1->language; if(langsel>10) langsel=0;
  1868. if(!titleid)
  1869. nand_mode= game_cfg_field1->nand_mode;
  1870. force_ingame_ios=0; // unused for disc games now //1*((game_datas[game_mode-1].config>>31)!=0);
  1871. //bca_mode=(game_datas[game_mode-1].config>>29) & 1;
  1872. hook_selected= (game_cfg_field1->hook_selected)+1;
  1873. //game_locked_cfg=1*((game_datas[game_mode-1].config & (1<<30))!=0);
  1874. if(!((bca_mode & 1) && get_bca(discid, BCA_Data))) bca_mode=0;
  1875. // alternative dol when it don't use WDM files
  1876. if(!skip_alternative_dol)
  1877. Get_AlternativeDol(discid);
  1878. load_wip_code(discid);
  1879. if(sd_ok)
  1880. {
  1881. fatUnmount("sd");
  1882. __io_wiisd.shutdown();
  1883. sd_ok=0;
  1884. }
  1885. __io_wiisd.shutdown();
  1886. __io_wiisd.shutdown();
  1887. if(ud_ok)
  1888. {
  1889. fatUnmount("ud");
  1890. __io_usbstorage2.shutdown();ud_ok=0;
  1891. }
  1892. USBStorage2_Watchdog(0); // disable watchdog
  1893. USBStorage2_Deinit();
  1894. // WARNING: this disable ehcmodule for USB 2.0 operations (only to work in DVD Mode without NAND emulation)
  1895. //if(!(flag_disc & 0x200000) && flag_disc && (nand_mode & 2)==0) USBStorage2_EHC_Off();
  1896. WDVD_Close();
  1897. /*
  1898. #ifdef USE_MODPLAYER
  1899. #ifdef ALTERNATIVE_VERSION
  1900. StopOgg();
  1901. #else
  1902. MODPlay_Stop(&mod_track);
  1903. #endif
  1904. //ASND_End(); // finaliza el sonido
  1905. #endif
  1906. */
  1907. if((cios!=cios_list[0] && force_ios249==0) || force_reload_ios222)
  1908. {
  1909. cabecera2("Loading...");
  1910. WPAD_Shutdown();
  1911. usleep(500*1000);
  1912. ret2=IOS_ReloadIOS(cios);
  1913. if((cios==cios_list[1] || cios==cios_list[2]) && ret2==0)
  1914. {
  1915. if((*(volatile u32 *)0x80003140 & 0xffff)<4) return -7777;
  1916. }
  1917. if(ret2<0)
  1918. {
  1919. cios=cios_list[0];
  1920. IOS_ReloadIOS(cios);
  1921. }
  1922. sleep(1);
  1923. cabecera2( "Loading...");
  1924. test_and_patch_for_port1();
  1925. load_ehc_module();
  1926. WPAD_Init();
  1927. WPAD_SetIdleTimeout(60*5); // 5 minutes
  1928. WPAD_SetDataFormat(WPAD_CHAN_ALL, WPAD_FMT_BTNS_ACC_IR); // ajusta el formato para acelerometros en todos los wiimotes
  1929. WPAD_SetVRes(WPAD_CHAN_ALL, SCR_WIDTH+is_16_9*208, SCR_HEIGHT);
  1930. // WARNING: this disable ehcmodule for USB 2.0 operations (only to work in DVD Mode)
  1931. if(!(flag_disc & 0x200000) && flag_disc && (nand_mode & 2)==0) {USBStorage2_EHC_Off();free_usb_ports();}
  1932. else
  1933. {
  1934. if(!dvd_only)
  1935. {
  1936. for(n=0;n<50;n++)
  1937. {
  1938. cabecera2("Loading...");
  1939. ret2 = USBStorage2_Init();
  1940. if(!ret2) break;
  1941. usleep(500*1000);
  1942. }
  1943. USBStorage2_Deinit();
  1944. }
  1945. }
  1946. }
  1947. // enables fake ES_ioctlv (to skip IOS_ReloadIOS(ios))
  1948. if(force_ingame_ios)
  1949. {
  1950. enable_ES_ioctlv_vector();
  1951. }
  1952. mload_close();
  1953. if(flag_disc & 0x200000) discid[6]=2; // mode DVD USB
  1954. else if(flag_disc) discid[6]=1; // mode DVD
  1955. if(banner_title && !dont_use_diary)
  1956. {
  1957. if(Diario_ActualizarDiario(banner_title,(char*) discid)<0) ;//exit(0);
  1958. }
  1959. else Diario_InvalidarDiario();
  1960. if(titleid)
  1961. {
  1962. memcpy((void*)0x80000000, discid, 6);
  1963. DCFlushRange((void*)0x80000000, 0x6);
  1964. ret=bootTitle(titleid);
  1965. }
  1966. else
  1967. ret = load_disc(discid);
  1968. ASND_StopVoice(4);
  1969. sleep(1);
  1970. ASND_End(); // finaliza el sonido
  1971. return ret;
  1972. }
  1973. void snd_explo(int voice, int pos)
  1974. {
  1975. #ifdef USE_MODPLAYER
  1976. if(ASND_StatusVoice(2+voice)!=SND_WORKING)
  1977. {
  1978. int l,r;
  1979. l=((pos-SCR_WIDTH/2)<100) ? 127 : 64;
  1980. r=((pos-SCR_WIDTH/2)>-100) ? 12