* Added initial support for the new wiiload (compressed protocol), uncompressed protocol is also supported

* Added initial (untested!) support for the zip file format, which is supported by the HBC
* Began working on compressed wad files. Uncompressing fails for now, so uploading WAD files should be done with the previous version of Wiiload.
* Fixed issue 902 (hence the large commit).
This commit is contained in:
e.bovendeur 2009-09-30 23:10:58 +00:00
parent b83a379014
commit 1cc7d3acd6
132 changed files with 60352 additions and 60174 deletions

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<app version="1">
<name>USB Loader GX</name>
<coder>dimok nIxx cyrex giantpune Hungyip84 NeoRame WiiShizzza ardi</coder>
<version>1.0</version>
<release_date>20090118030000</release_date>
<short_description>Loads games from USB-devices</short_description>
<long_description>USB Loader GX is a libwiigui based USB iso loader with a wii-like GUI. You can install games to your HDDs and boot them with shorter loading times. The interactive GUI is completely controllable with WiiMote, Classic Controller or GC Controller. Features are automatic widescreen detection, coverdownload, parental control, theme support and many more.</long_description>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<app version="1">
<name>USB Loader GX</name>
<coder>dimok nIxx cyrex giantpune Hungyip84 NeoRame WiiShizzza ardi</coder>
<version>1.0</version>
<release_date>20090118030000</release_date>
<short_description>Loads games from USB-devices</short_description>
<long_description>USB Loader GX is a libwiigui based USB iso loader with a wii-like GUI. You can install games to your HDDs and boot them with shorter loading times. The interactive GUI is completely controllable with WiiMote, Classic Controller or GC Controller. Features are automatic widescreen detection, coverdownload, parental control, theme support and many more.</long_description>
</app>

View File

@ -1,401 +1,401 @@
__,,__, ,__wywyywvyyyyywvywvyam,,_, _,,_
_uWB&#MBM$Wg&MQ$#$K&RMKMA0$&xNH&&MN@2W&#MM&#$KQg
JN&B&MM#MQ$gM#Q$N#R&&#N$M$#&#0E$##V$WKG###B&$&NW#b
j8W0##&M$W&$###&#0##&$0MN#BX&5&#$xA$A$#$#&#z$MNQWK#L
3#$$& N$&WK& XN#$&~~ ^VM#&#A~`^`"~^~"'K###2$M
SQN$# 9MB#@) $$$# ***, $&mR _,_ NU#$M
&0N## #M$$M# NA4 ****** *$g# *0$Q&H! ]$N$#
M\w&F ##&#@$ #W8- ~v"&N8&*#$# 0QB#&$& !#&$K
$QNNC E&M$0# g&&&_ "*$&QM #$MN$#
j$$0L $M@WWK #W&#M&k,,_ ~&$$ _,_ $NQN(
i&M4( N$K2## M#NNF$&####& 0#$ *0$Q&H! W#$(
j$B#N V&#AMS SRW $8$0M& 3M$ 0QB#&$& #N$I
jQ0&NL ""^ JB&ML '~^ jQ*A ` j##KF
K#$##& _#B#WNKM_ ,vB&#M _ _wp#&QAF
"&NAQAN&#$&MW#&###B#x$3@&$BA#WWWH$#KMM&K&NK###g&$#
*WN$&$$8QWNMMM#MM&<&A#&M$K&#WK@QM5#&*A$N&$&WM#@2
"M*^&N##&$W8$2B#&MB&DWR0#$$0#W>&&M$#QQMN#&""
\eeee6 F**A1
jM0$e4 ?**G\!
imw{Q- x%%%m \%z%%e mxx _%*%@& -ve/v mmm\ wvm
V3Q%m& /#0^0E&~/&\ $&E/&%1e^"E 55t7JcVsm0-\ &^#l@&}&-" $7MAE&&%/
$%x/z Wc&&t7-w&E4^ %VVM~1^\&$&&} e$&$$%$zQMxw w-v-#^ Q\W44 %-/%/\QS
et-SC e^00^ iF&E$- !%%$$%A*v 5^^4 EEZ/0 )%%0%4fimmEt" "$S8V
(WJ^%i m&MM#} /%\%%L 4Q\w WQ/Q\ &m<wS \v"v1 \74~1zM%&%/6s wEw//
&ssSs?s%wt&&-~~MM#& e1/'m% &5^jW &mw&\ SmVw^ S1&mw \^A5FE j7F*5, ~S3m%
j3Q"/&-&w&M%& ^^4$w^7QSQ@ t&&&%-"5w&E} e8"&&&&/%\W &5%1\%V*\0M &&7M
~?VW^$ ?&\81? ?mQ&&&- 00%%^~EE4E \&00 ^M43^ ^'"#5&$-^ ~wEE}
__ ,_
__ggggggggggggggg& jggggg#p gMMMMMMM
&MMMMMMMMMMMMMMMMMMF "MMMMMMM& j#MMMMMMP
#MMMMMMMMMMMMMMMMMMMF #MMMMM&g#MMMMMMP
#MMMMMF "MMMMMMMMMMM#^
#MMMMML pgppggggggp $MMMMMMMMF
$MMMMML 4#M#NRMMMMMF jMMMMMMMMMQ
$MMMMMF #MMMMF pMMMMMMMMMMMMp
4MMMMMMNNN#MMMMMMMMMF jMMMMMMF MMMMMM&_
MMMMMMMMMMMMMMMMMM& #MMMMM@~ ~MMMMMM&
"""""""""""""""" """""" """"""^
Congratulations. You are the proud Beta Tester for USB Loader GX. That's right. Beta Tester. That means that you are using Beta software. This program is still under heavy development. Not everything works perfectly. If you are expecting it to, stop and look else where. Some of the features covered here may be removed in your version of the application. And likewise, there may be features in your revision that are not covered here.
By using a Beta revision, you are agreeing to not be an idiot. Most of the features should be self explanatory. The rest of them can be figured out by clicking around a trying stuff out. There is no button or combination of buttons that you can click that will brick your wii or make irreparable changes to your wii so please try out all the features to see which options need to be enabled for your wii/tv/game combination.
This was written 6/15/2009 regarding revision 525
Official site
http://code.google.com/p/usbloader-gui/
changelog
http://code.google.com/p/usbloader-gui/source/list
sourcecode checkout
http://usbloader-gui.googlecode.com/svn/trunk/
game compatibility chart
http://wiki.gbatemp.net/wiki/index.php/USB_Loader_v1.x_Game_Compatibility
Other crap that you may find useful is here
http://usbloadergx.koureio.net/help
[1]prerequisites
[1a]files & paths
[2]usage
[3]adding games
[4]main menu
[4a]controls
[4b]Buttons & shit
[4c]view
[4d]game info
[4e]game prompt
[5]exit menu
[6]settings
[6a]gui settings
app language
display
clock
tooltips
flipx
prompts/buttons
keyboard
wiilight
rumble
unicode fix
titles from xml
[6b]game load
video mode
vidTVpatch
language
patch country strings
ocarina
boot/standard
quick boot
error 002fix
[6c]parental control
console
password
control level
[6d]sound
background music
music volume
SFX volume
[6e]custom paths
[6f]update
[6g]default settings
[6h]credits
[7]game settings
video mode
vidTV patch
language
ocarina
ios
parental control
error002 fix
online fix
patch country strings
default settings
alternate dol
The ocarina button
[8]Themes
[9]Cheatmanager
[10]Troubleshooting
###################################################################################
[1]Prerequisites and setup
To use this application, you will need a Wii that has been hacked and is able to run homebrew software. DO NOT ASK US HOW TO HACK YOUR WII. THERE ARE THOUSANDS OF TUTORIALS FOR THIS. You will need to have any 1 or more of cIOS 249rev9 or greater, cIOS222, or cIOS 223. There are advantages and disadvantages for each of the different cIOS. It is up to you to research and decide which one you want to use. It is also up to you to know about the bugs which are known bugs of the cIOS.
For the initial setup you will need to use a PC to format a USB drive to either FAT or NTFS. If you are going to use the USB device to store other data for this application besides games (images, settings, ect) now will be a good time to create a Secondary partition. 1gb is plenty for the second partition for what we are going to use it for. The second partition should be FAT (FAT32 /16 should work fine as well). Mark your partitions primary and active and if you want your PC to be able to interact with this drive, assign it a drive letter.
Now plug your drive into your wii and use your desired method of booting homebrew to launch our application. If everything was done right, you will be prompted to format your main partition to WBSF to use with this loader. Just follow the instructions on screen.
[1a]Files & paths
There are other files that are not necessary to the core functionality of this loader, but are used for extra features. The dev team have defined the following paths, most of which are configurable in the settings.
SD:/config/ this is where the application will create files to save settings and statistics. All the files it makes start with GX to make them easy to find. GxGlobal.cfg is the main settings and configuration for the loader. GXGameFavorites.cfg contains individual settings for games. GXGameCount.cfg stores the game play count and favorites choices. Also in this folder you can put a file called titles.txt to change the names of the games as seen in the loader if you are too much of a pussy to edit them directly on the WBFS filesystem. A database of information about each game can be stored in this folder as well. Get you hands on wiitb.zip (which contains wiitdb.xml) and put it here.
SD:/images/ This is where box art is downloaded to and displayed from. All images must be sized in multiples of 4 or they won't show up.
SD:/images/disc/ This is where pictures of the actual game discs are downloaded to and displayed from. All images must be sized in multiples of 4 or they won't show up.
SD:/config/backgroundmusic/ This is the default folder for custom bg music.
SD:/theme/(SD:/wtheme for widescreen wii) This is the default theme location.
SD:/codes/ This is the folder to put your gct cheat files. These fiiles should be named wich the 6 character ID of the game they are meant for.
SD:/txtcodes/ This is the folder to put your txt cheat files. They should be in the standard format for homebrew/ocarina. Some examples are available in the downloads section at the googlecode URL above.
SD:/ This is where replacement dols used to fix certain broken games go.
###################################################################################
[2]Usage
Using this application is simple. Launch it in the same manner that you did in the initial setup, pick a game (if you have any installed), and play the game. This is open source software. You are free to modify it, distribute it, and do anything you want with it. All we demand is that you do not claim our work as yours. We worked long and hard on this and let you use it for free. It would be a real bitch move if you put your name on it and said it was your own. You are also free to distribute the software/source code as you like as long as this file (or a similar one approved by the dev team) companies it. If you don't follow these guidelines, you are a douche-bag.
###################################################################################
[3]Adding games*****
To add a game to your drive using this program, click the install(+) button on the main screen and follow the on screen prompts. Games are automatically scrubbed (shrunk) and brickblocked (update partition removed) when adding them to the drive. Because of the way WBFS and the application work, you are only allowed to install 1 game for each game ID. If you do use another application to install 2 games with the same 6 character ID, only the first one one the drive will be loaded by our program. If the installation freezes ( doesn't move for over 2 minutes) you can simply hold the power button on the Wii to turn it off. There is no danger of bricking your wii. The data that was written during the failed install is still present on the drive, but not marked as active so it will be treated as free space. It does not get added into the used space displayed on the screen and it will overwritten next time you install a game.
###################################################################################
[4]main menu
This is the main screen, the first one you see when you start the program. It looks a lot like the Wii system menu.
[4a]controls
User input for the main menu is accepted through WiiMote, nunchuk, gamecube controller, and classic controller. While input is accepted from all these methods, the fastest and easiest method is with a WiiMote. Just point to the screen and click on shit. A is the main action button. B (for the most part) is back/cancel. The D-pad is used to highlight different options. Press 2 to view game info (with the xml file listed above in place).
[4b]Buttons & shit
Install--***** The + button in the lower left corner of the screen. Press to add games to your HDD from the Wii's DVD drive.
Settings-- The gear button to the right of the install button. Use it to access all the settings and options.
Exit-- The button in the lower right corner that says "wii". Press this to view the exit menu.
Power-- The button furthest to the right in the lower corner. I bet you can figure out what it does.
Download--***** When you are in the list view, click a game box to download stuff.
Reload-- This button looks like an SD card. Press it to reload your SD contents.
Sort bar--
Favorites-- the star button. Press it to hide all games that are not marked as a favorite.
Abc-- the button that says "ABC". Press it to sort games alphabetically.
Count-- the chart button. Press it to sort games by the number of times you have launched them from this application.
Games with the same count are sorted alphabetically.
List-- Press it to see games listed by name and any available box art for 1 game at a time.
Grid-- Press this button to see your games arranged in a grid. The number of rows available depends on how many games are on you drive. 39 games can be seen at the most.
Carousel-- Press this to see you games arranged in a rotating fan array. 7 games can be seen at a time.
clock-- This looks like a clock. Coincidently, it functions like a clock.
Hdd Info-- This shows some information about your connected HDD (only the WBFS partition). Free & total space in GB as well as the game count. GB is defined here as 1024MB. When you bought your drive, the manufacturer probably used 1000MB for GB so the size displayed here will be less than what your drive was advertised as. The game count will reflect the games you are choosing to display, not the actual amount of games on your drive. If you are hiding games with parental controls/favorites, they will not be added into this total.
[4c]view
There are 3 different ways to view your games.
List-- Games are listed by name (up to 9 at a time) box art for the selected game is displayed. This is currently the only screen you can initiate a download for artwork from. Also on this screen The B button has a slightly different use. If there are scrollbars present on your gamelist, holding B and moving the cursor scrolls the list.
grid-- Games are aranged in a grid (up to 320). The number of rows available depends on how many games are on you drive. By default, it is 3X14 (with the last column hidden)if there arent enough games to fill all 42 spots, it changes to 2x8 (2x7 shown on screen). Again, if there arent enough games to fil it up, the number of rows decreases. Currently there is no 4/3 support for this view.
carousel-- Games are arranged in a rotating fan array (up to 320). 7 games can be seen at a time.
[4d]Game Info
Pressing 2 (or x on GC an CC input) brings a prompt with information about the selected game. This info is read from the zipped xml file discussed earlier. Among the displayed information are the following:
Accessories-- the supported accessories for the game are shown in the lower left. The max number of players is shown on the image of the WiiMote. Any required accessories are shown in light blue.
Rating system-- the rating for the game is shown in the lower left of the screen. It is converted internally between PEGI,ESRB, and CERO( though not used for anything yet).
Wifi Shit-- the number of online players is displayed to the right of the accessories. Any other wifi features are listed above the accessories.
synopsis-- if a synopsis is present in the xml file, it can be viewed by pressing A on the game info screen.
[4e]Game Prompt
This is the prompt that comes up when a game is selected (if the quickboot option is not selected).
settings-- brings up a menu of settings for this game only
play-- Click the spinning disc to launch this game
rename--***** Click the title of the game in the top of the prompt to rename it directly on the WBFS file system. If you are using titles.txt or letting the XML rename the games, this will have no (visible) effect.
back-- closes this prompt
favorite-- Click the star to add/remove this game from your favorites.
size-- the amount of space that the game ocupies on the WBFS filesystem
count-- the number of times you have launched this game from this application
settings--*****Here is where you go to enter settings that will be used for this game only.
###################################################################################
[5]Exit Menu
This is the screen that appears when you press the home button on the WiiMote or the exit button in the main screen.
return to loader-- if you launched USB Loader GX from HBC, LoadMii, or similar chain loading application, you will see this button. Pressing it will take you back to the application that you came from.
Wii Menu-- exits to the Wii System Menu
batteries-- Status for all connected WiiMotes is displayed here
close-- closes this screen and returns you to where you were in the application before this screen was called
###################################################################################
[6]settings
This is where you customize the behavior of the program.
[6a]Gui settings
These are the settings that affect the behavior and feel of the GUI. Your settings are saved when exiting back to the main screen, change custom paths, change views in the main screen, and a few other times.
app language-- *****If you have a language file to translate this program, you can select it here. You can change the path by clicking it at the top of the screen. The button in the lower right will restore the defualt (english).
display-- In the list view, you can chose to display the selected game's region and ID here.
clock-- Chose how you want the clock displayed.
tooltips-- enable tooltip help with this.
flipx-- this changes the behavior of left and right on the gameprompt. if it feels un-natural, change this setting.
prompts/buttons-- Select weather or not to apply the widescreen fix to prompt windows and certain buttons in the GUI.
keyboard-- Chose between different layouts for the on screen keyboard used in the GUI.
wiilight-- Change the behavior of the disc slot light.
rumble-- turn rumble on/off
unicodefix-- Use this only if you have compiled the application with a Chinese,Japanese, etc font that does not display correctly.
titles from xml-- chose if you want to ignore the titles stored on the xml file and use the ones stored in the WBFS.
[6b]Gameload
Change settings that have to do with the way games are booted. These will be use as default if you don't set any spacific settings for that game.
videomode-- select the video mode use for games. Most games work with disc default. If this doesn't work, then try console default. Then if you still need to, try forcing your region.
vidTVpatch-- patches the signal after the game has rendered it in the mode selected in videomode. If none of the video modes work then try this.
language-- the language that is passed to the game when it is booted. if the language is supported by the game, it will be used in game.
patch country strings-- use this for Japanese games playing imports.
ocarina-- turn on/off the ocarina cheat engine. You need gct files in the cheatcode path mentioned earlier.
boot/standard-- *****Select the cIOS that is used to boot the program into.
quickboot-- Chose if you want to skip the gameprompt when starting games.
error 002fix-- with certain IOS, some games show an error that says "blablabla, 002, blablabla. Don't be a pirate." Turn this on to fix it. For certain games running under older cIOS versions, you will need to set this to anti for the games to boot.
[6c]Parental control
Settings for parents to control what content their kids see. Everything in this file with ***** beside it is hidden when the application is locked.
console--***** click here to lock/unlock advanced features.
password-- *****click here to set a password.
control level--***** set the level of parental control here. games will be excluded from the game list based on this and the settings you have for them in the game-specific settings.
[6d]sound
Settings related to audio are here
background music-- You can chose custom BG music to be heard in the application here. Click the path at the top to change it. Format is OGG. Keep in ming that bigger songs will result in decreased memory available for other functions. It is possible to completely crash the loader with big files. Try to keep it <3MB to be safe. If you want to rock out to your music, use a media player. This is a game loader.
music volume-- pick the volume for the BG music within this application, not in the games that are booted.
SFX volume-- Pick the volume for the sound effects within this application, not in the games that are booted.
[6e]Custom paths*****
Some of the paths the program uses are customizable. All paths should start with "SD:/" or "USB:/" (without quotes). USB paths will be on the first available FAT USB partition.
covers-- *****for boxart
discimage--***** for DVD art
themepath--*****for theme shit
titles.txt--*****for title.txt and wiitdb.zip
update--***** used for updating the dol. If you are using our forwarder, it loads dols from this path.
cheatcodes-- *****for gct & ocarina use
txtcheat path-*****for txt files holding the codes for your gams.
dolpath—*****for replacement dols for certain broken games.
[6f]Update*****
Click to get updates from online. Just because there is a newer revision than what you are using does not mean that it will be on the update server. Also, you get the choice to update your dol or the entire HBC package. If you are using a full channel (not a forwarder channel), you won't get the option to update all. It will just download a wad file and install that on your wii over top of the old version and then kick you out to the system menu so you can restart with the new version. This is assuming that the person that created the channel took the necessary steps when they made it. If you are using the full channel and you get the option to update all, then they fucked up and the update will do you no good.
[6g]default settings*****
Click here to restore default settings.
[6h]credits
Look at the people that made this application possible. You get to rock out to some cool music, too. In the upper right corner is displayed your rev# and the cIOS that your are currently running.
###################################################################################
[7]gamesettings
Settings are available on a per-game basis from the prompt window. These settings have the same effect as the global settings but are only used for the selected game. After making changes, you must click the save button for them to take effect.
videomode
vidTV patch
language
ocarina
ios
parental control
error002 fix
online fix --if you have attempted to use any online features of this application, the online features of any game you boot will not work. In order to fix this we can reload the IOS. Unfortunately, reloading IOS results in random blackscreens with certain IOS versions. Turn this option on to reload the IOS and risk random black screens.
patch country strings
alternate dol-- this is for advanced users only. There are certain games which do not run because they they reload IOS and this causes the USB to be dropped. If you extract the proper dol from the ISO and name it with the 6 character game ID and put in the dolpath, you can use enable this option to play these games.
default settings-- delete any saved settings for this game. After you press this, there is no need to press save.
save-- writes the settings that are on the screen right now to the GXGameSettings file with the current game ID
uninstall-- Delete the selected game from the WBFS table. The data is not erased from the drive, it is just marked as free space.
back-- Lose any unsaved changes and return to the previous screen.
ocarina button-- this is that blue thing in the upper right. If you have a txt file for the selected game in the txtcheat folder, click this button to go to the code selection page. You will see a list of the cheats in the txt file and you can turn them on and off. When you are happy with the codes you have selected, click the button to generate a gct file. This will make a gct file with only the codes that are turned on and put it in the proper folder. Then make sure you turn ocarina on or your cheats won't be used.
###################################################################################
[8]Themes
Is it possible to theme this program. Theme elements may include font, images, sounds, and GXtheme.cfg. If anything is not included in the theme path, the default will be used. For image names, look in the source. Not every image can be themed, but this is a good place to look for the names of the ones that can be. All images must be sized in multiples of 4 or they will not be displayed. To move elements of the gui around, you can use GXtheme.cfg. I template can be found here http://code.google.com/p/usbloader-gui/wiki/ThemeSettings. For More accurate list of themable elements, look in cfg.c from the source
###################################################################################
[9]Cheatmanager
The Cheatmanager makes it possible to directly convert TXT Cheat Codes files into GCT for Ocarina.
You can find the Cheatmanager in the Game Settings (click on the Ocarina Icon) select the Cheat you want to use and create the GCT file.
The TXT Files should look like this
GameID
GameTitle
Cheat1
*here the hexvalues*
Comment (actually only one line of comment is supported otherwise the GCT file will be messed up)
Cheat2
*here the hexvalues*
Comment
Cheat3
and so on
###################################################################################
[10]Troubleshooting
I get black screen when loading games.
check the game compatibility list, unhook extra controllers, turn off ocarina, play with video settings. If the list says the game works, then try different video settings if the game is not from the same region as your tv/wii.
Also try without ocarina. Unless you made the codes yourself, you don't know that they work. And you don't know which codes work together. Using codes from a different region will also fuck shit up.
Some games don't like it if you have certain controllers plugged in. Remove GC & CC controllers and try again.
If all else fails, rip the game again. It may have gotten messed up in the process.
I get a black screen with a bunch of numbers on it
This is a code dump. It is not bad for your wii. It just means that the program crashed. This is beta software, it happens. Different revs can have this happen at certain times. Just press reset on your wii. If you find that this happens every time you start the application, rename your config folder and restart it. This will cause the loader to use default settings. If it fixes the problem then you can copy the game settings and favorites files back into the config directory.
__,,__, ,__wywyywvyyyyywvywvyam,,_, _,,_
_uWB&#MBM$Wg&MQ$#$K&RMKMA0$&xNH&&MN@2W&#MM&#$KQg
JN&B&MM#MQ$gM#Q$N#R&&#N$M$#&#0E$##V$WKG###B&$&NW#b
j8W0##&M$W&$###&#0##&$0MN#BX&5&#$xA$A$#$#&#z$MNQWK#L
3#$$& N$&WK& XN#$&~~ ^VM#&#A~`^`"~^~"'K###2$M
SQN$# 9MB#@) $$$# ***, $&mR _,_ NU#$M
&0N## #M$$M# NA4 ****** *$g# *0$Q&H! ]$N$#
M\w&F ##&#@$ #W8- ~v"&N8&*#$# 0QB#&$& !#&$K
$QNNC E&M$0# g&&&_ "*$&QM #$MN$#
j$$0L $M@WWK #W&#M&k,,_ ~&$$ _,_ $NQN(
i&M4( N$K2## M#NNF$&####& 0#$ *0$Q&H! W#$(
j$B#N V&#AMS SRW $8$0M& 3M$ 0QB#&$& #N$I
jQ0&NL ""^ JB&ML '~^ jQ*A ` j##KF
K#$##& _#B#WNKM_ ,vB&#M _ _wp#&QAF
"&NAQAN&#$&MW#&###B#x$3@&$BA#WWWH$#KMM&K&NK###g&$#
*WN$&$$8QWNMMM#MM&<&A#&M$K&#WK@QM5#&*A$N&$&WM#@2
"M*^&N##&$W8$2B#&MB&DWR0#$$0#W>&&M$#QQMN#&""
\eeee6 F**A1
jM0$e4 ?**G\!
imw{Q- x%%%m \%z%%e mxx _%*%@& -ve/v mmm\ wvm
V3Q%m& /#0^0E&~/&\ $&E/&%1e^"E 55t7JcVsm0-\ &^#l@&}&-" $7MAE&&%/
$%x/z Wc&&t7-w&E4^ %VVM~1^\&$&&} e$&$$%$zQMxw w-v-#^ Q\W44 %-/%/\QS
et-SC e^00^ iF&E$- !%%$$%A*v 5^^4 EEZ/0 )%%0%4fimmEt" "$S8V
(WJ^%i m&MM#} /%\%%L 4Q\w WQ/Q\ &m<wS \v"v1 \74~1zM%&%/6s wEw//
&ssSs?s%wt&&-~~MM#& e1/'m% &5^jW &mw&\ SmVw^ S1&mw \^A5FE j7F*5, ~S3m%
j3Q"/&-&w&M%& ^^4$w^7QSQ@ t&&&%-"5w&E} e8"&&&&/%\W &5%1\%V*\0M &&7M
~?VW^$ ?&\81? ?mQ&&&- 00%%^~EE4E \&00 ^M43^ ^'"#5&$-^ ~wEE}
__ ,_
__ggggggggggggggg& jggggg#p gMMMMMMM
&MMMMMMMMMMMMMMMMMMF "MMMMMMM& j#MMMMMMP
#MMMMMMMMMMMMMMMMMMMF #MMMMM&g#MMMMMMP
#MMMMMF "MMMMMMMMMMM#^
#MMMMML pgppggggggp $MMMMMMMMF
$MMMMML 4#M#NRMMMMMF jMMMMMMMMMQ
$MMMMMF #MMMMF pMMMMMMMMMMMMp
4MMMMMMNNN#MMMMMMMMMF jMMMMMMF MMMMMM&_
MMMMMMMMMMMMMMMMMM& #MMMMM@~ ~MMMMMM&
"""""""""""""""" """""" """"""^
Congratulations. You are the proud Beta Tester for USB Loader GX. That's right. Beta Tester. That means that you are using Beta software. This program is still under heavy development. Not everything works perfectly. If you are expecting it to, stop and look else where. Some of the features covered here may be removed in your version of the application. And likewise, there may be features in your revision that are not covered here.
By using a Beta revision, you are agreeing to not be an idiot. Most of the features should be self explanatory. The rest of them can be figured out by clicking around a trying stuff out. There is no button or combination of buttons that you can click that will brick your wii or make irreparable changes to your wii so please try out all the features to see which options need to be enabled for your wii/tv/game combination.
This was written 6/15/2009 regarding revision 525
Official site
http://code.google.com/p/usbloader-gui/
changelog
http://code.google.com/p/usbloader-gui/source/list
sourcecode checkout
http://usbloader-gui.googlecode.com/svn/trunk/
game compatibility chart
http://wiki.gbatemp.net/wiki/index.php/USB_Loader_v1.x_Game_Compatibility
Other crap that you may find useful is here
http://usbloadergx.koureio.net/help
[1]prerequisites
[1a]files & paths
[2]usage
[3]adding games
[4]main menu
[4a]controls
[4b]Buttons & shit
[4c]view
[4d]game info
[4e]game prompt
[5]exit menu
[6]settings
[6a]gui settings
app language
display
clock
tooltips
flipx
prompts/buttons
keyboard
wiilight
rumble
unicode fix
titles from xml
[6b]game load
video mode
vidTVpatch
language
patch country strings
ocarina
boot/standard
quick boot
error 002fix
[6c]parental control
console
password
control level
[6d]sound
background music
music volume
SFX volume
[6e]custom paths
[6f]update
[6g]default settings
[6h]credits
[7]game settings
video mode
vidTV patch
language
ocarina
ios
parental control
error002 fix
online fix
patch country strings
default settings
alternate dol
The ocarina button
[8]Themes
[9]Cheatmanager
[10]Troubleshooting
###################################################################################
[1]Prerequisites and setup
To use this application, you will need a Wii that has been hacked and is able to run homebrew software. DO NOT ASK US HOW TO HACK YOUR WII. THERE ARE THOUSANDS OF TUTORIALS FOR THIS. You will need to have any 1 or more of cIOS 249rev9 or greater, cIOS222, or cIOS 223. There are advantages and disadvantages for each of the different cIOS. It is up to you to research and decide which one you want to use. It is also up to you to know about the bugs which are known bugs of the cIOS.
For the initial setup you will need to use a PC to format a USB drive to either FAT or NTFS. If you are going to use the USB device to store other data for this application besides games (images, settings, ect) now will be a good time to create a Secondary partition. 1gb is plenty for the second partition for what we are going to use it for. The second partition should be FAT (FAT32 /16 should work fine as well). Mark your partitions primary and active and if you want your PC to be able to interact with this drive, assign it a drive letter.
Now plug your drive into your wii and use your desired method of booting homebrew to launch our application. If everything was done right, you will be prompted to format your main partition to WBSF to use with this loader. Just follow the instructions on screen.
[1a]Files & paths
There are other files that are not necessary to the core functionality of this loader, but are used for extra features. The dev team have defined the following paths, most of which are configurable in the settings.
SD:/config/ this is where the application will create files to save settings and statistics. All the files it makes start with GX to make them easy to find. GxGlobal.cfg is the main settings and configuration for the loader. GXGameFavorites.cfg contains individual settings for games. GXGameCount.cfg stores the game play count and favorites choices. Also in this folder you can put a file called titles.txt to change the names of the games as seen in the loader if you are too much of a pussy to edit them directly on the WBFS filesystem. A database of information about each game can be stored in this folder as well. Get you hands on wiitb.zip (which contains wiitdb.xml) and put it here.
SD:/images/ This is where box art is downloaded to and displayed from. All images must be sized in multiples of 4 or they won't show up.
SD:/images/disc/ This is where pictures of the actual game discs are downloaded to and displayed from. All images must be sized in multiples of 4 or they won't show up.
SD:/config/backgroundmusic/ This is the default folder for custom bg music.
SD:/theme/(SD:/wtheme for widescreen wii) This is the default theme location.
SD:/codes/ This is the folder to put your gct cheat files. These fiiles should be named wich the 6 character ID of the game they are meant for.
SD:/txtcodes/ This is the folder to put your txt cheat files. They should be in the standard format for homebrew/ocarina. Some examples are available in the downloads section at the googlecode URL above.
SD:/ This is where replacement dols used to fix certain broken games go.
###################################################################################
[2]Usage
Using this application is simple. Launch it in the same manner that you did in the initial setup, pick a game (if you have any installed), and play the game. This is open source software. You are free to modify it, distribute it, and do anything you want with it. All we demand is that you do not claim our work as yours. We worked long and hard on this and let you use it for free. It would be a real bitch move if you put your name on it and said it was your own. You are also free to distribute the software/source code as you like as long as this file (or a similar one approved by the dev team) companies it. If you don't follow these guidelines, you are a douche-bag.
###################################################################################
[3]Adding games*****
To add a game to your drive using this program, click the install(+) button on the main screen and follow the on screen prompts. Games are automatically scrubbed (shrunk) and brickblocked (update partition removed) when adding them to the drive. Because of the way WBFS and the application work, you are only allowed to install 1 game for each game ID. If you do use another application to install 2 games with the same 6 character ID, only the first one one the drive will be loaded by our program. If the installation freezes ( doesn't move for over 2 minutes) you can simply hold the power button on the Wii to turn it off. There is no danger of bricking your wii. The data that was written during the failed install is still present on the drive, but not marked as active so it will be treated as free space. It does not get added into the used space displayed on the screen and it will overwritten next time you install a game.
###################################################################################
[4]main menu
This is the main screen, the first one you see when you start the program. It looks a lot like the Wii system menu.
[4a]controls
User input for the main menu is accepted through WiiMote, nunchuk, gamecube controller, and classic controller. While input is accepted from all these methods, the fastest and easiest method is with a WiiMote. Just point to the screen and click on shit. A is the main action button. B (for the most part) is back/cancel. The D-pad is used to highlight different options. Press 2 to view game info (with the xml file listed above in place).
[4b]Buttons & shit
Install--***** The + button in the lower left corner of the screen. Press to add games to your HDD from the Wii's DVD drive.
Settings-- The gear button to the right of the install button. Use it to access all the settings and options.
Exit-- The button in the lower right corner that says "wii". Press this to view the exit menu.
Power-- The button furthest to the right in the lower corner. I bet you can figure out what it does.
Download--***** When you are in the list view, click a game box to download stuff.
Reload-- This button looks like an SD card. Press it to reload your SD contents.
Sort bar--
Favorites-- the star button. Press it to hide all games that are not marked as a favorite.
Abc-- the button that says "ABC". Press it to sort games alphabetically.
Count-- the chart button. Press it to sort games by the number of times you have launched them from this application.
Games with the same count are sorted alphabetically.
List-- Press it to see games listed by name and any available box art for 1 game at a time.
Grid-- Press this button to see your games arranged in a grid. The number of rows available depends on how many games are on you drive. 39 games can be seen at the most.
Carousel-- Press this to see you games arranged in a rotating fan array. 7 games can be seen at a time.
clock-- This looks like a clock. Coincidently, it functions like a clock.
Hdd Info-- This shows some information about your connected HDD (only the WBFS partition). Free & total space in GB as well as the game count. GB is defined here as 1024MB. When you bought your drive, the manufacturer probably used 1000MB for GB so the size displayed here will be less than what your drive was advertised as. The game count will reflect the games you are choosing to display, not the actual amount of games on your drive. If you are hiding games with parental controls/favorites, they will not be added into this total.
[4c]view
There are 3 different ways to view your games.
List-- Games are listed by name (up to 9 at a time) box art for the selected game is displayed. This is currently the only screen you can initiate a download for artwork from. Also on this screen The B button has a slightly different use. If there are scrollbars present on your gamelist, holding B and moving the cursor scrolls the list.
grid-- Games are aranged in a grid (up to 320). The number of rows available depends on how many games are on you drive. By default, it is 3X14 (with the last column hidden)if there arent enough games to fill all 42 spots, it changes to 2x8 (2x7 shown on screen). Again, if there arent enough games to fil it up, the number of rows decreases. Currently there is no 4/3 support for this view.
carousel-- Games are arranged in a rotating fan array (up to 320). 7 games can be seen at a time.
[4d]Game Info
Pressing 2 (or x on GC an CC input) brings a prompt with information about the selected game. This info is read from the zipped xml file discussed earlier. Among the displayed information are the following:
Accessories-- the supported accessories for the game are shown in the lower left. The max number of players is shown on the image of the WiiMote. Any required accessories are shown in light blue.
Rating system-- the rating for the game is shown in the lower left of the screen. It is converted internally between PEGI,ESRB, and CERO( though not used for anything yet).
Wifi Shit-- the number of online players is displayed to the right of the accessories. Any other wifi features are listed above the accessories.
synopsis-- if a synopsis is present in the xml file, it can be viewed by pressing A on the game info screen.
[4e]Game Prompt
This is the prompt that comes up when a game is selected (if the quickboot option is not selected).
settings-- brings up a menu of settings for this game only
play-- Click the spinning disc to launch this game
rename--***** Click the title of the game in the top of the prompt to rename it directly on the WBFS file system. If you are using titles.txt or letting the XML rename the games, this will have no (visible) effect.
back-- closes this prompt
favorite-- Click the star to add/remove this game from your favorites.
size-- the amount of space that the game ocupies on the WBFS filesystem
count-- the number of times you have launched this game from this application
settings--*****Here is where you go to enter settings that will be used for this game only.
###################################################################################
[5]Exit Menu
This is the screen that appears when you press the home button on the WiiMote or the exit button in the main screen.
return to loader-- if you launched USB Loader GX from HBC, LoadMii, or similar chain loading application, you will see this button. Pressing it will take you back to the application that you came from.
Wii Menu-- exits to the Wii System Menu
batteries-- Status for all connected WiiMotes is displayed here
close-- closes this screen and returns you to where you were in the application before this screen was called
###################################################################################
[6]settings
This is where you customize the behavior of the program.
[6a]Gui settings
These are the settings that affect the behavior and feel of the GUI. Your settings are saved when exiting back to the main screen, change custom paths, change views in the main screen, and a few other times.
app language-- *****If you have a language file to translate this program, you can select it here. You can change the path by clicking it at the top of the screen. The button in the lower right will restore the defualt (english).
display-- In the list view, you can chose to display the selected game's region and ID here.
clock-- Chose how you want the clock displayed.
tooltips-- enable tooltip help with this.
flipx-- this changes the behavior of left and right on the gameprompt. if it feels un-natural, change this setting.
prompts/buttons-- Select weather or not to apply the widescreen fix to prompt windows and certain buttons in the GUI.
keyboard-- Chose between different layouts for the on screen keyboard used in the GUI.
wiilight-- Change the behavior of the disc slot light.
rumble-- turn rumble on/off
unicodefix-- Use this only if you have compiled the application with a Chinese,Japanese, etc font that does not display correctly.
titles from xml-- chose if you want to ignore the titles stored on the xml file and use the ones stored in the WBFS.
[6b]Gameload
Change settings that have to do with the way games are booted. These will be use as default if you don't set any spacific settings for that game.
videomode-- select the video mode use for games. Most games work with disc default. If this doesn't work, then try console default. Then if you still need to, try forcing your region.
vidTVpatch-- patches the signal after the game has rendered it in the mode selected in videomode. If none of the video modes work then try this.
language-- the language that is passed to the game when it is booted. if the language is supported by the game, it will be used in game.
patch country strings-- use this for Japanese games playing imports.
ocarina-- turn on/off the ocarina cheat engine. You need gct files in the cheatcode path mentioned earlier.
boot/standard-- *****Select the cIOS that is used to boot the program into.
quickboot-- Chose if you want to skip the gameprompt when starting games.
error 002fix-- with certain IOS, some games show an error that says "blablabla, 002, blablabla. Don't be a pirate." Turn this on to fix it. For certain games running under older cIOS versions, you will need to set this to anti for the games to boot.
[6c]Parental control
Settings for parents to control what content their kids see. Everything in this file with ***** beside it is hidden when the application is locked.
console--***** click here to lock/unlock advanced features.
password-- *****click here to set a password.
control level--***** set the level of parental control here. games will be excluded from the game list based on this and the settings you have for them in the game-specific settings.
[6d]sound
Settings related to audio are here
background music-- You can chose custom BG music to be heard in the application here. Click the path at the top to change it. Format is OGG. Keep in ming that bigger songs will result in decreased memory available for other functions. It is possible to completely crash the loader with big files. Try to keep it <3MB to be safe. If you want to rock out to your music, use a media player. This is a game loader.
music volume-- pick the volume for the BG music within this application, not in the games that are booted.
SFX volume-- Pick the volume for the sound effects within this application, not in the games that are booted.
[6e]Custom paths*****
Some of the paths the program uses are customizable. All paths should start with "SD:/" or "USB:/" (without quotes). USB paths will be on the first available FAT USB partition.
covers-- *****for boxart
discimage--***** for DVD art
themepath--*****for theme shit
titles.txt--*****for title.txt and wiitdb.zip
update--***** used for updating the dol. If you are using our forwarder, it loads dols from this path.
cheatcodes-- *****for gct & ocarina use
txtcheat path-*****for txt files holding the codes for your gams.
dolpath—*****for replacement dols for certain broken games.
[6f]Update*****
Click to get updates from online. Just because there is a newer revision than what you are using does not mean that it will be on the update server. Also, you get the choice to update your dol or the entire HBC package. If you are using a full channel (not a forwarder channel), you won't get the option to update all. It will just download a wad file and install that on your wii over top of the old version and then kick you out to the system menu so you can restart with the new version. This is assuming that the person that created the channel took the necessary steps when they made it. If you are using the full channel and you get the option to update all, then they fucked up and the update will do you no good.
[6g]default settings*****
Click here to restore default settings.
[6h]credits
Look at the people that made this application possible. You get to rock out to some cool music, too. In the upper right corner is displayed your rev# and the cIOS that your are currently running.
###################################################################################
[7]gamesettings
Settings are available on a per-game basis from the prompt window. These settings have the same effect as the global settings but are only used for the selected game. After making changes, you must click the save button for them to take effect.
videomode
vidTV patch
language
ocarina
ios
parental control
error002 fix
online fix --if you have attempted to use any online features of this application, the online features of any game you boot will not work. In order to fix this we can reload the IOS. Unfortunately, reloading IOS results in random blackscreens with certain IOS versions. Turn this option on to reload the IOS and risk random black screens.
patch country strings
alternate dol-- this is for advanced users only. There are certain games which do not run because they they reload IOS and this causes the USB to be dropped. If you extract the proper dol from the ISO and name it with the 6 character game ID and put in the dolpath, you can use enable this option to play these games.
default settings-- delete any saved settings for this game. After you press this, there is no need to press save.
save-- writes the settings that are on the screen right now to the GXGameSettings file with the current game ID
uninstall-- Delete the selected game from the WBFS table. The data is not erased from the drive, it is just marked as free space.
back-- Lose any unsaved changes and return to the previous screen.
ocarina button-- this is that blue thing in the upper right. If you have a txt file for the selected game in the txtcheat folder, click this button to go to the code selection page. You will see a list of the cheats in the txt file and you can turn them on and off. When you are happy with the codes you have selected, click the button to generate a gct file. This will make a gct file with only the codes that are turned on and put it in the proper folder. Then make sure you turn ocarina on or your cheats won't be used.
###################################################################################
[8]Themes
Is it possible to theme this program. Theme elements may include font, images, sounds, and GXtheme.cfg. If anything is not included in the theme path, the default will be used. For image names, look in the source. Not every image can be themed, but this is a good place to look for the names of the ones that can be. All images must be sized in multiples of 4 or they will not be displayed. To move elements of the gui around, you can use GXtheme.cfg. I template can be found here http://code.google.com/p/usbloader-gui/wiki/ThemeSettings. For More accurate list of themable elements, look in cfg.c from the source
###################################################################################
[9]Cheatmanager
The Cheatmanager makes it possible to directly convert TXT Cheat Codes files into GCT for Ocarina.
You can find the Cheatmanager in the Game Settings (click on the Ocarina Icon) select the Cheat you want to use and create the GCT file.
The TXT Files should look like this
GameID
GameTitle
Cheat1
*here the hexvalues*
Comment (actually only one line of comment is supported otherwise the GCT file will be messed up)
Cheat2
*here the hexvalues*
Comment
Cheat3
and so on
###################################################################################
[10]Troubleshooting
I get black screen when loading games.
check the game compatibility list, unhook extra controllers, turn off ocarina, play with video settings. If the list says the game works, then try different video settings if the game is not from the same region as your tv/wii.
Also try without ocarina. Unless you made the codes yourself, you don't know that they work. And you don't know which codes work together. Using codes from a different region will also fuck shit up.
Some games don't like it if you have certain controllers plugged in. Remove GC & CC controllers and try again.
If all else fails, rip the game again. It may have gotten messed up in the process.
I get a black screen with a bunch of numbers on it
This is a code dump. It is not bad for your wii. It just means that the program crashed. This is beta software, it happens. Different revs can have this happen at certain times. Just press reset on your wii. If you find that this happens every time you start the application, rename your config folder and restart it. This will cause the loader to use default settings. If it fixes the problem then you can copy the game settings and favorites files back into the config directory.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

404
Makefile
View File

@ -1,202 +1,202 @@
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif
include $(DEVKITPPC)/wii_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET := boot
BUILD := build
SOURCES := source source/libwiigui source/images source/fonts source/sounds \
source/libwbfs source/unzip source/language source/mload source/patches \
source/usbloader source/xml source/network source/settings source/prompts \
source/ramdisc source/wad source/banner source/cheats source/homebrewboot \
source/themefs
DATA := data
INCLUDES := source
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -g -O2 -save-temps -Wall $(MACHDEP) $(INCLUDE)
CXXFLAGS = -Xassembler -aln=$@.lst $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80B00000
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lfat -lpngu -lpng -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -ltremor -lmxml
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(DEVKITPPC)/lib $(CURDIR)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export PROJECTDIR := $(CURDIR)
export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
SVNREV := $(shell bash ./svnrev.sh)
export CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
export CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
ELFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.elf)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
TTFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ttf)))
PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png)))
OGGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ogg)))
PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
export LD := $(CC)
else
export LD := $(CXX)
endif
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o) \
$(TTFFILES:.ttf=.ttf.o) $(PNGFILES:.png=.png.o) \
$(OGGFILES:.ogg=.ogg.o) $(PCMFILES:.pcm=.pcm.o) \
$(addsuffix .o,$(ELFFILES))
#---------------------------------------------------------------------------------
# build a list of include paths
#---------------------------------------------------------------------------------
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD) \
-I$(LIBOGC_INC)
#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
-L$(LIBOGC_LIB)
export OUTPUT := $(CURDIR)/$(TARGET)
.PHONY: $(BUILD) lang all clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
lang:
@[ -d build ] || mkdir -p build
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile language
#---------------------------------------------------------------------------------
all:
@[ -d build ] || mkdir -p build
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile language
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol
#---------------------------------------------------------------------------------
run:
make
@echo Done building ...
@echo Now Run That Shit ...
wiiload $(OUTPUT).dol
#---------------------------------------------------------------------------------
reload:
wiiload -r $(OUTPUT).dol
#---------------------------------------------------------------------------------
release:
make
cp boot.dol ./hbc/boot.dol
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).dol: $(OUTPUT).elf
$(OUTPUT).elf: $(OFILES)
language: $(wildcard $(PROJECTDIR)/Languages/*.lang)
#---------------------------------------------------------------------------------
# This rule links in binary data with .ttf, .png, and .mp3 extensions
#---------------------------------------------------------------------------------
%.elf.o : %.elf
@echo $(notdir $<)
$(bin2o)
%.ttf.o : %.ttf
@echo $(notdir $<)
$(bin2o)
%.png.o : %.png
@echo $(notdir $<)
$(bin2o)
%.ogg.o : %.ogg
@echo $(notdir $<)
$(bin2o)
%.pcm.o : %.pcm
@echo $(notdir $<)
$(bin2o)
%.certs.o : %.certs
@echo $(notdir $<)
$(bin2o)
%.dat.o : %.dat
@echo $(notdir $<)
$(bin2o)
export PATH := $(PROJECTDIR)/gettext-bin:$(PATH)
%.pot: $(CFILES) $(CPPFILES)
@echo Update Language-Files ...
@xgettext -C -cTRANSLATORS --from-code=utf-8 --sort-output --no-wrap --no-location -k -ktr -ktrNOOP -o $@ $^
%.lang: $(PROJECTDIR)/Languages/$(TARGET).pot
@msgmerge -U -N --no-wrap --no-location --backup=none -q $@ $<
@touch $@
-include $(DEPENDS)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif
include $(DEVKITPPC)/wii_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET := boot
BUILD := build
SOURCES := source source/libwiigui source/images source/fonts source/sounds \
source/libwbfs source/unzip source/language source/mload source/patches \
source/usbloader source/xml source/network source/settings source/prompts \
source/ramdisc source/wad source/banner source/cheats source/homebrewboot \
source/themefs
DATA := data
INCLUDES := source
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -g -O2 -save-temps -Wall $(MACHDEP) $(INCLUDE)
CXXFLAGS = -Xassembler -aln=$@.lst $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80B00000
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lfat -lpngu -lpng -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -ltremor -lmxml
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(DEVKITPPC)/lib $(CURDIR)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export PROJECTDIR := $(CURDIR)
export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
SVNREV := $(shell bash ./svnrev.sh)
export CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
export CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
ELFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.elf)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
TTFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ttf)))
PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png)))
OGGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ogg)))
PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
export LD := $(CC)
else
export LD := $(CXX)
endif
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o) \
$(TTFFILES:.ttf=.ttf.o) $(PNGFILES:.png=.png.o) \
$(OGGFILES:.ogg=.ogg.o) $(PCMFILES:.pcm=.pcm.o) \
$(addsuffix .o,$(ELFFILES))
#---------------------------------------------------------------------------------
# build a list of include paths
#---------------------------------------------------------------------------------
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD) \
-I$(LIBOGC_INC)
#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
-L$(LIBOGC_LIB)
export OUTPUT := $(CURDIR)/$(TARGET)
.PHONY: $(BUILD) lang all clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
lang:
@[ -d build ] || mkdir -p build
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile language
#---------------------------------------------------------------------------------
all:
@[ -d build ] || mkdir -p build
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile language
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol
#---------------------------------------------------------------------------------
run:
make
@echo Done building ...
@echo Now Run That Shit ...
wiiload $(OUTPUT).dol
#---------------------------------------------------------------------------------
reload:
wiiload -r $(OUTPUT).dol
#---------------------------------------------------------------------------------
release:
make
cp boot.dol ./hbc/boot.dol
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).dol: $(OUTPUT).elf
$(OUTPUT).elf: $(OFILES)
language: $(wildcard $(PROJECTDIR)/Languages/*.lang)
#---------------------------------------------------------------------------------
# This rule links in binary data with .ttf, .png, and .mp3 extensions
#---------------------------------------------------------------------------------
%.elf.o : %.elf
@echo $(notdir $<)
$(bin2o)
%.ttf.o : %.ttf
@echo $(notdir $<)
$(bin2o)
%.png.o : %.png
@echo $(notdir $<)
$(bin2o)
%.ogg.o : %.ogg
@echo $(notdir $<)
$(bin2o)
%.pcm.o : %.pcm
@echo $(notdir $<)
$(bin2o)
%.certs.o : %.certs
@echo $(notdir $<)
$(bin2o)
%.dat.o : %.dat
@echo $(notdir $<)
$(bin2o)
export PATH := $(PROJECTDIR)/gettext-bin:$(PATH)
%.pot: $(CFILES) $(CPPFILES)
@echo Update Language-Files ...
@xgettext -C -cTRANSLATORS --from-code=utf-8 --sort-output --no-wrap --no-location -k -ktr -ktrNOOP -o $@ $^
%.lang: $(PROJECTDIR)/Languages/$(TARGET).pot
@msgmerge -U -N --no-wrap --no-location --backup=none -q $@ $<
@touch $@
-include $(DEPENDS)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

View File

@ -1,382 +1,382 @@
/*
* Metaphrasis is a static conversion class for transforming RGBA image
* buffers into verious GX texture formats for Wii homebrew development.
* Copyright (C) 2008 Armin Tamzarian
*
* This file is part of Metaphrasis.
*
* Metaphrasis is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Metaphrasis is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Metaphrasis. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Metaphrasis.h"
/**
* Default constructor for the Metaphrasis class.
*/
Metaphrasis::Metaphrasis() {
}
/**
* Default destructor for the Metaphrasis class.
*/
Metaphrasis::~Metaphrasis() {
}
/**
* Convert the specified RGBA data buffer into the I4 texture format
*
* This routine converts the RGBA data buffer into the I4 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToI4(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = bufferWidth * bufferHeight >> 1;
uint32_t* dataBufferI4 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferI4, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferI4;
for (uint16_t y = 0; y < bufferHeight; y += 8) {
for (uint16_t x = 0; x < bufferWidth; x += 8) {
for (uint16_t rows = 0; rows < 8; rows++) {
*dst++ = (src[((y + rows) * bufferWidth) + (x + 0)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 1)] & 0xf0) >> 4);
*dst++ = (src[((y + rows) * bufferWidth) + (x + 2)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 3)] & 0xf0) >> 4);
*dst++ = (src[((y + rows) * bufferWidth) + (x + 4)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 5)] & 0xf0) >> 4);
*dst++ = (src[((y + rows) * bufferWidth) + (x + 5)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 7)] & 0xf0) >> 4);
}
}
}
DCFlushRange(dataBufferI4, bufferSize);
return dataBufferI4;
}
/**
* Convert the specified RGBA data buffer into the I8 texture format
*
* This routine converts the RGBA data buffer into the I8 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToI8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = bufferWidth * bufferHeight;
uint32_t* dataBufferI8 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferI8, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferI8;
for (uint16_t y = 0; y < bufferHeight; y += 4) {
for (uint16_t x = 0; x < bufferWidth; x += 8) {
for (uint16_t rows = 0; rows < 4; rows++) {
*dst++ = src[((y + rows) * bufferWidth) + (x + 0)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 1)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 2)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 3)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 4)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 5)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 6)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 7)] & 0xff;
}
}
}
DCFlushRange(dataBufferI8, bufferSize);
return dataBufferI8;
}
/**
* Downsample the specified RGBA value data buffer to an IA4 value.
*
* This routine downsamples the given RGBA data value into the IA4 texture data format.
*
* @param rgba A 32-bit RGBA value to convert to the IA4 format.
* @return The IA4 value of the given RGBA value.
*/
uint8_t Metaphrasis::convertRGBAToIA4(uint32_t rgba) {
uint8_t i, a;
i = (rgba >> 8) & 0xf0;
a = (rgba ) & 0xff;
return i | (a >> 4);
}
/**
* Convert the specified RGBA data buffer into the IA4 texture format
*
* This routine converts the RGBA data buffer into the IA4 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToIA4(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = bufferWidth * bufferHeight;
uint32_t* dataBufferIA4 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferIA4, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferIA4;
for (uint16_t y = 0; y < bufferHeight; y += 4) {
for (uint16_t x = 0; x < bufferWidth; x += 8) {
for (uint16_t rows = 0; rows < 4; rows++) {
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 2)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 3)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 4)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 5)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 6)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 7)]);
}
}
}
DCFlushRange(dataBufferIA4, bufferSize);
return dataBufferIA4;
}
/**
* Downsample the specified RGBA value data buffer to an IA8 value.
*
* This routine downsamples the given RGBA data value into the IA8 texture data format.
*
* @param rgba A 32-bit RGBA value to convert to the IA8 format.
* @return The IA8 value of the given RGBA value.
*/
uint16_t Metaphrasis::convertRGBAToIA8(uint32_t rgba) {
uint8_t i, a;
i = (rgba >> 8) & 0xff;
a = (rgba ) & 0xff;
return (i << 8) | a;
}
/**
* Convert the specified RGBA data buffer into the IA8 texture format
*
* This routine converts the RGBA data buffer into the IA8 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToIA8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = (bufferWidth * bufferHeight) << 1;
uint32_t* dataBufferIA8 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferIA8, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint16_t *dst = (uint16_t *)dataBufferIA8;
for (uint16_t y = 0; y < bufferHeight; y += 4) {
for (uint16_t x = 0; x < bufferWidth; x += 4) {
for (uint16_t rows = 0; rows < 4; rows++) {
*dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 2)]);
*dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 3)]);
}
}
}
DCFlushRange(dataBufferIA8, bufferSize);
return dataBufferIA8;
}
/**
* Convert the specified RGBA data buffer into the RGBA8 texture format
*
* This routine converts the RGBA data buffer into the RGBA8 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToRGBA8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = (bufferWidth * bufferHeight) << 2;
uint32_t* dataBufferRGBA8 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferRGBA8, 0x00, bufferSize);
uint8_t *src = (uint8_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferRGBA8;
for (uint16_t block = 0; block < bufferHeight; block += 4) {
for (uint16_t i = 0; i < bufferWidth; i += 4) {
for (uint16_t c = 0; c < 4; c++) {
for (uint16_t ar = 0; ar < 4; ar++) {
*dst++ = src[(((i + ar) + ((block + c) * bufferWidth)) * 4) + 3];
*dst++ = src[((i + ar) + ((block + c) * bufferWidth)) * 4];
}
}
for (uint16_t c = 0; c < 4; c++) {
for (uint16_t gb = 0; gb < 4; gb++) {
*dst++ = src[(((i + gb) + ((block + c) * bufferWidth)) * 4) + 1];
*dst++ = src[(((i + gb) + ((block + c) * bufferWidth)) * 4) + 2];
}
}
}
}
DCFlushRange(dataBufferRGBA8, bufferSize);
return dataBufferRGBA8;
}
/**
* Downsample the specified RGBA value data buffer to an RGB565 value.
*
* This routine downsamples the given RGBA data value into the RGB565 texture data format.
* Attribution for this routine is given fully to NoNameNo of GRRLIB Wii library.
*
* @param rgba A 32-bit RGBA value to convert to the RGB565 format.
* @return The RGB565 value of the given RGBA value.
*/
uint16_t Metaphrasis::convertRGBAToRGB565(uint32_t rgba) {
uint8_t r, g, b;
r = (((rgba >> 24) & 0xff) * 31) / 255;
g = (((rgba >> 16) & 0xff) * 63) / 255;
b = (((rgba >> 8) & 0xff) * 31) / 255;
return (((r << 6) | g ) << 5 ) | b;
}
/**
* Convert the specified RGBA data buffer into the RGB565 texture format
*
* This routine converts the RGBA data buffer into the RGB565 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToRGB565(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = (bufferWidth * bufferHeight) << 1;
uint32_t* dataBufferRGB565 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferRGB565, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint16_t *dst = (uint16_t *)dataBufferRGB565;
for (uint16_t y = 0; y < bufferHeight; y += 4) {
for (uint16_t x = 0; x < bufferWidth; x += 4) {
for (uint16_t rows = 0; rows < 4; rows++) {
*dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 2)]);
*dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 3)]);
}
}
}
DCFlushRange(dataBufferRGB565, bufferSize);
return dataBufferRGB565;
}
/**
* Downsample the specified RGBA value data buffer to an RGB5A3 value.
*
* This routine downsamples the given RGBA data value into the RGB5A3 texture data format.
* Attribution for this routine is given fully to WiiGator via the TehSkeen forum.
*
* @param rgba A 32-bit RGBA value to convert to the RGB5A3 format.
* @return The RGB5A3 value of the given RGBA value.
*/
uint16_t Metaphrasis::convertRGBAToRGB5A3(uint32_t rgba) {
uint32_t r, g, b, a;
uint16_t color;
r = (rgba >> 24) & 0xff;
g = (rgba >> 16) & 0xff;
b = (rgba >> 8) & 0xff;
a = (rgba ) & 0xff;
if (a > 0xe0) {
r = r >> 3;
g = g >> 3;
b = b >> 3;
color = (r << 10) | (g << 5) | b;
color |= 0x8000;
} else {
r = r >> 4;
g = g >> 4;
b = b >> 4;
a = a >> 5;
color = (a << 12) | (r << 8) | (g << 4) | b;
}
return color;
}
/**
* Convert the specified RGBA data buffer into the RGB5A3 texture format
*
* This routine converts the RGBA data buffer into the RGB5A3 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToRGB5A3(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = (bufferWidth * bufferHeight) << 1;
uint32_t* dataBufferRGB5A3 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferRGB5A3, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint16_t *dst = (uint16_t *)dataBufferRGB5A3;
for (uint16_t y = 0; y < bufferHeight; y += 4) {
for (uint16_t x = 0; x < bufferWidth; x += 4) {
for (uint16_t rows = 0; rows < 4; rows++) {
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 2)]);
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 3)]);
}
}
}
DCFlushRange(dataBufferRGB5A3, bufferSize);
return dataBufferRGB5A3;
}
/*
* Metaphrasis is a static conversion class for transforming RGBA image
* buffers into verious GX texture formats for Wii homebrew development.
* Copyright (C) 2008 Armin Tamzarian
*
* This file is part of Metaphrasis.
*
* Metaphrasis is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Metaphrasis is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Metaphrasis. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Metaphrasis.h"
/**
* Default constructor for the Metaphrasis class.
*/
Metaphrasis::Metaphrasis() {
}
/**
* Default destructor for the Metaphrasis class.
*/
Metaphrasis::~Metaphrasis() {
}
/**
* Convert the specified RGBA data buffer into the I4 texture format
*
* This routine converts the RGBA data buffer into the I4 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToI4(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = bufferWidth * bufferHeight >> 1;
uint32_t* dataBufferI4 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferI4, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferI4;
for (uint16_t y = 0; y < bufferHeight; y += 8) {
for (uint16_t x = 0; x < bufferWidth; x += 8) {
for (uint16_t rows = 0; rows < 8; rows++) {
*dst++ = (src[((y + rows) * bufferWidth) + (x + 0)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 1)] & 0xf0) >> 4);
*dst++ = (src[((y + rows) * bufferWidth) + (x + 2)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 3)] & 0xf0) >> 4);
*dst++ = (src[((y + rows) * bufferWidth) + (x + 4)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 5)] & 0xf0) >> 4);
*dst++ = (src[((y + rows) * bufferWidth) + (x + 5)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 7)] & 0xf0) >> 4);
}
}
}
DCFlushRange(dataBufferI4, bufferSize);
return dataBufferI4;
}
/**
* Convert the specified RGBA data buffer into the I8 texture format
*
* This routine converts the RGBA data buffer into the I8 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToI8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = bufferWidth * bufferHeight;
uint32_t* dataBufferI8 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferI8, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferI8;
for (uint16_t y = 0; y < bufferHeight; y += 4) {
for (uint16_t x = 0; x < bufferWidth; x += 8) {
for (uint16_t rows = 0; rows < 4; rows++) {
*dst++ = src[((y + rows) * bufferWidth) + (x + 0)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 1)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 2)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 3)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 4)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 5)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 6)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 7)] & 0xff;
}
}
}
DCFlushRange(dataBufferI8, bufferSize);
return dataBufferI8;
}
/**
* Downsample the specified RGBA value data buffer to an IA4 value.
*
* This routine downsamples the given RGBA data value into the IA4 texture data format.
*
* @param rgba A 32-bit RGBA value to convert to the IA4 format.
* @return The IA4 value of the given RGBA value.
*/
uint8_t Metaphrasis::convertRGBAToIA4(uint32_t rgba) {
uint8_t i, a;
i = (rgba >> 8) & 0xf0;
a = (rgba ) & 0xff;
return i | (a >> 4);
}
/**
* Convert the specified RGBA data buffer into the IA4 texture format
*
* This routine converts the RGBA data buffer into the IA4 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToIA4(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = bufferWidth * bufferHeight;
uint32_t* dataBufferIA4 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferIA4, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferIA4;
for (uint16_t y = 0; y < bufferHeight; y += 4) {
for (uint16_t x = 0; x < bufferWidth; x += 8) {
for (uint16_t rows = 0; rows < 4; rows++) {
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 2)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 3)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 4)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 5)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 6)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 7)]);
}
}
}
DCFlushRange(dataBufferIA4, bufferSize);
return dataBufferIA4;
}
/**
* Downsample the specified RGBA value data buffer to an IA8 value.
*
* This routine downsamples the given RGBA data value into the IA8 texture data format.
*
* @param rgba A 32-bit RGBA value to convert to the IA8 format.
* @return The IA8 value of the given RGBA value.
*/
uint16_t Metaphrasis::convertRGBAToIA8(uint32_t rgba) {
uint8_t i, a;
i = (rgba >> 8) & 0xff;
a = (rgba ) & 0xff;
return (i << 8) | a;
}
/**
* Convert the specified RGBA data buffer into the IA8 texture format
*
* This routine converts the RGBA data buffer into the IA8 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToIA8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = (bufferWidth * bufferHeight) << 1;
uint32_t* dataBufferIA8 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferIA8, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint16_t *dst = (uint16_t *)dataBufferIA8;
for (uint16_t y = 0; y < bufferHeight; y += 4) {
for (uint16_t x = 0; x < bufferWidth; x += 4) {
for (uint16_t rows = 0; rows < 4; rows++) {
*dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 2)]);
*dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 3)]);
}
}
}
DCFlushRange(dataBufferIA8, bufferSize);
return dataBufferIA8;
}
/**
* Convert the specified RGBA data buffer into the RGBA8 texture format
*
* This routine converts the RGBA data buffer into the RGBA8 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToRGBA8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = (bufferWidth * bufferHeight) << 2;
uint32_t* dataBufferRGBA8 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferRGBA8, 0x00, bufferSize);
uint8_t *src = (uint8_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferRGBA8;
for (uint16_t block = 0; block < bufferHeight; block += 4) {
for (uint16_t i = 0; i < bufferWidth; i += 4) {
for (uint16_t c = 0; c < 4; c++) {
for (uint16_t ar = 0; ar < 4; ar++) {
*dst++ = src[(((i + ar) + ((block + c) * bufferWidth)) * 4) + 3];
*dst++ = src[((i + ar) + ((block + c) * bufferWidth)) * 4];
}
}
for (uint16_t c = 0; c < 4; c++) {
for (uint16_t gb = 0; gb < 4; gb++) {
*dst++ = src[(((i + gb) + ((block + c) * bufferWidth)) * 4) + 1];
*dst++ = src[(((i + gb) + ((block + c) * bufferWidth)) * 4) + 2];
}
}
}
}
DCFlushRange(dataBufferRGBA8, bufferSize);
return dataBufferRGBA8;
}
/**
* Downsample the specified RGBA value data buffer to an RGB565 value.
*
* This routine downsamples the given RGBA data value into the RGB565 texture data format.
* Attribution for this routine is given fully to NoNameNo of GRRLIB Wii library.
*
* @param rgba A 32-bit RGBA value to convert to the RGB565 format.
* @return The RGB565 value of the given RGBA value.
*/
uint16_t Metaphrasis::convertRGBAToRGB565(uint32_t rgba) {
uint8_t r, g, b;
r = (((rgba >> 24) & 0xff) * 31) / 255;
g = (((rgba >> 16) & 0xff) * 63) / 255;
b = (((rgba >> 8) & 0xff) * 31) / 255;
return (((r << 6) | g ) << 5 ) | b;
}
/**
* Convert the specified RGBA data buffer into the RGB565 texture format
*
* This routine converts the RGBA data buffer into the RGB565 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToRGB565(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = (bufferWidth * bufferHeight) << 1;
uint32_t* dataBufferRGB565 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferRGB565, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint16_t *dst = (uint16_t *)dataBufferRGB565;
for (uint16_t y = 0; y < bufferHeight; y += 4) {
for (uint16_t x = 0; x < bufferWidth; x += 4) {
for (uint16_t rows = 0; rows < 4; rows++) {
*dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 2)]);
*dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 3)]);
}
}
}
DCFlushRange(dataBufferRGB565, bufferSize);
return dataBufferRGB565;
}
/**
* Downsample the specified RGBA value data buffer to an RGB5A3 value.
*
* This routine downsamples the given RGBA data value into the RGB5A3 texture data format.
* Attribution for this routine is given fully to WiiGator via the TehSkeen forum.
*
* @param rgba A 32-bit RGBA value to convert to the RGB5A3 format.
* @return The RGB5A3 value of the given RGBA value.
*/
uint16_t Metaphrasis::convertRGBAToRGB5A3(uint32_t rgba) {
uint32_t r, g, b, a;
uint16_t color;
r = (rgba >> 24) & 0xff;
g = (rgba >> 16) & 0xff;
b = (rgba >> 8) & 0xff;
a = (rgba ) & 0xff;
if (a > 0xe0) {
r = r >> 3;
g = g >> 3;
b = b >> 3;
color = (r << 10) | (g << 5) | b;
color |= 0x8000;
} else {
r = r >> 4;
g = g >> 4;
b = b >> 4;
a = a >> 5;
color = (a << 12) | (r << 8) | (g << 4) | b;
}
return color;
}
/**
* Convert the specified RGBA data buffer into the RGB5A3 texture format
*
* This routine converts the RGBA data buffer into the RGB5A3 texture format and returns a pointer to the converted buffer.
*
* @param rgbaBuffer Buffer containing the temporarily rendered RGBA data.
* @param bufferWidth Pixel width of the data buffer.
* @param bufferHeight Pixel height of the data buffer.
* @return A pointer to the allocated buffer.
*/
uint32_t* Metaphrasis::convertBufferToRGB5A3(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) {
uint32_t bufferSize = (bufferWidth * bufferHeight) << 1;
uint32_t* dataBufferRGB5A3 = (uint32_t *)memalign(32, bufferSize);
memset(dataBufferRGB5A3, 0x00, bufferSize);
uint32_t *src = (uint32_t *)rgbaBuffer;
uint16_t *dst = (uint16_t *)dataBufferRGB5A3;
for (uint16_t y = 0; y < bufferHeight; y += 4) {
for (uint16_t x = 0; x < bufferWidth; x += 4) {
for (uint16_t rows = 0; rows < 4; rows++) {
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 2)]);
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 3)]);
}
}
}
DCFlushRange(dataBufferRGB5A3, bufferSize);
return dataBufferRGB5A3;
}

View File

@ -1,116 +1,116 @@
/*
* Metaphrasis is a static conversion class for transforming RGBA image
* buffers into verious GX texture formats for Wii homebrew development.
* Copyright (C) 2008 Armin Tamzarian
*
* This file is part of Metaphrasis.
*
* Metaphrasis is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Metaphrasis is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Metaphrasis. If not, see <http://www.gnu.org/licenses/>.
*/
/** \mainpage Metaphrasis
*
* \section sec_intro Introduction
*
* Metaphrasis is a static conversion class for transforming RGBA image buffers into verious GX texture formats for Wii homebrew development.
* <br>
* Metaphrasis is written in C++ and makes use of a community standard and newly developed algorithms for conversion of 32-bit RGBA data buffers into various GX texture formats common to both the Gamecube and Wii platforms.
* <p>
* This library was developed in-full by Armin Tamzarian with the support of developers in \#wiibrew on EFnet, Chaosteil of libwiisprite, and DrTwox of GRRLIB.
*
* \section sec_installation_source Installation (Source Code)
*
* -# Extract the Metaphrasis archive.
* -# Copy the contents of the <i>src</i> directory into your project's development path.
* -# Include the Metaphrasis header file in your code using syntax such as the following:
* \code
* #include "Metaphrasis.h"
* \endcode
*
* \section sec_installation_library Installation (Library)
*
* -# Extract the Metaphrasis archive.
* -# Copy the contents of the <i>lib</i> directory into your <i>devKitPro/libogc</i> directory.
* -# Include the Metaphrasis header file in your code using syntax such as the following:
* \code
* #include "Metaphrasis.h"
* \endcode
*
* \section sec_usage Usage
*
* -# Create a buffer full of 32-bit RGBA values noting both the pixel height and width of the buffer.
* -# Call one of the many conversion routines from within your code. (Note: All methods within the Metaphrasis class are static and thus no class instance need be allocated)
* \code
* uint32_t* rgba8Buffer = Metaphrasis::convertBufferToRGBA8(rgbaBuffer, bufferWidth, bufferHeight);
* \endcode
* -# Free your temporary RGBA value buffer if you no longer need said values.
*
* Currently supported conversion routines are as follows:
* \li convertBufferToI4
* \li convertBufferToI8
* \li convertBufferToIA4
* \li convertBufferToIA8
* \li convertBufferToRGBA8
* \li convertBufferToRGB565
* \li convertBufferToRGB5A3
*
* \section sec_license License
*
* Metaphrasis is distributed under the GNU Lesser General Public License.
*
* \section sec_contact Contact
*
* If you have any suggestions, questions, or comments regarding this library feel free to e-mail me at tamzarian1989 [at] gmail [dawt] com.
*/
#ifndef METAPHRASIS_H_
#define METAPHRASIS_H_
#include <gccore.h>
#include <stdint.h>
#include <malloc.h>
#include <string.h>
/*! \class Metaphrasis
* \brief A static conversion class for transforming RGBA image buffers into verious GX texture formats for
* Wii homebrew development.
* \author Armin Tamzarian
* \version 0.1.0
*
* Metaphrasis is a static conversion class for transforming RGBA image buffers into verious GX texture formats for
* Wii homebrew development. Metaphrasis is written in C++ and makes use of a community standard and newly developed
* algorithms for conversion of 32-bit RGBA data buffers into various GX texture formats common to both the Gamecube
* and Wii platforms.
*/
class Metaphrasis {
public:
Metaphrasis();
virtual ~Metaphrasis();
static uint32_t* convertBufferToI4(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToI8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToIA4(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToIA8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToRGBA8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToRGB565(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToRGB5A3(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint8_t convertRGBAToIA4(uint32_t rgba);
static uint16_t convertRGBAToIA8(uint32_t rgba);
static uint16_t convertRGBAToRGB565(uint32_t rgba);
static uint16_t convertRGBAToRGB5A3(uint32_t rgba);
};
#endif /*METAPHRASIS_H_*/
/*
* Metaphrasis is a static conversion class for transforming RGBA image
* buffers into verious GX texture formats for Wii homebrew development.
* Copyright (C) 2008 Armin Tamzarian
*
* This file is part of Metaphrasis.
*
* Metaphrasis is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Metaphrasis is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Metaphrasis. If not, see <http://www.gnu.org/licenses/>.
*/
/** \mainpage Metaphrasis
*
* \section sec_intro Introduction
*
* Metaphrasis is a static conversion class for transforming RGBA image buffers into verious GX texture formats for Wii homebrew development.
* <br>
* Metaphrasis is written in C++ and makes use of a community standard and newly developed algorithms for conversion of 32-bit RGBA data buffers into various GX texture formats common to both the Gamecube and Wii platforms.
* <p>
* This library was developed in-full by Armin Tamzarian with the support of developers in \#wiibrew on EFnet, Chaosteil of libwiisprite, and DrTwox of GRRLIB.
*
* \section sec_installation_source Installation (Source Code)
*
* -# Extract the Metaphrasis archive.
* -# Copy the contents of the <i>src</i> directory into your project's development path.
* -# Include the Metaphrasis header file in your code using syntax such as the following:
* \code
* #include "Metaphrasis.h"
* \endcode
*
* \section sec_installation_library Installation (Library)
*
* -# Extract the Metaphrasis archive.
* -# Copy the contents of the <i>lib</i> directory into your <i>devKitPro/libogc</i> directory.
* -# Include the Metaphrasis header file in your code using syntax such as the following:
* \code
* #include "Metaphrasis.h"
* \endcode
*
* \section sec_usage Usage
*
* -# Create a buffer full of 32-bit RGBA values noting both the pixel height and width of the buffer.
* -# Call one of the many conversion routines from within your code. (Note: All methods within the Metaphrasis class are static and thus no class instance need be allocated)
* \code
* uint32_t* rgba8Buffer = Metaphrasis::convertBufferToRGBA8(rgbaBuffer, bufferWidth, bufferHeight);
* \endcode
* -# Free your temporary RGBA value buffer if you no longer need said values.
*
* Currently supported conversion routines are as follows:
* \li convertBufferToI4
* \li convertBufferToI8
* \li convertBufferToIA4
* \li convertBufferToIA8
* \li convertBufferToRGBA8
* \li convertBufferToRGB565
* \li convertBufferToRGB5A3
*
* \section sec_license License
*
* Metaphrasis is distributed under the GNU Lesser General Public License.
*
* \section sec_contact Contact
*
* If you have any suggestions, questions, or comments regarding this library feel free to e-mail me at tamzarian1989 [at] gmail [dawt] com.
*/
#ifndef METAPHRASIS_H_
#define METAPHRASIS_H_
#include <gccore.h>
#include <stdint.h>
#include <malloc.h>
#include <string.h>
/*! \class Metaphrasis
* \brief A static conversion class for transforming RGBA image buffers into verious GX texture formats for
* Wii homebrew development.
* \author Armin Tamzarian
* \version 0.1.0
*
* Metaphrasis is a static conversion class for transforming RGBA image buffers into verious GX texture formats for
* Wii homebrew development. Metaphrasis is written in C++ and makes use of a community standard and newly developed
* algorithms for conversion of 32-bit RGBA data buffers into various GX texture formats common to both the Gamecube
* and Wii platforms.
*/
class Metaphrasis {
public:
Metaphrasis();
virtual ~Metaphrasis();
static uint32_t* convertBufferToI4(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToI8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToIA4(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToIA8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToRGBA8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToRGB565(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint32_t* convertBufferToRGB5A3(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight);
static uint8_t convertRGBAToIA4(uint32_t rgba);
static uint16_t convertRGBAToIA8(uint32_t rgba);
static uint16_t convertRGBAToRGB565(uint32_t rgba);
static uint16_t convertRGBAToRGB5A3(uint32_t rgba);
};
#endif /*METAPHRASIS_H_*/

View File

@ -1,22 +1,22 @@
/****************************************************************************
* USB Loader GX Team
* banner.h
*
* Dump opening.bnr thanks to Wiipower
***************************************************************************/
#ifndef BANNER_H
#define BANNER_H
#ifdef __cplusplus
extern "C"
{
#endif
s32 dump_banner(const char * discid,const char * dest);
#ifdef __cplusplus
}
#endif
#endif
/****************************************************************************
* USB Loader GX Team
* banner.h
*
* Dump opening.bnr thanks to Wiipower
***************************************************************************/
#ifndef BANNER_H
#define BANNER_H
#ifdef __cplusplus
extern "C"
{
#endif
s32 dump_banner(const char * discid,const char * dest);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,35 +1,35 @@
/****************************************************************************
* USB Loader GX Team
* gui_banner.h
*
* Shows TPL Banner images
***************************************************************************/
#ifndef _GUIBANNER_H_
#define _GUIBANNER_H_
#include "libwiigui/gui.h"
class GuiBanner : public GuiImage
{
public:
//!Constructor
//!\param tplfilepath Path of the tpl file
GuiBanner(const char *tplfilepath);
//!Constructor
//!\param mem Memory of the loaded tpl
//!\param len Filesize of the tpl
//!\param w Width of the tpl
//!\param h Height of the tpl
GuiBanner(void *mem, u32 len, int w, int h);
//!Destructor
~GuiBanner();
void Draw();
protected:
void * memory;
bool filecheck;
u32 tplfilesize;
GXTexObj texObj;
};
#endif /* _GUIBANNER_H_ */
/****************************************************************************
* USB Loader GX Team
* gui_banner.h
*
* Shows TPL Banner images
***************************************************************************/
#ifndef _GUIBANNER_H_
#define _GUIBANNER_H_
#include "libwiigui/gui.h"
class GuiBanner : public GuiImage
{
public:
//!Constructor
//!\param tplfilepath Path of the tpl file
GuiBanner(const char *tplfilepath);
//!Constructor
//!\param mem Memory of the loaded tpl
//!\param len Filesize of the tpl
//!\param w Width of the tpl
//!\param h Height of the tpl
GuiBanner(void *mem, u32 len, int w, int h);
//!Destructor
~GuiBanner();
void Draw();
protected:
void * memory;
bool filecheck;
u32 tplfilesize;
GXTexObj texObj;
};
#endif /* _GUIBANNER_H_ */

View File

@ -1,459 +1,459 @@
/****************************************************************************
* USB Loader GX Team
* openingbnr
*
* Extract opening.bnr/banner.bin/sound.bin/icon.bin
*
* Copyright 2008 Magicus <magicus@gmail.com>
* Licensed under the terms of the GNU GPL, version 2
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
* Version 1.0 Initial release
***************************************************************************/
#define _GNU_SOURCE
#include <ogcsys.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fat.h>
#include "MD5.h"
#include "banner.h"
u16 be16(const u8 *p)
{
return (p[0] << 8) | p[1];
}
u32 be32(const u8 *p)
{
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}
u64 be64(const u8 *p)
{
return ((u64)be32(p) << 32) | be32(p + 4);
}
u64 be34(const u8 *p)
{
return 4 * (u64)be32(p);
}
void wbe16(u8 *p, u16 x)
{
p[0] = x >> 8;
p[1] = x;
}
void wbe32(u8 *p, u32 x)
{
wbe16(p, x >> 16);
wbe16(p + 2, x);
}
void wbe64(u8 *p, u64 x)
{
wbe32(p, x >> 32);
wbe32(p + 4, x);
}
void md5(u8 *data, u32 len, u8 *hash)
{
MD5(hash, data, len);
}
static FILE *fp;
typedef struct {
u8 zeroes[0x40];
u32 imet; // "IMET"
u8 zero_six_zero_three[8]; // fixed, unknown purpose
u32 sizes[3];
u32 flag1;
u16 name_jp[0x2a]; // might be empty
u16 name_en[0x2a];
u16 name_de[0x2a];
u16 name_fr[0x2a];
u16 name_es[0x2a];
u16 name_it[0x2a];
u16 name_nl[0x2a];
u8 zeroes_2[0x348];
u8 crypto[0x10];
} imet_data_t;
typedef struct {
u32 imd5_tag; // 0x494D4435 "IMD5";
u32 size; // size of the rest of part B, starting from next field.
u8 zeroes[8];
u8 md5[16];
u32 payload_tag; // 0x4C5A3737 "LZ77" if this is lz77
u32 payload_data;
} imd5_header_t;
typedef struct
{
u16 type;
u16 name_offset;
u32 data_offset; // == absolut offset från U.8- headerns början
u32 size; // last included file num for directories
} U8_node;
typedef struct
{
u32 tag; // 0x55AA382D "U.8-"
u32 rootnode_offset; // offset to root_node, always 0x20.
u32 header_size; // size of header from root_node to end of string table.
u32 data_offset; // offset to data -- this is rootnode_offset + header_size, aligned to 0x40.
u8 zeroes[16];
} U8_archive_header;
static void write_file(void* data, size_t size, char* name)
{
FILE *out;
out = fopen(name, "wb");
fwrite(data, 1, size, out);
fclose(out);
}
u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size)
{
u8 *data_end;
u8 *decompressed_data;
size_t unpacked_size;
u8 *in_ptr;
u8 *out_ptr;
u8 *out_end;
in_ptr = data;
data_end = data + data_size;
// Assume this for now and grow when needed
unpacked_size = data_size;
decompressed_data = malloc(unpacked_size);
out_end = decompressed_data + unpacked_size;
out_ptr = decompressed_data;
while (in_ptr < data_end) {
int bit;
u8 bitmask = *in_ptr;
in_ptr++;
for (bit = 0x80; bit != 0; bit >>= 1) {
if (bitmask & bit) {
// Next section is compressed
u8 rep_length;
u16 rep_offset;
rep_length = (*in_ptr >> 4) + 3;
rep_offset = *in_ptr & 0x0f;
in_ptr++;
rep_offset = *in_ptr | (rep_offset << 8);
in_ptr++;
if (out_ptr-decompressed_data < rep_offset) {
return NULL;
}
for ( ; rep_length > 0; rep_length--) {
*out_ptr = out_ptr[-rep_offset-1];
out_ptr++;
if (out_ptr >= out_end) {
// Need to grow buffer
decompressed_data = realloc(decompressed_data, unpacked_size*2);
out_ptr = decompressed_data + unpacked_size;
unpacked_size *= 2;
out_end = decompressed_data + unpacked_size;
}
}
} else {
// Just copy byte
*out_ptr = *in_ptr;
out_ptr++;
if (out_ptr >= out_end) {
// Need to grow buffer
decompressed_data = realloc(decompressed_data, unpacked_size*2);
out_ptr = decompressed_data + unpacked_size;
unpacked_size *= 2;
out_end = decompressed_data + unpacked_size;
}
in_ptr++;
}
}
}
*decompressed_size = (out_ptr - decompressed_data);
return decompressed_data;
}
static int write_imd5_lz77(u8* data, size_t size, char* outname)
{
imd5_header_t* header = (imd5_header_t*) data;
u32 tag;
u32 size_in_imd5;
u8 md5_calc[16];
u8 *decompressed_data;
size_t decompressed_size;
tag = be32((u8*) &header->imd5_tag);
if (tag != 0x494D4435) {
return -4;
}
md5(data+32, size-32, md5_calc);
if (memcmp(&header->md5, md5_calc, 0x10)) {
return -5;
}
size_in_imd5 = be32((u8*) &header->size);
if (size_in_imd5 != size - 32) {
return -6;
}
tag = be32((u8*) &header->payload_tag);
if (tag == 0x4C5A3737) {
// "LZ77" - uncompress
decompressed_data = decompress_lz77(data + sizeof(imd5_header_t), size - sizeof(imd5_header_t), &decompressed_size);
if(decompressed_data == NULL)
return -7;
write_file(decompressed_data, decompressed_size, outname);
//printf(", uncompressed %d bytes, md5 ok", decompressed_size);
free(decompressed_data);
} else {
write_file(&header->payload_tag, size-32, outname);
//printf(", md5 ok");
}
return 0;
}
static int do_U8_archive(void)
{
U8_archive_header header;
U8_node root_node;
u32 tag;
u32 num_nodes;
U8_node* nodes;
u8* string_table;
size_t rest_size;
unsigned int i;
u32 data_offset;
u32 current_offset;
u16 dir_stack[16];
int dir_index = 0;
fread(&header, 1, sizeof header, fp);
tag = be32((u8*) &header.tag);
if (tag != 0x55AA382D) {
return -1;
}
fread(&root_node, 1, sizeof(root_node), fp);
num_nodes = be32((u8*) &root_node.size) - 1;
//printf("Number of files: %d\n", num_nodes);
nodes = malloc(sizeof(U8_node) * (num_nodes));
fread(nodes, 1, num_nodes * sizeof(U8_node), fp);
data_offset = be32((u8*) &header.data_offset);
rest_size = data_offset - sizeof(header) - (num_nodes+1)*sizeof(U8_node);
string_table = malloc(rest_size);
fread(string_table, 1, rest_size, fp);
current_offset = data_offset;
for (i = 0; i < num_nodes; i++) {
U8_node* node = &nodes[i];
u16 type = be16((u8*)&node->type);
u16 name_offset = be16((u8*)&node->name_offset);
u32 my_data_offset = be32((u8*)&node->data_offset);
u32 size = be32((u8*)&node->size);
char* name = (char*) &string_table[name_offset];
u8* file_data;
if (type == 0x0100) {
// Directory
mkdir(name, 0777);
chdir(name);
dir_stack[++dir_index] = size;
//printf("%*s%s/\n", dir_index, "", name);
} else {
// Normal file
u8 padding[32];
if (type != 0x0000) {
return -2;
}
if (current_offset < my_data_offset) {
int diff = my_data_offset - current_offset;
if (diff > 32) {
return -3;
}
fread(padding, 1, diff, fp);
current_offset += diff;
}
file_data = malloc(size);
fread(file_data, 1, size, fp);
//printf("%*s %s (%d bytes", dir_index, "", name, size);
int result;
result = write_imd5_lz77(file_data, size, name);
if(result < 0)
return result;
//printf(")\n");
current_offset += size;
}
while (dir_stack[dir_index] == i+2 && dir_index > 0) {
chdir("..");
dir_index--;
}
}
return 0;
}
static void do_imet_header(void)
{
imet_data_t header;
fread(&header, 1, sizeof header, fp);
write_file(&header, sizeof(header), "header.imet");
}
void do_U8_archivebanner(FILE *fp)
{
U8_archive_header header;
U8_node root_node;
u32 tag;
u32 num_nodes;
U8_node* nodes;
u8* string_table;
size_t rest_size;
unsigned int i;
u32 data_offset;
u16 dir_stack[16];
int dir_index = 0;
fread(&header, 1, sizeof header, fp);
tag = be32((u8*) &header.tag);
if (tag != 0x55AA382D) {
//printf("No U8 tag");
exit(0);
}
fread(&root_node, 1, sizeof(root_node), fp);
num_nodes = be32((u8*) &root_node.size) - 1;
printf("Number of files: %d\n", num_nodes);
nodes = malloc(sizeof(U8_node) * (num_nodes));
fread(nodes, 1, num_nodes * sizeof(U8_node), fp);
data_offset = be32((u8*) &header.data_offset);
rest_size = data_offset - sizeof(header) - (num_nodes+1)*sizeof(U8_node);
string_table = malloc(rest_size);
fread(string_table, 1, rest_size, fp);
for (i = 0; i < num_nodes; i++) {
U8_node* node = &nodes[i];
u16 type = be16((u8*)&node->type);
u16 name_offset = be16((u8*)&node->name_offset);
u32 my_data_offset = be32((u8*)&node->data_offset);
u32 size = be32((u8*)&node->size);
char* name = (char*) &string_table[name_offset];
u8* file_data;
if (type == 0x0100) {
// Directory
mkdir(name, 0777);
chdir(name);
dir_stack[++dir_index] = size;
//printf("%*s%s/\n", dir_index, "", name);
} else {
// Normal file
if (type != 0x0000) {
printf("Unknown type");
exit(0);
}
fseek(fp, my_data_offset, SEEK_SET);
file_data = malloc(size);
fread(file_data, 1, size, fp);
write_file(file_data, size, name);
free(file_data);
//printf("%*s %s (%d bytes)\n", dir_index, "", name, size);
}
while (dir_stack[dir_index] == i+2 && dir_index > 0) {
chdir("..");
dir_index--;
}
}
}
int extractbnrfile(const char * filepath, const char * destpath)
{
int ret;
fp = fopen(filepath, "rb");
mkdir(destpath, 0777);
chdir(destpath);
do_imet_header();
ret = do_U8_archive();
fclose(fp);
return ret;
}
int unpackBin(const char * filename,const char * outdir)
{
FILE *fp;
fp = fopen(filename,"rb");
if(fp!=NULL)
{
mkdir(outdir, 0777);
chdir(outdir);
do_U8_archivebanner(fp);
fclose(fp);
return 1;
}
return 0;
}
int unpackBanner(char * gameid, char * outdir)
{
s32 ret = dump_banner(gameid,"SD:/opening.bnr");
if (ret != 1) return -1;
ret = extractbnrfile("SD:/opening.bnr","SD:/neu");
if (ret != 0) return -1;
remove("SD:/opening.bnr");
char iconpath[60];
snprintf(iconpath,sizeof(iconpath),"%s/meta/icon.bin",outdir);
ret = unpackBin(iconpath,"SD:/icon");
if (ret != 1) return -1;
if (unlink("/neu/meta/banner.bin") == -1) return -1;
if (unlink("/neu/meta/icon.bin") == -1) return -1;
if (unlink("/neu/meta/sound.bin") == -1) return -1;
if (unlink("/neu/header.imet") == -1) return -1;
if (unlink("/neu/meta") == -1) return -1;
if (unlink("/neu") == -1) return -1;
return 1;
}
/****************************************************************************
* USB Loader GX Team
* openingbnr
*
* Extract opening.bnr/banner.bin/sound.bin/icon.bin
*
* Copyright 2008 Magicus <magicus@gmail.com>
* Licensed under the terms of the GNU GPL, version 2
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
* Version 1.0 Initial release
***************************************************************************/
#define _GNU_SOURCE
#include <ogcsys.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fat.h>
#include "MD5.h"
#include "banner.h"
u16 be16(const u8 *p)
{
return (p[0] << 8) | p[1];
}
u32 be32(const u8 *p)
{
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}
u64 be64(const u8 *p)
{
return ((u64)be32(p) << 32) | be32(p + 4);
}
u64 be34(const u8 *p)
{
return 4 * (u64)be32(p);
}
void wbe16(u8 *p, u16 x)
{
p[0] = x >> 8;
p[1] = x;
}
void wbe32(u8 *p, u32 x)
{
wbe16(p, x >> 16);
wbe16(p + 2, x);
}
void wbe64(u8 *p, u64 x)
{
wbe32(p, x >> 32);
wbe32(p + 4, x);
}
void md5(u8 *data, u32 len, u8 *hash)
{
MD5(hash, data, len);
}
static FILE *fp;
typedef struct {
u8 zeroes[0x40];
u32 imet; // "IMET"
u8 zero_six_zero_three[8]; // fixed, unknown purpose
u32 sizes[3];
u32 flag1;
u16 name_jp[0x2a]; // might be empty
u16 name_en[0x2a];
u16 name_de[0x2a];
u16 name_fr[0x2a];
u16 name_es[0x2a];
u16 name_it[0x2a];
u16 name_nl[0x2a];
u8 zeroes_2[0x348];
u8 crypto[0x10];
} imet_data_t;
typedef struct {
u32 imd5_tag; // 0x494D4435 "IMD5";
u32 size; // size of the rest of part B, starting from next field.
u8 zeroes[8];
u8 md5[16];
u32 payload_tag; // 0x4C5A3737 "LZ77" if this is lz77
u32 payload_data;
} imd5_header_t;
typedef struct
{
u16 type;
u16 name_offset;
u32 data_offset; // == absolut offset från U.8- headerns början
u32 size; // last included file num for directories
} U8_node;
typedef struct
{
u32 tag; // 0x55AA382D "U.8-"
u32 rootnode_offset; // offset to root_node, always 0x20.
u32 header_size; // size of header from root_node to end of string table.
u32 data_offset; // offset to data -- this is rootnode_offset + header_size, aligned to 0x40.
u8 zeroes[16];
} U8_archive_header;
static void write_file(void* data, size_t size, char* name)
{
FILE *out;
out = fopen(name, "wb");
fwrite(data, 1, size, out);
fclose(out);
}
u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size)
{
u8 *data_end;
u8 *decompressed_data;
size_t unpacked_size;
u8 *in_ptr;
u8 *out_ptr;
u8 *out_end;
in_ptr = data;
data_end = data + data_size;
// Assume this for now and grow when needed
unpacked_size = data_size;
decompressed_data = malloc(unpacked_size);
out_end = decompressed_data + unpacked_size;
out_ptr = decompressed_data;
while (in_ptr < data_end) {
int bit;
u8 bitmask = *in_ptr;
in_ptr++;
for (bit = 0x80; bit != 0; bit >>= 1) {
if (bitmask & bit) {
// Next section is compressed
u8 rep_length;
u16 rep_offset;
rep_length = (*in_ptr >> 4) + 3;
rep_offset = *in_ptr & 0x0f;
in_ptr++;
rep_offset = *in_ptr | (rep_offset << 8);
in_ptr++;
if (out_ptr-decompressed_data < rep_offset) {
return NULL;
}
for ( ; rep_length > 0; rep_length--) {
*out_ptr = out_ptr[-rep_offset-1];
out_ptr++;
if (out_ptr >= out_end) {
// Need to grow buffer
decompressed_data = realloc(decompressed_data, unpacked_size*2);
out_ptr = decompressed_data + unpacked_size;
unpacked_size *= 2;
out_end = decompressed_data + unpacked_size;
}
}
} else {
// Just copy byte
*out_ptr = *in_ptr;
out_ptr++;
if (out_ptr >= out_end) {
// Need to grow buffer
decompressed_data = realloc(decompressed_data, unpacked_size*2);
out_ptr = decompressed_data + unpacked_size;
unpacked_size *= 2;
out_end = decompressed_data + unpacked_size;
}
in_ptr++;
}
}
}
*decompressed_size = (out_ptr - decompressed_data);
return decompressed_data;
}
static int write_imd5_lz77(u8* data, size_t size, char* outname)
{
imd5_header_t* header = (imd5_header_t*) data;
u32 tag;
u32 size_in_imd5;
u8 md5_calc[16];
u8 *decompressed_data;
size_t decompressed_size;
tag = be32((u8*) &header->imd5_tag);
if (tag != 0x494D4435) {
return -4;
}
md5(data+32, size-32, md5_calc);
if (memcmp(&header->md5, md5_calc, 0x10)) {
return -5;
}
size_in_imd5 = be32((u8*) &header->size);
if (size_in_imd5 != size - 32) {
return -6;
}
tag = be32((u8*) &header->payload_tag);
if (tag == 0x4C5A3737) {
// "LZ77" - uncompress
decompressed_data = decompress_lz77(data + sizeof(imd5_header_t), size - sizeof(imd5_header_t), &decompressed_size);
if(decompressed_data == NULL)
return -7;
write_file(decompressed_data, decompressed_size, outname);
//printf(", uncompressed %d bytes, md5 ok", decompressed_size);
free(decompressed_data);
} else {
write_file(&header->payload_tag, size-32, outname);
//printf(", md5 ok");
}
return 0;
}
static int do_U8_archive(void)
{
U8_archive_header header;
U8_node root_node;
u32 tag;
u32 num_nodes;
U8_node* nodes;
u8* string_table;
size_t rest_size;
unsigned int i;
u32 data_offset;
u32 current_offset;
u16 dir_stack[16];
int dir_index = 0;
fread(&header, 1, sizeof header, fp);
tag = be32((u8*) &header.tag);
if (tag != 0x55AA382D) {
return -1;
}
fread(&root_node, 1, sizeof(root_node), fp);
num_nodes = be32((u8*) &root_node.size) - 1;
//printf("Number of files: %d\n", num_nodes);
nodes = malloc(sizeof(U8_node) * (num_nodes));
fread(nodes, 1, num_nodes * sizeof(U8_node), fp);
data_offset = be32((u8*) &header.data_offset);
rest_size = data_offset - sizeof(header) - (num_nodes+1)*sizeof(U8_node);
string_table = malloc(rest_size);
fread(string_table, 1, rest_size, fp);
current_offset = data_offset;
for (i = 0; i < num_nodes; i++) {
U8_node* node = &nodes[i];
u16 type = be16((u8*)&node->type);
u16 name_offset = be16((u8*)&node->name_offset);
u32 my_data_offset = be32((u8*)&node->data_offset);
u32 size = be32((u8*)&node->size);
char* name = (char*) &string_table[name_offset];
u8* file_data;
if (type == 0x0100) {
// Directory
mkdir(name, 0777);
chdir(name);
dir_stack[++dir_index] = size;
//printf("%*s%s/\n", dir_index, "", name);
} else {
// Normal file
u8 padding[32];
if (type != 0x0000) {
return -2;
}
if (current_offset < my_data_offset) {
int diff = my_data_offset - current_offset;
if (diff > 32) {
return -3;
}
fread(padding, 1, diff, fp);
current_offset += diff;
}
file_data = malloc(size);
fread(file_data, 1, size, fp);
//printf("%*s %s (%d bytes", dir_index, "", name, size);
int result;
result = write_imd5_lz77(file_data, size, name);
if(result < 0)
return result;
//printf(")\n");
current_offset += size;
}
while (dir_stack[dir_index] == i+2 && dir_index > 0) {
chdir("..");
dir_index--;
}
}
return 0;
}
static void do_imet_header(void)
{
imet_data_t header;
fread(&header, 1, sizeof header, fp);
write_file(&header, sizeof(header), "header.imet");
}
void do_U8_archivebanner(FILE *fp)
{
U8_archive_header header;
U8_node root_node;
u32 tag;
u32 num_nodes;
U8_node* nodes;
u8* string_table;
size_t rest_size;
unsigned int i;
u32 data_offset;
u16 dir_stack[16];
int dir_index = 0;
fread(&header, 1, sizeof header, fp);
tag = be32((u8*) &header.tag);
if (tag != 0x55AA382D) {
//printf("No U8 tag");
exit(0);
}
fread(&root_node, 1, sizeof(root_node), fp);
num_nodes = be32((u8*) &root_node.size) - 1;
printf("Number of files: %d\n", num_nodes);
nodes = malloc(sizeof(U8_node) * (num_nodes));
fread(nodes, 1, num_nodes * sizeof(U8_node), fp);
data_offset = be32((u8*) &header.data_offset);
rest_size = data_offset - sizeof(header) - (num_nodes+1)*sizeof(U8_node);
string_table = malloc(rest_size);
fread(string_table, 1, rest_size, fp);
for (i = 0; i < num_nodes; i++) {
U8_node* node = &nodes[i];
u16 type = be16((u8*)&node->type);
u16 name_offset = be16((u8*)&node->name_offset);
u32 my_data_offset = be32((u8*)&node->data_offset);
u32 size = be32((u8*)&node->size);
char* name = (char*) &string_table[name_offset];
u8* file_data;
if (type == 0x0100) {
// Directory
mkdir(name, 0777);
chdir(name);
dir_stack[++dir_index] = size;
//printf("%*s%s/\n", dir_index, "", name);
} else {
// Normal file
if (type != 0x0000) {
printf("Unknown type");
exit(0);
}
fseek(fp, my_data_offset, SEEK_SET);
file_data = malloc(size);
fread(file_data, 1, size, fp);
write_file(file_data, size, name);
free(file_data);
//printf("%*s %s (%d bytes)\n", dir_index, "", name, size);
}
while (dir_stack[dir_index] == i+2 && dir_index > 0) {
chdir("..");
dir_index--;
}
}
}
int extractbnrfile(const char * filepath, const char * destpath)
{
int ret;
fp = fopen(filepath, "rb");
mkdir(destpath, 0777);
chdir(destpath);
do_imet_header();
ret = do_U8_archive();
fclose(fp);
return ret;
}
int unpackBin(const char * filename,const char * outdir)
{
FILE *fp;
fp = fopen(filename,"rb");
if(fp!=NULL)
{
mkdir(outdir, 0777);
chdir(outdir);
do_U8_archivebanner(fp);
fclose(fp);
return 1;
}
return 0;
}
int unpackBanner(char * gameid, char * outdir)
{
s32 ret = dump_banner(gameid,"SD:/opening.bnr");
if (ret != 1) return -1;
ret = extractbnrfile("SD:/opening.bnr","SD:/neu");
if (ret != 0) return -1;
remove("SD:/opening.bnr");
char iconpath[60];
snprintf(iconpath,sizeof(iconpath),"%s/meta/icon.bin",outdir);
ret = unpackBin(iconpath,"SD:/icon");
if (ret != 1) return -1;
if (unlink("/neu/meta/banner.bin") == -1) return -1;
if (unlink("/neu/meta/icon.bin") == -1) return -1;
if (unlink("/neu/meta/sound.bin") == -1) return -1;
if (unlink("/neu/header.imet") == -1) return -1;
if (unlink("/neu/meta") == -1) return -1;
if (unlink("/neu") == -1) return -1;
return 1;
}

View File

@ -1,44 +1,44 @@
/****************************************************************************
* USB Loader GX Team
* openingbnr
*
* Extract opening.bnr/banner.bin/sound.bin/icon.bin
***************************************************************************/
#ifndef _OPENINGBNR_H_
#define _OPENINGBNR_H_
#ifdef __cplusplus
extern "C"
{
#endif
/***********************************************************
* Error description:
* 0 Successfully extracted
* -1 No U8 tag
* -2 Unknown type
* -3 Archive inconsistency, too much padding
* -4 No IMD5 tag
* -5 MD5 mismatch
* -6 Size mismatch
* -7 Inconsistency in LZ77 encoding
************************************************************/
//! Extract opening.bnr from filepath to destpath
//! Files extracted: banner.bin icon.bin and sound.bin
int extractbnrfile(const char * filepath, const char * destpath);
int unpackBin(const char * filename,const char * outdir);
//int unpackBanner(const char * filename,const char * outdir);
int unpackBanner(const char * gameid, const char * outdir);
//! Extract the lz77 compressed banner, icon and sound .bin
u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size);
u16 be16(const u8 *p);
u32 be32(const u8 *p);
#ifdef __cplusplus
}
#endif
#endif
/****************************************************************************
* USB Loader GX Team
* openingbnr
*
* Extract opening.bnr/banner.bin/sound.bin/icon.bin
***************************************************************************/
#ifndef _OPENINGBNR_H_
#define _OPENINGBNR_H_
#ifdef __cplusplus
extern "C"
{
#endif
/***********************************************************
* Error description:
* 0 Successfully extracted
* -1 No U8 tag
* -2 Unknown type
* -3 Archive inconsistency, too much padding
* -4 No IMD5 tag
* -5 MD5 mismatch
* -6 Size mismatch
* -7 Inconsistency in LZ77 encoding
************************************************************/
//! Extract opening.bnr from filepath to destpath
//! Files extracted: banner.bin icon.bin and sound.bin
int extractbnrfile(const char * filepath, const char * destpath);
int unpackBin(const char * filename,const char * outdir);
//int unpackBanner(const char * filename,const char * outdir);
int unpackBanner(const char * gameid, const char * outdir);
//! Extract the lz77 compressed banner, icon and sound .bin
u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size);
u16 be16(const u8 *p);
u32 be32(const u8 *p);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,56 +1,56 @@
#include <fat.h>
#include <string.h>
#include <ogc/lwp_watchdog.h>
#include <ogc/mutex.h>
#include <ogc/system.h>
#include <ogc/usbstorage.h>
#include <sdcard/wiisd_io.h>
#include "usbloader/usbstorage.h"
//these are the only stable and speed is good
#define CACHE 8
#define SECTORS 64
int USBDevice_Init() {
//closing all open Files write back the cache and then shutdown em!
fatUnmount("USB:/");
//right now mounts first FAT-partition
if (fatMount("USB", &__io_wiiums, 0, CACHE, SECTORS)) {
//try first mount with cIOS
return 1;
} else if (fatMount("USB", &__io_usbstorage, 0, CACHE, SECTORS)) {
//try now mount with libogc
return 1;
}
return -1;
}
void USBDevice_deInit() {
//closing all open Files write back the cache and then shutdown em!
fatUnmount("USB:/");
}
int isSdInserted() {
return __io_wiisd.isInserted();
}
int isInserted(const char *path) {
if (!strncmp(path, "USB:", 4))
return 1;
return __io_wiisd.isInserted();
}
int SDCard_Init() {
//closing all open Files write back the cache and then shutdown em!
fatUnmount("SD:/");
//right now mounts first FAT-partition
if (fatMount("SD", &__io_wiisd, 0, CACHE, SECTORS))
return 1;
return -1;
}
void SDCard_deInit() {
//closing all open Files write back the cache and then shutdown em!
fatUnmount("SD:/");
}
#include <fat.h>
#include <string.h>
#include <ogc/lwp_watchdog.h>
#include <ogc/mutex.h>
#include <ogc/system.h>
#include <ogc/usbstorage.h>
#include <sdcard/wiisd_io.h>
#include "usbloader/usbstorage.h"
//these are the only stable and speed is good
#define CACHE 8
#define SECTORS 64
int USBDevice_Init() {
//closing all open Files write back the cache and then shutdown em!
fatUnmount("USB:/");
//right now mounts first FAT-partition
if (fatMount("USB", &__io_wiiums, 0, CACHE, SECTORS)) {
//try first mount with cIOS
return 1;
} else if (fatMount("USB", &__io_usbstorage, 0, CACHE, SECTORS)) {
//try now mount with libogc
return 1;
}
return -1;
}
void USBDevice_deInit() {
//closing all open Files write back the cache and then shutdown em!
fatUnmount("USB:/");
}
int isSdInserted() {
return __io_wiisd.isInserted();
}
int isInserted(const char *path) {
if (!strncmp(path, "USB:", 4))
return 1;
return __io_wiisd.isInserted();
}
int SDCard_Init() {
//closing all open Files write back the cache and then shutdown em!
fatUnmount("SD:/");
//right now mounts first FAT-partition
if (fatMount("SD", &__io_wiisd, 0, CACHE, SECTORS))
return 1;
return -1;
}
void SDCard_deInit() {
//closing all open Files write back the cache and then shutdown em!
fatUnmount("SD:/");
}

View File

@ -1,19 +1,19 @@
#ifndef _FATMOUNTER_H_
#define _FATMOUNTER_H_
#ifdef __cplusplus
extern "C" {
#endif
int USBDevice_Init();
void USBDevice_deInit();
int isSdInserted();
int isInserted(const char *path);
int SDCard_Init();
void SDCard_deInit();
#ifdef __cplusplus
}
#endif
#endif
#ifndef _FATMOUNTER_H_
#define _FATMOUNTER_H_
#ifdef __cplusplus
extern "C" {
#endif
int USBDevice_Init();
void USBDevice_deInit();
int isSdInserted();
int isInserted(const char *path);
int SDCard_Init();
void SDCard_deInit();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,18 +1,18 @@
#ifndef _BOOTHOMEBREW_H_
#define _BOOTHOMEBREW_H_
#ifdef __cplusplus
extern "C" {
#endif
int BootHomebrew(char * path);
int BootHomebrewFromMem();
void CopyHomebrewMemory(u32 read, u8 *temp, u32 len);
int AllocHomebrewMemory(u32 filesize);
void FreeHomebrewBuffer();
#ifdef __cplusplus
}
#endif
#endif
#ifndef _BOOTHOMEBREW_H_
#define _BOOTHOMEBREW_H_
#ifdef __cplusplus
extern "C" {
#endif
int BootHomebrew(char * path);
int BootHomebrewFromMem();
void CopyHomebrewMemory(u32 read, u8 *temp, u32 len);
int AllocHomebrewMemory(u32 filesize);
void FreeHomebrewBuffer();
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,15 @@
/****************************************************************************
* HomebrewBrowse
* USB Loader GX 2009
*
* Homebrew launcher for USB Loader GX
*
* homebrewbrowse.h
***************************************************************************/
#ifndef _HOMEBREWBROWSE_H_
#define _HOMEBREWBROWSE_H_
int MenuHomebrewBrowse();
#endif
/****************************************************************************
* HomebrewBrowse
* USB Loader GX 2009
*
* Homebrew launcher for USB Loader GX
*
* homebrewbrowse.h
***************************************************************************/
#ifndef _HOMEBREWBROWSE_H_
#define _HOMEBREWBROWSE_H_
int MenuHomebrewBrowse();
#endif

View File

@ -1,116 +1,116 @@
/****************************************************************************
* HomebrewFiles Class
* for USB Loader GX
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/dir.h>
#include "HomebrewFiles.h"
HomebrewFiles::HomebrewFiles(const char * path) {
filecount = 0;
FileInfo = (FileInfos *) malloc(sizeof(FileInfos));
if (!FileInfo) {
return;
}
memset(&FileInfo[filecount], 0, sizeof(FileInfos));
this->LoadPath(path);
this->SortList();
}
HomebrewFiles::~HomebrewFiles() {
if (FileInfo) {
free(FileInfo);
FileInfo = NULL;
}
}
bool HomebrewFiles::LoadPath(const char * folderpath) {
struct stat st;
DIR_ITER *dir = NULL;
char filename[1024];
dir = diropen(folderpath);
if (dir == NULL) {
return false;
}
while (dirnext(dir,filename,&st) == 0) {
if ((st.st_mode & S_IFDIR) != 0) {
if (strcmp(filename,".") != 0 && strcmp(filename,"..") != 0) {
char currentname[200];
snprintf(currentname, sizeof(currentname), "%s%s/", folderpath, filename);
this->LoadPath(currentname);
}
} else {
char temp[5];
for (int i = 0; i < 5; i++) {
temp[i] = filename[strlen(filename)-4+i];
}
if ((strncasecmp(temp, ".dol", 4) == 0 || strncasecmp(temp, ".elf", 4) == 0)
&& filecount < MAXHOMEBREWS && filename[0]!='.') {
FileInfo = (FileInfos *) realloc(FileInfo, (filecount+1)*sizeof(FileInfos));
if (!FileInfo) {
free(FileInfo);
FileInfo = NULL;
filecount = 0;
dirclose(dir);
return false;
}
memset(&(FileInfo[filecount]), 0, sizeof(FileInfo));
strlcpy(FileInfo[filecount].FilePath, folderpath, sizeof(FileInfo[filecount].FilePath));
strlcpy(FileInfo[filecount].FileName, filename, sizeof(FileInfo[filecount].FileName));
FileInfo[filecount].FileSize = st.st_size;
filecount++;
}
}
}
dirclose(dir);
return true;
}
char * HomebrewFiles::GetFilename(int ind) {
if (ind > filecount)
return NULL;
else
return FileInfo[ind].FileName;
}
char * HomebrewFiles::GetFilepath(int ind) {
if (ind > filecount)
return NULL;
else
return FileInfo[ind].FilePath;
}
unsigned int HomebrewFiles::GetFilesize(int ind) {
if (ind > filecount || !filecount || !FileInfo)
return NULL;
else
return FileInfo[ind].FileSize;
}
int HomebrewFiles::GetFilecount() {
return filecount;
}
static int ListCompare(const void *a, const void *b) {
FileInfos *ab = (FileInfos*) a;
FileInfos *bb = (FileInfos*) b;
return stricmp((char *) ab->FilePath, (char *) bb->FilePath);
}
void HomebrewFiles::SortList() {
qsort(FileInfo, filecount, sizeof(FileInfos), ListCompare);
}
/****************************************************************************
* HomebrewFiles Class
* for USB Loader GX
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/dir.h>
#include "HomebrewFiles.h"
HomebrewFiles::HomebrewFiles(const char * path) {
filecount = 0;
FileInfo = (FileInfos *) malloc(sizeof(FileInfos));
if (!FileInfo) {
return;
}
memset(&FileInfo[filecount], 0, sizeof(FileInfos));
this->LoadPath(path);
this->SortList();
}
HomebrewFiles::~HomebrewFiles() {
if (FileInfo) {
free(FileInfo);
FileInfo = NULL;
}
}
bool HomebrewFiles::LoadPath(const char * folderpath) {
struct stat st;
DIR_ITER *dir = NULL;
char filename[1024];
dir = diropen(folderpath);
if (dir == NULL) {
return false;
}
while (dirnext(dir,filename,&st) == 0) {
if ((st.st_mode & S_IFDIR) != 0) {
if (strcmp(filename,".") != 0 && strcmp(filename,"..") != 0) {
char currentname[200];
snprintf(currentname, sizeof(currentname), "%s%s/", folderpath, filename);
this->LoadPath(currentname);
}
} else {
char temp[5];
for (int i = 0; i < 5; i++) {
temp[i] = filename[strlen(filename)-4+i];
}
if ((strncasecmp(temp, ".dol", 4) == 0 || strncasecmp(temp, ".elf", 4) == 0)
&& filecount < MAXHOMEBREWS && filename[0]!='.') {
FileInfo = (FileInfos *) realloc(FileInfo, (filecount+1)*sizeof(FileInfos));
if (!FileInfo) {
free(FileInfo);
FileInfo = NULL;
filecount = 0;
dirclose(dir);
return false;
}
memset(&(FileInfo[filecount]), 0, sizeof(FileInfo));
strlcpy(FileInfo[filecount].FilePath, folderpath, sizeof(FileInfo[filecount].FilePath));
strlcpy(FileInfo[filecount].FileName, filename, sizeof(FileInfo[filecount].FileName));
FileInfo[filecount].FileSize = st.st_size;
filecount++;
}
}
}
dirclose(dir);
return true;
}
char * HomebrewFiles::GetFilename(int ind) {
if (ind > filecount)
return NULL;
else
return FileInfo[ind].FileName;
}
char * HomebrewFiles::GetFilepath(int ind) {
if (ind > filecount)
return NULL;
else
return FileInfo[ind].FilePath;
}
unsigned int HomebrewFiles::GetFilesize(int ind) {
if (ind > filecount || !filecount || !FileInfo)
return NULL;
else
return FileInfo[ind].FileSize;
}
int HomebrewFiles::GetFilecount() {
return filecount;
}
static int ListCompare(const void *a, const void *b) {
FileInfos *ab = (FileInfos*) a;
FileInfos *bb = (FileInfos*) b;
return stricmp((char *) ab->FilePath, (char *) bb->FilePath);
}
void HomebrewFiles::SortList() {
qsort(FileInfo, filecount, sizeof(FileInfos), ListCompare);
}

View File

@ -1,44 +1,44 @@
/****************************************************************************
* HomebrewFiles Class
* for USB Loader GX
***************************************************************************/
#ifndef ___HOMEBREWFILES_H_
#define ___HOMEBREWFILES_H_
#define MAXHOMEBREWS 500
typedef struct {
char FileName[100];
char FilePath[150];
unsigned int FileSize;
} FileInfos;
class HomebrewFiles {
public:
//!Constructor
//!\param path Path where to check for homebrew files
HomebrewFiles(const char * path);
//!Destructor
~HomebrewFiles();
//! Load the dol/elf list of a path
//!\param path Path where to check for homebrew files
bool LoadPath(const char * path);
//! Get the a filename of the list
//!\param list index
char * GetFilename(int index);
//! Get the a filepath of the list
//!\param list index
char * GetFilepath(int index);
//! Get the a filesize of the list
//!\param list index
unsigned int GetFilesize(int index);
//! Get the filecount of the whole list
int GetFilecount();
//! Sort list by filepath
void SortList();
protected:
int filecount;
FileInfos *FileInfo;
};
#endif
/****************************************************************************
* HomebrewFiles Class
* for USB Loader GX
***************************************************************************/
#ifndef ___HOMEBREWFILES_H_
#define ___HOMEBREWFILES_H_
#define MAXHOMEBREWS 500
typedef struct {
char FileName[100];
char FilePath[150];
unsigned int FileSize;
} FileInfos;
class HomebrewFiles {
public:
//!Constructor
//!\param path Path where to check for homebrew files
HomebrewFiles(const char * path);
//!Destructor
~HomebrewFiles();
//! Load the dol/elf list of a path
//!\param path Path where to check for homebrew files
bool LoadPath(const char * path);
//! Get the a filename of the list
//!\param list index
char * GetFilename(int index);
//! Get the a filepath of the list
//!\param list index
char * GetFilepath(int index);
//! Get the a filesize of the list
//!\param list index
unsigned int GetFilesize(int index);
//! Get the filecount of the whole list
int GetFilecount();
//! Sort list by filepath
void SortList();
protected:
int filecount;
FileInfos *FileInfo;
};
#endif

View File

@ -1,67 +1,67 @@
/****************************************************************************
* HomebrewXML Class
* for USB Loader GX
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xml/xml.h"
#include "HomebrewXML.h"
HomebrewXML::HomebrewXML() {
strcpy(name,"");
strcpy(coder,"");
strcpy(version,"");
strcpy(releasedate,"");
strcpy(shortdescription,"");
strcpy(longdescription,"");
}
HomebrewXML::~HomebrewXML() {
}
int HomebrewXML::LoadHomebrewXMLData(const char* filename) {
mxml_node_t *nodedataHB = NULL;
mxml_node_t *nodetreeHB = NULL;
char tmp1[40];
/* Load XML file */
FILE *filexml;
filexml = fopen(filename, "rb");
if (!filexml) {
return -1;
}
nodetreeHB = mxmlLoadFile(NULL, filexml, MXML_OPAQUE_CALLBACK);
fclose(filexml);
if (nodetreeHB == NULL) {
return -2;
}
nodedataHB = mxmlFindElement(nodetreeHB, nodetreeHB, "app", NULL, NULL, MXML_DESCEND);
if (nodedataHB == NULL) {
return -5;
}
GetTextFromNode(nodedataHB, nodedataHB, (char*) "name", NULL, NULL, MXML_DESCEND, name,sizeof(name));
GetTextFromNode(nodedataHB, nodedataHB, (char*) "coder", NULL, NULL, MXML_DESCEND, coder,sizeof(coder));
GetTextFromNode(nodedataHB, nodedataHB, (char*) "version", NULL, NULL, MXML_DESCEND, version,sizeof(version));
GetTextFromNode(nodedataHB, nodedataHB, (char*) "release_date", NULL, NULL, MXML_DESCEND, tmp1,sizeof(tmp1));
GetTextFromNode(nodedataHB, nodedataHB, (char*) "short_description", NULL, NULL, MXML_DESCEND, shortdescription,sizeof(shortdescription));
GetTextFromNode(nodedataHB, nodedataHB, (char*) "long_description", NULL, NULL, MXML_DESCEND, longdescription,sizeof(longdescription));
int len = (strlen(tmp1)-6); //length of the date string without the 200000 at the end
if (len == 8)
snprintf(releasedate, sizeof(releasedate), "%c%c/%c%c/%c%c%c%c", tmp1[4],tmp1[5],tmp1[6],tmp1[7],tmp1[0],tmp1[1],tmp1[2],tmp1[3]);
else if (len == 6)
snprintf(releasedate, sizeof(releasedate), "%c%c/%c%c%c%c", tmp1[4],tmp1[5],tmp1[0],tmp1[1],tmp1[2],tmp1[3]);
else snprintf(releasedate, sizeof(releasedate), "%s", tmp1);
free(nodedataHB);
free(nodetreeHB);
return 1;
}
/****************************************************************************
* HomebrewXML Class
* for USB Loader GX
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xml/xml.h"
#include "HomebrewXML.h"
HomebrewXML::HomebrewXML() {
strcpy(name,"");
strcpy(coder,"");
strcpy(version,"");
strcpy(releasedate,"");
strcpy(shortdescription,"");
strcpy(longdescription,"");
}
HomebrewXML::~HomebrewXML() {
}
int HomebrewXML::LoadHomebrewXMLData(const char* filename) {
mxml_node_t *nodedataHB = NULL;
mxml_node_t *nodetreeHB = NULL;
char tmp1[40];
/* Load XML file */
FILE *filexml;
filexml = fopen(filename, "rb");
if (!filexml) {
return -1;
}
nodetreeHB = mxmlLoadFile(NULL, filexml, MXML_OPAQUE_CALLBACK);
fclose(filexml);
if (nodetreeHB == NULL) {
return -2;
}
nodedataHB = mxmlFindElement(nodetreeHB, nodetreeHB, "app", NULL, NULL, MXML_DESCEND);
if (nodedataHB == NULL) {
return -5;
}
GetTextFromNode(nodedataHB, nodedataHB, (char*) "name", NULL, NULL, MXML_DESCEND, name,sizeof(name));
GetTextFromNode(nodedataHB, nodedataHB, (char*) "coder", NULL, NULL, MXML_DESCEND, coder,sizeof(coder));
GetTextFromNode(nodedataHB, nodedataHB, (char*) "version", NULL, NULL, MXML_DESCEND, version,sizeof(version));
GetTextFromNode(nodedataHB, nodedataHB, (char*) "release_date", NULL, NULL, MXML_DESCEND, tmp1,sizeof(tmp1));
GetTextFromNode(nodedataHB, nodedataHB, (char*) "short_description", NULL, NULL, MXML_DESCEND, shortdescription,sizeof(shortdescription));
GetTextFromNode(nodedataHB, nodedataHB, (char*) "long_description", NULL, NULL, MXML_DESCEND, longdescription,sizeof(longdescription));
int len = (strlen(tmp1)-6); //length of the date string without the 200000 at the end
if (len == 8)
snprintf(releasedate, sizeof(releasedate), "%c%c/%c%c/%c%c%c%c", tmp1[4],tmp1[5],tmp1[6],tmp1[7],tmp1[0],tmp1[1],tmp1[2],tmp1[3]);
else if (len == 6)
snprintf(releasedate, sizeof(releasedate), "%c%c/%c%c%c%c", tmp1[4],tmp1[5],tmp1[0],tmp1[1],tmp1[2],tmp1[3]);
else snprintf(releasedate, sizeof(releasedate), "%s", tmp1);
free(nodedataHB);
free(nodetreeHB);
return 1;
}

View File

@ -1,54 +1,54 @@
/****************************************************************************
* HomebrewXML Class
* for USB Loader GX
***************************************************************************/
#ifndef ___HOMEBREWXML_H_
#define ___HOMEBREWXML_H_
class HomebrewXML {
public:
//!Constructor
//!\param path Path for the xml file
HomebrewXML();
//!Destructor
~HomebrewXML();
//!\param filename Filepath of the XML file
int LoadHomebrewXMLData(const char* filename);
//! Get name
char * GetName() {
return name;
}
//! Get coder
char * GetCoder() {
return coder;
}
//! Get version
char * GetVersion() {
return version;
}
//! Get releasedate
char * GetReleasedate() {
return releasedate;
}
//! Get shortdescription
char * GetShortDescription() {
return shortdescription;
}
//! Get longdescription
char * GetLongDescription() {
return longdescription;
}
//! Set Name
void SetName(char * path) {
strlcpy(name, path, sizeof(name));
}
protected:
char name[50];
char coder[100];
char version[30];
char releasedate[30];
char shortdescription[150];
char longdescription[500];
};
#endif
/****************************************************************************
* HomebrewXML Class
* for USB Loader GX
***************************************************************************/
#ifndef ___HOMEBREWXML_H_
#define ___HOMEBREWXML_H_
class HomebrewXML {
public:
//!Constructor
//!\param path Path for the xml file
HomebrewXML();
//!Destructor
~HomebrewXML();
//!\param filename Filepath of the XML file
int LoadHomebrewXMLData(const char* filename);
//! Get name
char * GetName() {
return name;
}
//! Get coder
char * GetCoder() {
return coder;
}
//! Get version
char * GetVersion() {
return version;
}
//! Get releasedate
char * GetReleasedate() {
return releasedate;
}
//! Get shortdescription
char * GetShortDescription() {
return shortdescription;
}
//! Get longdescription
char * GetLongDescription() {
return longdescription;
}
//! Set Name
void SetName(char * path) {
strlcpy(name, path, sizeof(name));
}
protected:
char name[50];
char coder[100];
char version[30];
char releasedate[30];
char shortdescription[150];
char longdescription[500];
};
#endif

View File

@ -1,55 +1,55 @@
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <ogc/machine/processor.h>
#include <gccore.h>
#include <dirent.h>
#include <string.h>
#include "dolloader.h"
typedef struct _dolheader {
u32 text_pos[7];
u32 data_pos[11];
u32 text_start[7];
u32 data_start[11];
u32 text_size[7];
u32 data_size[11];
u32 bss_start;
u32 bss_size;
u32 entry_point;
} dolheader;
u32 load_dol(void *dolstart, struct __argv *argv) {
u32 i;
dolheader *dolfile;
if (dolstart) {
dolfile = (dolheader *) dolstart;
for (i = 0; i < 7; i++) {
if ((!dolfile->text_size[i]) || (dolfile->text_start[i] < 0x100)) continue;
VIDEO_WaitVSync();
ICInvalidateRange ((void *) dolfile->text_start[i],dolfile->text_size[i]);
memmove ((void *) dolfile->text_start[i],dolstart+dolfile->text_pos[i],dolfile->text_size[i]);
}
for (i = 0; i < 11; i++) {
if ((!dolfile->data_size[i]) || (dolfile->data_start[i] < 0x100)) continue;
VIDEO_WaitVSync();
memmove ((void *) dolfile->data_start[i],dolstart+dolfile->data_pos[i],dolfile->data_size[i]);
DCFlushRangeNoSync ((void *) dolfile->data_start[i],dolfile->data_size[i]);
}
memset ((void *) dolfile->bss_start, 0, dolfile->bss_size);
DCFlushRange((void *) dolfile->bss_start, dolfile->bss_size);
if (argv && argv->argvMagic == ARGV_MAGIC) {
void *new_argv = (void *)(dolfile->entry_point + 8);
memmove(new_argv, argv, sizeof(*argv));
DCFlushRange(new_argv, sizeof(*argv));
}
return dolfile->entry_point;
}
return 0;
}
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <ogc/machine/processor.h>
#include <gccore.h>
#include <dirent.h>
#include <string.h>
#include "dolloader.h"
typedef struct _dolheader {
u32 text_pos[7];
u32 data_pos[11];
u32 text_start[7];
u32 data_start[11];
u32 text_size[7];
u32 data_size[11];
u32 bss_start;
u32 bss_size;
u32 entry_point;
} dolheader;
u32 load_dol(void *dolstart, struct __argv *argv) {
u32 i;
dolheader *dolfile;
if (dolstart) {
dolfile = (dolheader *) dolstart;
for (i = 0; i < 7; i++) {
if ((!dolfile->text_size[i]) || (dolfile->text_start[i] < 0x100)) continue;
VIDEO_WaitVSync();
ICInvalidateRange ((void *) dolfile->text_start[i],dolfile->text_size[i]);
memmove ((void *) dolfile->text_start[i],dolstart+dolfile->text_pos[i],dolfile->text_size[i]);
}
for (i = 0; i < 11; i++) {
if ((!dolfile->data_size[i]) || (dolfile->data_start[i] < 0x100)) continue;
VIDEO_WaitVSync();
memmove ((void *) dolfile->data_start[i],dolstart+dolfile->data_pos[i],dolfile->data_size[i]);
DCFlushRangeNoSync ((void *) dolfile->data_start[i],dolfile->data_size[i]);
}
memset ((void *) dolfile->bss_start, 0, dolfile->bss_size);
DCFlushRange((void *) dolfile->bss_start, dolfile->bss_size);
if (argv && argv->argvMagic == ARGV_MAGIC) {
void *new_argv = (void *)(dolfile->entry_point + 8);
memmove(new_argv, argv, sizeof(*argv));
DCFlushRange(new_argv, sizeof(*argv));
}
return dolfile->entry_point;
}
return 0;
}

View File

@ -1,18 +1,18 @@
#ifndef _DOLLOADER_H_
#define _DOLLOADER_H_
#ifdef __cplusplus
extern "C" {
#endif
extern void __exception_closeall();
typedef void (*entrypoint) (void);
u32 load_dol(void *dolstart, struct __argv *argv);
#ifdef __cplusplus
}
#endif
#endif
#ifndef _DOLLOADER_H_
#define _DOLLOADER_H_
#ifdef __cplusplus
extern "C" {
#endif
extern void __exception_closeall();
typedef void (*entrypoint) (void);
u32 load_dol(void *dolstart, struct __argv *argv);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,101 +1,101 @@
/*
* Copyright (c) 2001 William L. Pitts
* Modifications (c) 2004 Felix Domke
* All rights reserved.
*
* Redistribution and use in source and binary forms are freely
* permitted provided that the above copyright notice and this
* paragraph and the following disclaimer are duplicated in all
* such forms.
*
* This software is provided "AS IS" and without any express or
* implied warranties, including, without limitation, the implied
* warranties of merchantability and fitness for a particular
* purpose.
*/
#include <stdio.h>
#include <string.h>
#include <gccore.h>
#include "elf_abi.h"
/* ======================================================================
* Determine if a valid ELF image exists at the given memory location.
* First looks at the ELF header magic field, the makes sure that it is
* executable and makes sure that it is for a PowerPC.
* ====================================================================== */
s32 valid_elf_image (void *addr) {
Elf32_Ehdr *ehdr; /* Elf header structure pointer */
ehdr = (Elf32_Ehdr *) addr;
if (!IS_ELF (*ehdr))
return 0;
if (ehdr->e_type != ET_EXEC)
return -1;
if (ehdr->e_machine != EM_PPC)
return -1;
return 1;
}
/* ======================================================================
* A very simple elf loader, assumes the image is valid, returns the
* entry point address.
* ====================================================================== */
u32 load_elf_image (void *addr) {
Elf32_Ehdr *ehdr;
Elf32_Shdr *shdr;
u8 *strtab = 0;
u8 *image;
int i;
ehdr = (Elf32_Ehdr *) addr;
/* Find the section header string table for output info */
shdr = (Elf32_Shdr *) (addr + ehdr->e_shoff +
(ehdr->e_shstrndx * sizeof (Elf32_Shdr)));
if (shdr->sh_type == SHT_STRTAB)
strtab = (u8 *) (addr + shdr->sh_offset);
/* Load each appropriate section */
for (i = 0; i < ehdr->e_shnum; ++i) {
shdr = (Elf32_Shdr *) (addr + ehdr->e_shoff +
(i * sizeof (Elf32_Shdr)));
if (!(shdr->sh_flags & SHF_ALLOC)
|| shdr->sh_addr == 0 || shdr->sh_size == 0) {
continue;
}
shdr->sh_addr &= 0x3FFFFFFF;
shdr->sh_addr |= 0x80000000;
if (strtab) {
/*printf ("%sing section %s @ 0x%08x (0x%08x bytes)\n",
(shdr->sh_type == SHT_NOBITS) ?
"clear" : "load",
&strtab[shdr->sh_name],
(u32) shdr->sh_addr,
(u32) shdr->sh_size);*/
}
if (shdr->sh_type == SHT_NOBITS) {
memset ((void *) shdr->sh_addr, 0, shdr->sh_size);
} else {
image = (u8 *) addr + shdr->sh_offset;
memcpy ((void *) shdr->sh_addr,
(const void *) image,
shdr->sh_size);
}
DCFlushRangeNoSync ((void *) shdr->sh_addr, shdr->sh_size);
}
return (ehdr->e_entry & 0x3FFFFFFF) | 0x80000000;
}
/*
* Copyright (c) 2001 William L. Pitts
* Modifications (c) 2004 Felix Domke
* All rights reserved.
*
* Redistribution and use in source and binary forms are freely
* permitted provided that the above copyright notice and this
* paragraph and the following disclaimer are duplicated in all
* such forms.
*
* This software is provided "AS IS" and without any express or
* implied warranties, including, without limitation, the implied
* warranties of merchantability and fitness for a particular
* purpose.
*/
#include <stdio.h>
#include <string.h>
#include <gccore.h>
#include "elf_abi.h"
/* ======================================================================
* Determine if a valid ELF image exists at the given memory location.
* First looks at the ELF header magic field, the makes sure that it is
* executable and makes sure that it is for a PowerPC.
* ====================================================================== */
s32 valid_elf_image (void *addr) {
Elf32_Ehdr *ehdr; /* Elf header structure pointer */
ehdr = (Elf32_Ehdr *) addr;
if (!IS_ELF (*ehdr))
return 0;
if (ehdr->e_type != ET_EXEC)
return -1;
if (ehdr->e_machine != EM_PPC)
return -1;
return 1;
}
/* ======================================================================
* A very simple elf loader, assumes the image is valid, returns the
* entry point address.
* ====================================================================== */
u32 load_elf_image (void *addr) {
Elf32_Ehdr *ehdr;
Elf32_Shdr *shdr;
u8 *strtab = 0;
u8 *image;
int i;
ehdr = (Elf32_Ehdr *) addr;
/* Find the section header string table for output info */
shdr = (Elf32_Shdr *) (addr + ehdr->e_shoff +
(ehdr->e_shstrndx * sizeof (Elf32_Shdr)));
if (shdr->sh_type == SHT_STRTAB)
strtab = (u8 *) (addr + shdr->sh_offset);
/* Load each appropriate section */
for (i = 0; i < ehdr->e_shnum; ++i) {
shdr = (Elf32_Shdr *) (addr + ehdr->e_shoff +
(i * sizeof (Elf32_Shdr)));
if (!(shdr->sh_flags & SHF_ALLOC)
|| shdr->sh_addr == 0 || shdr->sh_size == 0) {
continue;
}
shdr->sh_addr &= 0x3FFFFFFF;
shdr->sh_addr |= 0x80000000;
if (strtab) {
/*printf ("%sing section %s @ 0x%08x (0x%08x bytes)\n",
(shdr->sh_type == SHT_NOBITS) ?
"clear" : "load",
&strtab[shdr->sh_name],
(u32) shdr->sh_addr,
(u32) shdr->sh_size);*/
}
if (shdr->sh_type == SHT_NOBITS) {
memset ((void *) shdr->sh_addr, 0, shdr->sh_size);
} else {
image = (u8 *) addr + shdr->sh_offset;
memcpy ((void *) shdr->sh_addr,
(const void *) image,
shdr->sh_size);
}
DCFlushRangeNoSync ((void *) shdr->sh_addr, shdr->sh_size);
}
return (ehdr->e_entry & 0x3FFFFFFF) | 0x80000000;
}

View File

@ -1,17 +1,17 @@
#ifndef _ELFLOADER_H_
#define _ELFLOADER_H_
#include <wiiuse/wpad.h>
#ifdef __cplusplus
extern "C" {
#endif
s32 valid_elf_image (void *addr);
u32 load_elf_image (void *addr);
#ifdef __cplusplus
}
#endif
#endif
#ifndef _ELFLOADER_H_
#define _ELFLOADER_H_
#include <wiiuse/wpad.h>
#ifdef __cplusplus
extern "C" {
#endif
s32 valid_elf_image (void *addr);
u32 load_elf_image (void *addr);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,101 +1,101 @@
/****************************************************************************
* libwiigui Template
* Tantric 2009
*
* input.cpp
* Wii/GameCube controller management
***************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ogcsys.h>
#include <unistd.h>
#include <wiiuse/wpad.h>
#include "menu.h"
#include "video.h"
#include "input.h"
#include "libwiigui/gui.h"
int rumbleRequest[4] = {0,0,0,0};
GuiTrigger userInput[4];
static int rumbleCount[4] = {0,0,0,0};
/****************************************************************************
* ShutoffRumble
***************************************************************************/
void ShutoffRumble() {
for (int i=0;i<4;i++) {
WPAD_Rumble(i, 0);
rumbleCount[i] = 0;
}
}
/****************************************************************************
* DoRumble
***************************************************************************/
void DoRumble(int i) {
if (rumbleRequest[i] && rumbleCount[i] < 3) {
WPAD_Rumble(i, 1); // rumble on
rumbleCount[i]++;
} else if (rumbleRequest[i]) {
rumbleCount[i] = 20;
rumbleRequest[i] = 0;
} else {
if (rumbleCount[i])
rumbleCount[i]--;
WPAD_Rumble(i, 0); // rumble off
}
}
/****************************************************************************
* WPAD_Stick
*
* Get X/Y value from Wii Joystick (classic, nunchuk) input
***************************************************************************/
s8 WPAD_Stick(u8 chan, u8 right, int axis) {
float mag = 0.0;
float ang = 0.0;
WPADData *data = WPAD_Data(chan);
switch (data->exp.type) {
case WPAD_EXP_NUNCHUK:
case WPAD_EXP_GUITARHERO3:
if (right == 0) {
mag = data->exp.nunchuk.js.mag;
ang = data->exp.nunchuk.js.ang;
}
break;
case WPAD_EXP_CLASSIC:
if (right == 0) {
mag = data->exp.classic.ljs.mag;
ang = data->exp.classic.ljs.ang;
} else {
mag = data->exp.classic.rjs.mag;
ang = data->exp.classic.rjs.ang;
}
break;
default:
break;
}
/* calculate x/y value (angle need to be converted into radian) */
if (mag > 1.0) mag = 1.0;
else if (mag < -1.0) mag = -1.0;
double val;
if (axis == 0) // x-axis
val = mag * sin((PI * ang)/180.0f);
else // y-axis
val = mag * cos((PI * ang)/180.0f);
return (s8)(val * 128.0f);
}
/****************************************************************************
* libwiigui Template
* Tantric 2009
*
* input.cpp
* Wii/GameCube controller management
***************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ogcsys.h>
#include <unistd.h>
#include <wiiuse/wpad.h>
#include "menu.h"
#include "video.h"
#include "input.h"
#include "libwiigui/gui.h"
int rumbleRequest[4] = {0,0,0,0};
GuiTrigger userInput[4];
static int rumbleCount[4] = {0,0,0,0};
/****************************************************************************
* ShutoffRumble
***************************************************************************/
void ShutoffRumble() {
for (int i=0;i<4;i++) {
WPAD_Rumble(i, 0);
rumbleCount[i] = 0;
}
}
/****************************************************************************
* DoRumble
***************************************************************************/
void DoRumble(int i) {
if (rumbleRequest[i] && rumbleCount[i] < 3) {
WPAD_Rumble(i, 1); // rumble on
rumbleCount[i]++;
} else if (rumbleRequest[i]) {
rumbleCount[i] = 20;
rumbleRequest[i] = 0;
} else {
if (rumbleCount[i])
rumbleCount[i]--;
WPAD_Rumble(i, 0); // rumble off
}
}
/****************************************************************************
* WPAD_Stick
*
* Get X/Y value from Wii Joystick (classic, nunchuk) input
***************************************************************************/
s8 WPAD_Stick(u8 chan, u8 right, int axis) {
float mag = 0.0;
float ang = 0.0;
WPADData *data = WPAD_Data(chan);
switch (data->exp.type) {
case WPAD_EXP_NUNCHUK:
case WPAD_EXP_GUITARHERO3:
if (right == 0) {
mag = data->exp.nunchuk.js.mag;
ang = data->exp.nunchuk.js.ang;
}
break;
case WPAD_EXP_CLASSIC:
if (right == 0) {
mag = data->exp.classic.ljs.mag;
ang = data->exp.classic.ljs.ang;
} else {
mag = data->exp.classic.rjs.mag;
ang = data->exp.classic.rjs.ang;
}
break;
default:
break;
}
/* calculate x/y value (angle need to be converted into radian) */
if (mag > 1.0) mag = 1.0;
else if (mag < -1.0) mag = -1.0;
double val;
if (axis == 0) // x-axis
val = mag * sin((PI * ang)/180.0f);
else // y-axis
val = mag * cos((PI * ang)/180.0f);
return (s8)(val * 128.0f);
}

View File

@ -1,23 +1,23 @@
/****************************************************************************
* libwiigui Template
* Tantric 2009
*
* input.h
* Wii/GameCube controller management
***************************************************************************/
#ifndef _INPUT_H_
#define _INPUT_H_
#include <gccore.h>
#include <wiiuse/wpad.h>
#define PI 3.14159265f
#define PADCAL 50
extern int rumbleRequest[4];
void ShutoffRumble();
void DoRumble(int i);
#endif
/****************************************************************************
* libwiigui Template
* Tantric 2009
*
* input.h
* Wii/GameCube controller management
***************************************************************************/
#ifndef _INPUT_H_
#define _INPUT_H_
#include <gccore.h>
#include <wiiuse/wpad.h>
#define PI 3.14159265f
#define PADCAL 50
extern int rumbleRequest[4];
void ShutoffRumble();
void DoRumble(int i);
#endif

View File

@ -1,72 +1,72 @@
/****************************************************************************
* languagefile updater
* for USB Loader GX *giantpune*
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/dir.h>
#include "UpdateLanguage.h"
#include "listfiles.h"
#include "menu.h"
#include "network/networkops.h"
#include "network/http.h"
int updateLanguageFiles() {
char languageFiles[50][MAXLANGUAGEFILES];
//get all the files in the language path
int countfiles = GetAllDirFiles(Settings.languagefiles_path);
//give up now if we didn't find any
if (!countfiles) return -2;
//now from the files we got, get only the .lang files
for (int cnt = 0; cnt < countfiles; cnt++) {
char filename[64];
strlcpy(filename, GetFileName(cnt),sizeof(filename));
if (strcasestr(filename,".lang")) {
strcpy(languageFiles[cnt],filename);
}
}
subfoldercreate(Settings.languagefiles_path);
//we assume that the network will already be init by another function
// ( that has gui eletents in it because this one doesn't)
int done = 0,j = 0;
if (IsNetworkInit()) {
//build the URL, save path, and download each file and save it
while (j<countfiles) {
char savepath[150];
char codeurl[200];
snprintf(codeurl, sizeof(codeurl), "http://usbloader-gui.googlecode.com/svn/trunk/Languages/%s",languageFiles[j]);
snprintf(savepath, sizeof(savepath), "%s%s",Settings.languagefiles_path,languageFiles[j]);
struct block file = downloadfile(codeurl);
if (file.data != NULL) {
FILE * pfile;
pfile = fopen(savepath, "wb");
if(pfile != NULL) {
fwrite(file.data,1,file.size,pfile);
fclose(pfile);
free(file.data);
done++;
}
}
j++;
}
}
//if there was no network init
else return -1;
// return the number of files we updated
return done;
}
/****************************************************************************
* languagefile updater
* for USB Loader GX *giantpune*
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/dir.h>
#include "UpdateLanguage.h"
#include "listfiles.h"
#include "menu.h"
#include "network/networkops.h"
#include "network/http.h"
int updateLanguageFiles() {
char languageFiles[50][MAXLANGUAGEFILES];
//get all the files in the language path
int countfiles = GetAllDirFiles(Settings.languagefiles_path);
//give up now if we didn't find any
if (!countfiles) return -2;
//now from the files we got, get only the .lang files
for (int cnt = 0; cnt < countfiles; cnt++) {
char filename[64];
strlcpy(filename, GetFileName(cnt),sizeof(filename));
if (strcasestr(filename,".lang")) {
strcpy(languageFiles[cnt],filename);
}
}
subfoldercreate(Settings.languagefiles_path);
//we assume that the network will already be init by another function
// ( that has gui eletents in it because this one doesn't)
int done = 0,j = 0;
if (IsNetworkInit()) {
//build the URL, save path, and download each file and save it
while (j<countfiles) {
char savepath[150];
char codeurl[200];
snprintf(codeurl, sizeof(codeurl), "http://usbloader-gui.googlecode.com/svn/trunk/Languages/%s",languageFiles[j]);
snprintf(savepath, sizeof(savepath), "%s%s",Settings.languagefiles_path,languageFiles[j]);
struct block file = downloadfile(codeurl);
if (file.data != NULL) {
FILE * pfile;
pfile = fopen(savepath, "wb");
if(pfile != NULL) {
fwrite(file.data,1,file.size,pfile);
fclose(pfile);
free(file.data);
done++;
}
}
j++;
}
}
//if there was no network init
else return -1;
// return the number of files we updated
return done;
}

View File

@ -1,18 +1,18 @@
/****************************************************************************
* language update
* for USB Loader GX *giantpune*
***************************************************************************/
#ifndef ___UPDATELANGUAGE_H_
#define ___UPDATELANGUAGE_H_
#define MAXLANGUAGEFILES 50
//! Checks the language path for files ending in .lang and updates them (up to MAXLANGUAGEFILES)
//! This function expects that the network is already init before it is called
//! returns the number of files successfully updated
//! returns -2 if it can't find any .lang files in the path
//! return -1 if there is no network connection
int updateLanguageFiles();
#endif
/****************************************************************************
* language update
* for USB Loader GX *giantpune*
***************************************************************************/
#ifndef ___UPDATELANGUAGE_H_
#define ___UPDATELANGUAGE_H_
#define MAXLANGUAGEFILES 50
//! Checks the language path for files ending in .lang and updates them (up to MAXLANGUAGEFILES)
//! This function expects that the network is already init before it is called
//! returns the number of files successfully updated
//! returns -2 if it can't find any .lang files in the path
//! return -1 if there is no network connection
int updateLanguageFiles();
#endif

View File

@ -1,223 +1,223 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <gctypes.h>
#include "gettext.h"
typedef struct _MSG {
u32 id;
char* msgstr;
struct _MSG *next;
} MSG;
static MSG *baseMSG=0;
#define HASHWORDBITS 32
/* Defines the so called `hashpjw' function by P.J. Weinberger
[see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
1986, 1987 Bell Telephone Laboratories, Inc.] */
static inline u32
hash_string (const char *str_param) {
u32 hval, g;
const char *str = str_param;
/* Compute the hash value for the given string. */
hval = 0;
while (*str != '\0') {
hval <<= 4;
hval += (u8) *str++;
g = hval & ((u32) 0xf << (HASHWORDBITS - 4));
if (g != 0) {
hval ^= g >> (HASHWORDBITS - 8);
hval ^= g;
}
}
return hval;
}
/* Expand some escape sequences found in the argument string. */
static char *
expand_escape (const char *str) {
char *retval, *rp;
const char *cp = str;
retval = (char *) malloc (strlen (str)+1);
if (retval==NULL) return NULL;
rp = retval;
while (cp[0] != '\0' && cp[0] != '\\')
*rp++ = *cp++;
if (cp[0] == '\0')
goto terminate;
do {
/* Here cp[0] == '\\'. */
switch (*++cp) {
case '\"': /* " */
*rp++ = '\"';
++cp;
break;
case 'a': /* alert */
*rp++ = '\a';
++cp;
break;
case 'b': /* backspace */
*rp++ = '\b';
++cp;
break;
case 'f': /* form feed */
*rp++ = '\f';
++cp;
break;
case 'n': /* new line */
*rp++ = '\n';
++cp;
break;
case 'r': /* carriage return */
*rp++ = '\r';
++cp;
break;
case 't': /* horizontal tab */
*rp++ = '\t';
++cp;
break;
case 'v': /* vertical tab */
*rp++ = '\v';
++cp;
break;
case '\\':
*rp = '\\';
++cp;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7': {
int ch = *cp++ - '0';
if (*cp >= '0' && *cp <= '7') {
ch *= 8;
ch += *cp++ - '0';
if (*cp >= '0' && *cp <= '7') {
ch *= 8;
ch += *cp++ - '0';
}
}
*rp = ch;
}
break;
default:
*rp = '\\';
break;
}
while (cp[0] != '\0' && cp[0] != '\\')
*rp++ = *cp++;
} while (cp[0] != '\0');
/* Terminate string. */
terminate:
*rp = '\0';
return retval;
}
static MSG *findMSG(u32 id) {
MSG *msg;
for (msg=baseMSG; msg; msg=msg->next) {
if (msg->id == id)
return msg;
}
return NULL;
}
static MSG *setMSG(const char *msgid, const char *msgstr) {
u32 id = hash_string(msgid);
MSG *msg = findMSG(id);
if (!msg) {
msg = (MSG *)malloc(sizeof(MSG));
msg->id = id;
msg->msgstr = NULL;
msg->next = baseMSG;
baseMSG = msg;
}
if (msg) {
if (msgstr) {
if (msg->msgstr) free(msg->msgstr);
//msg->msgstr = strdup(msgstr);
msg->msgstr = expand_escape(msgstr);
}
return msg;
}
return NULL;
}
void gettextCleanUp(void) {
while (baseMSG) {
MSG *nextMsg =baseMSG->next;
free(baseMSG->msgstr);
free(baseMSG);
baseMSG = nextMsg;
}
}
bool gettextLoadLanguage(const char* langFile) {
FILE *f;
char line[200];
char *lastID=NULL;
gettextCleanUp();
f = fopen(langFile, "r");
if (!f)
return false;
while (fgets(line, sizeof(line), f)) {
// lines starting with # are comments
if (line[0] == '#')
continue;
else if (strncmp(line, "msgid \"", 7) == 0) {
char *msgid, *end;
if (lastID) {
free(lastID);
lastID=NULL;
}
msgid = &line[7];
end = strrchr(msgid, '"');
if (end && end-msgid>1) {
*end = 0;
lastID = strdup(msgid);
}
} else if (strncmp(line, "msgstr \"", 8) == 0) {
char *msgstr, *end;
if (lastID == NULL)
continue;
msgstr = &line[8];
end = strrchr(msgstr, '"');
if (end && end-msgstr>1) {
*end = 0;
setMSG(lastID, msgstr);
}
free(lastID);
lastID=NULL;
}
}
fclose(f);
return true;
}
const char *gettext(const char *msgid) {
MSG *msg = findMSG(hash_string(msgid));
if (msg && msg->msgstr) return msg->msgstr;
return msgid;
}
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <gctypes.h>
#include "gettext.h"
typedef struct _MSG {
u32 id;
char* msgstr;
struct _MSG *next;
} MSG;
static MSG *baseMSG=0;
#define HASHWORDBITS 32
/* Defines the so called `hashpjw' function by P.J. Weinberger
[see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
1986, 1987 Bell Telephone Laboratories, Inc.] */
static inline u32
hash_string (const char *str_param) {
u32 hval, g;
const char *str = str_param;
/* Compute the hash value for the given string. */
hval = 0;
while (*str != '\0') {
hval <<= 4;
hval += (u8) *str++;
g = hval & ((u32) 0xf << (HASHWORDBITS - 4));
if (g != 0) {
hval ^= g >> (HASHWORDBITS - 8);
hval ^= g;
}
}
return hval;
}
/* Expand some escape sequences found in the argument string. */
static char *
expand_escape (const char *str) {
char *retval, *rp;
const char *cp = str;
retval = (char *) malloc (strlen (str)+1);
if (retval==NULL) return NULL;
rp = retval;
while (cp[0] != '\0' && cp[0] != '\\')
*rp++ = *cp++;
if (cp[0] == '\0')
goto terminate;
do {
/* Here cp[0] == '\\'. */
switch (*++cp) {
case '\"': /* " */
*rp++ = '\"';
++cp;
break;
case 'a': /* alert */
*rp++ = '\a';
++cp;
break;
case 'b': /* backspace */
*rp++ = '\b';
++cp;
break;
case 'f': /* form feed */
*rp++ = '\f';
++cp;
break;
case 'n': /* new line */
*rp++ = '\n';
++cp;
break;
case 'r': /* carriage return */
*rp++ = '\r';
++cp;
break;
case 't': /* horizontal tab */
*rp++ = '\t';
++cp;
break;
case 'v': /* vertical tab */
*rp++ = '\v';
++cp;
break;
case '\\':
*rp = '\\';
++cp;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7': {
int ch = *cp++ - '0';
if (*cp >= '0' && *cp <= '7') {
ch *= 8;
ch += *cp++ - '0';
if (*cp >= '0' && *cp <= '7') {
ch *= 8;
ch += *cp++ - '0';
}
}
*rp = ch;
}
break;
default:
*rp = '\\';
break;
}
while (cp[0] != '\0' && cp[0] != '\\')
*rp++ = *cp++;
} while (cp[0] != '\0');
/* Terminate string. */
terminate:
*rp = '\0';
return retval;
}
static MSG *findMSG(u32 id) {
MSG *msg;
for (msg=baseMSG; msg; msg=msg->next) {
if (msg->id == id)
return msg;
}
return NULL;
}
static MSG *setMSG(const char *msgid, const char *msgstr) {
u32 id = hash_string(msgid);
MSG *msg = findMSG(id);
if (!msg) {
msg = (MSG *)malloc(sizeof(MSG));
msg->id = id;
msg->msgstr = NULL;
msg->next = baseMSG;
baseMSG = msg;
}
if (msg) {
if (msgstr) {
if (msg->msgstr) free(msg->msgstr);
//msg->msgstr = strdup(msgstr);
msg->msgstr = expand_escape(msgstr);
}
return msg;
}
return NULL;
}
void gettextCleanUp(void) {
while (baseMSG) {
MSG *nextMsg =baseMSG->next;
free(baseMSG->msgstr);
free(baseMSG);
baseMSG = nextMsg;
}
}
bool gettextLoadLanguage(const char* langFile) {
FILE *f;
char line[200];
char *lastID=NULL;
gettextCleanUp();
f = fopen(langFile, "r");
if (!f)
return false;
while (fgets(line, sizeof(line), f)) {
// lines starting with # are comments
if (line[0] == '#')
continue;
else if (strncmp(line, "msgid \"", 7) == 0) {
char *msgid, *end;
if (lastID) {
free(lastID);
lastID=NULL;
}
msgid = &line[7];
end = strrchr(msgid, '"');
if (end && end-msgid>1) {
*end = 0;
lastID = strdup(msgid);
}
} else if (strncmp(line, "msgstr \"", 8) == 0) {
char *msgstr, *end;
if (lastID == NULL)
continue;
msgstr = &line[8];
end = strrchr(msgstr, '"');
if (end && end-msgstr>1) {
*end = 0;
setMSG(lastID, msgstr);
}
free(lastID);
lastID=NULL;
}
}
fclose(f);
return true;
}
const char *gettext(const char *msgid) {
MSG *msg = findMSG(hash_string(msgid));
if (msg && msg->msgstr) return msg->msgstr;
return msgid;
}

View File

@ -1,24 +1,24 @@
#ifndef _GETTEXT_H_
#define _GETTEXT_H_
#ifdef __cplusplus
extern "C" {
#endif
bool gettextLoadLanguage(const char* langFile);
void gettextCleanUp(void);
/*
* input msg = a text in ASCII
* output = the translated msg in utf-8
*/
const char *gettext(const char *msg);
#define tr(s) gettext(s)
#define trNOOP(s) (s)
#ifdef __cplusplus
}
#endif
#endif /* _GETTEXT_H_ */
#ifndef _GETTEXT_H_
#define _GETTEXT_H_
#ifdef __cplusplus
extern "C" {
#endif
bool gettextLoadLanguage(const char* langFile);
void gettextCleanUp(void);
/*
* input msg = a text in ASCII
* output = the translated msg in utf-8
*/
const char *gettext(const char *msg);
#define tr(s) gettext(s)
#define trNOOP(s) (s)
#ifdef __cplusplus
}
#endif
#endif /* _GETTEXT_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,90 +1,90 @@
#include "gui.h"
class customOptionList {
public:
customOptionList(int size);
~customOptionList();
void SetName(int i, const char *format, ...) __attribute__((format (printf, 3, 4)));
const char *GetName(int i)
{
if(i >= 0 && i < length && name[i])
return name[i];
else
return "";
}
void SetValue(int i, const char *format, ...) __attribute__((format (printf, 3, 4)));
const char *GetValue(int i)
{
if(i >= 0 && i < length && value[i])
return value[i];
else
return "";
}
int GetLength() { return length; }
bool IsChanged() { bool ret = changed; changed = false; return ret;}
private:
int length;
char ** name;
char ** value;
bool changed;
};
//!Display a list of menu options
class GuiCustomOptionBrowser : public GuiElement
{
public:
GuiCustomOptionBrowser(int w, int h, customOptionList * l, const char * themePath, const char *custombg, const u8 *imagebg, int scrollbar, int col2);
~GuiCustomOptionBrowser();
int FindMenuItem(int c, int d);
int GetClickedOption();
int GetSelectedOption();
void SetClickable(bool enable);
void SetScrollbar(int enable);
void SetOffset(int optionnumber);
void ResetState();
void SetFocus(int f);
void Draw();
void Update(GuiTrigger * t);
protected:
void UpdateListEntries();
int selectedItem;
int listOffset;
int size;
int coL2;
int scrollbaron;
customOptionList * options;
int * optionIndex;
GuiButton ** optionBtn;
GuiText ** optionTxt;
GuiText ** optionVal;
GuiText ** optionValOver;
GuiImage ** optionBg;
GuiButton * arrowUpBtn;
GuiButton * arrowDownBtn;
GuiButton * scrollbarBoxBtn;
GuiImage * bgOptionsImg;
GuiImage * scrollbarImg;
GuiImage * arrowDownImg;
GuiImage * arrowDownOverImg;
GuiImage * arrowUpImg;
GuiImage * arrowUpOverImg;
GuiImage * scrollbarBoxImg;
GuiImage * scrollbarBoxOverImg;
GuiImageData * bgOptions;
GuiImageData * bgOptionsEntry;
GuiImageData * scrollbar;
GuiImageData * arrowDown;
GuiImageData * arrowDownOver;
GuiImageData * arrowUp;
GuiImageData * arrowUpOver;
GuiImageData * scrollbarBox;
GuiImageData * scrollbarBoxOver;
GuiSound * btnSoundClick;
GuiTrigger * trigA;
GuiTrigger * trigHeldA;
};
#include "gui.h"
class customOptionList {
public:
customOptionList(int size);
~customOptionList();
void SetName(int i, const char *format, ...) __attribute__((format (printf, 3, 4)));
const char *GetName(int i)
{
if(i >= 0 && i < length && name[i])
return name[i];
else
return "";
}
void SetValue(int i, const char *format, ...) __attribute__((format (printf, 3, 4)));
const char *GetValue(int i)
{
if(i >= 0 && i < length && value[i])
return value[i];
else
return "";
}
int GetLength() { return length; }
bool IsChanged() { bool ret = changed; changed = false; return ret;}
private:
int length;
char ** name;
char ** value;
bool changed;
};
//!Display a list of menu options
class GuiCustomOptionBrowser : public GuiElement
{
public:
GuiCustomOptionBrowser(int w, int h, customOptionList * l, const char * themePath, const char *custombg, const u8 *imagebg, int scrollbar, int col2);
~GuiCustomOptionBrowser();
int FindMenuItem(int c, int d);
int GetClickedOption();
int GetSelectedOption();
void SetClickable(bool enable);
void SetScrollbar(int enable);
void SetOffset(int optionnumber);
void ResetState();
void SetFocus(int f);
void Draw();
void Update(GuiTrigger * t);
protected:
void UpdateListEntries();
int selectedItem;
int listOffset;
int size;
int coL2;
int scrollbaron;
customOptionList * options;
int * optionIndex;
GuiButton ** optionBtn;
GuiText ** optionTxt;
GuiText ** optionVal;
GuiText ** optionValOver;
GuiImage ** optionBg;
GuiButton * arrowUpBtn;
GuiButton * arrowDownBtn;
GuiButton * scrollbarBoxBtn;
GuiImage * bgOptionsImg;
GuiImage * scrollbarImg;
GuiImage * arrowDownImg;
GuiImage * arrowDownOverImg;
GuiImage * arrowUpImg;
GuiImage * arrowUpOverImg;
GuiImage * scrollbarBoxImg;
GuiImage * scrollbarBoxOverImg;
GuiImageData * bgOptions;
GuiImageData * bgOptionsEntry;
GuiImageData * scrollbar;
GuiImageData * arrowDown;
GuiImageData * arrowDownOver;
GuiImageData * arrowUp;
GuiImageData * arrowUpOver;
GuiImageData * scrollbarBox;
GuiImageData * scrollbarBoxOver;
GuiSound * btnSoundClick;
GuiTrigger * trigA;
GuiTrigger * trigHeldA;
};

View File

@ -1,78 +1,78 @@
#include "gui_diskcover.h"
GuiDiskCover::GuiDiskCover()
{
deg_beta=0.0;
eff_step=0;
// spin_angle = 0;
spin_speedup = 1.0;
spin_up = false;
}
GuiDiskCover::GuiDiskCover(GuiImageData *Disk) : GuiImage(Disk)
{
deg_beta=0.0;
eff_step=0;
// spin_angle = 0;
spin_speedup = 1.0;
spin_up = false;
}
GuiDiskCover::~GuiDiskCover()
{
}
void GuiDiskCover::SetBeta(f32 beta)
{
deg_beta=beta;
}
void GuiDiskCover::SetBetaRotateEffect(f32 beta, u16 step)
{
eff_beta = beta/(f32)step;
eff_step = step;
}
bool GuiDiskCover::GetBetaRotateEffect()
{
return eff_step != 0;
}
void GuiDiskCover::SetSpin(bool Up)
{
spin_up = Up;
}
void Menu_DrawDiskCover(f32 xpos, f32 ypos, f32 zpos, u16 width, u16 height, u16 distance,u8 data[],
f32 deg_alpha, f32 deg_beta, f32 scaleX, f32 scaleY, u8 alpha, bool shadow);
void Menu_DrawDiskCoverShadow(f32 xpos, f32 ypos, f32 zpos, u16 width, u16 height, u16 distance,u8 data[],
f32 deg_alpha, f32 deg_beta, f32 scaleX, f32 scaleY, u8 alpha, bool shadow);
void GuiDiskCover::Draw()
{
LOCK(this);
if(!image || !this->IsVisible())
return;
float currScale = this->GetScale();
// Menu_DrawDiskCoverShadow(this->GetLeft(), this->GetTop(), 190, width, height, 40, image, imageangle, deg_beta, widescreen ? currScale*0.8 : currScale, currScale, this->GetAlpha(), true);
Menu_DrawDiskCover(this->GetLeft(), this->GetTop(), 50, width, height, 55, image, imageangle, deg_beta, widescreen ? currScale*0.8 : currScale, currScale, 64, true);
Menu_DrawDiskCover(this->GetLeft(), this->GetTop(), 50, width, height, 55, image, imageangle, deg_beta, widescreen ? currScale*0.8 : currScale, currScale, this->GetAlpha(), false);
if(eff_step)
{
deg_beta += eff_beta;
eff_step--;
}
GuiImage::imageangle += spin_speedup;
while(GuiImage::imageangle >= 360.0) GuiImage::imageangle -= 360.0;
if(spin_up)
{
if (spin_speedup < 11) // speed up
spin_speedup += 0.20;
}
else
{
if (spin_speedup > 1)
spin_speedup -=0.05; //slow down
}
this->UpdateEffects();
}
#include "gui_diskcover.h"
GuiDiskCover::GuiDiskCover()
{
deg_beta=0.0;
eff_step=0;
// spin_angle = 0;
spin_speedup = 1.0;
spin_up = false;
}
GuiDiskCover::GuiDiskCover(GuiImageData *Disk) : GuiImage(Disk)
{
deg_beta=0.0;
eff_step=0;
// spin_angle = 0;
spin_speedup = 1.0;
spin_up = false;
}
GuiDiskCover::~GuiDiskCover()
{
}
void GuiDiskCover::SetBeta(f32 beta)
{
deg_beta=beta;
}
void GuiDiskCover::SetBetaRotateEffect(f32 beta, u16 step)
{
eff_beta = beta/(f32)step;
eff_step = step;
}
bool GuiDiskCover::GetBetaRotateEffect()
{
return eff_step != 0;
}
void GuiDiskCover::SetSpin(bool Up)
{
spin_up = Up;
}
void Menu_DrawDiskCover(f32 xpos, f32 ypos, f32 zpos, u16 width, u16 height, u16 distance,u8 data[],
f32 deg_alpha, f32 deg_beta, f32 scaleX, f32 scaleY, u8 alpha, bool shadow);
void Menu_DrawDiskCoverShadow(f32 xpos, f32 ypos, f32 zpos, u16 width, u16 height, u16 distance,u8 data[],
f32 deg_alpha, f32 deg_beta, f32 scaleX, f32 scaleY, u8 alpha, bool shadow);
void GuiDiskCover::Draw()
{
LOCK(this);
if(!image || !this->IsVisible())
return;
float currScale = this->GetScale();
// Menu_DrawDiskCoverShadow(this->GetLeft(), this->GetTop(), 190, width, height, 40, image, imageangle, deg_beta, widescreen ? currScale*0.8 : currScale, currScale, this->GetAlpha(), true);
Menu_DrawDiskCover(this->GetLeft(), this->GetTop(), 50, width, height, 55, image, imageangle, deg_beta, widescreen ? currScale*0.8 : currScale, currScale, 64, true);
Menu_DrawDiskCover(this->GetLeft(), this->GetTop(), 50, width, height, 55, image, imageangle, deg_beta, widescreen ? currScale*0.8 : currScale, currScale, this->GetAlpha(), false);
if(eff_step)
{
deg_beta += eff_beta;
eff_step--;
}
GuiImage::imageangle += spin_speedup;
while(GuiImage::imageangle >= 360.0) GuiImage::imageangle -= 360.0;
if(spin_up)
{
if (spin_speedup < 11) // speed up
spin_speedup += 0.20;
}
else
{
if (spin_speedup > 1)
spin_speedup -=0.05; //slow down
}
this->UpdateEffects();
}

View File

@ -1,42 +1,42 @@
#ifndef _GUIDISCCOVER_H_
#define _GUIDISCCOVER_H_
#include "gui.h"
class GuiDiskCover : public GuiImage
{
public:
GuiDiskCover();
GuiDiskCover(GuiImageData * img);
~GuiDiskCover();
void SetBeta(f32 beta);
void SetBetaRotateEffect(f32 beta, u16 Step);
bool GetBetaRotateEffect();
void SetSpin(bool Up);
void Draw();
private:
f32 deg_beta;
f32 eff_beta;
u16 eff_step;
// f32 spin_angle;
f32 spin_speedup;
bool spin_up;
};
#endif /* _GUIDISCCOVER_H_ */
#ifndef _GUIDISCCOVER_H_
#define _GUIDISCCOVER_H_
#include "gui.h"
class GuiDiskCover : public GuiImage
{
public:
GuiDiskCover();
GuiDiskCover(GuiImageData * img);
~GuiDiskCover();
void SetBeta(f32 beta);
void SetBetaRotateEffect(f32 beta, u16 Step);
bool GetBetaRotateEffect();
void SetSpin(bool Up);
void Draw();
private:
f32 deg_beta;
f32 eff_beta;
u16 eff_step;
// f32 spin_angle;
f32 spin_speedup;
bool spin_up;
};
#endif /* _GUIDISCCOVER_H_ */

View File

@ -1,418 +1,418 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_filebrowser.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
#include "prompts/filebrowser.h"
#include "../settings/cfg.h"
#define FILEBROWSERSIZE 8
/**
* Constructor for the GuiFileBrowser class.
*/
GuiFileBrowser::GuiFileBrowser(int w, int h)
{
width = w;
height = h;
selectedItem = 0;
selectable = true;
listChanged = true; // trigger an initial list update
triggerdisabled = false; // trigger disable
focus = 1; // allow focus
trigA = new GuiTrigger;
trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
trigHeldA = new GuiTrigger;
trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, SOUND_PCM);
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND_PCM);
char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbg_browser.png", CFG.theme_path);
bgFileSelection = new GuiImageData(imgPath, bg_browser_png);
bgFileSelectionImg = new GuiImage(bgFileSelection);
bgFileSelectionImg->SetParent(this);
bgFileSelectionImg->SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
snprintf(imgPath, sizeof(imgPath), "%sbg_browser_selection.png", CFG.theme_path);
bgFileSelectionEntry = new GuiImageData(imgPath, bg_browser_selection_png);
fileFolder = new GuiImageData(folder_png);
snprintf(imgPath, sizeof(imgPath), "%sscrollbar.png", CFG.theme_path);
scrollbar = new GuiImageData(imgPath, scrollbar_png);
scrollbarImg = new GuiImage(scrollbar);
scrollbarImg->SetParent(this);
scrollbarImg->SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
scrollbarImg->SetPosition(0, 2);
scrollbarImg->SetSkew(0,0,0,0,0,-30,0,-30);
snprintf(imgPath, sizeof(imgPath), "%sscrollbar_arrowdown.png", CFG.theme_path);
arrowDown = new GuiImageData(imgPath, scrollbar_arrowdown_png);
arrowDownImg = new GuiImage(arrowDown);
snprintf(imgPath, sizeof(imgPath), "%sscrollbar_arrowup.png", CFG.theme_path);
arrowUp = new GuiImageData(imgPath, scrollbar_arrowup_png);
arrowUpImg = new GuiImage(arrowUp);
snprintf(imgPath, sizeof(imgPath), "%sscrollbar_box.png", CFG.theme_path);
scrollbarBox = new GuiImageData(imgPath, scrollbar_box_png);
scrollbarBoxImg = new GuiImage(scrollbarBox);
arrowUpBtn = new GuiButton(arrowUpImg->GetWidth(), arrowUpImg->GetHeight());
arrowUpBtn->SetParent(this);
arrowUpBtn->SetImage(arrowUpImg);
arrowUpBtn->SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
arrowUpBtn->SetPosition(12,-12);
arrowUpBtn->SetSelectable(false);
arrowUpBtn->SetClickable(false);
arrowUpBtn->SetHoldable(true);
arrowUpBtn->SetTrigger(trigHeldA);
arrowUpBtn->SetSoundOver(btnSoundOver);
arrowUpBtn->SetSoundClick(btnSoundClick);
arrowDownBtn = new GuiButton(arrowDownImg->GetWidth(), arrowDownImg->GetHeight());
arrowDownBtn->SetParent(this);
arrowDownBtn->SetImage(arrowDownImg);
arrowDownBtn->SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
arrowDownBtn->SetPosition(12,12);
arrowDownBtn->SetSelectable(false);
arrowDownBtn->SetClickable(false);
arrowDownBtn->SetHoldable(true);
arrowDownBtn->SetTrigger(trigHeldA);
arrowDownBtn->SetSoundOver(btnSoundOver);
arrowDownBtn->SetSoundClick(btnSoundClick);
scrollbarBoxBtn = new GuiButton(scrollbarBoxImg->GetWidth(), scrollbarBoxImg->GetHeight());
scrollbarBoxBtn->SetParent(this);
scrollbarBoxBtn->SetImage(scrollbarBoxImg);
scrollbarBoxBtn->SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
scrollbarBoxBtn->SetMinY(-10);
scrollbarBoxBtn->SetMaxY(156);
scrollbarBoxBtn->SetSelectable(false);
scrollbarBoxBtn->SetClickable(false);
scrollbarBoxBtn->SetHoldable(true);
scrollbarBoxBtn->SetTrigger(trigHeldA);
for(int i=0; i<FILEBROWSERSIZE; i++)
{
fileListText[i] = new GuiText(NULL,20, (GXColor){0, 0, 0, 0xff});
fileListText[i]->SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
fileListText[i]->SetPosition(5,0);
fileListText[i]->SetMaxWidth(bgFileSelectionImg->GetWidth() - (arrowDownImg->GetWidth()+20), GuiText::DOTTED);
fileListTextOver[i] = new GuiText(NULL,20, (GXColor){0, 0, 0, 0xff});
fileListTextOver[i]->SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
fileListTextOver[i]->SetPosition(5,0);
fileListTextOver[i]->SetMaxWidth(bgFileSelectionImg->GetWidth() - (arrowDownImg->GetWidth()+20), GuiText::SCROLL);
fileListBg[i] = new GuiImage(bgFileSelectionEntry);
fileListFolder[i] = new GuiImage(fileFolder);
fileList[i] = new GuiButton(350,30);
fileList[i]->SetParent(this);
fileList[i]->SetLabel(fileListText[i]);
fileList[i]->SetLabelOver(fileListTextOver[i]);
fileList[i]->SetImageOver(fileListBg[i]);
fileList[i]->SetPosition(2,30*i+3);
fileList[i]->SetTrigger(trigA);
fileList[i]->SetRumble(false);
fileList[i]->SetSoundClick(btnSoundClick);
}
}
/**
* Destructor for the GuiFileBrowser class.
*/
GuiFileBrowser::~GuiFileBrowser()
{
delete arrowUpBtn;
delete arrowDownBtn;
delete scrollbarBoxBtn;
delete bgFileSelectionImg;
delete scrollbarImg;
delete arrowDownImg;
delete arrowUpImg;
delete scrollbarBoxImg;
delete bgFileSelection;
delete bgFileSelectionEntry;
delete fileFolder;
delete scrollbar;
delete arrowDown;
delete arrowUp;
delete scrollbarBox;
delete btnSoundOver;
delete btnSoundClick;
delete trigHeldA;
delete trigA;
for(int i=0; i<FILEBROWSERSIZE; i++)
{
delete fileListText[i];
delete fileListTextOver[i];
delete fileList[i];
delete fileListBg[i];
delete fileListFolder[i];
}
}
void GuiFileBrowser::SetFocus(int f)
{
focus = f;
for(int i=0; i<FILEBROWSERSIZE; i++)
fileList[i]->ResetState();
if(f == 1)
fileList[selectedItem]->SetState(STATE_SELECTED);
}
void GuiFileBrowser::DisableTriggerUpdate(bool set)
{
triggerdisabled = set;
}
void GuiFileBrowser::ResetState()
{
state = STATE_DEFAULT;
stateChan = -1;
selectedItem = 0;
for(int i=0; i<FILEBROWSERSIZE; i++)
{
fileList[i]->ResetState();
}
}
void GuiFileBrowser::TriggerUpdate()
{
listChanged = true;
}
/**
* Draw the button on screen
*/
void GuiFileBrowser::Draw()
{
if(!this->IsVisible())
return;
bgFileSelectionImg->Draw();
for(int i=0; i<FILEBROWSERSIZE; i++)
{
fileList[i]->Draw();
}
scrollbarImg->Draw();
arrowUpBtn->Draw();
arrowDownBtn->Draw();
scrollbarBoxBtn->Draw();
this->UpdateEffects();
}
void GuiFileBrowser::Update(GuiTrigger * t)
{
if(state == STATE_DISABLED || !t || triggerdisabled)
return;
int position = 0;
int positionWiimote = 0;
arrowUpBtn->Update(t);
arrowDownBtn->Update(t);
scrollbarBoxBtn->Update(t);
// move the file listing to respond to wiimote cursor movement
if(scrollbarBoxBtn->GetState() == STATE_HELD &&
scrollbarBoxBtn->GetStateChan() == t->chan &&
t->wpad.ir.valid &&
browser.numEntries > FILEBROWSERSIZE
)
{
scrollbarBoxBtn->SetPosition(20,-10);
positionWiimote = t->wpad.ir.y - 60 - scrollbarBoxBtn->GetTop();
if(positionWiimote < scrollbarBoxBtn->GetMinY())
positionWiimote = scrollbarBoxBtn->GetMinY();
else if(positionWiimote > scrollbarBoxBtn->GetMaxY())
positionWiimote = scrollbarBoxBtn->GetMaxY();
browser.pageIndex = (positionWiimote * browser.numEntries)/166.0 - selectedItem;
if(browser.pageIndex <= 0)
{
browser.pageIndex = 0;
}
else if(browser.pageIndex+FILEBROWSERSIZE >= browser.numEntries)
{
browser.pageIndex = browser.numEntries-FILEBROWSERSIZE;
}
listChanged = true;
focus = false;
}
if(arrowDownBtn->GetState() == STATE_HELD && arrowDownBtn->GetStateChan() == t->chan)
{
t->wpad.btns_h |= WPAD_BUTTON_DOWN;
if(!this->IsFocused())
((GuiWindow *)this->GetParent())->ChangeFocus(this);
}
else if(arrowUpBtn->GetState() == STATE_HELD && arrowUpBtn->GetStateChan() == t->chan)
{
t->wpad.btns_h |= WPAD_BUTTON_UP;
if(!this->IsFocused())
((GuiWindow *)this->GetParent())->ChangeFocus(this);
}
// pad/joystick navigation
if(!focus)
{
goto endNavigation; // skip navigation
listChanged = false;
}
if(t->Right())
{
if(browser.pageIndex < browser.numEntries && browser.numEntries > FILEBROWSERSIZE)
{
browser.pageIndex += FILEBROWSERSIZE;
if(browser.pageIndex+FILEBROWSERSIZE >= browser.numEntries)
browser.pageIndex = browser.numEntries-FILEBROWSERSIZE;
listChanged = true;
}
}
else if(t->Left())
{
if(browser.pageIndex > 0)
{
browser.pageIndex -= FILEBROWSERSIZE;
if(browser.pageIndex < 0)
browser.pageIndex = 0;
listChanged = true;
}
}
else if(t->Down())
{
if(browser.pageIndex + selectedItem + 1 < browser.numEntries)
{
if(selectedItem == FILEBROWSERSIZE-1)
{
// move list down by 1
browser.pageIndex++;
listChanged = true;
}
else if(fileList[selectedItem+1]->IsVisible())
{
fileList[selectedItem]->ResetState();
fileList[++selectedItem]->SetState(STATE_SELECTED, t->chan);
}
}
}
else if(t->Up())
{
if(selectedItem == 0 && browser.pageIndex + selectedItem > 0)
{
// move list up by 1
browser.pageIndex--;
listChanged = true;
}
else if(selectedItem > 0)
{
fileList[selectedItem]->ResetState();
fileList[--selectedItem]->SetState(STATE_SELECTED, t->chan);
}
}
endNavigation:
for(int i=0; i<FILEBROWSERSIZE; i++)
{
if(listChanged)
{
if(browser.pageIndex+i < browser.numEntries)
{
if(fileList[i]->GetState() == STATE_DISABLED)
fileList[i]->SetState(STATE_DEFAULT);
fileList[i]->SetVisible(true);
fileListText[i]->SetText(browserList[browser.pageIndex+i].displayname);
fileListTextOver[i]->SetText(browserList[browser.pageIndex+i].displayname);
if(browserList[browser.pageIndex+i].isdir) // directory
{
fileList[i]->SetIcon(fileListFolder[i]);
fileListText[i]->SetPosition(30,0);
fileListTextOver[i]->SetPosition(30,0);
}
else
{
fileList[i]->SetIcon(NULL);
fileListText[i]->SetPosition(10,0);
fileListTextOver[i]->SetPosition(10,0);
}
}
else
{
fileList[i]->SetVisible(false);
fileList[i]->SetState(STATE_DISABLED);
}
}
if(i != selectedItem && fileList[i]->GetState() == STATE_SELECTED)
fileList[i]->ResetState();
else if(focus && i == selectedItem && fileList[i]->GetState() == STATE_DEFAULT)
fileList[selectedItem]->SetState(STATE_SELECTED, t->chan);
int currChan = t->chan;
if(t->wpad.ir.valid && !fileList[i]->IsInside(t->wpad.ir.x, t->wpad.ir.y))
t->chan = -1;
fileList[i]->Update(t);
t->chan = currChan;
if(fileList[i]->GetState() == STATE_SELECTED)
{
selectedItem = i;
browser.selIndex = browser.pageIndex + i;
}
}
// update the location of the scroll box based on the position in the file list
if(positionWiimote > 0)
{
position = positionWiimote; // follow wiimote cursor
}
else
{
position = -10+(166*(browser.pageIndex + FILEBROWSERSIZE/2.0) / (browser.numEntries*1.0));
if(browser.pageIndex/(FILEBROWSERSIZE/2.0) < 1)
position = -10;
else if((browser.pageIndex+FILEBROWSERSIZE)/(FILEBROWSERSIZE*1.0) >= (browser.numEntries)/(FILEBROWSERSIZE*1.0))
position = 156;
}
scrollbarBoxBtn->SetPosition(12,position+26);
listChanged = false;
if(updateCB)
updateCB(this);
}
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_filebrowser.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
#include "prompts/filebrowser.h"
#include "../settings/cfg.h"
#define FILEBROWSERSIZE 8
/**
* Constructor for the GuiFileBrowser class.
*/
GuiFileBrowser::GuiFileBrowser(int w, int h)
{
width = w;
height = h;
selectedItem = 0;
selectable = true;
listChanged = true; // trigger an initial list update
triggerdisabled = false; // trigger disable
focus = 1; // allow focus
trigA = new GuiTrigger;
trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
trigHeldA = new GuiTrigger;
trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, SOUND_PCM);
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND_PCM);
char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbg_browser.png", CFG.theme_path);
bgFileSelection = new GuiImageData(imgPath, bg_browser_png);
bgFileSelectionImg = new GuiImage(bgFileSelection);
bgFileSelectionImg->SetParent(this);
bgFileSelectionImg->SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
snprintf(imgPath, sizeof(imgPath), "%sbg_browser_selection.png", CFG.theme_path);
bgFileSelectionEntry = new GuiImageData(imgPath, bg_browser_selection_png);
fileFolder = new GuiImageData(folder_png);
snprintf(imgPath, sizeof(imgPath), "%sscrollbar.png", CFG.theme_path);
scrollbar = new GuiImageData(imgPath, scrollbar_png);
scrollbarImg = new GuiImage(scrollbar);
scrollbarImg->SetParent(this);
scrollbarImg->SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
scrollbarImg->SetPosition(0, 2);
scrollbarImg->SetSkew(0,0,0,0,0,-30,0,-30);
snprintf(imgPath, sizeof(imgPath), "%sscrollbar_arrowdown.png", CFG.theme_path);
arrowDown = new GuiImageData(imgPath, scrollbar_arrowdown_png);
arrowDownImg = new GuiImage(arrowDown);
snprintf(imgPath, sizeof(imgPath), "%sscrollbar_arrowup.png", CFG.theme_path);
arrowUp = new GuiImageData(imgPath, scrollbar_arrowup_png);
arrowUpImg = new GuiImage(arrowUp);
snprintf(imgPath, sizeof(imgPath), "%sscrollbar_box.png", CFG.theme_path);
scrollbarBox = new GuiImageData(imgPath, scrollbar_box_png);
scrollbarBoxImg = new GuiImage(scrollbarBox);
arrowUpBtn = new GuiButton(arrowUpImg->GetWidth(), arrowUpImg->GetHeight());
arrowUpBtn->SetParent(this);
arrowUpBtn->SetImage(arrowUpImg);
arrowUpBtn->SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
arrowUpBtn->SetPosition(12,-12);
arrowUpBtn->SetSelectable(false);
arrowUpBtn->SetClickable(false);
arrowUpBtn->SetHoldable(true);
arrowUpBtn->SetTrigger(trigHeldA);
arrowUpBtn->SetSoundOver(btnSoundOver);
arrowUpBtn->SetSoundClick(btnSoundClick);
arrowDownBtn = new GuiButton(arrowDownImg->GetWidth(), arrowDownImg->GetHeight());
arrowDownBtn->SetParent(this);
arrowDownBtn->SetImage(arrowDownImg);
arrowDownBtn->SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
arrowDownBtn->SetPosition(12,12);
arrowDownBtn->SetSelectable(false);
arrowDownBtn->SetClickable(false);
arrowDownBtn->SetHoldable(true);
arrowDownBtn->SetTrigger(trigHeldA);
arrowDownBtn->SetSoundOver(btnSoundOver);
arrowDownBtn->SetSoundClick(btnSoundClick);
scrollbarBoxBtn = new GuiButton(scrollbarBoxImg->GetWidth(), scrollbarBoxImg->GetHeight());
scrollbarBoxBtn->SetParent(this);
scrollbarBoxBtn->SetImage(scrollbarBoxImg);
scrollbarBoxBtn->SetAlignment(ALIGN_RIGHT, ALIGN_TOP);
scrollbarBoxBtn->SetMinY(-10);
scrollbarBoxBtn->SetMaxY(156);
scrollbarBoxBtn->SetSelectable(false);
scrollbarBoxBtn->SetClickable(false);
scrollbarBoxBtn->SetHoldable(true);
scrollbarBoxBtn->SetTrigger(trigHeldA);
for(int i=0; i<FILEBROWSERSIZE; i++)
{
fileListText[i] = new GuiText(NULL,20, (GXColor){0, 0, 0, 0xff});
fileListText[i]->SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
fileListText[i]->SetPosition(5,0);
fileListText[i]->SetMaxWidth(bgFileSelectionImg->GetWidth() - (arrowDownImg->GetWidth()+20), GuiText::DOTTED);
fileListTextOver[i] = new GuiText(NULL,20, (GXColor){0, 0, 0, 0xff});
fileListTextOver[i]->SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
fileListTextOver[i]->SetPosition(5,0);
fileListTextOver[i]->SetMaxWidth(bgFileSelectionImg->GetWidth() - (arrowDownImg->GetWidth()+20), GuiText::SCROLL);
fileListBg[i] = new GuiImage(bgFileSelectionEntry);
fileListFolder[i] = new GuiImage(fileFolder);
fileList[i] = new GuiButton(350,30);
fileList[i]->SetParent(this);
fileList[i]->SetLabel(fileListText[i]);
fileList[i]->SetLabelOver(fileListTextOver[i]);
fileList[i]->SetImageOver(fileListBg[i]);
fileList[i]->SetPosition(2,30*i+3);
fileList[i]->SetTrigger(trigA);
fileList[i]->SetRumble(false);
fileList[i]->SetSoundClick(btnSoundClick);
}
}
/**
* Destructor for the GuiFileBrowser class.
*/
GuiFileBrowser::~GuiFileBrowser()
{
delete arrowUpBtn;
delete arrowDownBtn;
delete scrollbarBoxBtn;
delete bgFileSelectionImg;
delete scrollbarImg;
delete arrowDownImg;
delete arrowUpImg;
delete scrollbarBoxImg;
delete bgFileSelection;
delete bgFileSelectionEntry;
delete fileFolder;
delete scrollbar;
delete arrowDown;
delete arrowUp;
delete scrollbarBox;
delete btnSoundOver;
delete btnSoundClick;
delete trigHeldA;
delete trigA;
for(int i=0; i<FILEBROWSERSIZE; i++)
{
delete fileListText[i];
delete fileListTextOver[i];
delete fileList[i];
delete fileListBg[i];
delete fileListFolder[i];
}
}
void GuiFileBrowser::SetFocus(int f)
{
focus = f;
for(int i=0; i<FILEBROWSERSIZE; i++)
fileList[i]->ResetState();
if(f == 1)
fileList[selectedItem]->SetState(STATE_SELECTED);
}
void GuiFileBrowser::DisableTriggerUpdate(bool set)
{
triggerdisabled = set;
}
void GuiFileBrowser::ResetState()
{
state = STATE_DEFAULT;
stateChan = -1;
selectedItem = 0;
for(int i=0; i<FILEBROWSERSIZE; i++)
{
fileList[i]->ResetState();
}
}
void GuiFileBrowser::TriggerUpdate()
{
listChanged = true;
}
/**
* Draw the button on screen
*/
void GuiFileBrowser::Draw()
{
if(!this->IsVisible())
return;
bgFileSelectionImg->Draw();
for(int i=0; i<FILEBROWSERSIZE; i++)
{
fileList[i]->Draw();
}
scrollbarImg->Draw();
arrowUpBtn->Draw();
arrowDownBtn->Draw();
scrollbarBoxBtn->Draw();
this->UpdateEffects();
}
void GuiFileBrowser::Update(GuiTrigger * t)
{
if(state == STATE_DISABLED || !t || triggerdisabled)
return;
int position = 0;
int positionWiimote = 0;
arrowUpBtn->Update(t);
arrowDownBtn->Update(t);
scrollbarBoxBtn->Update(t);
// move the file listing to respond to wiimote cursor movement
if(scrollbarBoxBtn->GetState() == STATE_HELD &&
scrollbarBoxBtn->GetStateChan() == t->chan &&
t->wpad.ir.valid &&
browser.numEntries > FILEBROWSERSIZE
)
{
scrollbarBoxBtn->SetPosition(20,-10);
positionWiimote = t->wpad.ir.y - 60 - scrollbarBoxBtn->GetTop();
if(positionWiimote < scrollbarBoxBtn->GetMinY())
positionWiimote = scrollbarBoxBtn->GetMinY();
else if(positionWiimote > scrollbarBoxBtn->GetMaxY())
positionWiimote = scrollbarBoxBtn->GetMaxY();
browser.pageIndex = (positionWiimote * browser.numEntries)/166.0 - selectedItem;
if(browser.pageIndex <= 0)
{
browser.pageIndex = 0;
}
else if(browser.pageIndex+FILEBROWSERSIZE >= browser.numEntries)
{
browser.pageIndex = browser.numEntries-FILEBROWSERSIZE;
}
listChanged = true;
focus = false;
}
if(arrowDownBtn->GetState() == STATE_HELD && arrowDownBtn->GetStateChan() == t->chan)
{
t->wpad.btns_h |= WPAD_BUTTON_DOWN;
if(!this->IsFocused())
((GuiWindow *)this->GetParent())->ChangeFocus(this);
}
else if(arrowUpBtn->GetState() == STATE_HELD && arrowUpBtn->GetStateChan() == t->chan)
{
t->wpad.btns_h |= WPAD_BUTTON_UP;
if(!this->IsFocused())
((GuiWindow *)this->GetParent())->ChangeFocus(this);
}
// pad/joystick navigation
if(!focus)
{
goto endNavigation; // skip navigation
listChanged = false;
}
if(t->Right())
{
if(browser.pageIndex < browser.numEntries && browser.numEntries > FILEBROWSERSIZE)
{
browser.pageIndex += FILEBROWSERSIZE;
if(browser.pageIndex+FILEBROWSERSIZE >= browser.numEntries)
browser.pageIndex = browser.numEntries-FILEBROWSERSIZE;
listChanged = true;
}
}
else if(t->Left())
{
if(browser.pageIndex > 0)
{
browser.pageIndex -= FILEBROWSERSIZE;
if(browser.pageIndex < 0)
browser.pageIndex = 0;
listChanged = true;
}
}
else if(t->Down())
{
if(browser.pageIndex + selectedItem + 1 < browser.numEntries)
{
if(selectedItem == FILEBROWSERSIZE-1)
{
// move list down by 1
browser.pageIndex++;
listChanged = true;
}
else if(fileList[selectedItem+1]->IsVisible())
{
fileList[selectedItem]->ResetState();
fileList[++selectedItem]->SetState(STATE_SELECTED, t->chan);
}
}
}
else if(t->Up())
{
if(selectedItem == 0 && browser.pageIndex + selectedItem > 0)
{
// move list up by 1
browser.pageIndex--;
listChanged = true;
}
else if(selectedItem > 0)
{
fileList[selectedItem]->ResetState();
fileList[--selectedItem]->SetState(STATE_SELECTED, t->chan);
}
}
endNavigation:
for(int i=0; i<FILEBROWSERSIZE; i++)
{
if(listChanged)
{
if(browser.pageIndex+i < browser.numEntries)
{
if(fileList[i]->GetState() == STATE_DISABLED)
fileList[i]->SetState(STATE_DEFAULT);
fileList[i]->SetVisible(true);
fileListText[i]->SetText(browserList[browser.pageIndex+i].displayname);
fileListTextOver[i]->SetText(browserList[browser.pageIndex+i].displayname);
if(browserList[browser.pageIndex+i].isdir) // directory
{
fileList[i]->SetIcon(fileListFolder[i]);
fileListText[i]->SetPosition(30,0);
fileListTextOver[i]->SetPosition(30,0);
}
else
{
fileList[i]->SetIcon(NULL);
fileListText[i]->SetPosition(10,0);
fileListTextOver[i]->SetPosition(10,0);
}
}
else
{
fileList[i]->SetVisible(false);
fileList[i]->SetState(STATE_DISABLED);
}
}
if(i != selectedItem && fileList[i]->GetState() == STATE_SELECTED)
fileList[i]->ResetState();
else if(focus && i == selectedItem && fileList[i]->GetState() == STATE_DEFAULT)
fileList[selectedItem]->SetState(STATE_SELECTED, t->chan);
int currChan = t->chan;
if(t->wpad.ir.valid && !fileList[i]->IsInside(t->wpad.ir.x, t->wpad.ir.y))
t->chan = -1;
fileList[i]->Update(t);
t->chan = currChan;
if(fileList[i]->GetState() == STATE_SELECTED)
{
selectedItem = i;
browser.selIndex = browser.pageIndex + i;
}
}
// update the location of the scroll box based on the position in the file list
if(positionWiimote > 0)
{
position = positionWiimote; // follow wiimote cursor
}
else
{
position = -10+(166*(browser.pageIndex + FILEBROWSERSIZE/2.0) / (browser.numEntries*1.0));
if(browser.pageIndex/(FILEBROWSERSIZE/2.0) < 1)
position = -10;
else if((browser.pageIndex+FILEBROWSERSIZE)/(FILEBROWSERSIZE*1.0) >= (browser.numEntries)/(FILEBROWSERSIZE*1.0))
position = 156;
}
scrollbarBoxBtn->SetPosition(12,position+26);
listChanged = false;
if(updateCB)
updateCB(this);
}

View File

@ -1,62 +1,62 @@
#ifndef _GUIGAMEGRID_H_
#define _GUIGAMEGRID_H_
#include "gui.h"
#include "../usbloader/disc.h"
class GuiImageAsync;
class GuiGameGrid : public GuiElement
{
public:
GuiGameGrid(int w, int h, struct discHdr * l, int gameCnt, const char *themePath, const u8 *imagebg, int selected = 0, int offset = 0);
~GuiGameGrid();
int FindMenuItem(int c, int d);
int GetClickedOption();
int GetSelectedOption();
void ResetState();
void SetFocus(int f);
void Draw();
void Update(GuiTrigger * t);
int GetOffset();
void Reload(struct discHdr * l, int count, int Rows, int ListOffset);
void ChangeRows(int n);
protected:
GuiImageData noCover;
int selectedItem;
int listOffset;
int pagesize;
int clickedItem;
int rows;
int goLeft;
int goRight;
struct discHdr * gameList;
int gameCnt;
int * gameIndex;
GuiButton ** game;
GuiTooltip ** titleTT;
GuiImageAsync ** coverImg;
GuiButton * btnRight;
GuiButton * btnLeft;
GuiButton * btnRowUp;
GuiButton * btnRowDown;
GuiImage * btnLeftImg;
GuiImage * btnRightImg;
GuiImageData * imgLeft;
GuiImageData * imgRight;
GuiSound * btnSoundOver;
GuiSound * btnSoundClick;
GuiTrigger * trigA;
GuiTrigger * trigL;
GuiTrigger * trigR;
GuiTrigger * trigPlus;
GuiTrigger * trigMinus;
GuiTrigger * trig1;
GuiTrigger * trig2;
};
#endif
#ifndef _GUIGAMEGRID_H_
#define _GUIGAMEGRID_H_
#include "gui.h"
#include "../usbloader/disc.h"
class GuiImageAsync;
class GuiGameGrid : public GuiElement
{
public:
GuiGameGrid(int w, int h, struct discHdr * l, int gameCnt, const char *themePath, const u8 *imagebg, int selected = 0, int offset = 0);
~GuiGameGrid();
int FindMenuItem(int c, int d);
int GetClickedOption();
int GetSelectedOption();
void ResetState();
void SetFocus(int f);
void Draw();
void Update(GuiTrigger * t);
int GetOffset();
void Reload(struct discHdr * l, int count, int Rows, int ListOffset);
void ChangeRows(int n);
protected:
GuiImageData noCover;
int selectedItem;
int listOffset;
int pagesize;
int clickedItem;
int rows;
int goLeft;
int goRight;
struct discHdr * gameList;
int gameCnt;
int * gameIndex;
GuiButton ** game;
GuiTooltip ** titleTT;
GuiImageAsync ** coverImg;
GuiButton * btnRight;
GuiButton * btnLeft;
GuiButton * btnRowUp;
GuiButton * btnRowDown;
GuiImage * btnLeftImg;
GuiImage * btnRightImg;
GuiImageData * imgLeft;
GuiImageData * imgRight;
GuiSound * btnSoundOver;
GuiSound * btnSoundClick;
GuiTrigger * trigA;
GuiTrigger * trigL;
GuiTrigger * trigR;
GuiTrigger * trigPlus;
GuiTrigger * trigMinus;
GuiTrigger * trig1;
GuiTrigger * trig2;
};
#endif

View File

@ -1,454 +1,454 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_image.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
/**
* Constructor for the GuiImage class.
*/
GuiImage::GuiImage()
{
image = NULL;
width = 0;
height = 0;
imageangle = 0;
tile = -1;
stripe = 0;
widescreen = 0;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_DATA;
}
GuiImage::GuiImage(GuiImageData * img)
{
if(img)
{
image = img->GetImage();
width = img->GetWidth();
height = img->GetHeight();
}
else
{
image = NULL;
width = 0;
height = 0;
}
imageangle = 0;
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_DATA;
}
GuiImage::GuiImage(u8 * img, int w, int h)
{
image = img;
width = w;
height = h;
imageangle = 0;
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_TEXTURE;
}
GuiImage::GuiImage(int w, int h, GXColor c)
{
image = (u8 *)memalign (32, w * h * 4);
width = w;
height = h;
imageangle = 0;
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COLOR;
if(!image)
return;
int x, y;
for(y=0; y < h; y++)
{
for(x=0; x < w; x++)
{
this->SetPixel(x, y, c);
}
}
int len = w*h*4;
if(len%32) len += (32-len%32);
DCFlushRange(image, len);
}
GuiImage::GuiImage(GuiImage &srcimage) : GuiElement()
{
width = srcimage.GetWidth();
height = srcimage.GetHeight();
int len = width * height * 4;
if(len%32) len += (32-len%32);
image = (u8 *)memalign (32, len);
memcpy(image, srcimage.GetImage(), len);
DCFlushRange(image, len);
imageangle = srcimage.GetAngle();
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COPY;
}
GuiImage::GuiImage(GuiImage *srcimage) : GuiElement()
{
width = srcimage->GetWidth();
height = srcimage->GetHeight();
int len = width * height * 4;
if(len%32) len += (32-len%32);
image = (u8 *)memalign (32, len);
memcpy(image, srcimage->GetImage(), len);
DCFlushRange(image, len);
imageangle = srcimage->GetAngle();
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COPY;
}
GuiImage &GuiImage::operator=(GuiImage &srcimage)
{
if((imgType == IMAGE_COLOR || imgType == IMAGE_COPY) && image) {
free(image);
image = NULL;
}
width = srcimage.GetWidth();
height = srcimage.GetHeight();
int len = width * height * 4;
if(len%32) len += (32-len%32);
image = (u8 *)memalign (32, len);
memcpy(image, srcimage.GetImage(), len);
DCFlushRange(image, len);
imageangle = srcimage.GetAngle();
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COPY;
return *this;
}
/**
* Destructor for the GuiImage class.
*/
GuiImage::~GuiImage()
{
if((imgType == IMAGE_COLOR || imgType == IMAGE_COPY) && image) {
free(image);
image = NULL;
}
}
u8 * GuiImage::GetImage()
{
return image;
}
void GuiImage::SetImage(GuiImageData * img)
{
LOCK(this);
if((imgType == IMAGE_COLOR || imgType == IMAGE_COPY) && image) {
free(image);
image = NULL;
}
image = img->GetImage();
width = img->GetWidth();
height = img->GetHeight();
imgType = IMAGE_DATA;
}
void GuiImage::SetImage(u8 * img, int w, int h)
{
LOCK(this);
if((imgType == IMAGE_COLOR || imgType == IMAGE_COPY) && image) {
free(image);
image = NULL;
}
image = img;
width = w;
height = h;
imgType = IMAGE_TEXTURE;
}
void GuiImage::SetAngle(float a)
{
LOCK(this);
imageangle = a;
}
float GuiImage::GetAngle()
{
return imageangle;
}
void GuiImage::SetTile(int t)
{
LOCK(this);
tile = t;
}
void GuiImage::SetWidescreen(bool w)
{
LOCK(this);
widescreen = w;
}
void GuiImage::SetParentAngle(bool a)
{
LOCK(this);
parentangle = a;
}
GXColor GuiImage::GetPixel(int x, int y)
{
if(!image || this->GetWidth() <= 0 || x < 0 || y < 0)
return (GXColor){0, 0, 0, 0};
u32 offset = (((y >> 2)<<4)*this->GetWidth()) + ((x >> 2)<<6) + (((y%4 << 2) + x%4 ) << 1);
GXColor color;
color.a = *(image+offset);
color.r = *(image+offset+1);
color.g = *(image+offset+32);
color.b = *(image+offset+33);
return color;
}
void GuiImage::SetPixel(int x, int y, GXColor color)
{
LOCK(this);
if(!image || this->GetWidth() <= 0 || x < 0 || y < 0)
return;
u32 offset = (((y >> 2)<<4)*this->GetWidth()) + ((x >> 2)<<6) + (((y%4 << 2) + x%4 ) << 1);
*(image+offset) = color.a;
*(image+offset+1) = color.r;
*(image+offset+32) = color.g;
*(image+offset+33) = color.b;
}
void GuiImage::SetGrayscale(void)
{
LOCK(this);
GXColor color;
u32 offset, gray;
for(int x = 0; x < width; x++) {
for(int y = 0; y < height; y++) {
offset = (((y >> 2)<<4)*width) + ((x >> 2)<<6) + (((y%4 << 2) + x%4 ) << 1);
color.r = *(image+offset+1);
color.g = *(image+offset+32);
color.b = *(image+offset+33);
gray = (77*color.r + 150*color.g + 28*color.b)/255;
*(image+offset+1) = gray;
*(image+offset+32) = gray;
*(image+offset+33) = gray;
}
}
}
void GuiImage::SetStripe(int s)
{
LOCK(this);
stripe = s;
}
void GuiImage::SetSkew(int XX1, int YY1,int XX2, int YY2,int XX3, int YY3,int XX4, int YY4)
{
xx1 = XX1;
yy1 = YY1;
xx2 = XX2;
yy2 = YY2;
xx3 = XX3;
yy3 = YY3;
xx4 = XX4;
yy4 = YY4;
}
void GuiImage::SetSkew(int *skew)
{
xx1 = *skew++;
yy1 = *skew++;
xx2 = *skew++;
yy2 = *skew++;
xx3 = *skew++;
yy3 = *skew++;
xx4 = *skew++;
yy4 = *skew;
}
void GuiImage::ColorStripe(int shift)
{
LOCK(this);
int x, y;
GXColor color;
int alt = 0;
for(y=0; y < this->GetHeight(); y++)
{
if(y % 3 == 0)
alt ^= 1;
for(x=0; x < this->GetWidth(); x++)
{
color = GetPixel(x, y);
if(alt)
{
if(color.r < 255-shift)
color.r += shift;
else
color.r = 255;
if(color.g < 255-shift)
color.g += shift;
else
color.g = 255;
if(color.b < 255-shift)
color.b += shift;
else
color.b = 255;
color.a = 255;
}
else
{
if(color.r > shift)
color.r -= shift;
else
color.r = 0;
if(color.g > shift)
color.g -= shift;
else
color.g = 0;
if(color.b > shift)
color.b -= shift;
else
color.b = 0;
color.a = 255;
}
SetPixel(x, y, color);
}
}
}
/**
* Draw the button on screen
*/
void GuiImage::Draw()
{
LOCK(this);
if(!image || !this->IsVisible() || tile == 0)
return;
float currScale = this->GetScale();
int currLeft = this->GetLeft();
float currAngleDyn = this->GetAngleDyn();
if(currAngleDyn && parentangle)
imageangle = currAngleDyn;
if(tile > 0)
{
for(int i=0; i<tile; i++)
Menu_DrawImg(currLeft+width*i, this->GetTop(), zoffset, width, height, image, imageangle, widescreen ? currScale*0.80 : currScale, currScale, this->GetAlpha(), xx1,yy1,xx2,yy2,xx3,yy3,xx4,yy4);
}
else
{
// temporary (maybe), used to correct offset for scaled images
if(scale != 1)
currLeft = currLeft - width/2 + (width*scale)/2;
Menu_DrawImg(currLeft, this->GetTop(), zoffset, width, height, image, imageangle, widescreen ? currScale*0.80 : currScale, currScale, this->GetAlpha(), xx1,yy1,xx2,yy2,xx3,yy3,xx4,yy4);
}
if(stripe > 0)
for(int y=0; y < this->GetHeight(); y+=6)
Menu_DrawRectangle(currLeft,this->GetTop()+y,this->GetWidth(),3,(GXColor){0, 0, 0, stripe},1);
this->UpdateEffects();
}
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_image.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
/**
* Constructor for the GuiImage class.
*/
GuiImage::GuiImage()
{
image = NULL;
width = 0;
height = 0;
imageangle = 0;
tile = -1;
stripe = 0;
widescreen = 0;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_DATA;
}
GuiImage::GuiImage(GuiImageData * img)
{
if(img)
{
image = img->GetImage();
width = img->GetWidth();
height = img->GetHeight();
}
else
{
image = NULL;
width = 0;
height = 0;
}
imageangle = 0;
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_DATA;
}
GuiImage::GuiImage(u8 * img, int w, int h)
{
image = img;
width = w;
height = h;
imageangle = 0;
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_TEXTURE;
}
GuiImage::GuiImage(int w, int h, GXColor c)
{
image = (u8 *)memalign (32, w * h * 4);
width = w;
height = h;
imageangle = 0;
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COLOR;
if(!image)
return;
int x, y;
for(y=0; y < h; y++)
{
for(x=0; x < w; x++)
{
this->SetPixel(x, y, c);
}
}
int len = w*h*4;
if(len%32) len += (32-len%32);
DCFlushRange(image, len);
}
GuiImage::GuiImage(GuiImage &srcimage) : GuiElement()
{
width = srcimage.GetWidth();
height = srcimage.GetHeight();
int len = width * height * 4;
if(len%32) len += (32-len%32);
image = (u8 *)memalign (32, len);
memcpy(image, srcimage.GetImage(), len);
DCFlushRange(image, len);
imageangle = srcimage.GetAngle();
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COPY;
}
GuiImage::GuiImage(GuiImage *srcimage) : GuiElement()
{
width = srcimage->GetWidth();
height = srcimage->GetHeight();
int len = width * height * 4;
if(len%32) len += (32-len%32);
image = (u8 *)memalign (32, len);
memcpy(image, srcimage->GetImage(), len);
DCFlushRange(image, len);
imageangle = srcimage->GetAngle();
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COPY;
}
GuiImage &GuiImage::operator=(GuiImage &srcimage)
{
if((imgType == IMAGE_COLOR || imgType == IMAGE_COPY) && image) {
free(image);
image = NULL;
}
width = srcimage.GetWidth();
height = srcimage.GetHeight();
int len = width * height * 4;
if(len%32) len += (32-len%32);
image = (u8 *)memalign (32, len);
memcpy(image, srcimage.GetImage(), len);
DCFlushRange(image, len);
imageangle = srcimage.GetAngle();
tile = -1;
stripe = 0;
widescreen = 0;
parentangle = true;
xx1 = 0;
yy1 = 0;
xx2 = 0;
yy2 = 0;
xx3 = 0;
yy3 = 0;
xx4 = 0;
yy4 = 0;
imgType = IMAGE_COPY;
return *this;
}
/**
* Destructor for the GuiImage class.
*/
GuiImage::~GuiImage()
{
if((imgType == IMAGE_COLOR || imgType == IMAGE_COPY) && image) {
free(image);
image = NULL;
}
}
u8 * GuiImage::GetImage()
{
return image;
}
void GuiImage::SetImage(GuiImageData * img)
{
LOCK(this);
if((imgType == IMAGE_COLOR || imgType == IMAGE_COPY) && image) {
free(image);
image = NULL;
}
image = img->GetImage();
width = img->GetWidth();
height = img->GetHeight();
imgType = IMAGE_DATA;
}
void GuiImage::SetImage(u8 * img, int w, int h)
{
LOCK(this);
if((imgType == IMAGE_COLOR || imgType == IMAGE_COPY) && image) {
free(image);
image = NULL;
}
image = img;
width = w;
height = h;
imgType = IMAGE_TEXTURE;
}
void GuiImage::SetAngle(float a)
{
LOCK(this);
imageangle = a;
}
float GuiImage::GetAngle()
{
return imageangle;
}
void GuiImage::SetTile(int t)
{
LOCK(this);
tile = t;
}
void GuiImage::SetWidescreen(bool w)
{
LOCK(this);
widescreen = w;
}
void GuiImage::SetParentAngle(bool a)
{
LOCK(this);
parentangle = a;
}
GXColor GuiImage::GetPixel(int x, int y)
{
if(!image || this->GetWidth() <= 0 || x < 0 || y < 0)
return (GXColor){0, 0, 0, 0};
u32 offset = (((y >> 2)<<4)*this->GetWidth()) + ((x >> 2)<<6) + (((y%4 << 2) + x%4 ) << 1);
GXColor color;
color.a = *(image+offset);
color.r = *(image+offset+1);
color.g = *(image+offset+32);
color.b = *(image+offset+33);
return color;
}
void GuiImage::SetPixel(int x, int y, GXColor color)
{
LOCK(this);
if(!image || this->GetWidth() <= 0 || x < 0 || y < 0)
return;
u32 offset = (((y >> 2)<<4)*this->GetWidth()) + ((x >> 2)<<6) + (((y%4 << 2) + x%4 ) << 1);
*(image+offset) = color.a;
*(image+offset+1) = color.r;
*(image+offset+32) = color.g;
*(image+offset+33) = color.b;
}
void GuiImage::SetGrayscale(void)
{
LOCK(this);
GXColor color;
u32 offset, gray;
for(int x = 0; x < width; x++) {
for(int y = 0; y < height; y++) {
offset = (((y >> 2)<<4)*width) + ((x >> 2)<<6) + (((y%4 << 2) + x%4 ) << 1);
color.r = *(image+offset+1);
color.g = *(image+offset+32);
color.b = *(image+offset+33);
gray = (77*color.r + 150*color.g + 28*color.b)/255;
*(image+offset+1) = gray;
*(image+offset+32) = gray;
*(image+offset+33) = gray;
}
}
}
void GuiImage::SetStripe(int s)
{
LOCK(this);
stripe = s;
}
void GuiImage::SetSkew(int XX1, int YY1,int XX2, int YY2,int XX3, int YY3,int XX4, int YY4)
{
xx1 = XX1;
yy1 = YY1;
xx2 = XX2;
yy2 = YY2;
xx3 = XX3;
yy3 = YY3;
xx4 = XX4;
yy4 = YY4;
}
void GuiImage::SetSkew(int *skew)
{
xx1 = *skew++;
yy1 = *skew++;
xx2 = *skew++;
yy2 = *skew++;
xx3 = *skew++;
yy3 = *skew++;
xx4 = *skew++;
yy4 = *skew;
}
void GuiImage::ColorStripe(int shift)
{
LOCK(this);
int x, y;
GXColor color;
int alt = 0;
for(y=0; y < this->GetHeight(); y++)
{
if(y % 3 == 0)
alt ^= 1;
for(x=0; x < this->GetWidth(); x++)
{
color = GetPixel(x, y);
if(alt)
{
if(color.r < 255-shift)
color.r += shift;
else
color.r = 255;
if(color.g < 255-shift)
color.g += shift;
else
color.g = 255;
if(color.b < 255-shift)
color.b += shift;
else
color.b = 255;
color.a = 255;
}
else
{
if(color.r > shift)
color.r -= shift;
else
color.r = 0;
if(color.g > shift)
color.g -= shift;
else
color.g = 0;
if(color.b > shift)
color.b -= shift;
else
color.b = 0;
color.a = 255;
}
SetPixel(x, y, color);
}
}
}
/**
* Draw the button on screen
*/
void GuiImage::Draw()
{
LOCK(this);
if(!image || !this->IsVisible() || tile == 0)
return;
float currScale = this->GetScale();
int currLeft = this->GetLeft();
float currAngleDyn = this->GetAngleDyn();
if(currAngleDyn && parentangle)
imageangle = currAngleDyn;
if(tile > 0)
{
for(int i=0; i<tile; i++)
Menu_DrawImg(currLeft+width*i, this->GetTop(), zoffset, width, height, image, imageangle, widescreen ? currScale*0.80 : currScale, currScale, this->GetAlpha(), xx1,yy1,xx2,yy2,xx3,yy3,xx4,yy4);
}
else
{
// temporary (maybe), used to correct offset for scaled images
if(scale != 1)
currLeft = currLeft - width/2 + (width*scale)/2;
Menu_DrawImg(currLeft, this->GetTop(), zoffset, width, height, image, imageangle, widescreen ? currScale*0.80 : currScale, currScale, this->GetAlpha(), xx1,yy1,xx2,yy2,xx3,yy3,xx4,yy4);
}
if(stripe > 0)
for(int y=0; y < this->GetHeight(); y+=6)
Menu_DrawRectangle(currLeft,this->GetTop()+y,this->GetWidth(),3,(GXColor){0, 0, 0, stripe},1);
this->UpdateEffects();
}

View File

@ -1,201 +1,201 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_imagedata.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
/**
* Constructor for the GuiImageData class.
*/
extern int idiotFlag;
extern char idiotChar[50];
GuiImageData::GuiImageData(const u8 * img)
{
data = NULL;
width = 0;
height = 0;
if(img)
{
PNGUPROP imgProp;
IMGCTX ctx = PNGU_SelectImageFromBuffer(img);
if(!ctx)
return;
int res = PNGU_GetImageProperties(ctx, &imgProp);
//if (((4%imgProp.imgWidth)!=0)||((4%imgProp.imgHeight)!=0))idiotFlag=1;
if(res == PNGU_OK)
{
int len = imgProp.imgWidth * imgProp.imgHeight * 4;
if(len%32) len += (32-len%32);
data = (u8 *)memalign (32, len);
if(data)
{
res = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, data, 255);
if(res == PNGU_OK)
{
width = imgProp.imgWidth;
height = imgProp.imgHeight;
DCFlushRange(data, len);
}
else
{
free(data);
data = NULL;
idiotFlag=1;
snprintf(idiotChar, sizeof(idiotChar), "%s", img);
}
}
}
PNGU_ReleaseImageContext (ctx);
}
}
/**
* Constructor for the GuiImageData class.
*/
GuiImageData::GuiImageData(const char * imgPath, const u8 * buffer)
{
data = NULL;
width = 0;
height = 0;
if(imgPath)
{
PNGUPROP imgProp;
IMGCTX ctx = PNGU_SelectImageFromDevice(imgPath);
//if (((4%imgProp.imgWidth)!=0)||((4%imgProp.imgHeight)!=0))idiotFlag=1;
if(ctx)
{
int res = PNGU_GetImageProperties(ctx, &imgProp);
if(res == PNGU_OK)
{
int len = imgProp.imgWidth * imgProp.imgHeight * 4;
if(len%32) len += (32-len%32);
data = (u8 *)memalign (32, len);
if(data)
{
res = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, data, 255);
if(res == PNGU_OK)
{
width = imgProp.imgWidth;
height = imgProp.imgHeight;
DCFlushRange(data, len);
}
else
{
free(data);
data = NULL;
idiotFlag=1;
snprintf(idiotChar, sizeof(idiotChar), "%s", imgPath);
}
}
}
PNGU_ReleaseImageContext (ctx);
}
}
if (!data) //use buffer data instead
{
width = 0;
height = 0;
if(buffer)
{
PNGUPROP imgProp;
IMGCTX ctx = PNGU_SelectImageFromBuffer(buffer);
if(!ctx)
return;
int res = PNGU_GetImageProperties(ctx, &imgProp);
if(res == PNGU_OK)
{
int len = imgProp.imgWidth * imgProp.imgHeight * 4;
if(len%32) len += (32-len%32);
data = (u8 *)memalign (32, len);
if(data)
{
res = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, data, 255);
if(res == PNGU_OK)
{
width = imgProp.imgWidth;
height = imgProp.imgHeight;
DCFlushRange(data, len);
}
else
{
free(data);
data = NULL;
}
}
}
PNGU_ReleaseImageContext (ctx);
}
}
}
/**
* Destructor for the GuiImageData class.
*/
GuiImageData::~GuiImageData()
{
if(data)
{
free(data);
data = NULL;
}
}
u8 * GuiImageData::GetImage()
{
return data;
}
int GuiImageData::GetWidth()
{
return width;
}
int GuiImageData::GetHeight()
{
return height;
}
void GuiImageData::SetGrayscale(void)
{
GXColor color;
u32 offset, gray;
for(int x = 0; x < width; x++) {
for(int y = 0; y < height; y++) {
offset = (((y >> 2)<<4)*width) + ((x >> 2)<<6) + (((y%4 << 2) + x%4 ) << 1);
color.r = *(data+offset+1);
color.g = *(data+offset+32);
color.b = *(data+offset+33);
gray = (77*color.r + 150*color.g + 28*color.b)/255;
*(data+offset+1) = gray;
*(data+offset+32) = gray;
*(data+offset+33) = gray;
}
}
}
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_imagedata.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
/**
* Constructor for the GuiImageData class.
*/
extern int idiotFlag;
extern char idiotChar[50];
GuiImageData::GuiImageData(const u8 * img)
{
data = NULL;
width = 0;
height = 0;
if(img)
{
PNGUPROP imgProp;
IMGCTX ctx = PNGU_SelectImageFromBuffer(img);
if(!ctx)
return;
int res = PNGU_GetImageProperties(ctx, &imgProp);
//if (((4%imgProp.imgWidth)!=0)||((4%imgProp.imgHeight)!=0))idiotFlag=1;
if(res == PNGU_OK)
{
int len = imgProp.imgWidth * imgProp.imgHeight * 4;
if(len%32) len += (32-len%32);
data = (u8 *)memalign (32, len);
if(data)
{
res = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, data, 255);
if(res == PNGU_OK)
{
width = imgProp.imgWidth;
height = imgProp.imgHeight;
DCFlushRange(data, len);
}
else
{
free(data);
data = NULL;
idiotFlag=1;
snprintf(idiotChar, sizeof(idiotChar), "%s", img);
}
}
}
PNGU_ReleaseImageContext (ctx);
}
}
/**
* Constructor for the GuiImageData class.
*/
GuiImageData::GuiImageData(const char * imgPath, const u8 * buffer)
{
data = NULL;
width = 0;
height = 0;
if(imgPath)
{
PNGUPROP imgProp;
IMGCTX ctx = PNGU_SelectImageFromDevice(imgPath);
//if (((4%imgProp.imgWidth)!=0)||((4%imgProp.imgHeight)!=0))idiotFlag=1;
if(ctx)
{
int res = PNGU_GetImageProperties(ctx, &imgProp);
if(res == PNGU_OK)
{
int len = imgProp.imgWidth * imgProp.imgHeight * 4;
if(len%32) len += (32-len%32);
data = (u8 *)memalign (32, len);
if(data)
{
res = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, data, 255);
if(res == PNGU_OK)
{
width = imgProp.imgWidth;
height = imgProp.imgHeight;
DCFlushRange(data, len);
}
else
{
free(data);
data = NULL;
idiotFlag=1;
snprintf(idiotChar, sizeof(idiotChar), "%s", imgPath);
}
}
}
PNGU_ReleaseImageContext (ctx);
}
}
if (!data) //use buffer data instead
{
width = 0;
height = 0;
if(buffer)
{
PNGUPROP imgProp;
IMGCTX ctx = PNGU_SelectImageFromBuffer(buffer);
if(!ctx)
return;
int res = PNGU_GetImageProperties(ctx, &imgProp);
if(res == PNGU_OK)
{
int len = imgProp.imgWidth * imgProp.imgHeight * 4;
if(len%32) len += (32-len%32);
data = (u8 *)memalign (32, len);
if(data)
{
res = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, data, 255);
if(res == PNGU_OK)
{
width = imgProp.imgWidth;
height = imgProp.imgHeight;
DCFlushRange(data, len);
}
else
{
free(data);
data = NULL;
}
}
}
PNGU_ReleaseImageContext (ctx);
}
}
}
/**
* Destructor for the GuiImageData class.
*/
GuiImageData::~GuiImageData()
{
if(data)
{
free(data);
data = NULL;
}
}
u8 * GuiImageData::GetImage()
{
return data;
}
int GuiImageData::GetWidth()
{
return width;
}
int GuiImageData::GetHeight()
{
return height;
}
void GuiImageData::SetGrayscale(void)
{
GXColor color;
u32 offset, gray;
for(int x = 0; x < width; x++) {
for(int y = 0; y < height; y++) {
offset = (((y >> 2)<<4)*width) + ((x >> 2)<<6) + (((y%4 << 2) + x%4 ) << 1);
color.r = *(data+offset+1);
color.g = *(data+offset+32);
color.b = *(data+offset+33);
gray = (77*color.r + 150*color.g + 28*color.b)/255;
*(data+offset+1) = gray;
*(data+offset+32) = gray;
*(data+offset+33) = gray;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,195 +1,195 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_sound.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
/**
* Constructor for the GuiSound class.
*/
GuiSound::GuiSound(const u8 * snd, s32 len, int t)
{
sound = snd;
length = len;
type = t;
voice = -1;
volume = 100;
loop = false;
}
GuiSound::GuiSound(const u8 * snd, s32 len, int t, int v)
{
sound = snd;
length = len;
type = t;
voice = -1;
volume = v;
loop = false;
}
/**
* Destructor for the GuiSound class.
*/
GuiSound::~GuiSound()
{
if(type == SOUND_OGG)
StopOgg();
}
int GuiSound::PlayOggFile(char * path)
{ /*
u32 filesize = 0;
char * bufferogg = NULL;
size_t resultogg;
FILE * pFile;
pFile = fopen (path, "rb");
// get file size:
fseek (pFile , 0 , SEEK_END);
filesize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
bufferogg = (char*) malloc (sizeof(char)*filesize);
if (bufferogg == NULL) {fputs (" Memory error",stderr); exit (2);}
// copy the file into the buffer:
resultogg = fread (bufferogg,1,filesize,pFile);
if (resultogg != filesize) {fputs (" Reading error",stderr); exit (3);}
fclose (pFile);
sound = (const u8 *) bufferogg;
length = filesize;
*/
int ret = PlayOggFromFile(path, loop);
SetVolumeOgg(255*(volume/100.0));
return ret;
}
void GuiSound::Play()
{
int vol;
switch(type)
{
case SOUND_PCM:
vol = 255*(volume/100.0);
voice = ASND_GetFirstUnusedVoice();
if(voice >= 0)
ASND_SetVoice(voice, VOICE_STEREO_16BIT, 48000, 0,
(u8 *)sound, length, vol, vol, NULL);
break;
case SOUND_OGG:
voice = 0;
if(loop)
PlayOgg(mem_open((char *)sound, length), 0, OGG_INFINITE_TIME);
else
PlayOgg(mem_open((char *)sound, length), 0, OGG_ONE_TIME);
SetVolumeOgg(255*(volume/100.0));
break;
}
}
void GuiSound::Stop()
{
if(voice < 0)
return;
switch(type)
{
case SOUND_PCM:
ASND_StopVoice(voice);
break;
case SOUND_OGG:
StopOgg();
break;
}
}
void GuiSound::Pause()
{
if(voice < 0)
return;
switch(type)
{
case SOUND_PCM:
ASND_PauseVoice(voice, 1);
break;
case SOUND_OGG:
PauseOgg(1);
break;
}
}
void GuiSound::Resume()
{
if(voice < 0)
return;
switch(type)
{
case SOUND_PCM:
ASND_PauseVoice(voice, 0);
break;
case SOUND_OGG:
PauseOgg(0);
break;
}
}
bool GuiSound::IsPlaying()
{
if(ASND_StatusVoice(voice) == SND_WORKING || ASND_StatusVoice(voice) == SND_WAITING)
return true;
else
return false;
}
void GuiSound::SetVolume(int vol)
{
volume = vol;
if(voice < 0)
return;
int newvol = 255*(volume/100.0);
switch(type)
{
case SOUND_PCM:
ASND_ChangeVolumeVoice(voice, newvol, newvol);
break;
case SOUND_OGG:
SetVolumeOgg(255*(volume/100.0));
break;
}
}
void GuiSound::SetLoop(bool l)
{
loop = l;
}
s32 GuiSound::GetPlayTime()
{
return GetTimeOgg();
}
void GuiSound::SetPlayTime(s32 time_pos)
{
SetTimeOgg(time_pos);
}
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_sound.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
/**
* Constructor for the GuiSound class.
*/
GuiSound::GuiSound(const u8 * snd, s32 len, int t)
{
sound = snd;
length = len;
type = t;
voice = -1;
volume = 100;
loop = false;
}
GuiSound::GuiSound(const u8 * snd, s32 len, int t, int v)
{
sound = snd;
length = len;
type = t;
voice = -1;
volume = v;
loop = false;
}
/**
* Destructor for the GuiSound class.
*/
GuiSound::~GuiSound()
{
if(type == SOUND_OGG)
StopOgg();
}
int GuiSound::PlayOggFile(char * path)
{ /*
u32 filesize = 0;
char * bufferogg = NULL;
size_t resultogg;
FILE * pFile;
pFile = fopen (path, "rb");
// get file size:
fseek (pFile , 0 , SEEK_END);
filesize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
bufferogg = (char*) malloc (sizeof(char)*filesize);
if (bufferogg == NULL) {fputs (" Memory error",stderr); exit (2);}
// copy the file into the buffer:
resultogg = fread (bufferogg,1,filesize,pFile);
if (resultogg != filesize) {fputs (" Reading error",stderr); exit (3);}
fclose (pFile);
sound = (const u8 *) bufferogg;
length = filesize;
*/
int ret = PlayOggFromFile(path, loop);
SetVolumeOgg(255*(volume/100.0));
return ret;
}
void GuiSound::Play()
{
int vol;
switch(type)
{
case SOUND_PCM:
vol = 255*(volume/100.0);
voice = ASND_GetFirstUnusedVoice();
if(voice >= 0)
ASND_SetVoice(voice, VOICE_STEREO_16BIT, 48000, 0,
(u8 *)sound, length, vol, vol, NULL);
break;
case SOUND_OGG:
voice = 0;
if(loop)
PlayOgg(mem_open((char *)sound, length), 0, OGG_INFINITE_TIME);
else
PlayOgg(mem_open((char *)sound, length), 0, OGG_ONE_TIME);
SetVolumeOgg(255*(volume/100.0));
break;
}
}
void GuiSound::Stop()
{
if(voice < 0)
return;
switch(type)
{
case SOUND_PCM:
ASND_StopVoice(voice);
break;
case SOUND_OGG:
StopOgg();
break;
}
}
void GuiSound::Pause()
{
if(voice < 0)
return;
switch(type)
{
case SOUND_PCM:
ASND_PauseVoice(voice, 1);
break;
case SOUND_OGG:
PauseOgg(1);
break;
}
}
void GuiSound::Resume()
{
if(voice < 0)
return;
switch(type)
{
case SOUND_PCM:
ASND_PauseVoice(voice, 0);
break;
case SOUND_OGG:
PauseOgg(0);
break;
}
}
bool GuiSound::IsPlaying()
{
if(ASND_StatusVoice(voice) == SND_WORKING || ASND_StatusVoice(voice) == SND_WAITING)
return true;
else
return false;
}
void GuiSound::SetVolume(int vol)
{
volume = vol;
if(voice < 0)
return;
int newvol = 255*(volume/100.0);
switch(type)
{
case SOUND_PCM:
ASND_ChangeVolumeVoice(voice, newvol, newvol);
break;
case SOUND_OGG:
SetVolumeOgg(255*(volume/100.0));
break;
}
}
void GuiSound::SetLoop(bool l)
{
loop = l;
}
s32 GuiSound::GetPlayTime()
{
return GetTimeOgg();
}
void GuiSound::SetPlayTime(s32 time_pos)
{
SetTimeOgg(time_pos);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,91 +1,91 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_tooltip.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
static GuiImageData tooltipLeft(tooltip_left_png);
static GuiImageData tooltipTile(tooltip_tile_png);
static GuiImageData tooltipRight(tooltip_right_png);
/**
* Constructor for the GuiTooltip class.
*/
GuiTooltip::GuiTooltip(const char *t, int Alpha/*=255*/)
:
leftImage(&tooltipLeft), tileImage(&tooltipTile), rightImage(&tooltipRight)
{
text = NULL;
height = leftImage.GetHeight();
leftImage.SetParent(this);
tileImage.SetParent(this);
rightImage.SetParent(this);
leftImage.SetParentAngle(false);
tileImage.SetParentAngle(false);
rightImage.SetParentAngle(false);
SetText(t);
SetAlpha(Alpha);
}
/*
* Destructor for the GuiTooltip class.
*/
GuiTooltip::~GuiTooltip()
{
if(text) delete text;
}
float GuiTooltip::GetScale()
{
float s = scale * scaleDyn;
return s;
}
/* !Sets the text of the GuiTooltip element
* !\param t Text
*/
void GuiTooltip::SetText(const char * t)
{
LOCK(this);
if(text)
{
delete text;
text = NULL;
}
int tile_cnt = 0;
if(t && (text = new GuiText(t, 22, (GXColor){0, 0, 0, 255})))
{
text->SetParent(this);
tile_cnt = (text->GetTextWidth()-12) /tileImage.GetWidth();
if(tile_cnt < 0) tile_cnt = 0;
}
tileImage.SetPosition(leftImage.GetWidth(), 0);
tileImage.SetTile(tile_cnt);
rightImage.SetPosition(leftImage.GetWidth() + tile_cnt * tileImage.GetWidth(), 0);
width = leftImage.GetWidth() + tile_cnt * tileImage.GetWidth() + rightImage.GetWidth();
}
void GuiTooltip::SetWidescreen(bool){}
/*
* Draw the Tooltip on screen
*/
void GuiTooltip::Draw()
{
LOCK(this);
if(!this->IsVisible()) return;
leftImage.Draw();
tileImage.Draw();
rightImage.Draw();
if(text) text->Draw();
this->UpdateEffects();
}
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_tooltip.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
static GuiImageData tooltipLeft(tooltip_left_png);
static GuiImageData tooltipTile(tooltip_tile_png);
static GuiImageData tooltipRight(tooltip_right_png);
/**
* Constructor for the GuiTooltip class.
*/
GuiTooltip::GuiTooltip(const char *t, int Alpha/*=255*/)
:
leftImage(&tooltipLeft), tileImage(&tooltipTile), rightImage(&tooltipRight)
{
text = NULL;
height = leftImage.GetHeight();
leftImage.SetParent(this);
tileImage.SetParent(this);
rightImage.SetParent(this);
leftImage.SetParentAngle(false);
tileImage.SetParentAngle(false);
rightImage.SetParentAngle(false);
SetText(t);
SetAlpha(Alpha);
}
/*
* Destructor for the GuiTooltip class.
*/
GuiTooltip::~GuiTooltip()
{
if(text) delete text;
}
float GuiTooltip::GetScale()
{
float s = scale * scaleDyn;
return s;
}
/* !Sets the text of the GuiTooltip element
* !\param t Text
*/
void GuiTooltip::SetText(const char * t)
{
LOCK(this);
if(text)
{
delete text;
text = NULL;
}
int tile_cnt = 0;
if(t && (text = new GuiText(t, 22, (GXColor){0, 0, 0, 255})))
{
text->SetParent(this);
tile_cnt = (text->GetTextWidth()-12) /tileImage.GetWidth();
if(tile_cnt < 0) tile_cnt = 0;
}
tileImage.SetPosition(leftImage.GetWidth(), 0);
tileImage.SetTile(tile_cnt);
rightImage.SetPosition(leftImage.GetWidth() + tile_cnt * tileImage.GetWidth(), 0);
width = leftImage.GetWidth() + tile_cnt * tileImage.GetWidth() + rightImage.GetWidth();
}
void GuiTooltip::SetWidescreen(bool){}
/*
* Draw the Tooltip on screen
*/
void GuiTooltip::Draw()
{
LOCK(this);
if(!this->IsVisible()) return;
leftImage.Draw();
tileImage.Draw();
rightImage.Draw();
if(text) text->Draw();
this->UpdateEffects();
}

View File

@ -1,255 +1,255 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_trigger.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
static int scrollDelay = 0;
/**
* Constructor for the GuiTrigger class.
*/
GuiTrigger::GuiTrigger()
{
chan = -1;
memset(&wpad, 0, sizeof(WPADData));
memset(&pad, 0, sizeof(PADData));
}
/**
* Destructor for the GuiTrigger class.
*/
GuiTrigger::~GuiTrigger()
{
}
/**
* Sets a simple trigger. Requires:
* - Element is selected
* - Trigger button is pressed
*/
void GuiTrigger::SetSimpleTrigger(s32 ch, u32 wiibtns, u16 gcbtns)
{
type = TRIGGER_SIMPLE;
chan = ch;
wpad.btns_d = wiibtns;
pad.btns_d = gcbtns;
}
/**
* Sets a held trigger. Requires:
* - Element is selected
* - Trigger button is pressed and held
*/
void GuiTrigger::SetHeldTrigger(s32 ch, u32 wiibtns, u16 gcbtns)
{
type = TRIGGER_HELD;
chan = ch;
wpad.btns_h = wiibtns;
pad.btns_h = gcbtns;
}
/**
* Sets a button trigger. Requires:
* - Trigger button is pressed
*/
void GuiTrigger::SetButtonOnlyTrigger(s32 ch, u32 wiibtns, u16 gcbtns)
{
type = TRIGGER_BUTTON_ONLY;
chan = ch;
wpad.btns_d = wiibtns;
pad.btns_d = gcbtns;
}
/**
* Sets a button trigger. Requires:
* - Trigger button is pressed
* - Parent window is in focus
*/
void GuiTrigger::SetButtonOnlyInFocusTrigger(s32 ch, u32 wiibtns, u16 gcbtns)
{
type = TRIGGER_BUTTON_ONLY_IN_FOCUS;
chan = ch;
wpad.btns_d = wiibtns;
pad.btns_d = gcbtns;
}
/****************************************************************************
* WPAD_Stick
*
* Get X/Y value from Wii Joystick (classic, nunchuk) input
***************************************************************************/
s8 GuiTrigger::WPAD_Stick(u8 right, int axis)
{
#ifdef HW_RVL
float mag = 0.0;
float ang = 0.0;
switch (wpad.exp.type)
{
case WPAD_EXP_NUNCHUK:
case WPAD_EXP_GUITARHERO3:
if (right == 0)
{
mag = wpad.exp.nunchuk.js.mag;
ang = wpad.exp.nunchuk.js.ang;
}
break;
case WPAD_EXP_CLASSIC:
if (right == 0)
{
mag = wpad.exp.classic.ljs.mag;
ang = wpad.exp.classic.ljs.ang;
}
else
{
mag = wpad.exp.classic.rjs.mag;
ang = wpad.exp.classic.rjs.ang;
}
break;
default:
break;
}
/* calculate x/y value (angle need to be converted into radian) */
if (mag > 1.0) mag = 1.0;
else if (mag < -1.0) mag = -1.0;
double val;
if(axis == 0) // x-axis
val = mag * sin((PI * ang)/180.0f);
else // y-axis
val = mag * cos((PI * ang)/180.0f);
return (s8)(val * 128.0f);
#else
return 0;
#endif
}
bool GuiTrigger::Left()
{
u32 wiibtn = WPAD_BUTTON_LEFT;
if((wpad.btns_d | wpad.btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_LEFT)
|| (pad.btns_d | pad.btns_h) & PAD_BUTTON_LEFT
|| pad.stickX < -PADCAL
|| WPAD_Stick(0,0) < -PADCAL)
{
if(wpad.btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_LEFT)
|| pad.btns_d & PAD_BUTTON_LEFT)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
return true;
}
else if(scrollDelay == 0)
{
scrollDelay = SCROLL_LOOP_DELAY;
return true;
}
else
{
if(scrollDelay > 0)
scrollDelay--;
}
}
return false;
}
bool GuiTrigger::Right()
{
u32 wiibtn = WPAD_BUTTON_RIGHT;
if((wpad.btns_d | wpad.btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_RIGHT)
|| (pad.btns_d | pad.btns_h) & PAD_BUTTON_RIGHT
|| pad.stickX > PADCAL
|| WPAD_Stick(0,0) > PADCAL)
{
if(wpad.btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_RIGHT)
|| pad.btns_d & PAD_BUTTON_RIGHT)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
return true;
}
else if(scrollDelay == 0)
{
scrollDelay = SCROLL_LOOP_DELAY;
return true;
}
else
{
if(scrollDelay > 0)
scrollDelay--;
}
}
return false;
}
bool GuiTrigger::Up()
{
u32 wiibtn = WPAD_BUTTON_UP;
if((wpad.btns_d | wpad.btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_UP)
|| (pad.btns_d | pad.btns_h) & PAD_BUTTON_UP
|| pad.stickY > PADCAL
|| WPAD_Stick(0,1) > PADCAL)
{
if(wpad.btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_UP)
|| pad.btns_d & PAD_BUTTON_UP)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
return true;
}
else if(scrollDelay == 0)
{
scrollDelay = SCROLL_LOOP_DELAY;
return true;
}
else
{
if(scrollDelay > 0)
scrollDelay--;
}
}
return false;
}
bool GuiTrigger::Down()
{
u32 wiibtn = WPAD_BUTTON_DOWN;
if((wpad.btns_d | wpad.btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_DOWN)
|| (pad.btns_d | pad.btns_h) & PAD_BUTTON_DOWN
|| pad.stickY < -PADCAL
|| WPAD_Stick(0,1) < -PADCAL)
{
if(wpad.btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_DOWN)
|| pad.btns_d & PAD_BUTTON_DOWN)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
return true;
}
else if(scrollDelay == 0)
{
scrollDelay = SCROLL_LOOP_DELAY;
return true;
}
else
{
if(scrollDelay > 0)
scrollDelay--;
}
}
return false;
}
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_trigger.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
static int scrollDelay = 0;
/**
* Constructor for the GuiTrigger class.
*/
GuiTrigger::GuiTrigger()
{
chan = -1;
memset(&wpad, 0, sizeof(WPADData));
memset(&pad, 0, sizeof(PADData));
}
/**
* Destructor for the GuiTrigger class.
*/
GuiTrigger::~GuiTrigger()
{
}
/**
* Sets a simple trigger. Requires:
* - Element is selected
* - Trigger button is pressed
*/
void GuiTrigger::SetSimpleTrigger(s32 ch, u32 wiibtns, u16 gcbtns)
{
type = TRIGGER_SIMPLE;
chan = ch;
wpad.btns_d = wiibtns;
pad.btns_d = gcbtns;
}
/**
* Sets a held trigger. Requires:
* - Element is selected
* - Trigger button is pressed and held
*/
void GuiTrigger::SetHeldTrigger(s32 ch, u32 wiibtns, u16 gcbtns)
{
type = TRIGGER_HELD;
chan = ch;
wpad.btns_h = wiibtns;
pad.btns_h = gcbtns;
}
/**
* Sets a button trigger. Requires:
* - Trigger button is pressed
*/
void GuiTrigger::SetButtonOnlyTrigger(s32 ch, u32 wiibtns, u16 gcbtns)
{
type = TRIGGER_BUTTON_ONLY;
chan = ch;
wpad.btns_d = wiibtns;
pad.btns_d = gcbtns;
}
/**
* Sets a button trigger. Requires:
* - Trigger button is pressed
* - Parent window is in focus
*/
void GuiTrigger::SetButtonOnlyInFocusTrigger(s32 ch, u32 wiibtns, u16 gcbtns)
{
type = TRIGGER_BUTTON_ONLY_IN_FOCUS;
chan = ch;
wpad.btns_d = wiibtns;
pad.btns_d = gcbtns;
}
/****************************************************************************
* WPAD_Stick
*
* Get X/Y value from Wii Joystick (classic, nunchuk) input
***************************************************************************/
s8 GuiTrigger::WPAD_Stick(u8 right, int axis)
{
#ifdef HW_RVL
float mag = 0.0;
float ang = 0.0;
switch (wpad.exp.type)
{
case WPAD_EXP_NUNCHUK:
case WPAD_EXP_GUITARHERO3:
if (right == 0)
{
mag = wpad.exp.nunchuk.js.mag;
ang = wpad.exp.nunchuk.js.ang;
}
break;
case WPAD_EXP_CLASSIC:
if (right == 0)
{
mag = wpad.exp.classic.ljs.mag;
ang = wpad.exp.classic.ljs.ang;
}
else
{
mag = wpad.exp.classic.rjs.mag;
ang = wpad.exp.classic.rjs.ang;
}
break;
default:
break;
}
/* calculate x/y value (angle need to be converted into radian) */
if (mag > 1.0) mag = 1.0;
else if (mag < -1.0) mag = -1.0;
double val;
if(axis == 0) // x-axis
val = mag * sin((PI * ang)/180.0f);
else // y-axis
val = mag * cos((PI * ang)/180.0f);
return (s8)(val * 128.0f);
#else
return 0;
#endif
}
bool GuiTrigger::Left()
{
u32 wiibtn = WPAD_BUTTON_LEFT;
if((wpad.btns_d | wpad.btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_LEFT)
|| (pad.btns_d | pad.btns_h) & PAD_BUTTON_LEFT
|| pad.stickX < -PADCAL
|| WPAD_Stick(0,0) < -PADCAL)
{
if(wpad.btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_LEFT)
|| pad.btns_d & PAD_BUTTON_LEFT)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
return true;
}
else if(scrollDelay == 0)
{
scrollDelay = SCROLL_LOOP_DELAY;
return true;
}
else
{
if(scrollDelay > 0)
scrollDelay--;
}
}
return false;
}
bool GuiTrigger::Right()
{
u32 wiibtn = WPAD_BUTTON_RIGHT;
if((wpad.btns_d | wpad.btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_RIGHT)
|| (pad.btns_d | pad.btns_h) & PAD_BUTTON_RIGHT
|| pad.stickX > PADCAL
|| WPAD_Stick(0,0) > PADCAL)
{
if(wpad.btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_RIGHT)
|| pad.btns_d & PAD_BUTTON_RIGHT)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
return true;
}
else if(scrollDelay == 0)
{
scrollDelay = SCROLL_LOOP_DELAY;
return true;
}
else
{
if(scrollDelay > 0)
scrollDelay--;
}
}
return false;
}
bool GuiTrigger::Up()
{
u32 wiibtn = WPAD_BUTTON_UP;
if((wpad.btns_d | wpad.btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_UP)
|| (pad.btns_d | pad.btns_h) & PAD_BUTTON_UP
|| pad.stickY > PADCAL
|| WPAD_Stick(0,1) > PADCAL)
{
if(wpad.btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_UP)
|| pad.btns_d & PAD_BUTTON_UP)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
return true;
}
else if(scrollDelay == 0)
{
scrollDelay = SCROLL_LOOP_DELAY;
return true;
}
else
{
if(scrollDelay > 0)
scrollDelay--;
}
}
return false;
}
bool GuiTrigger::Down()
{
u32 wiibtn = WPAD_BUTTON_DOWN;
if((wpad.btns_d | wpad.btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_DOWN)
|| (pad.btns_d | pad.btns_h) & PAD_BUTTON_DOWN
|| pad.stickY < -PADCAL
|| WPAD_Stick(0,1) < -PADCAL)
{
if(wpad.btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_DOWN)
|| pad.btns_d & PAD_BUTTON_DOWN)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
return true;
}
else if(scrollDelay == 0)
{
scrollDelay = SCROLL_LOOP_DELAY;
return true;
}
else
{
if(scrollDelay > 0)
scrollDelay--;
}
}
return false;
}

View File

@ -1,430 +1,430 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_window.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
GuiWindow::GuiWindow()
{
width = 0;
height = 0;
focus = 0; // allow focus
}
GuiWindow::GuiWindow(int w, int h)
{
width = w;
height = h;
focus = 0; // allow focus
}
GuiWindow::~GuiWindow()
{
}
void GuiWindow::Append(GuiElement* e)
{
LOCK(this);
if (e == NULL)
return;
Remove(e);
_elements.push_back(e);
e->SetParent(this);
}
void GuiWindow::Insert(GuiElement* e, u32 index)
{
LOCK(this);
if (e == NULL || index > (_elements.size() - 1))
return;
Remove(e);
_elements.insert(_elements.begin()+index, e);
e->SetParent(this);
}
void GuiWindow::Remove(GuiElement* e)
{
LOCK(this);
if (e == NULL)
return;
for (u8 i = 0; i < _elements.size(); i++)
{
if(e == _elements.at(i))
{
_elements.erase(_elements.begin()+i);
break;
}
}
}
void GuiWindow::RemoveAll()
{
LOCK(this);
_elements.clear();
}
GuiElement* GuiWindow::GetGuiElementAt(u32 index) const
{
if (index >= _elements.size())
return NULL;
return _elements.at(index);
}
u32 GuiWindow::GetSize()
{
return _elements.size();
}
void GuiWindow::Draw()
{
LOCK(this);
if(_elements.size() == 0 || !this->IsVisible())
return;
for (u8 i = 0; i < _elements.size(); i++)
{
try { _elements.at(i)->Draw(); }
catch (const std::exception& e) { }
}
this->UpdateEffects();
if(parentElement && state == STATE_DISABLED)
//Menu_DrawRectangle(0,0,screenwidth,screenheight,(GXColor){0xbe, 0xca, 0xd5, 0x70},1);
Menu_DrawRectangle(0,0,screenwidth,screenheight,(GXColor){0, 0, 0, 0x70},1);
}
void GuiWindow::DrawTooltip()
{
LOCK(this);
if(_elements.size() == 0 || !this->IsVisible())
return;
for (u8 i = 0; i < _elements.size(); i++)
{
try { _elements.at(i)->DrawTooltip(); }
catch (const std::exception& e) { }
}
}
void GuiWindow::ResetState()
{
LOCK(this);
if(state != STATE_DISABLED)
state = STATE_DEFAULT;
for (u8 i = 0; i < _elements.size(); i++)
{
try { _elements.at(i)->ResetState(); }
catch (const std::exception& e) { }
}
}
void GuiWindow::SetState(int s)
{
LOCK(this);
state = s;
for (u8 i = 0; i < _elements.size(); i++)
{
try { _elements.at(i)->SetState(s); }
catch (const std::exception& e) { }
}
}
void GuiWindow::SetVisible(bool v)
{
LOCK(this);
visible = v;
for (u8 i = 0; i < _elements.size(); i++)
{
try { _elements.at(i)->SetVisible(v); }
catch (const std::exception& e) { }
}
}
void GuiWindow::SetFocus(int f)
{
LOCK(this);
focus = f;
if(f == 1)
this->MoveSelectionVert(1);
else
this->ResetState();
}
void GuiWindow::ChangeFocus(GuiElement* e)
{
LOCK(this);
if(parentElement)
return; // this is only intended for the main window
for (u8 i = 0; i < _elements.size(); i++)
{
if(e == _elements.at(i))
_elements.at(i)->SetFocus(1);
else if(_elements.at(i)->IsFocused() == 1)
_elements.at(i)->SetFocus(0);
}
}
void GuiWindow::ToggleFocus(GuiTrigger * t)
{
LOCK(this);
if(parentElement)
return; // this is only intended for the main window
int found = -1;
int newfocus = -1;
u8 i;
// look for currently in focus element
for (i = 0; i < _elements.size(); i++)
{
try
{
if(_elements.at(i)->IsFocused() == 1)
{
found = i;
break;
}
}
catch (const std::exception& e) { }
}
// element with focus not found, try to give focus
if(found == -1)
{
for (i = 0; i < _elements.size(); i++)
{
try
{
if(_elements.at(i)->IsFocused() == 0 && _elements.at(i)->GetState() != STATE_DISABLED) // focus is possible (but not set)
{
_elements.at(i)->SetFocus(1); // give this element focus
break;
}
}
catch (const std::exception& e) { }
}
}
// change focus
else if(t->wpad.btns_d & (WPAD_BUTTON_1 | WPAD_BUTTON_1 | WPAD_CLASSIC_BUTTON_PLUS)
|| t->pad.btns_d & PAD_BUTTON_B)
{
for (i = found; i < _elements.size(); i++)
{
try
{
if(_elements.at(i)->IsFocused() == 0 && _elements.at(i)->GetState() != STATE_DISABLED) // focus is possible (but not set)
{
newfocus = i;
_elements.at(i)->SetFocus(1); // give this element focus
_elements.at(found)->SetFocus(0); // disable focus on other element
break;
}
}
catch (const std::exception& e) { }
}
if(newfocus == -1)
{
for (i = 0; i < found; i++)
{
try
{
if(_elements.at(i)->IsFocused() == 0 && _elements.at(i)->GetState() != STATE_DISABLED) // focus is possible (but not set)
{
_elements.at(i)->SetFocus(1); // give this element focus
_elements.at(found)->SetFocus(0); // disable focus on other element
break;
}
}
catch (const std::exception& e) { }
}
}
}
}
int GuiWindow::GetSelected()
{
// find selected element
int found = -1;
for (u8 i = 0; i < _elements.size(); i++)
{
try
{
if(_elements.at(i)->GetState() == STATE_SELECTED)
{
found = i;
break;
}
}
catch (const std::exception& e) { }
}
return found;
}
// set element to left/right as selected
// there's probably a more clever way to do this, but this way works
void GuiWindow::MoveSelectionHor(int dir)
{
LOCK(this);
int found = -1;
u16 left = 0;
u16 top = 0;
u8 i = 0;
int selected = this->GetSelected();
if(selected >= 0)
{
left = _elements.at(selected)->GetLeft();
top = _elements.at(selected)->GetTop();
}
// look for a button on the same row, to the left/right
for (i = 0; i < _elements.size(); i++)
{
try
{
if(_elements.at(i)->IsSelectable())
{
if(_elements.at(i)->GetLeft()*dir > left*dir && _elements.at(i)->GetTop() == top)
{
if(found == -1)
found = i;
else if(_elements.at(i)->GetLeft()*dir < _elements.at(found)->GetLeft()*dir)
found = i; // this is a better match
}
}
}
catch (const std::exception& e) { }
}
if(found >= 0)
goto matchfound;
// match still not found, let's try the first button in the next row
for (i = 0; i < _elements.size(); i++)
{
try
{
if(_elements.at(i)->IsSelectable())
{
if(_elements.at(i)->GetTop()*dir > top*dir)
{
if(found == -1)
found = i;
else if(_elements.at(i)->GetTop()*dir < _elements.at(found)->GetTop()*dir)
found = i; // this is a better match
else if(_elements.at(i)->GetTop()*dir == _elements.at(found)->GetTop()*dir
&&
_elements.at(i)->GetLeft()*dir < _elements.at(found)->GetLeft()*dir)
found = i; // this is a better match
}
}
}
catch (const std::exception& e) { }
}
// match found
matchfound:
if(found >= 0)
{
_elements.at(found)->SetState(STATE_SELECTED);
if(selected >= 0)
_elements.at(selected)->ResetState();
}
}
void GuiWindow::MoveSelectionVert(int dir)
{
LOCK(this);
int found = -1;
u16 left = 0;
u16 top = 0;
u8 i = 0;
int selected = this->GetSelected();
if(selected >= 0)
{
left = _elements.at(selected)->GetLeft();
top = _elements.at(selected)->GetTop();
}
// look for a button above/below, with the least horizontal difference
for (i = 0; i < _elements.size(); i++)
{
try
{
if(_elements.at(i)->IsSelectable())
{
if(_elements.at(i)->GetTop()*dir > top*dir)
{
if(found == -1)
found = i;
else if(_elements.at(i)->GetTop()*dir < _elements.at(found)->GetTop()*dir)
found = i; // this is a better match
else if(_elements.at(i)->GetTop()*dir == _elements.at(found)->GetTop()*dir
&&
abs(_elements.at(i)->GetLeft() - left) <
abs(_elements.at(found)->GetLeft() - left))
found = i;
}
}
}
catch (const std::exception& e) { }
}
if(found >= 0)
goto matchfound;
// match found
matchfound:
if(found >= 0)
{
_elements.at(found)->SetState(STATE_SELECTED);
if(selected >= 0)
_elements.at(selected)->ResetState();
}
}
void GuiWindow::Update(GuiTrigger * t)
{
LOCK(this);
if(_elements.size() == 0 || (state == STATE_DISABLED && parentElement))
return;
for (u8 i = 0; i < _elements.size(); i++)
{
try { _elements.at(i)->Update(t); }
catch (const std::exception& e) { }
}
this->ToggleFocus(t);
if(focus) // only send actions to this window if it's in focus
{
// pad/joystick navigation
if(t->Right())
this->MoveSelectionHor(1);
else if(t->Left())
this->MoveSelectionHor(-1);
else if(t->Down())
this->MoveSelectionVert(1);
else if(t->Up())
this->MoveSelectionVert(-1);
}
if(updateCB)
updateCB(this);
}
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_window.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
GuiWindow::GuiWindow()
{
width = 0;
height = 0;
focus = 0; // allow focus
}
GuiWindow::GuiWindow(int w, int h)
{
width = w;
height = h;
focus = 0; // allow focus
}
GuiWindow::~GuiWindow()
{
}
void GuiWindow::Append(GuiElement* e)
{
LOCK(this);
if (e == NULL)
return;
Remove(e);
_elements.push_back(e);
e->SetParent(this);
}
void GuiWindow::Insert(GuiElement* e, u32 index)
{
LOCK(this);
if (e == NULL || index > (_elements.size() - 1))
return;
Remove(e);
_elements.insert(_elements.begin()+index, e);
e->SetParent(this);
}
void GuiWindow::Remove(GuiElement* e)
{
LOCK(this);
if (e == NULL)
return;
for (u8 i = 0; i < _elements.size(); i++)
{
if(e == _elements.at(i))
{
_elements.erase(_elements.begin()+i);
break;
}
}
}
void GuiWindow::RemoveAll()
{
LOCK(this);
_elements.clear();
}
GuiElement* GuiWindow::GetGuiElementAt(u32 index) const
{
if (index >= _elements.size())
return NULL;
return _elements.at(index);
}
u32 GuiWindow::GetSize()
{
return _elements.size();
}
void GuiWindow::Draw()
{
LOCK(this);
if(_elements.size() == 0 || !this->IsVisible())
return;
for (u8 i = 0; i < _elements.size(); i++)
{
try { _elements.at(i)->Draw(); }
catch (const std::exception& e) { }
}
this->UpdateEffects();
if(parentElement && state == STATE_DISABLED)
//Menu_DrawRectangle(0,0,screenwidth,screenheight,(GXColor){0xbe, 0xca, 0xd5, 0x70},1);
Menu_DrawRectangle(0,0,screenwidth,screenheight,(GXColor){0, 0, 0, 0x70},1);
}
void GuiWindow::DrawTooltip()
{
LOCK(this);
if(_elements.size() == 0 || !this->IsVisible())
return;
for (u8 i = 0; i < _elements.size(); i++)
{
try { _elements.at(i)->DrawTooltip(); }
catch (const std::exception& e) { }
}
}
void GuiWindow::ResetState()
{
LOCK(this);
if(state != STATE_DISABLED)
state = STATE_DEFAULT;
for (u8 i = 0; i < _elements.size(); i++)
{
try { _elements.at(i)->ResetState(); }
catch (const std::exception& e) { }
}
}
void GuiWindow::SetState(int s)
{
LOCK(this);
state = s;
for (u8 i = 0; i < _elements.size(); i++)
{
try { _elements.at(i)->SetState(s); }
catch (const std::exception& e) { }
}
}
void GuiWindow::SetVisible(bool v)
{
LOCK(this);
visible = v;
for (u8 i = 0; i < _elements.size(); i++)
{
try { _elements.at(i)->SetVisible(v); }
catch (const std::exception& e) { }
}
}
void GuiWindow::SetFocus(int f)
{
LOCK(this);
focus = f;
if(f == 1)
this->MoveSelectionVert(1);
else
this->ResetState();
}
void GuiWindow::ChangeFocus(GuiElement* e)
{
LOCK(this);
if(parentElement)
return; // this is only intended for the main window
for (u8 i = 0; i < _elements.size(); i++)
{
if(e == _elements.at(i))
_elements.at(i)->SetFocus(1);
else if(_elements.at(i)->IsFocused() == 1)
_elements.at(i)->SetFocus(0);
}
}
void GuiWindow::ToggleFocus(GuiTrigger * t)
{
LOCK(this);
if(parentElement)
return; // this is only intended for the main window
int found = -1;
int newfocus = -1;
u8 i;
// look for currently in focus element
for (i = 0; i < _elements.size(); i++)
{
try
{
if(_elements.at(i)->IsFocused() == 1)
{
found = i;
break;
}
}
catch (const std::exception& e) { }
}
// element with focus not found, try to give focus
if(found == -1)
{
for (i = 0; i < _elements.size(); i++)
{
try
{
if(_elements.at(i)->IsFocused() == 0 && _elements.at(i)->GetState() != STATE_DISABLED) // focus is possible (but not set)
{
_elements.at(i)->SetFocus(1); // give this element focus
break;
}
}
catch (const std::exception& e) { }
}
}
// change focus
else if(t->wpad.btns_d & (WPAD_BUTTON_1 | WPAD_BUTTON_1 | WPAD_CLASSIC_BUTTON_PLUS)
|| t->pad.btns_d & PAD_BUTTON_B)
{
for (i = found; i < _elements.size(); i++)
{
try
{
if(_elements.at(i)->IsFocused() == 0 && _elements.at(i)->GetState() != STATE_DISABLED) // focus is possible (but not set)
{
newfocus = i;
_elements.at(i)->SetFocus(1); // give this element focus
_elements.at(found)->SetFocus(0); // disable focus on other element
break;
}
}
catch (const std::exception& e) { }
}
if(newfocus == -1)
{
for (i = 0; i < found; i++)
{
try
{
if(_elements.at(i)->IsFocused() == 0 && _elements.at(i)->GetState() != STATE_DISABLED) // focus is possible (but not set)
{
_elements.at(i)->SetFocus(1); // give this element focus
_elements.at(found)->SetFocus(0); // disable focus on other element
break;
}
}
catch (const std::exception& e) { }
}
}
}
}
int GuiWindow::GetSelected()
{
// find selected element
int found = -1;
for (u8 i = 0; i < _elements.size(); i++)
{
try
{
if(_elements.at(i)->GetState() == STATE_SELECTED)
{
found = i;
break;
}
}
catch (const std::exception& e) { }
}
return found;
}
// set element to left/right as selected
// there's probably a more clever way to do this, but this way works
void GuiWindow::MoveSelectionHor(int dir)
{
LOCK(this);
int found = -1;
u16 left = 0;
u16 top = 0;
u8 i = 0;
int selected = this->GetSelected();
if(selected >= 0)
{
left = _elements.at(selected)->GetLeft();
top = _elements.at(selected)->GetTop();
}
// look for a button on the same row, to the left/right
for (i = 0; i < _elements.size(); i++)
{
try
{
if(_elements.at(i)->IsSelectable())
{
if(_elements.at(i)->GetLeft()*dir > left*dir && _elements.at(i)->GetTop() == top)
{
if(found == -1)
found = i;
else if(_elements.at(i)->GetLeft()*dir < _elements.at(found)->GetLeft()*dir)
found = i; // this is a better match
}
}
}
catch (const std::exception& e) { }
}
if(found >= 0)
goto matchfound;
// match still not found, let's try the first button in the next row
for (i = 0; i < _elements.size(); i++)
{
try
{
if(_elements.at(i)->IsSelectable())
{
if(_elements.at(i)->GetTop()*dir > top*dir)
{
if(found == -1)
found = i;
else if(_elements.at(i)->GetTop()*dir < _elements.at(found)->GetTop()*dir)
found = i; // this is a better match
else if(_elements.at(i)->GetTop()*dir == _elements.at(found)->GetTop()*dir
&&
_elements.at(i)->GetLeft()*dir < _elements.at(found)->GetLeft()*dir)
found = i; // this is a better match
}
}
}
catch (const std::exception& e) { }
}
// match found
matchfound:
if(found >= 0)
{
_elements.at(found)->SetState(STATE_SELECTED);
if(selected >= 0)
_elements.at(selected)->ResetState();
}
}
void GuiWindow::MoveSelectionVert(int dir)
{
LOCK(this);
int found = -1;
u16 left = 0;
u16 top = 0;
u8 i = 0;
int selected = this->GetSelected();
if(selected >= 0)
{
left = _elements.at(selected)->GetLeft();
top = _elements.at(selected)->GetTop();
}
// look for a button above/below, with the least horizontal difference
for (i = 0; i < _elements.size(); i++)
{
try
{
if(_elements.at(i)->IsSelectable())
{
if(_elements.at(i)->GetTop()*dir > top*dir)
{
if(found == -1)
found = i;
else if(_elements.at(i)->GetTop()*dir < _elements.at(found)->GetTop()*dir)
found = i; // this is a better match
else if(_elements.at(i)->GetTop()*dir == _elements.at(found)->GetTop()*dir
&&
abs(_elements.at(i)->GetLeft() - left) <
abs(_elements.at(found)->GetLeft() - left))
found = i;
}
}
}
catch (const std::exception& e) { }
}
if(found >= 0)
goto matchfound;
// match found
matchfound:
if(found >= 0)
{
_elements.at(found)->SetState(STATE_SELECTED);
if(selected >= 0)
_elements.at(selected)->ResetState();
}
}
void GuiWindow::Update(GuiTrigger * t)
{
LOCK(this);
if(_elements.size() == 0 || (state == STATE_DISABLED && parentElement))
return;
for (u8 i = 0; i < _elements.size(); i++)
{
try { _elements.at(i)->Update(t); }
catch (const std::exception& e) { }
}
this->ToggleFocus(t);
if(focus) // only send actions to this window if it's in focus
{
// pad/joystick navigation
if(t->Right())
this->MoveSelectionHor(1);
else if(t->Left())
this->MoveSelectionHor(-1);
else if(t->Down())
this->MoveSelectionVert(1);
else if(t->Up())
this->MoveSelectionVert(-1);
}
if(updateCB)
updateCB(this);
}

View File

@ -1,102 +1,102 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gccore.h>
#include <fat.h>
#include <sys/dir.h>
#include <dirent.h>
#include <unistd.h>
#include "listfiles.h"
static char alldirfiles[300][70];
char filenames[80];
bool findfile(const char * filename, const char * path) {
DIR *dir;
struct dirent *file;
dir = opendir(path);
char temp[11];
while ((file = readdir(dir))) {
snprintf(temp,sizeof(temp),"%s",file->d_name);
if (!strncmpi(temp,filename,11)) {
closedir(dir);
return true;
}
}
closedir(dir);
return false;
}
bool subfoldercreate(char * fullpath) {
//check forsubfolders
char dircheck[300];
char dirnoslash[300];
char * pch = NULL;
u32 cnt = 0;
struct stat st;
snprintf(dirnoslash, strlen(fullpath), "%s", fullpath);
if (stat(fullpath, &st) != 0) {
pch = strrchr(dirnoslash, '/');
cnt = pch-dirnoslash;
snprintf(dircheck, cnt+2, "%s", dirnoslash);
subfoldercreate(dircheck);
};
if (mkdir(dirnoslash, 0777) == -1) {
return false;
}
return true;
}
char * GetFileName(int i) {
return alldirfiles[i];
}
s32 filenamescmp(const void *a, const void *b) {
/* Compare strings */
return stricmp((char *)a, (char *)b);
}
int GetAllDirFiles(char * filespath) {
int countfiles = 0;
struct stat st;
DIR_ITER* dir;
dir = diropen (filespath);
if (dir == NULL) //If empty
return 0;
while (dirnext(dir,filenames,&st) == 0) {
if ((st.st_mode & S_IFDIR) == 0) {
// st.st_mode & S_IFDIR indicates a directory
snprintf(alldirfiles[countfiles], 70, "%s", filenames);
countfiles++;
}
}
dirclose(dir);
qsort(alldirfiles, countfiles, sizeof(char[70]), filenamescmp);
return countfiles;
}
bool checkfile(char * path) {
FILE * f;
f = fopen(path,"r");
if (f) {
fclose(f);
return true;
}
return false;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gccore.h>
#include <fat.h>
#include <sys/dir.h>
#include <dirent.h>
#include <unistd.h>
#include "listfiles.h"
static char alldirfiles[300][70];
char filenames[80];
bool findfile(const char * filename, const char * path) {
DIR *dir;
struct dirent *file;
dir = opendir(path);
char temp[11];
while ((file = readdir(dir))) {
snprintf(temp,sizeof(temp),"%s",file->d_name);
if (!strncmpi(temp,filename,11)) {
closedir(dir);
return true;
}
}
closedir(dir);
return false;
}
bool subfoldercreate(char * fullpath) {
//check forsubfolders
char dircheck[300];
char dirnoslash[300];
char * pch = NULL;
u32 cnt = 0;
struct stat st;
snprintf(dirnoslash, strlen(fullpath), "%s", fullpath);
if (stat(fullpath, &st) != 0) {
pch = strrchr(dirnoslash, '/');
cnt = pch-dirnoslash;
snprintf(dircheck, cnt+2, "%s", dirnoslash);
subfoldercreate(dircheck);
};
if (mkdir(dirnoslash, 0777) == -1) {
return false;
}
return true;
}
char * GetFileName(int i) {
return alldirfiles[i];
}
s32 filenamescmp(const void *a, const void *b) {
/* Compare strings */
return stricmp((char *)a, (char *)b);
}
int GetAllDirFiles(char * filespath) {
int countfiles = 0;
struct stat st;
DIR_ITER* dir;
dir = diropen (filespath);
if (dir == NULL) //If empty
return 0;
while (dirnext(dir,filenames,&st) == 0) {
if ((st.st_mode & S_IFDIR) == 0) {
// st.st_mode & S_IFDIR indicates a directory
snprintf(alldirfiles[countfiles], 70, "%s", filenames);
countfiles++;
}
}
dirclose(dir);
qsort(alldirfiles, countfiles, sizeof(char[70]), filenamescmp);
return countfiles;
}
bool checkfile(char * path) {
FILE * f;
f = fopen(path,"r");
if (f) {
fclose(f);
return true;
}
return false;
}

View File

@ -1,18 +1,18 @@
#ifndef _LISTFILES_H_
#define _LISTFILES_H_
#ifdef __cplusplus
extern "C" {
#endif
bool findfile(const char * filename, const char * path);
char * GetFileName(int i);
int GetAllDirFiles(char * filespath);
bool subfoldercreate(char * fullpath);
bool checkfile(char * path);
#ifdef __cplusplus
}
#endif
#endif
#ifndef _LISTFILES_H_
#define _LISTFILES_H_
#ifdef __cplusplus
extern "C" {
#endif
bool findfile(const char * filename, const char * path);
char * GetFileName(int i);
int GetAllDirFiles(char * filespath);
bool subfoldercreate(char * fullpath);
bool checkfile(char * path);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,257 +1,257 @@
/****************************************************************************
* USB Loader GX Team
*
* Main loadup of the application
*
* libwiigui
* Tantric 2009
***************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/dir.h>
#include <ogcsys.h>
#include <unistd.h>
#include <wiiuse/wpad.h>
#include "libwiigui/gui.h"
#include "usbloader/wbfs.h"
#include "settings/cfg.h"
#include "language/gettext.h"
#include "mload/mload.h"
#include "FreeTypeGX.h"
#include "video.h"
#include "audio.h"
#include "menu.h"
#include "input.h"
#include "filelist.h"
#include "listfiles.h"
#include "main.h"
#include "fatmounter.h"
#include "sys.h"
#include "wpad.h"
#include "fat.h"
/* Constants */
#define CONSOLE_XCOORD 260
#define CONSOLE_YCOORD 115
#define CONSOLE_WIDTH 340
#define CONSOLE_HEIGHT 218
FreeTypeGX *fontSystem=0;
FreeTypeGX *fontClock=0;
static void BootUpProblems()
{
s32 ret2;
// load main font from file, or default to built-in font
fontSystem = new FreeTypeGX();
fontSystem->loadFont(NULL, font_ttf, font_ttf_size, 0);
fontSystem->setCompatibilityMode(FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_PASSCLR | FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_NONE);
GuiImageData bootimageData(gxlogo_png);
GuiImage bootimage(&bootimageData);
GuiText boottext(NULL, 20, (GXColor) {255, 255, 255, 255});
boottext.SetPosition(200, 240-1.2*bootimage.GetHeight()/2+250);
bootimage.SetPosition(320-1.2*bootimage.GetWidth()/2, 240-1.2*bootimage.GetHeight()/2);
bootimage.SetScale(1.2);
GuiImageData usbimageData(usbport_png);
GuiImage usbimage(&usbimageData);
usbimage.SetPosition(400,300);
usbimage.SetScale(.7);
usbimage.SetAlpha(200);
time_t curtime;
time_t endtime = time(0) + 30;
do {
ret2 = IOS_ReloadIOS(249);
if (ret2 < 0) {
ret2 = IOS_ReloadIOS(222);
SDCard_Init();
load_ehc_module();
SDCard_deInit();
if(ret2 <0) {
boottext.SetText("ERROR: cIOS could not be loaded!");
bootimage.Draw();
boottext.Draw();
Menu_Render();
sleep(5);
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
}
}
ret2 = WBFS_Init(WBFS_DEVICE_USB);
if (ret2 >= 0) {
boottext.SetText("Loading...");
bootimage.Draw();
boottext.Draw();
Menu_Render();
break;
}
curtime = time(0);
boottext.SetTextf("Waiting for your slow USB Device: %i secs...", int(endtime-curtime));
while(curtime == time(0)) {
boottext.Draw();
bootimage.Draw();
if (endtime-curtime<15)usbimage.Draw();
Menu_Render();
}
} while((endtime-time(0)) > 0);
if(ret2 < 0) {
boottext.SetText("ERROR: USB device could not be loaded!");
usbimage.Draw();
bootimage.Draw();
boottext.Draw();
Menu_Render();
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
}
///delete font to load up custom if set
if(fontSystem) {
delete fontSystem;
fontSystem = NULL;
}
}
int
main(int argc, char *argv[]) {
s32 ret;
bool startupproblem = false;
bool bootDevice_found=false;
if (argc >= 1) {
if (!strncasecmp(argv[0], "usb:/", 5)) {
strcpy(bootDevice, "USB:");
bootDevice_found = true;
} else if (!strncasecmp(argv[0], "sd:/", 4))
bootDevice_found = true;
}
/** PAD_Init has to be before InitVideo don't move that **/
PAD_Init(); // initialize PAD/WPAD
USBDevice_deInit();// seems enough to wake up some HDDs if they are in sleep mode when the loader starts (tested with WD MyPassport Essential 2.5")
ret = IOS_ReloadIOS(249);
if (ret < 0) {
ret = IOS_ReloadIOS(222);
SDCard_Init();
load_ehc_module();
SDCard_deInit();
if(ret <0) {
printf("\n\tERROR: cIOS could not be loaded!\n");
sleep(5);
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
}
}
ret = WBFS_Init(WBFS_DEVICE_USB);
if (ret < 0) {
ret = IOS_ReloadIOS(222);
SDCard_Init();
load_ehc_module();
SDCard_deInit();
if(ret < 0) {
InitVideo(); // Initialise video
Menu_Render();
BootUpProblems();
startupproblem = true;
ret = 1;
}
ret = WBFS_Init(WBFS_DEVICE_USB);
if(ret < 0) {
InitVideo(); // Initialise video
Menu_Render();
BootUpProblems();
startupproblem = true;
ret = 1;
}
}
SDCard_Init(); // mount SD for loading cfg's
USBDevice_Init(); // and mount USB:/
if (!bootDevice_found) {
//try USB
//left in all the dol and elf files in this check in case this is the first time running the app and they dont have the config
if (checkfile((char*) "USB:/config/GXglobal.cfg") || (checkfile((char*) "USB:/apps/usbloader_gx/boot.elf"))
|| checkfile((char*) "USB:/apps/usbloadergx/boot.dol") || (checkfile((char*) "USB:/apps/usbloadergx/boot.elf"))
|| checkfile((char*) "USB:/apps/usbloader_gx/boot.dol"))
strcpy(bootDevice, "USB:");
}
gettextCleanUp();
CFG_Load();
/* Load Custom IOS */
if (Settings.cios == ios222 && IOS_GetVersion() != 222) {
SDCard_deInit();// unmount SD for reloading IOS
USBDevice_deInit();// unmount USB for reloading IOS
ret = IOS_ReloadIOS(222);
SDCard_Init();
load_ehc_module();
if (ret < 0) {
SDCard_deInit();
Settings.cios = ios249;
ret = IOS_ReloadIOS(249);
}
SDCard_Init(); // now mount SD:/
USBDevice_Init(); // and mount USB:/
} else if (Settings.cios == ios249 && IOS_GetVersion() != 249) {
SDCard_deInit();// unmount SD for reloading IOS
USBDevice_deInit();// unmount USB for reloading IOS
ret = IOS_ReloadIOS(249);
if (ret < 0) {
Settings.cios = ios222;
ret = IOS_ReloadIOS(222);
SDCard_Init();
load_ehc_module();
}
SDCard_Init(); // now mount SD:/
USBDevice_Init(); // and mount USB:/
}
if (ret < 0) {
printf("ERROR: cIOS could not be loaded!");
sleep(5);
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
}
//! Init the rest of the System
Sys_Init();
Wpad_Init();
if(!startupproblem)
InitVideo();
InitAudio(); // Initialize audio
WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR);
WPAD_SetVRes(WPAD_CHAN_ALL, screenwidth, screenheight);
// load main font from file, or default to built-in font
fontSystem = new FreeTypeGX();
char *fontPath = NULL;
asprintf(&fontPath, "%sfont.ttf", CFG.theme_path);
fontSystem->loadFont(fontPath, font_ttf, font_ttf_size, 0);
fontSystem->setCompatibilityMode(FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_PASSCLR | FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_NONE);
free(fontPath);
fontClock = new FreeTypeGX();
fontClock->loadFont(NULL, clock_ttf, clock_ttf_size, 0);
fontClock->setCompatibilityMode(FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_PASSCLR | FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_NONE);
InitGUIThreads();
MainMenu(MENU_CHECK);
return 0;
}
/****************************************************************************
* USB Loader GX Team
*
* Main loadup of the application
*
* libwiigui
* Tantric 2009
***************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/dir.h>
#include <ogcsys.h>
#include <unistd.h>
#include <wiiuse/wpad.h>
#include "libwiigui/gui.h"
#include "usbloader/wbfs.h"
#include "settings/cfg.h"
#include "language/gettext.h"
#include "mload/mload.h"
#include "FreeTypeGX.h"
#include "video.h"
#include "audio.h"
#include "menu.h"
#include "input.h"
#include "filelist.h"
#include "listfiles.h"
#include "main.h"
#include "fatmounter.h"
#include "sys.h"
#include "wpad.h"
#include "fat.h"
/* Constants */
#define CONSOLE_XCOORD 260
#define CONSOLE_YCOORD 115
#define CONSOLE_WIDTH 340
#define CONSOLE_HEIGHT 218
FreeTypeGX *fontSystem=0;
FreeTypeGX *fontClock=0;
static void BootUpProblems()
{
s32 ret2;
// load main font from file, or default to built-in font
fontSystem = new FreeTypeGX();
fontSystem->loadFont(NULL, font_ttf, font_ttf_size, 0);
fontSystem->setCompatibilityMode(FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_PASSCLR | FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_NONE);
GuiImageData bootimageData(gxlogo_png);
GuiImage bootimage(&bootimageData);
GuiText boottext(NULL, 20, (GXColor) {255, 255, 255, 255});
boottext.SetPosition(200, 240-1.2*bootimage.GetHeight()/2+250);
bootimage.SetPosition(320-1.2*bootimage.GetWidth()/2, 240-1.2*bootimage.GetHeight()/2);
bootimage.SetScale(1.2);
GuiImageData usbimageData(usbport_png);
GuiImage usbimage(&usbimageData);
usbimage.SetPosition(400,300);
usbimage.SetScale(.7);
usbimage.SetAlpha(200);
time_t curtime;
time_t endtime = time(0) + 30;
do {
ret2 = IOS_ReloadIOS(249);
if (ret2 < 0) {
ret2 = IOS_ReloadIOS(222);
SDCard_Init();
load_ehc_module();
SDCard_deInit();
if(ret2 <0) {
boottext.SetText("ERROR: cIOS could not be loaded!");
bootimage.Draw();
boottext.Draw();
Menu_Render();
sleep(5);
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
}
}
ret2 = WBFS_Init(WBFS_DEVICE_USB);
if (ret2 >= 0) {
boottext.SetText("Loading...");
bootimage.Draw();
boottext.Draw();
Menu_Render();
break;
}
curtime = time(0);
boottext.SetTextf("Waiting for your slow USB Device: %i secs...", int(endtime-curtime));
while(curtime == time(0)) {
boottext.Draw();
bootimage.Draw();
if (endtime-curtime<15)usbimage.Draw();
Menu_Render();
}
} while((endtime-time(0)) > 0);
if(ret2 < 0) {
boottext.SetText("ERROR: USB device could not be loaded!");
usbimage.Draw();
bootimage.Draw();
boottext.Draw();
Menu_Render();
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
}
///delete font to load up custom if set
if(fontSystem) {
delete fontSystem;
fontSystem = NULL;
}
}
int
main(int argc, char *argv[]) {
s32 ret;
bool startupproblem = false;
bool bootDevice_found=false;
if (argc >= 1) {
if (!strncasecmp(argv[0], "usb:/", 5)) {
strcpy(bootDevice, "USB:");
bootDevice_found = true;
} else if (!strncasecmp(argv[0], "sd:/", 4))
bootDevice_found = true;
}
/** PAD_Init has to be before InitVideo don't move that **/
PAD_Init(); // initialize PAD/WPAD
USBDevice_deInit();// seems enough to wake up some HDDs if they are in sleep mode when the loader starts (tested with WD MyPassport Essential 2.5")
ret = IOS_ReloadIOS(249);
if (ret < 0) {
ret = IOS_ReloadIOS(222);
SDCard_Init();
load_ehc_module();
SDCard_deInit();
if(ret <0) {
printf("\n\tERROR: cIOS could not be loaded!\n");
sleep(5);
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
}
}
ret = WBFS_Init(WBFS_DEVICE_USB);
if (ret < 0) {
ret = IOS_ReloadIOS(222);
SDCard_Init();
load_ehc_module();
SDCard_deInit();
if(ret < 0) {
InitVideo(); // Initialise video
Menu_Render();
BootUpProblems();
startupproblem = true;
ret = 1;
}
ret = WBFS_Init(WBFS_DEVICE_USB);
if(ret < 0) {
InitVideo(); // Initialise video
Menu_Render();
BootUpProblems();
startupproblem = true;
ret = 1;
}
}
SDCard_Init(); // mount SD for loading cfg's
USBDevice_Init(); // and mount USB:/
if (!bootDevice_found) {
//try USB
//left in all the dol and elf files in this check in case this is the first time running the app and they dont have the config
if (checkfile((char*) "USB:/config/GXglobal.cfg") || (checkfile((char*) "USB:/apps/usbloader_gx/boot.elf"))
|| checkfile((char*) "USB:/apps/usbloadergx/boot.dol") || (checkfile((char*) "USB:/apps/usbloadergx/boot.elf"))
|| checkfile((char*) "USB:/apps/usbloader_gx/boot.dol"))
strcpy(bootDevice, "USB:");
}
gettextCleanUp();
CFG_Load();
/* Load Custom IOS */
if (Settings.cios == ios222 && IOS_GetVersion() != 222) {
SDCard_deInit();// unmount SD for reloading IOS
USBDevice_deInit();// unmount USB for reloading IOS
ret = IOS_ReloadIOS(222);
SDCard_Init();
load_ehc_module();
if (ret < 0) {
SDCard_deInit();
Settings.cios = ios249;
ret = IOS_ReloadIOS(249);
}
SDCard_Init(); // now mount SD:/
USBDevice_Init(); // and mount USB:/
} else if (Settings.cios == ios249 && IOS_GetVersion() != 249) {
SDCard_deInit();// unmount SD for reloading IOS
USBDevice_deInit();// unmount USB for reloading IOS
ret = IOS_ReloadIOS(249);
if (ret < 0) {
Settings.cios = ios222;
ret = IOS_ReloadIOS(222);
SDCard_Init();
load_ehc_module();
}
SDCard_Init(); // now mount SD:/
USBDevice_Init(); // and mount USB:/
}
if (ret < 0) {
printf("ERROR: cIOS could not be loaded!");
sleep(5);
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
}
//! Init the rest of the System
Sys_Init();
Wpad_Init();
if(!startupproblem)
InitVideo();
InitAudio(); // Initialize audio
WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR);
WPAD_SetVRes(WPAD_CHAN_ALL, screenwidth, screenheight);
// load main font from file, or default to built-in font
fontSystem = new FreeTypeGX();
char *fontPath = NULL;
asprintf(&fontPath, "%sfont.ttf", CFG.theme_path);
fontSystem->loadFont(fontPath, font_ttf, font_ttf_size, 0);
fontSystem->setCompatibilityMode(FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_PASSCLR | FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_NONE);
free(fontPath);
fontClock = new FreeTypeGX();
fontClock->loadFont(NULL, clock_ttf, clock_ttf_size, 0);
fontClock->setCompatibilityMode(FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_PASSCLR | FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_NONE);
InitGUIThreads();
MainMenu(MENU_CHECK);
return 0;
}

View File

@ -1,37 +1,37 @@
#ifndef __MEMORY_H_
#define __MEMORY_H_
#ifdef __cplusplus
extern "C" {
#endif
#define Disc_ID ((u32*) 0x80000000)
#define Disc_Region ((u32*) 0x80000003)
#define Disc_Magic ((u32*) 0x80000018)
#define Sys_Magic ((u32*) 0x80000020)
#define Version ((u32*) 0x80000024)
#define Mem_Size ((u32*) 0x80000028)
#define Board_Model ((u32*) 0x8000002C)
#define Arena_L ((u32*) 0x80000030)
#define Arena_H ((u32*) 0x80000034)
#define FST ((u32*) 0x80000038)
#define Max_FST ((u32*) 0x8000003C)
#define Assembler ((u32*) 0x80000060)
#define Video_Mode ((u32*) 0x800000CC)
#define Dev_Debugger ((u32*) 0x800000EC)
#define Simulated_Mem ((u32*) 0x800000F0)
#define BI2 ((u32*) 0x800000F4)
#define Bus_Speed ((u32*) 0x800000F8)
#define CPU_Speed ((u32*) 0x800000FC)
#define Online_Check ((u32*) 0x80003180)
#define GameID_Address ((u32*) 0x80003184)
#define allocate_memory(size) memalign(32, (size+31)&(~31))
#ifdef __cplusplus
}
#endif
#endif
#ifndef __MEMORY_H_
#define __MEMORY_H_
#ifdef __cplusplus
extern "C" {
#endif
#define Disc_ID ((u32*) 0x80000000)
#define Disc_Region ((u32*) 0x80000003)
#define Disc_Magic ((u32*) 0x80000018)
#define Sys_Magic ((u32*) 0x80000020)
#define Version ((u32*) 0x80000024)
#define Mem_Size ((u32*) 0x80000028)
#define Board_Model ((u32*) 0x8000002C)
#define Arena_L ((u32*) 0x80000030)
#define Arena_H ((u32*) 0x80000034)
#define FST ((u32*) 0x80000038)
#define Max_FST ((u32*) 0x8000003C)
#define Assembler ((u32*) 0x80000060)
#define Video_Mode ((u32*) 0x800000CC)
#define Dev_Debugger ((u32*) 0x800000EC)
#define Simulated_Mem ((u32*) 0x800000F0)
#define BI2 ((u32*) 0x800000F4)
#define Bus_Speed ((u32*) 0x800000F8)
#define CPU_Speed ((u32*) 0x800000FC)
#define Online_Check ((u32*) 0x80003180)
#define GameID_Address ((u32*) 0x80003184)
#define allocate_memory(size) memalign(32, (size+31)&(~31))
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,117 +1,117 @@
#define size_dip_plugin 3080
unsigned char dip_plugin[3080] __attribute__((aligned (32)))={
19, 119, 228, 85, 18, 52, 0, 1, 32, 34, 205, 172, 32, 32, 13, 57, 32, 32, 8, 197, 32, 32, 8, 153, 32, 32, 91, 129, 32,
32, 0, 73, 32, 32, 40, 117, 32, 32, 54, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
19, 119, 233, 53, 70, 192, 70, 192, 70, 192, 70, 192, 70, 192, 70, 192, 70, 192, 71, 120, 234, 0, 2, 7, 70, 192, 71,
120, 234, 0, 2, 23, 70, 192, 71, 120, 234, 0, 2, 39, 70, 192, 71, 120, 234, 0, 2, 31, 70, 192, 71, 120, 234, 0, 2, 5,
70, 192, 71, 120, 234, 0, 1, 247, 70, 192, 71, 120, 234, 0, 2, 29, 70, 192, 71, 120, 234, 0, 2, 25, 70, 192, 71, 120,
234, 0, 2, 33, 181, 0, 75, 7, 176, 137, 147, 0, 70, 104, 35, 0, 33, 0, 34, 0, 147, 1, 147, 2, 240, 0, 252, 85, 176,
9, 188, 2, 71, 8, 70, 192, 227, 0, 0, 0, 181, 16, 28, 3, 34, 32, 28, 12, 72, 13, 28, 25, 247, 255, 255, 210, 33, 32,
72, 11, 247, 255, 255, 202, 73, 10, 34, 1, 104, 11, 66, 19, 209, 253, 34, 32, 28, 32, 73, 6, 247, 255, 255, 196, 28,
32, 33, 32, 247, 255, 255, 188, 75, 4, 104, 24, 188, 16, 188, 2, 71, 8, 70, 192, 13, 0, 96, 0, 13, 0, 96, 28, 13, 0,
96, 32, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 10, 203, 70, 154, 75, 20, 176, 137, 37, 0, 28, 7, 28, 14,
70, 145, 70, 108, 70, 155, 70, 168, 70, 91, 96, 35, 70, 67, 96, 99, 96, 163, 70, 83, 96, 227, 28, 56, 70, 75, 28, 49,
97, 35, 247, 255, 255, 162, 70, 104, 28, 57, 28, 50, 240, 0, 252, 6, 53, 1, 40, 0, 209, 8, 176, 9, 188, 60, 70, 144,
70, 153, 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 45, 15, 217, 223, 231, 243, 208, 0, 0, 0, 181, 112, 176, 136, 75,
8, 28, 6, 28, 13, 70, 108, 147, 0, 96, 97, 146, 2, 247, 255, 255, 129, 28, 49, 28, 42, 70, 104, 240, 0, 251, 229, 176,
8, 188, 112, 188, 2, 71, 8, 168, 0, 0, 0, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 176, 143, 144, 4, 145,
3, 146, 2, 41, 0, 209, 0, 224, 126, 10, 82, 70, 145, 35, 128, 34, 0, 1, 27, 70, 147, 34, 255, 147, 1, 3, 210, 171, 6,
146, 0, 70, 152, 224, 7, 154, 3, 68, 179, 69, 90, 217, 62, 154, 5, 24, 179, 10, 219, 68, 153, 154, 3, 70, 91, 26, 214,
70, 74, 2, 83, 154, 2, 66, 154, 216, 87, 35, 0, 147, 5, 36, 0, 159, 4, 34, 128, 68, 95, 28, 56, 28, 49, 1, 18, 240,
0, 248, 103, 44, 0, 209, 47, 40, 0, 208, 45, 155, 0, 28, 6, 66, 152, 217, 1, 38, 255, 3, 246, 10, 242, 70, 146, 36,
0, 75, 43, 70, 66, 96, 19, 35, 0, 96, 83, 96, 147, 70, 83, 96, 211, 70, 75, 97, 19, 28, 56, 28, 49, 247, 255, 255, 38,
70, 64, 28, 57, 28, 50, 240, 0, 251, 138, 52, 1, 28, 5, 40, 0, 208, 192, 44, 15, 217, 230, 45, 0, 208, 188, 176, 15,
28, 40, 188, 60, 70, 144, 70, 153, 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 154, 5, 25, 147, 154, 1, 66, 147, 217,
1, 155, 5, 26, 214, 32, 128, 1, 0, 33, 32, 247, 255, 254, 251, 28, 4, 40, 0, 208, 18, 33, 128, 1, 9, 70, 74, 247, 255,
255, 59, 28, 5, 40, 0, 208, 15, 28, 32, 247, 255, 254, 217, 231, 216, 26, 211, 0, 155, 28, 28, 147, 5, 30, 99, 65, 156,
231, 163, 37, 1, 66, 109, 231, 208, 37, 0, 231, 206, 154, 5, 28, 56, 24, 161, 28, 50, 247, 255, 254, 214, 28, 56, 28,
49, 247, 255, 254, 206, 231, 228, 70, 192, 208, 0, 0, 0, 181, 48, 28, 13, 28, 20, 6, 195, 209, 18, 75, 15, 66, 152,
217, 19, 33, 0, 75, 14, 24, 194, 75, 14, 66, 154, 216, 1, 75, 13, 26, 25, 66, 161, 211, 5, 28, 8, 66, 169, 216, 10,
30, 99, 67, 152, 224, 0, 32, 0, 188, 48, 188, 2, 71, 8, 35, 192, 4, 91, 26, 25, 231, 232, 28, 40, 30, 99, 67, 152, 231,
244, 1, 127, 255, 255, 240, 0, 0, 0, 3, 97, 127, 255, 19, 97, 128, 0, 71, 112, 70, 192, 181, 48, 28, 4, 72, 15, 28,
13, 104, 131, 104, 193, 176, 129, 24, 91, 24, 154, 105, 3, 43, 0, 209, 15, 104, 67, 43, 0, 209, 7, 28, 32, 28, 41, 247,
255, 255, 13, 176, 1, 188, 48, 188, 2, 71, 8, 28, 32, 28, 41, 247, 255, 255, 27, 231, 246, 28, 32, 28, 41, 240, 0, 249,
220, 231, 241, 70, 192, 19, 119, 240, 0, 181, 240, 79, 27, 35, 1, 28, 4, 96, 59, 176, 129, 33, 32, 247, 255, 254, 127,
104, 227, 43, 8, 208, 8, 28, 32, 240, 0, 250, 214, 35, 0, 96, 59, 176, 1, 188, 240, 188, 2, 71, 8, 105, 163, 37, 197,
104, 24, 104, 89, 247, 255, 254, 109, 105, 163, 1, 173, 104, 27, 28, 40, 33, 8, 104, 92, 104, 30, 247, 255, 254, 100,
75, 10, 4, 36, 64, 30, 67, 52, 78, 9, 96, 44, 28, 40, 33, 4, 96, 52, 247, 255, 254, 73, 28, 48, 33, 4, 247, 255, 254,
69, 35, 0, 96, 59, 32, 0, 231, 217, 70, 192, 19, 119, 240, 40, 0, 0, 255, 255, 0, 0, 49, 136, 181, 16, 73, 20, 28, 4,
104, 139, 104, 202, 24, 154, 105, 11, 43, 0, 209, 18, 104, 75, 43, 0, 209, 11, 33, 32, 247, 255, 254, 175, 40, 0, 219,
3, 105, 162, 75, 12, 66, 154, 208, 10, 188, 16, 188, 2, 71, 8, 33, 32, 247, 255, 254, 185, 231, 242, 33, 32, 240, 0,
249, 123, 231, 238, 75, 6, 34, 1, 112, 26, 120, 91, 43, 0, 209, 238, 247, 255, 254, 10, 231, 235, 70, 192, 19, 119,
240, 0, 93, 28, 158, 163, 32, 34, 205, 172, 181, 240, 70, 87, 70, 70, 180, 192, 28, 4, 120, 0, 176, 129, 28, 14, 28,
23, 40, 224, 208, 24, 77, 133, 35, 0, 98, 43, 28, 3, 59, 112, 43, 143, 217, 13, 28, 32, 28, 49, 28, 58, 240, 0, 250,
108, 28, 4, 176, 1, 28, 32, 188, 12, 70, 144, 70, 154, 188, 240, 188, 2, 71, 8, 74, 123, 0, 155, 88, 211, 70, 159, 77,
120, 106, 43, 43, 0, 209, 2, 105, 43, 43, 0, 208, 230, 28, 48, 33, 0, 28, 58, 240, 0, 248, 240, 106, 43, 224, 143, 104,
107, 43, 0, 209, 2, 105, 43, 43, 0, 208, 217, 36, 0, 231, 221, 35, 1, 34, 37, 84, 171, 104, 43, 43, 0, 208, 0, 224,
173, 28, 32, 28, 58, 240, 0, 250, 62, 28, 4, 34, 0, 35, 37, 84, 234, 44, 0, 209, 204, 224, 46, 104, 235, 104, 169, 70,
154, 105, 43, 70, 136, 43, 0, 209, 0, 224, 176, 32, 0, 34, 0, 70, 67, 70, 81, 67, 11, 209, 2, 42, 0, 209, 0, 224, 176,
28, 3, 30, 90, 65, 147, 96, 107, 28, 48, 28, 57, 247, 255, 255, 107, 28, 4, 231, 176, 105, 43, 43, 0, 208, 167, 35,
2, 224, 85, 104, 97, 104, 162, 40, 208, 209, 0, 224, 144, 28, 48, 247, 255, 254, 250, 28, 4, 40, 0, 209, 160, 35, 37,
92, 235, 43, 0, 209, 156, 28, 48, 28, 57, 247, 255, 254, 237, 231, 151, 35, 36, 92, 234, 42, 0, 209, 179, 105, 41, 84,
234, 35, 37, 96, 42, 96, 106, 96, 170, 96, 234, 98, 42, 84, 234, 70, 136, 41, 0, 209, 0, 231, 128, 105, 108, 247, 255,
253, 142, 70, 64, 28, 41, 28, 34, 56, 1, 49, 24, 240, 0, 248, 249, 28, 4, 231, 122, 104, 107, 43, 0, 208, 93, 75, 60,
36, 160, 98, 43, 2, 36, 231, 114, 104, 107, 43, 0, 209, 3, 105, 43, 43, 0, 209, 0, 231, 101, 104, 99, 104, 162, 7, 155,
67, 19, 74, 53, 36, 0, 64, 19, 96, 235, 231, 98, 104, 99, 72, 51, 64, 24, 247, 255, 253, 122, 28, 4, 231, 91, 104, 98,
35, 36, 84, 234, 36, 0, 231, 86, 105, 43, 96, 51, 28, 48, 28, 57, 247, 255, 253, 67, 36, 0, 231, 78, 104, 99, 97, 43,
43, 0, 209, 40, 105, 99, 36, 0, 97, 107, 231, 70, 104, 43, 231, 238, 104, 99, 36, 0, 96, 43, 231, 64, 104, 171, 231,
232, 104, 99, 36, 0, 96, 171, 231, 58, 104, 107, 43, 0, 209, 3, 105, 43, 43, 0, 209, 0, 231, 45, 28, 48, 33, 0, 28,
58, 240, 0, 248, 55, 28, 48, 28, 57, 247, 255, 253, 29, 36, 0, 231, 40, 104, 97, 104, 162, 28, 48, 247, 255, 254, 122,
28, 4, 231, 79, 28, 40, 28, 33, 49, 8, 34, 6, 48, 24, 247, 255, 253, 17, 231, 206, 105, 43, 43, 0, 209, 158, 231, 15,
2, 201, 2, 82, 231, 107, 28, 58, 28, 32, 28, 49, 240, 0, 249, 121, 28, 2, 30, 83, 65, 154, 231, 71, 105, 43, 43, 0,
208, 0, 231, 74, 96, 106, 36, 0, 231, 2, 70, 192, 19, 119, 240, 0, 19, 119, 233, 144, 0, 5, 49, 0, 255, 255, 128, 0,
127, 255, 255, 255, 181, 240, 70, 87, 70, 78, 70, 69, 180, 224, 70, 128, 28, 14, 70, 148, 42, 0, 208, 51, 33, 3, 28,
2, 64, 10, 35, 4, 26, 155, 28, 24, 64, 8, 69, 96, 216, 49, 40, 0, 208, 49, 36, 0, 70, 67, 85, 30, 52, 1, 66, 160, 216,
250, 69, 132, 208, 32, 70, 99, 26, 27, 8, 159, 70, 153, 0, 187, 70, 154, 43, 0, 208, 17, 4, 51, 6, 50, 2, 49, 67, 26,
67, 10, 28, 21, 70, 67, 67, 53, 24, 26, 33, 0, 0, 139, 49, 1, 80, 213, 66, 185, 211, 250, 68, 84, 69, 209, 208, 6, 70,
67, 25, 24, 52, 1, 112, 6, 48, 1, 69, 164, 216, 250, 188, 28, 70, 144, 70, 153, 70, 162, 188, 240, 188, 1, 71, 0, 70,
96, 231, 203, 36, 0, 231, 211, 70, 192, 181, 112, 76, 17, 28, 6, 104, 32, 176, 130, 28, 13, 98, 2, 97, 6, 100, 1, 97,
65, 33, 68, 247, 255, 252, 147, 28, 48, 28, 41, 247, 255, 252, 143, 75, 10, 34, 2, 104, 24, 104, 35, 73, 9, 147, 0,
35, 1, 247, 255, 252, 154, 28, 41, 28, 4, 28, 48, 247, 255, 252, 145, 176, 2, 28, 32, 188, 112, 188, 2, 71, 8, 19, 119,
240, 44, 19, 119, 240, 48, 87, 70, 83, 2, 181, 240, 176, 133, 28, 4, 28, 15, 146, 3, 40, 2, 216, 75, 77, 47, 104, 43,
43, 0, 208, 74, 78, 46, 104, 48, 40, 0, 219, 1, 247, 255, 252, 97, 74, 44, 0, 163, 88, 152, 33, 1, 247, 255, 252, 107,
96, 48, 40, 0, 219, 66, 104, 48, 40, 0, 219, 49, 104, 40, 28, 57, 34, 6, 48, 32, 247, 255, 252, 87, 104, 40, 169, 3,
34, 4, 48, 64, 247, 255, 252, 81, 104, 42, 36, 4, 28, 19, 51, 32, 96, 19, 104, 42, 35, 6, 96, 83, 104, 42, 33, 68, 28,
19, 51, 64, 96, 147, 104, 43, 96, 220, 104, 40, 247, 255, 252, 59, 104, 43, 104, 48, 34, 2, 147, 0, 73, 22, 35, 0, 247,
255, 252, 71, 104, 42, 28, 19, 51, 32, 96, 19, 104, 43, 96, 92, 104, 42, 28, 19, 51, 64, 96, 147, 104, 43, 96, 220,
176, 5, 188, 240, 188, 2, 71, 8, 32, 1, 66, 64, 231, 248, 75, 11, 78, 8, 96, 43, 35, 1, 66, 91, 96, 51, 231, 179, 44,
0, 209, 186, 72, 8, 33, 1, 247, 255, 252, 31, 96, 48, 231, 180, 70, 192, 19, 119, 240, 44, 19, 119, 240, 48, 19, 119,
235, 252, 87, 70, 83, 1, 19, 119, 240, 64, 19, 119, 235, 208, 233, 45, 64, 128, 229, 159, 113, 0, 229, 151, 112, 0,
235, 0, 0, 45, 232, 189, 64, 128, 225, 47, 255, 30, 233, 45, 64, 128, 229, 159, 112, 236, 229, 151, 112, 0, 235, 0,
0, 39, 232, 189, 64, 128, 225, 47, 255, 30, 233, 45, 64, 128, 229, 159, 112, 216, 229, 151, 112, 0, 235, 0, 0, 33, 232,
189, 64, 128, 225, 47, 255, 30, 233, 45, 64, 128, 229, 159, 112, 196, 229, 151, 112, 0, 235, 0, 0, 27, 232, 189, 64,
128, 225, 47, 255, 30, 233, 45, 64, 128, 229, 159, 112, 176, 229, 151, 112, 0, 235, 0, 0, 21, 232, 189, 64, 128, 225,
47, 255, 30, 233, 45, 64, 128, 229, 159, 112, 156, 229, 151, 112, 0, 235, 0, 0, 15, 232, 189, 64, 128, 225, 47, 255,
30, 230, 0, 8, 16, 225, 47, 255, 30, 230, 0, 7, 240, 225, 47, 255, 30, 230, 0, 3, 144, 225, 47, 255, 30, 230, 0, 3,
176, 225, 47, 255, 30, 230, 0, 3, 208, 225, 47, 255, 30, 230, 0, 3, 240, 225, 47, 255, 30, 230, 0, 4, 80, 225, 47, 255,
30, 225, 47, 255, 23, 239, 0, 0, 204, 225, 47, 255, 30, 180, 124, 181, 0, 247, 255, 253, 30, 188, 2, 188, 124, 71, 8,
181, 112, 176, 136, 104, 133, 28, 1, 75, 14, 71, 24, 70, 192, 70, 114, 28, 1, 32, 4, 223, 171, 71, 16, 181, 240, 70,
95, 70, 86, 70, 77, 70, 68, 180, 240, 75, 8, 104, 27, 71, 24, 19, 119, 224, 16, 19, 119, 224, 20, 19, 119, 224, 24,
19, 119, 224, 28, 19, 119, 224, 32, 19, 119, 224, 36, 32, 16, 0, 213, 19, 119, 224, 12, 70, 192, 70, 192, 19, 119, 228,
236, 19, 119, 228, 200, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120,
19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 190, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19,
119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119,
228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 229, 34, 19, 119, 228,
120, 19, 119, 229, 84, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 229, 44, 19, 119, 228, 120, 19, 119, 228, 120,
19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19,
119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119,
228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228,
120, 19, 119, 228, 120, 19, 119, 229, 142, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 229, 44,
19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 184, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19,
119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119,
228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228,
120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120,
19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19,
119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119,
228, 120, 19, 119, 228, 120, 19, 119, 229, 44, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228,
120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 229, 158, 19, 119, 228, 120,
19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 158, 19,
119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 230, 14, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119,
228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228,
120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 230, 6, 19, 119, 230, 2, 19, 119, 229, 250, 19, 119, 229, 246, 19,
119, 229, 230, 19, 119, 229, 214, 19, 119, 229, 204, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119,
228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 229, 190, 47, 100, 101,
118, 47, 117, 115, 98, 47, 101, 104, 99, 0, 0, 0, 0, 47, 100, 101, 118, 47, 117, 115, 98, 50, 0, 0, 0, 47, 100, 101,
118, 47, 115, 100, 105, 111, 47, 115, 100, 104, 99, 0, 0, 19, 119, 235, 224, 19, 119, 235, 236, 19, 119, 235, 208
};
#define size_dip_plugin 3080
unsigned char dip_plugin[3080] __attribute__((aligned (32)))={
19, 119, 228, 85, 18, 52, 0, 1, 32, 34, 205, 172, 32, 32, 13, 57, 32, 32, 8, 197, 32, 32, 8, 153, 32, 32, 91, 129, 32,
32, 0, 73, 32, 32, 40, 117, 32, 32, 54, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
19, 119, 233, 53, 70, 192, 70, 192, 70, 192, 70, 192, 70, 192, 70, 192, 70, 192, 71, 120, 234, 0, 2, 7, 70, 192, 71,
120, 234, 0, 2, 23, 70, 192, 71, 120, 234, 0, 2, 39, 70, 192, 71, 120, 234, 0, 2, 31, 70, 192, 71, 120, 234, 0, 2, 5,
70, 192, 71, 120, 234, 0, 1, 247, 70, 192, 71, 120, 234, 0, 2, 29, 70, 192, 71, 120, 234, 0, 2, 25, 70, 192, 71, 120,
234, 0, 2, 33, 181, 0, 75, 7, 176, 137, 147, 0, 70, 104, 35, 0, 33, 0, 34, 0, 147, 1, 147, 2, 240, 0, 252, 85, 176,
9, 188, 2, 71, 8, 70, 192, 227, 0, 0, 0, 181, 16, 28, 3, 34, 32, 28, 12, 72, 13, 28, 25, 247, 255, 255, 210, 33, 32,
72, 11, 247, 255, 255, 202, 73, 10, 34, 1, 104, 11, 66, 19, 209, 253, 34, 32, 28, 32, 73, 6, 247, 255, 255, 196, 28,
32, 33, 32, 247, 255, 255, 188, 75, 4, 104, 24, 188, 16, 188, 2, 71, 8, 70, 192, 13, 0, 96, 0, 13, 0, 96, 28, 13, 0,
96, 32, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 10, 203, 70, 154, 75, 20, 176, 137, 37, 0, 28, 7, 28, 14,
70, 145, 70, 108, 70, 155, 70, 168, 70, 91, 96, 35, 70, 67, 96, 99, 96, 163, 70, 83, 96, 227, 28, 56, 70, 75, 28, 49,
97, 35, 247, 255, 255, 162, 70, 104, 28, 57, 28, 50, 240, 0, 252, 6, 53, 1, 40, 0, 209, 8, 176, 9, 188, 60, 70, 144,
70, 153, 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 45, 15, 217, 223, 231, 243, 208, 0, 0, 0, 181, 112, 176, 136, 75,
8, 28, 6, 28, 13, 70, 108, 147, 0, 96, 97, 146, 2, 247, 255, 255, 129, 28, 49, 28, 42, 70, 104, 240, 0, 251, 229, 176,
8, 188, 112, 188, 2, 71, 8, 168, 0, 0, 0, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 176, 143, 144, 4, 145,
3, 146, 2, 41, 0, 209, 0, 224, 126, 10, 82, 70, 145, 35, 128, 34, 0, 1, 27, 70, 147, 34, 255, 147, 1, 3, 210, 171, 6,
146, 0, 70, 152, 224, 7, 154, 3, 68, 179, 69, 90, 217, 62, 154, 5, 24, 179, 10, 219, 68, 153, 154, 3, 70, 91, 26, 214,
70, 74, 2, 83, 154, 2, 66, 154, 216, 87, 35, 0, 147, 5, 36, 0, 159, 4, 34, 128, 68, 95, 28, 56, 28, 49, 1, 18, 240,
0, 248, 103, 44, 0, 209, 47, 40, 0, 208, 45, 155, 0, 28, 6, 66, 152, 217, 1, 38, 255, 3, 246, 10, 242, 70, 146, 36,
0, 75, 43, 70, 66, 96, 19, 35, 0, 96, 83, 96, 147, 70, 83, 96, 211, 70, 75, 97, 19, 28, 56, 28, 49, 247, 255, 255, 38,
70, 64, 28, 57, 28, 50, 240, 0, 251, 138, 52, 1, 28, 5, 40, 0, 208, 192, 44, 15, 217, 230, 45, 0, 208, 188, 176, 15,
28, 40, 188, 60, 70, 144, 70, 153, 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 154, 5, 25, 147, 154, 1, 66, 147, 217,
1, 155, 5, 26, 214, 32, 128, 1, 0, 33, 32, 247, 255, 254, 251, 28, 4, 40, 0, 208, 18, 33, 128, 1, 9, 70, 74, 247, 255,
255, 59, 28, 5, 40, 0, 208, 15, 28, 32, 247, 255, 254, 217, 231, 216, 26, 211, 0, 155, 28, 28, 147, 5, 30, 99, 65, 156,
231, 163, 37, 1, 66, 109, 231, 208, 37, 0, 231, 206, 154, 5, 28, 56, 24, 161, 28, 50, 247, 255, 254, 214, 28, 56, 28,
49, 247, 255, 254, 206, 231, 228, 70, 192, 208, 0, 0, 0, 181, 48, 28, 13, 28, 20, 6, 195, 209, 18, 75, 15, 66, 152,
217, 19, 33, 0, 75, 14, 24, 194, 75, 14, 66, 154, 216, 1, 75, 13, 26, 25, 66, 161, 211, 5, 28, 8, 66, 169, 216, 10,
30, 99, 67, 152, 224, 0, 32, 0, 188, 48, 188, 2, 71, 8, 35, 192, 4, 91, 26, 25, 231, 232, 28, 40, 30, 99, 67, 152, 231,
244, 1, 127, 255, 255, 240, 0, 0, 0, 3, 97, 127, 255, 19, 97, 128, 0, 71, 112, 70, 192, 181, 48, 28, 4, 72, 15, 28,
13, 104, 131, 104, 193, 176, 129, 24, 91, 24, 154, 105, 3, 43, 0, 209, 15, 104, 67, 43, 0, 209, 7, 28, 32, 28, 41, 247,
255, 255, 13, 176, 1, 188, 48, 188, 2, 71, 8, 28, 32, 28, 41, 247, 255, 255, 27, 231, 246, 28, 32, 28, 41, 240, 0, 249,
220, 231, 241, 70, 192, 19, 119, 240, 0, 181, 240, 79, 27, 35, 1, 28, 4, 96, 59, 176, 129, 33, 32, 247, 255, 254, 127,
104, 227, 43, 8, 208, 8, 28, 32, 240, 0, 250, 214, 35, 0, 96, 59, 176, 1, 188, 240, 188, 2, 71, 8, 105, 163, 37, 197,
104, 24, 104, 89, 247, 255, 254, 109, 105, 163, 1, 173, 104, 27, 28, 40, 33, 8, 104, 92, 104, 30, 247, 255, 254, 100,
75, 10, 4, 36, 64, 30, 67, 52, 78, 9, 96, 44, 28, 40, 33, 4, 96, 52, 247, 255, 254, 73, 28, 48, 33, 4, 247, 255, 254,
69, 35, 0, 96, 59, 32, 0, 231, 217, 70, 192, 19, 119, 240, 40, 0, 0, 255, 255, 0, 0, 49, 136, 181, 16, 73, 20, 28, 4,
104, 139, 104, 202, 24, 154, 105, 11, 43, 0, 209, 18, 104, 75, 43, 0, 209, 11, 33, 32, 247, 255, 254, 175, 40, 0, 219,
3, 105, 162, 75, 12, 66, 154, 208, 10, 188, 16, 188, 2, 71, 8, 33, 32, 247, 255, 254, 185, 231, 242, 33, 32, 240, 0,
249, 123, 231, 238, 75, 6, 34, 1, 112, 26, 120, 91, 43, 0, 209, 238, 247, 255, 254, 10, 231, 235, 70, 192, 19, 119,
240, 0, 93, 28, 158, 163, 32, 34, 205, 172, 181, 240, 70, 87, 70, 70, 180, 192, 28, 4, 120, 0, 176, 129, 28, 14, 28,
23, 40, 224, 208, 24, 77, 133, 35, 0, 98, 43, 28, 3, 59, 112, 43, 143, 217, 13, 28, 32, 28, 49, 28, 58, 240, 0, 250,
108, 28, 4, 176, 1, 28, 32, 188, 12, 70, 144, 70, 154, 188, 240, 188, 2, 71, 8, 74, 123, 0, 155, 88, 211, 70, 159, 77,
120, 106, 43, 43, 0, 209, 2, 105, 43, 43, 0, 208, 230, 28, 48, 33, 0, 28, 58, 240, 0, 248, 240, 106, 43, 224, 143, 104,
107, 43, 0, 209, 2, 105, 43, 43, 0, 208, 217, 36, 0, 231, 221, 35, 1, 34, 37, 84, 171, 104, 43, 43, 0, 208, 0, 224,
173, 28, 32, 28, 58, 240, 0, 250, 62, 28, 4, 34, 0, 35, 37, 84, 234, 44, 0, 209, 204, 224, 46, 104, 235, 104, 169, 70,
154, 105, 43, 70, 136, 43, 0, 209, 0, 224, 176, 32, 0, 34, 0, 70, 67, 70, 81, 67, 11, 209, 2, 42, 0, 209, 0, 224, 176,
28, 3, 30, 90, 65, 147, 96, 107, 28, 48, 28, 57, 247, 255, 255, 107, 28, 4, 231, 176, 105, 43, 43, 0, 208, 167, 35,
2, 224, 85, 104, 97, 104, 162, 40, 208, 209, 0, 224, 144, 28, 48, 247, 255, 254, 250, 28, 4, 40, 0, 209, 160, 35, 37,
92, 235, 43, 0, 209, 156, 28, 48, 28, 57, 247, 255, 254, 237, 231, 151, 35, 36, 92, 234, 42, 0, 209, 179, 105, 41, 84,
234, 35, 37, 96, 42, 96, 106, 96, 170, 96, 234, 98, 42, 84, 234, 70, 136, 41, 0, 209, 0, 231, 128, 105, 108, 247, 255,
253, 142, 70, 64, 28, 41, 28, 34, 56, 1, 49, 24, 240, 0, 248, 249, 28, 4, 231, 122, 104, 107, 43, 0, 208, 93, 75, 60,
36, 160, 98, 43, 2, 36, 231, 114, 104, 107, 43, 0, 209, 3, 105, 43, 43, 0, 209, 0, 231, 101, 104, 99, 104, 162, 7, 155,
67, 19, 74, 53, 36, 0, 64, 19, 96, 235, 231, 98, 104, 99, 72, 51, 64, 24, 247, 255, 253, 122, 28, 4, 231, 91, 104, 98,
35, 36, 84, 234, 36, 0, 231, 86, 105, 43, 96, 51, 28, 48, 28, 57, 247, 255, 253, 67, 36, 0, 231, 78, 104, 99, 97, 43,
43, 0, 209, 40, 105, 99, 36, 0, 97, 107, 231, 70, 104, 43, 231, 238, 104, 99, 36, 0, 96, 43, 231, 64, 104, 171, 231,
232, 104, 99, 36, 0, 96, 171, 231, 58, 104, 107, 43, 0, 209, 3, 105, 43, 43, 0, 209, 0, 231, 45, 28, 48, 33, 0, 28,
58, 240, 0, 248, 55, 28, 48, 28, 57, 247, 255, 253, 29, 36, 0, 231, 40, 104, 97, 104, 162, 28, 48, 247, 255, 254, 122,
28, 4, 231, 79, 28, 40, 28, 33, 49, 8, 34, 6, 48, 24, 247, 255, 253, 17, 231, 206, 105, 43, 43, 0, 209, 158, 231, 15,
2, 201, 2, 82, 231, 107, 28, 58, 28, 32, 28, 49, 240, 0, 249, 121, 28, 2, 30, 83, 65, 154, 231, 71, 105, 43, 43, 0,
208, 0, 231, 74, 96, 106, 36, 0, 231, 2, 70, 192, 19, 119, 240, 0, 19, 119, 233, 144, 0, 5, 49, 0, 255, 255, 128, 0,
127, 255, 255, 255, 181, 240, 70, 87, 70, 78, 70, 69, 180, 224, 70, 128, 28, 14, 70, 148, 42, 0, 208, 51, 33, 3, 28,
2, 64, 10, 35, 4, 26, 155, 28, 24, 64, 8, 69, 96, 216, 49, 40, 0, 208, 49, 36, 0, 70, 67, 85, 30, 52, 1, 66, 160, 216,
250, 69, 132, 208, 32, 70, 99, 26, 27, 8, 159, 70, 153, 0, 187, 70, 154, 43, 0, 208, 17, 4, 51, 6, 50, 2, 49, 67, 26,
67, 10, 28, 21, 70, 67, 67, 53, 24, 26, 33, 0, 0, 139, 49, 1, 80, 213, 66, 185, 211, 250, 68, 84, 69, 209, 208, 6, 70,
67, 25, 24, 52, 1, 112, 6, 48, 1, 69, 164, 216, 250, 188, 28, 70, 144, 70, 153, 70, 162, 188, 240, 188, 1, 71, 0, 70,
96, 231, 203, 36, 0, 231, 211, 70, 192, 181, 112, 76, 17, 28, 6, 104, 32, 176, 130, 28, 13, 98, 2, 97, 6, 100, 1, 97,
65, 33, 68, 247, 255, 252, 147, 28, 48, 28, 41, 247, 255, 252, 143, 75, 10, 34, 2, 104, 24, 104, 35, 73, 9, 147, 0,
35, 1, 247, 255, 252, 154, 28, 41, 28, 4, 28, 48, 247, 255, 252, 145, 176, 2, 28, 32, 188, 112, 188, 2, 71, 8, 19, 119,
240, 44, 19, 119, 240, 48, 87, 70, 83, 2, 181, 240, 176, 133, 28, 4, 28, 15, 146, 3, 40, 2, 216, 75, 77, 47, 104, 43,
43, 0, 208, 74, 78, 46, 104, 48, 40, 0, 219, 1, 247, 255, 252, 97, 74, 44, 0, 163, 88, 152, 33, 1, 247, 255, 252, 107,
96, 48, 40, 0, 219, 66, 104, 48, 40, 0, 219, 49, 104, 40, 28, 57, 34, 6, 48, 32, 247, 255, 252, 87, 104, 40, 169, 3,
34, 4, 48, 64, 247, 255, 252, 81, 104, 42, 36, 4, 28, 19, 51, 32, 96, 19, 104, 42, 35, 6, 96, 83, 104, 42, 33, 68, 28,
19, 51, 64, 96, 147, 104, 43, 96, 220, 104, 40, 247, 255, 252, 59, 104, 43, 104, 48, 34, 2, 147, 0, 73, 22, 35, 0, 247,
255, 252, 71, 104, 42, 28, 19, 51, 32, 96, 19, 104, 43, 96, 92, 104, 42, 28, 19, 51, 64, 96, 147, 104, 43, 96, 220,
176, 5, 188, 240, 188, 2, 71, 8, 32, 1, 66, 64, 231, 248, 75, 11, 78, 8, 96, 43, 35, 1, 66, 91, 96, 51, 231, 179, 44,
0, 209, 186, 72, 8, 33, 1, 247, 255, 252, 31, 96, 48, 231, 180, 70, 192, 19, 119, 240, 44, 19, 119, 240, 48, 19, 119,
235, 252, 87, 70, 83, 1, 19, 119, 240, 64, 19, 119, 235, 208, 233, 45, 64, 128, 229, 159, 113, 0, 229, 151, 112, 0,
235, 0, 0, 45, 232, 189, 64, 128, 225, 47, 255, 30, 233, 45, 64, 128, 229, 159, 112, 236, 229, 151, 112, 0, 235, 0,
0, 39, 232, 189, 64, 128, 225, 47, 255, 30, 233, 45, 64, 128, 229, 159, 112, 216, 229, 151, 112, 0, 235, 0, 0, 33, 232,
189, 64, 128, 225, 47, 255, 30, 233, 45, 64, 128, 229, 159, 112, 196, 229, 151, 112, 0, 235, 0, 0, 27, 232, 189, 64,
128, 225, 47, 255, 30, 233, 45, 64, 128, 229, 159, 112, 176, 229, 151, 112, 0, 235, 0, 0, 21, 232, 189, 64, 128, 225,
47, 255, 30, 233, 45, 64, 128, 229, 159, 112, 156, 229, 151, 112, 0, 235, 0, 0, 15, 232, 189, 64, 128, 225, 47, 255,
30, 230, 0, 8, 16, 225, 47, 255, 30, 230, 0, 7, 240, 225, 47, 255, 30, 230, 0, 3, 144, 225, 47, 255, 30, 230, 0, 3,
176, 225, 47, 255, 30, 230, 0, 3, 208, 225, 47, 255, 30, 230, 0, 3, 240, 225, 47, 255, 30, 230, 0, 4, 80, 225, 47, 255,
30, 225, 47, 255, 23, 239, 0, 0, 204, 225, 47, 255, 30, 180, 124, 181, 0, 247, 255, 253, 30, 188, 2, 188, 124, 71, 8,
181, 112, 176, 136, 104, 133, 28, 1, 75, 14, 71, 24, 70, 192, 70, 114, 28, 1, 32, 4, 223, 171, 71, 16, 181, 240, 70,
95, 70, 86, 70, 77, 70, 68, 180, 240, 75, 8, 104, 27, 71, 24, 19, 119, 224, 16, 19, 119, 224, 20, 19, 119, 224, 24,
19, 119, 224, 28, 19, 119, 224, 32, 19, 119, 224, 36, 32, 16, 0, 213, 19, 119, 224, 12, 70, 192, 70, 192, 19, 119, 228,
236, 19, 119, 228, 200, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120,
19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 190, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19,
119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119,
228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 229, 34, 19, 119, 228,
120, 19, 119, 229, 84, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 229, 44, 19, 119, 228, 120, 19, 119, 228, 120,
19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19,
119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119,
228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228,
120, 19, 119, 228, 120, 19, 119, 229, 142, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 229, 44,
19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 184, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19,
119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119,
228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228,
120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120,
19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19,
119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119,
228, 120, 19, 119, 228, 120, 19, 119, 229, 44, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228,
120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 229, 158, 19, 119, 228, 120,
19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 158, 19,
119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 230, 14, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119,
228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228,
120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 230, 6, 19, 119, 230, 2, 19, 119, 229, 250, 19, 119, 229, 246, 19,
119, 229, 230, 19, 119, 229, 214, 19, 119, 229, 204, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119,
228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 228, 120, 19, 119, 229, 190, 47, 100, 101,
118, 47, 117, 115, 98, 47, 101, 104, 99, 0, 0, 0, 0, 47, 100, 101, 118, 47, 117, 115, 98, 50, 0, 0, 0, 47, 100, 101,
118, 47, 115, 100, 105, 111, 47, 115, 100, 104, 99, 0, 0, 19, 119, 235, 224, 19, 119, 235, 236, 19, 119, 235, 208
};

View File

@ -1,3 +1,3 @@
#define size_dip_plugin 3080
extern unsigned char dip_plugin[3080];
#define size_dip_plugin 3080
extern unsigned char dip_plugin[3080];

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,3 @@
#define size_ehcmodule 32432
extern unsigned char ehcmodule[32432];
#define size_ehcmodule 32432
extern unsigned char ehcmodule[32432];

File diff suppressed because it is too large Load Diff

View File

@ -1,230 +1,230 @@
/* mload.c (for PPC) (c) 2009, Hermes
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __MLOAD_H__
#define __MLOAD_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ogcsys.h>
#include <gccore.h>
#include "unistd.h"
#define MLOAD_MLOAD_THREAD_ID 0x4D4C4400
#define MLOAD_GET_IOS_BASE 0x4D4C4401
#define MLOAD_LOAD_MODULE 0x4D4C4480
#define MLOAD_RUN_MODULE 0x4D4C4481
#define MLOAD_RUN_THREAD 0x4D4C4482
#define MLOAD_STOP_THREAD 0x4D4C4484
#define MLOAD_CONTINUE_THREAD 0x4D4C4485
#define MLOAD_GET_LOAD_BASE 0x4D4C4490
#define MLOAD_MEMSET 0x4D4C4491
#define MLOAD_GET_EHCI_DATA 0x4D4C44A0
#define MLOAD_GET_LOG 0x4D4C44A1
#define MLOAD_SET_ES_IOCTLV 0x4D4C44B0
#define MLOAD_GETW 0x4D4C44C0
#define MLOAD_GETH 0x4D4C44C1
#define MLOAD_GETB 0x4D4C44C2
#define MLOAD_SETW 0x4D4C44C3
#define MLOAD_SETH 0x4D4C44C4
#define MLOAD_SETB 0x4D4C44C5
#ifdef __cplusplus
extern "C" {
#endif
// from IOS ELF stripper of neimod
#define getbe32(x) ((adr[x]<<24) | (adr[x+1]<<16) | (adr[x+2]<<8) | (adr[x+3]))
typedef struct
{
u32 ident0;
u32 ident1;
u32 ident2;
u32 ident3;
u32 machinetype;
u32 version;
u32 entry;
u32 phoff;
u32 shoff;
u32 flags;
u16 ehsize;
u16 phentsize;
u16 phnum;
u16 shentsize;
u16 shnum;
u16 shtrndx;
} elfheader;
typedef struct
{
u32 type;
u32 offset;
u32 vaddr;
u32 paddr;
u32 filesz;
u32 memsz;
u32 flags;
u32 align;
} elfphentry;
typedef struct
{
void *start;
int prio;
void *stack;
int size_stack;
} data_elf;
/*--------------------------------------------------------------------------------------------------------------*/
// to init/test if the device is running
int mload_init();
/*--------------------------------------------------------------------------------------------------------------*/
// to close the device (remember call it when rebooting the IOS!)
int mload_close();
/*--------------------------------------------------------------------------------------------------------------*/
// to get the thread id of mload
int mload_get_thread_id();
/*--------------------------------------------------------------------------------------------------------------*/
// get the base and the size of the memory readable/writable to load modules
int mload_get_load_base(u32 *starlet_base, int *size);
/*--------------------------------------------------------------------------------------------------------------*/
// load and run a module from starlet (it need to allocate MEM2 to send the elf file)
// the module must be a elf made with stripios
int mload_module(void *addr, int len);
/*--------------------------------------------------------------------------------------------------------------*/
// load a module from the PPC
// the module must be a elf made with stripios
int mload_elf(void *my_elf, data_elf *data_elf);
/*--------------------------------------------------------------------------------------------------------------*/
// run one thread (you can use to load modules or binary files)
int mload_run_thread(void *starlet_addr, void *starlet_top_stack, int stack_size, int priority);
/*--------------------------------------------------------------------------------------------------------------*/
// stops one starlet thread
int mload_stop_thread(int id);
/*--------------------------------------------------------------------------------------------------------------*/
// continue one stopped starlet thread
int mload_continue_thread(int id);
/*--------------------------------------------------------------------------------------------------------------*/
// fix starlet address to read/write (uses SEEK_SET, etc as mode)
int mload_seek(int offset, int mode);
/*--------------------------------------------------------------------------------------------------------------*/
// read bytes from starlet (it update the offset)
int mload_read(void* buf, u32 size);
/*--------------------------------------------------------------------------------------------------------------*/
// write bytes from starlet (it update the offset)
int mload_write(const void * buf, u32 size);
/*--------------------------------------------------------------------------------------------------------------*/
// fill a block (similar to memset)
int mload_memset(void *starlet_addr, int set, int len);
/*--------------------------------------------------------------------------------------------------------------*/
// get the ehci datas ( ehcmodule.elf uses this address)
void * mload_get_ehci_data();
/*--------------------------------------------------------------------------------------------------------------*/
// set the dev/es ioctlv in routine
int mload_set_ES_ioctlv_vector(void *starlet_addr);
/*--------------------------------------------------------------------------------------------------------------*/
// to get log buffer
// this function return the size of the log buffer and prepare it to read with mload_read() the datas
int mload_get_log();
/*--------------------------------------------------------------------------------------------------------------*/
// to get IOS base for dev/es to create the cIOS
int mload_get_IOS_base();
/*--------------------------------------------------------------------------------------------------------------*/
int mload_getw(const void * addr, u32 *dat);
int mload_geth(const void * addr, u16 *dat);
int mload_getb(const void * addr, u8 *dat);
int mload_setw(const void * addr, u32 dat);
int mload_seth(const void * addr, u16 dat);
int mload_setb(const void * addr, u8 dat);
/*--------------------------------------------------------------------------------------------------------------*/
int load_ehc_module();
int patch_cios_data();
#ifdef __cplusplus
}
#endif
#endif
/* mload.c (for PPC) (c) 2009, Hermes
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __MLOAD_H__
#define __MLOAD_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ogcsys.h>
#include <gccore.h>
#include "unistd.h"
#define MLOAD_MLOAD_THREAD_ID 0x4D4C4400
#define MLOAD_GET_IOS_BASE 0x4D4C4401
#define MLOAD_LOAD_MODULE 0x4D4C4480
#define MLOAD_RUN_MODULE 0x4D4C4481
#define MLOAD_RUN_THREAD 0x4D4C4482
#define MLOAD_STOP_THREAD 0x4D4C4484
#define MLOAD_CONTINUE_THREAD 0x4D4C4485
#define MLOAD_GET_LOAD_BASE 0x4D4C4490
#define MLOAD_MEMSET 0x4D4C4491
#define MLOAD_GET_EHCI_DATA 0x4D4C44A0
#define MLOAD_GET_LOG 0x4D4C44A1
#define MLOAD_SET_ES_IOCTLV 0x4D4C44B0
#define MLOAD_GETW 0x4D4C44C0
#define MLOAD_GETH 0x4D4C44C1
#define MLOAD_GETB 0x4D4C44C2
#define MLOAD_SETW 0x4D4C44C3
#define MLOAD_SETH 0x4D4C44C4
#define MLOAD_SETB 0x4D4C44C5
#ifdef __cplusplus
extern "C" {
#endif
// from IOS ELF stripper of neimod
#define getbe32(x) ((adr[x]<<24) | (adr[x+1]<<16) | (adr[x+2]<<8) | (adr[x+3]))
typedef struct
{
u32 ident0;
u32 ident1;
u32 ident2;
u32 ident3;
u32 machinetype;
u32 version;
u32 entry;
u32 phoff;
u32 shoff;
u32 flags;
u16 ehsize;
u16 phentsize;
u16 phnum;
u16 shentsize;
u16 shnum;
u16 shtrndx;
} elfheader;
typedef struct
{
u32 type;
u32 offset;
u32 vaddr;
u32 paddr;
u32 filesz;
u32 memsz;
u32 flags;
u32 align;
} elfphentry;
typedef struct
{
void *start;
int prio;
void *stack;
int size_stack;
} data_elf;
/*--------------------------------------------------------------------------------------------------------------*/
// to init/test if the device is running
int mload_init();
/*--------------------------------------------------------------------------------------------------------------*/
// to close the device (remember call it when rebooting the IOS!)
int mload_close();
/*--------------------------------------------------------------------------------------------------------------*/
// to get the thread id of mload
int mload_get_thread_id();
/*--------------------------------------------------------------------------------------------------------------*/
// get the base and the size of the memory readable/writable to load modules
int mload_get_load_base(u32 *starlet_base, int *size);
/*--------------------------------------------------------------------------------------------------------------*/
// load and run a module from starlet (it need to allocate MEM2 to send the elf file)
// the module must be a elf made with stripios
int mload_module(void *addr, int len);
/*--------------------------------------------------------------------------------------------------------------*/
// load a module from the PPC
// the module must be a elf made with stripios
int mload_elf(void *my_elf, data_elf *data_elf);
/*--------------------------------------------------------------------------------------------------------------*/
// run one thread (you can use to load modules or binary files)
int mload_run_thread(void *starlet_addr, void *starlet_top_stack, int stack_size, int priority);
/*--------------------------------------------------------------------------------------------------------------*/
// stops one starlet thread
int mload_stop_thread(int id);
/*--------------------------------------------------------------------------------------------------------------*/
// continue one stopped starlet thread
int mload_continue_thread(int id);
/*--------------------------------------------------------------------------------------------------------------*/
// fix starlet address to read/write (uses SEEK_SET, etc as mode)
int mload_seek(int offset, int mode);
/*--------------------------------------------------------------------------------------------------------------*/
// read bytes from starlet (it update the offset)
int mload_read(void* buf, u32 size);
/*--------------------------------------------------------------------------------------------------------------*/
// write bytes from starlet (it update the offset)
int mload_write(const void * buf, u32 size);
/*--------------------------------------------------------------------------------------------------------------*/
// fill a block (similar to memset)
int mload_memset(void *starlet_addr, int set, int len);
/*--------------------------------------------------------------------------------------------------------------*/
// get the ehci datas ( ehcmodule.elf uses this address)
void * mload_get_ehci_data();
/*--------------------------------------------------------------------------------------------------------------*/
// set the dev/es ioctlv in routine
int mload_set_ES_ioctlv_vector(void *starlet_addr);
/*--------------------------------------------------------------------------------------------------------------*/
// to get log buffer
// this function return the size of the log buffer and prepare it to read with mload_read() the datas
int mload_get_log();
/*--------------------------------------------------------------------------------------------------------------*/
// to get IOS base for dev/es to create the cIOS
int mload_get_IOS_base();
/*--------------------------------------------------------------------------------------------------------------*/
int mload_getw(const void * addr, u32 *dat);
int mload_geth(const void * addr, u16 *dat);
int mload_getb(const void * addr, u8 *dat);
int mload_setw(const void * addr, u32 dat);
int mload_seth(const void * addr, u16 dat);
int mload_setb(const void * addr, u8 dat);
/*--------------------------------------------------------------------------------------------------------------*/
int load_ehc_module();
int patch_cios_data();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,38 +1,38 @@
/****************************************************************************
* URL List Class
* for USB Loader GX
* by dimok
***************************************************************************/
#ifndef ___URLLIST_H_
#define ___URLLIST_H_
#include "network/networkops.h"
#include "network/http.h"
typedef struct {
char *URL;
bool direct;
} Link_Info;
class URL_List {
public:
//!Constructor
//!\param url from where to get the list of links
URL_List(const char *url);
//!Destructor
~URL_List();
//! Get the a filepath of the list
//!\param list index
char * GetURL(int index);
//! Is it a direct URL or just a file or path under the main url
bool IsDirectURL(int index);
//! Get the number of links counted
int GetURLCount();
//! Sort list
void SortList();
protected:
int urlcount;
Link_Info *Links;
};
#endif
/****************************************************************************
* URL List Class
* for USB Loader GX
* by dimok
***************************************************************************/
#ifndef ___URLLIST_H_
#define ___URLLIST_H_
#include "network/networkops.h"
#include "network/http.h"
typedef struct {
char *URL;
bool direct;
} Link_Info;
class URL_List {
public:
//!Constructor
//!\param url from where to get the list of links
URL_List(const char *url);
//!Destructor
~URL_List();
//! Get the a filepath of the list
//!\param list index
char * GetURL(int index);
//! Is it a direct URL or just a file or path under the main url
bool IsDirectURL(int index);
//! Get the number of links counted
int GetURLCount();
//! Sort list
void SortList();
protected:
int urlcount;
Link_Info *Links;
};
#endif

View File

@ -1,371 +1,380 @@
/****************************************************************************
* Network Operations
* for USB Loader GX
*
* HTTP operations
* Written by dhewg/bushing modified by dimok
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <ogcsys.h>
#include <ogc/machine/processor.h>
#include "prompts/PromptWindows.h"
#include "language/gettext.h"
#include "settings/cfg.h"
#include "main.h"
#include "http.h"
#include "../svnrev.h"
#define PORT 4299
/*** Incomming filesize ***/
u32 infilesize = 0;
bool updateavailable = false;
s32 connection;
static s32 socket;
static bool updatechecked = false;
static bool networkinitialized = false;
static bool checkincomming = false;
static bool waitforanswer = false;
static char IP[16];
char incommingIP[50];
static lwp_t networkthread = LWP_THREAD_NULL;
static bool networkHalt = true;
/****************************************************************************
* Initialize_Network
***************************************************************************/
void Initialize_Network(void) {
if (networkinitialized) return;
s32 result;
result = if_config(IP, NULL, NULL, true);
if (result < 0) {
networkinitialized = false;
return;
} else {
networkinitialized = true;
return;
}
}
/****************************************************************************
* Check if network was initialised
***************************************************************************/
bool IsNetworkInit(void) {
return networkinitialized;
}
/****************************************************************************
* Get network IP
***************************************************************************/
char * GetNetworkIP(void) {
return IP;
}
/****************************************************************************
* Get incomming IP
***************************************************************************/
char * GetIncommingIP(void) {
return incommingIP;
}
/****************************************************************************
* Get network IP
***************************************************************************/
bool ShutdownWC24() {
bool onlinefix = IsNetworkInit();
if (onlinefix) {
s32 kd_fd, ret;
STACK_ALIGN(u8, kd_buf, 0x20, 32);
kd_fd = IOS_Open("/dev/net/kd/request", 0);
if (kd_fd >= 0) {
ret = IOS_Ioctl(kd_fd, 7, NULL, 0, kd_buf, 0x20);
if (ret >= 0)
onlinefix = false; // fixed no IOS reload needed
IOS_Close(kd_fd);
}
}
return onlinefix;
}
s32 network_request(const char * request) {
char buf[1024];
char *ptr = NULL;
u32 cnt, size;
s32 ret;
/* Send request */
ret = net_send(connection, request, strlen(request), 0);
if (ret < 0)
return ret;
/* Clear buffer */
memset(buf, 0, sizeof(buf));
/* Read HTTP header */
for (cnt = 0; !strstr(buf, "\r\n\r\n"); cnt++)
if (net_recv(connection, buf + cnt, 1, 0) <= 0)
return -1;
/* HTTP request OK? */
if (!strstr(buf, "HTTP/1.1 200 OK"))
return -1;
/* Retrieve content size */
ptr = strstr(buf, "Content-Length:");
if (!ptr)
return -1;
sscanf(ptr, "Content-Length: %u", &size);
return size;
}
s32 network_read(u8 *buf, u32 len) {
u32 read = 0;
s32 ret = -1;
/* Data to be read */
while (read < len) {
/* Read network data */
ret = net_read(connection, buf + read, len - read);
if (ret < 0)
return ret;
/* Read finished */
if (!ret)
break;
/* Increment read variable */
read += ret;
}
return read;
}
/****************************************************************************
* Download request
***************************************************************************/
s32 download_request(const char * url) {
//Check if the url starts with "http://", if not it is not considered a valid url
if (strncmp(url, "http://", strlen("http://")) != 0) {
return -1;
}
//Locate the path part of the url by searching for '/' past "http://"
char *path = strchr(url + strlen("http://"), '/');
//At the very least the url has to end with '/', ending with just a domain is invalid
if (path == NULL) {
return -1;
}
//Extract the domain part out of the url
int domainlength = path - url - strlen("http://");
if (domainlength == 0) {
return -1;
}
char domain[domainlength + 1];
strlcpy(domain, url + strlen("http://"), domainlength+1);
connection = GetConnection(domain);
if (connection < 0) {
return -1;
}
//Form a nice request header to send to the webserver
char header[strlen(path)+strlen(domain)+100];
sprintf(header, "GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", path, domain);
s32 filesize = network_request(header);
return filesize;
}
void CloseConnection() {
net_close(connection);
if (waitforanswer) {
net_close(socket);
waitforanswer = false;
}
}
/****************************************************************************
* NetworkWait
***************************************************************************/
int NetworkWait() {
if (!checkincomming)
return -3;
struct sockaddr_in sin;
struct sockaddr_in client_address;
socklen_t addrlen = sizeof(client_address);
//Open socket
socket = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (socket == INVALID_SOCKET) {
return socket;
}
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = htonl(INADDR_ANY);
if (net_bind(socket, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
net_close(socket);
return -1;
}
if (net_listen(socket, 3) < 0) {
net_close(socket);
return -1;
}
connection = net_accept(socket, (struct sockaddr*)&client_address, &addrlen);
sprintf(incommingIP, "%s", inet_ntoa(client_address.sin_addr));
if (connection < 0) {
net_close(connection);
net_close(socket);
return -4;
} else {
unsigned char haxx[9];
//skip haxx
net_read(connection, &haxx, 8);
net_read(connection, &infilesize, 4);
waitforanswer = true;
checkincomming = false;
networkHalt = true;
}
return 1;
}
/****************************************************************************
* Update check
***************************************************************************/
int CheckUpdate() {
if (!networkinitialized)
return -1;
int revnumber = 0;
int currentrev = atoi(GetRev());
#ifdef NOTFULLCHANNEL
struct block file = downloadfile("http://www.techjawa.com/usbloadergx/rev.txt");
#else
struct block file = downloadfile("http://www.techjawa.com/usbloadergx/wadrev.txt");
#endif
char revtxt[10];
u8 i;
if (file.data != NULL) {
for (i=0; i<9 || i < file.size; i++)
revtxt[i] = file.data[i];
revtxt[i] = 0;
revnumber = atoi(revtxt);
free(file.data);
}
if (revnumber > currentrev)
//if(revnumber > 1)//for testing updates
return revnumber;
else
return -1;
}
/****************************************************************************
* HaltNetwork
***************************************************************************/
void HaltNetworkThread() {
networkHalt = true;
checkincomming = false;
if (waitforanswer)
CloseConnection();
// wait for thread to finish
while (!LWP_ThreadIsSuspended(networkthread))
usleep(100);
}
/****************************************************************************
* ResumeNetworkThread
***************************************************************************/
void ResumeNetworkThread() {
networkHalt = false;
LWP_ResumeThread(networkthread);
}
/****************************************************************************
* Resume NetworkWait
***************************************************************************/
void ResumeNetworkWait() {
networkHalt = true;
checkincomming = true;
waitforanswer = true;
infilesize = 0;
connection = -1;
LWP_ResumeThread(networkthread);
}
/*********************************************************************************
* Networkthread for background network initialize and update check with idle prio
*********************************************************************************/
static void * networkinitcallback(void *arg) {
while (1) {
if (!checkincomming && networkHalt)
LWP_SuspendThread(networkthread);
Initialize_Network();
if (networkinitialized == true && updatechecked == false) {
if (CheckUpdate() > 0)
updateavailable = true;
//suspend thread
updatechecked = true;
networkHalt = true;
checkincomming = false;
}
if (checkincomming)
NetworkWait();
}
return NULL;
}
/****************************************************************************
* InitNetworkThread with priority 0 (idle)
***************************************************************************/
void InitNetworkThread() {
LWP_CreateThread (&networkthread, networkinitcallback, NULL, NULL, 0, 0);
}
/****************************************************************************
* ShutdownThread
***************************************************************************/
void ShutdownNetworkThread() {
LWP_JoinThread (networkthread, NULL);
networkthread = LWP_THREAD_NULL;
}
/****************************************************************************
* Network Operations
* for USB Loader GX
*
* HTTP operations
* Written by dhewg/bushing modified by dimok
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <ogcsys.h>
#include <ogc/machine/processor.h>
#include "prompts/PromptWindows.h"
#include "language/gettext.h"
#include "settings/cfg.h"
#include "main.h"
#include "http.h"
#include "../svnrev.h"
#define PORT 4299
/*** Incomming filesize ***/
u32 infilesize = 0;
u32 uncfilesize = 0;
bool updateavailable = false;
s32 connection;
static s32 socket;
static bool updatechecked = false;
static bool networkinitialized = false;
static bool checkincomming = false;
static bool waitforanswer = false;
static char IP[16];
char incommingIP[50];
char wiiloadVersion[2];
static lwp_t networkthread = LWP_THREAD_NULL;
static bool networkHalt = true;
/****************************************************************************
* Initialize_Network
***************************************************************************/
void Initialize_Network(void) {
if (networkinitialized) return;
s32 result;
result = if_config(IP, NULL, NULL, true);
if (result < 0) {
networkinitialized = false;
return;
} else {
networkinitialized = true;
return;
}
}
/****************************************************************************
* Check if network was initialised
***************************************************************************/
bool IsNetworkInit(void) {
return networkinitialized;
}
/****************************************************************************
* Get network IP
***************************************************************************/
char * GetNetworkIP(void) {
return IP;
}
/****************************************************************************
* Get incomming IP
***************************************************************************/
char * GetIncommingIP(void) {
return incommingIP;
}
/****************************************************************************
* Get network IP
***************************************************************************/
bool ShutdownWC24() {
bool onlinefix = IsNetworkInit();
if (onlinefix) {
s32 kd_fd, ret;
STACK_ALIGN(u8, kd_buf, 0x20, 32);
kd_fd = IOS_Open("/dev/net/kd/request", 0);
if (kd_fd >= 0) {
ret = IOS_Ioctl(kd_fd, 7, NULL, 0, kd_buf, 0x20);
if (ret >= 0)
onlinefix = false; // fixed no IOS reload needed
IOS_Close(kd_fd);
}
}
return onlinefix;
}
s32 network_request(const char * request) {
char buf[1024];
char *ptr = NULL;
u32 cnt, size;
s32 ret;
/* Send request */
ret = net_send(connection, request, strlen(request), 0);
if (ret < 0)
return ret;
/* Clear buffer */
memset(buf, 0, sizeof(buf));
/* Read HTTP header */
for (cnt = 0; !strstr(buf, "\r\n\r\n"); cnt++)
if (net_recv(connection, buf + cnt, 1, 0) <= 0)
return -1;
/* HTTP request OK? */
if (!strstr(buf, "HTTP/1.1 200 OK"))
return -1;
/* Retrieve content size */
ptr = strstr(buf, "Content-Length:");
if (!ptr)
return -1;
sscanf(ptr, "Content-Length: %u", &size);
return size;
}
s32 network_read(u8 *buf, u32 len) {
u32 read = 0;
s32 ret = -1;
/* Data to be read */
while (read < len) {
/* Read network data */
ret = net_read(connection, buf + read, len - read);
if (ret < 0)
return ret;
/* Read finished */
if (!ret)
break;
/* Increment read variable */
read += ret;
}
return read;
}
/****************************************************************************
* Download request
***************************************************************************/
s32 download_request(const char * url) {
//Check if the url starts with "http://", if not it is not considered a valid url
if (strncmp(url, "http://", strlen("http://")) != 0) {
return -1;
}
//Locate the path part of the url by searching for '/' past "http://"
char *path = strchr(url + strlen("http://"), '/');
//At the very least the url has to end with '/', ending with just a domain is invalid
if (path == NULL) {
return -1;
}
//Extract the domain part out of the url
int domainlength = path - url - strlen("http://");
if (domainlength == 0) {
return -1;
}
char domain[domainlength + 1];
strlcpy(domain, url + strlen("http://"), domainlength+1);
connection = GetConnection(domain);
if (connection < 0) {
return -1;
}
//Form a nice request header to send to the webserver
char header[strlen(path)+strlen(domain)+100];
sprintf(header, "GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", path, domain);
s32 filesize = network_request(header);
return filesize;
}
void CloseConnection() {
net_close(connection);
if (waitforanswer) {
net_close(socket);
waitforanswer = false;
}
}
/****************************************************************************
* NetworkWait
***************************************************************************/
int NetworkWait() {
if (!checkincomming)
return -3;
struct sockaddr_in sin;
struct sockaddr_in client_address;
socklen_t addrlen = sizeof(client_address);
//Open socket
socket = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (socket == INVALID_SOCKET) {
return socket;
}
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = htonl(INADDR_ANY);
if (net_bind(socket, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
net_close(socket);
return -1;
}
if (net_listen(socket, 3) < 0) {
net_close(socket);
return -1;
}
connection = net_accept(socket, (struct sockaddr*)&client_address, &addrlen);
sprintf(incommingIP, "%s", inet_ntoa(client_address.sin_addr));
if (connection < 0) {
net_close(connection);
net_close(socket);
return -4;
} else {
unsigned char haxx[9];
//skip haxx
net_read(connection, &haxx, 8);
wiiloadVersion[0] = haxx[4];
wiiloadVersion[1] = haxx[5];
net_read(connection, &infilesize, 4);
if (haxx[4] > 0 || haxx[5] > 4) {
net_read(connection, &uncfilesize, 4); // Compressed protocol, read another 4 bytes
}
waitforanswer = true;
checkincomming = false;
networkHalt = true;
}
return 1;
}
/****************************************************************************
* Update check
***************************************************************************/
int CheckUpdate() {
if (!networkinitialized)
return -1;
int revnumber = 0;
int currentrev = atoi(GetRev());
#ifdef NOTFULLCHANNEL
struct block file = downloadfile("http://www.techjawa.com/usbloadergx/rev.txt");
#else
struct block file = downloadfile("http://www.techjawa.com/usbloadergx/wadrev.txt");
#endif
char revtxt[10];
u8 i;
if (file.data != NULL) {
for (i=0; i<9 || i < file.size; i++)
revtxt[i] = file.data[i];
revtxt[i] = 0;
revnumber = atoi(revtxt);
free(file.data);
}
if (revnumber > currentrev)
//if(revnumber > 1)//for testing updates
return revnumber;
else
return -1;
}
/****************************************************************************
* HaltNetwork
***************************************************************************/
void HaltNetworkThread() {
networkHalt = true;
checkincomming = false;
if (waitforanswer)
CloseConnection();
// wait for thread to finish
while (!LWP_ThreadIsSuspended(networkthread))
usleep(100);
}
/****************************************************************************
* ResumeNetworkThread
***************************************************************************/
void ResumeNetworkThread() {
networkHalt = false;
LWP_ResumeThread(networkthread);
}
/****************************************************************************
* Resume NetworkWait
***************************************************************************/
void ResumeNetworkWait() {
networkHalt = true;
checkincomming = true;
waitforanswer = true;
infilesize = 0;
connection = -1;
LWP_ResumeThread(networkthread);
}
/*********************************************************************************
* Networkthread for background network initialize and update check with idle prio
*********************************************************************************/
static void * networkinitcallback(void *arg) {
while (1) {
if (!checkincomming && networkHalt)
LWP_SuspendThread(networkthread);
Initialize_Network();
if (networkinitialized == true && updatechecked == false) {
if (CheckUpdate() > 0)
updateavailable = true;
//suspend thread
updatechecked = true;
networkHalt = true;
checkincomming = false;
}
if (checkincomming)
NetworkWait();
}
return NULL;
}
/****************************************************************************
* InitNetworkThread with priority 0 (idle)
***************************************************************************/
void InitNetworkThread() {
LWP_CreateThread (&networkthread, networkinitcallback, NULL, NULL, 0, 0);
}
/****************************************************************************
* ShutdownThread
***************************************************************************/
void ShutdownNetworkThread() {
LWP_JoinThread (networkthread, NULL);
networkthread = LWP_THREAD_NULL;
}

View File

@ -1,336 +1,336 @@
/*
Copyright (c) 2008 Francisco Muñoz 'Hermes' <www.elotrolado.net>
All rights reserved.
Threading modifications/corrections by Tantric, 2009
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "oggplayer.h"
#include <gccore.h>
#include <malloc.h>
#include <stdlib.h>
#include <unistd.h>
/* OGG control */
#define READ_SAMPLES 4096 // samples that it must read before to send
#define MAX_PCMOUT 4096 // minimum size to read ogg samples
typedef struct {
OggVorbis_File vf;
vorbis_info *vi;
int current_section;
// OGG file operation
int fd;
int mode;
int eof;
int flag;
int volume;
int seek_time;
/* OGG buffer control */
short pcmout[2][READ_SAMPLES + MAX_PCMOUT * 2]; /* take 4k out of the data segment, not the stack */
int pcmout_pos;
int pcm_indx;
} private_data_ogg;
static private_data_ogg private_ogg;
// OGG thread control
#define STACKSIZE 8192
static u8 oggplayer_stack[STACKSIZE];
static lwpq_t oggplayer_queue = LWP_THREAD_NULL;
static lwp_t h_oggplayer = LWP_THREAD_NULL;
static int ogg_thread_running = 0;
static void ogg_add_callback(int voice) {
if (!ogg_thread_running) {
ASND_StopVoice(0);
return;
}
if (private_ogg.flag & 128)
return; // Ogg is paused
if (private_ogg.pcm_indx >= READ_SAMPLES) {
if (ASND_AddVoice(0,
(void *) private_ogg.pcmout[private_ogg.pcmout_pos],
private_ogg.pcm_indx << 1) == 0) {
private_ogg.pcmout_pos ^= 1;
private_ogg.pcm_indx = 0;
private_ogg.flag = 0;
LWP_ThreadSignal(oggplayer_queue);
}
} else {
if (private_ogg.flag & 64) {
private_ogg.flag &= ~64;
LWP_ThreadSignal(oggplayer_queue);
}
}
}
static void * ogg_player_thread(private_data_ogg * priv) {
int first_time = 1;
long ret;
ogg_thread_running = 0;
//init
LWP_InitQueue(&oggplayer_queue);
priv[0].vi = ov_info(&priv[0].vf, -1);
ASND_Pause(0);
priv[0].pcm_indx = 0;
priv[0].pcmout_pos = 0;
priv[0].eof = 0;
priv[0].flag = 0;
priv[0].current_section = 0;
ogg_thread_running = 1;
while (!priv[0].eof && ogg_thread_running) {
if (priv[0].flag)
LWP_ThreadSleep(oggplayer_queue); // wait only when i have samples to send
if (priv[0].flag == 0) { // wait to all samples are sended
if (ASND_TestPointer(0, priv[0].pcmout[priv[0].pcmout_pos])
&& ASND_StatusVoice(0) != SND_UNUSED) {
priv[0].flag |= 64;
continue;
}
if (priv[0].pcm_indx < READ_SAMPLES) {
priv[0].flag = 3;
if (priv[0].seek_time >= 0) {
ov_time_seek(&priv[0].vf, priv[0].seek_time);
priv[0].seek_time = -1;
}
ret
= ov_read(
&priv[0].vf,
(void *) &priv[0].pcmout[priv[0].pcmout_pos][priv[0].pcm_indx],
MAX_PCMOUT,/*0,2,1,*/&priv[0].current_section);
priv[0].flag &= 192;
if (ret == 0) {
/* EOF */
if (priv[0].mode & 1)
ov_time_seek(&priv[0].vf, 0); // repeat
else
priv[0].eof = 1; // stops
//
} else if (ret < 0) {
/* error in the stream. Not a problem, just reporting it in
case we (the app) cares. In this case, we don't. */
if (ret != OV_HOLE) {
if (priv[0].mode & 1)
ov_time_seek(&priv[0].vf, 0); // repeat
else
priv[0].eof = 1; // stops
}
} else {
/* we don't bother dealing with sample rate changes, etc, but
you'll have to*/
priv[0].pcm_indx += ret >> 1; //get 16 bits samples
}
} else
priv[0].flag = 1;
}
if (priv[0].flag == 1) {
if (ASND_StatusVoice(0) == SND_UNUSED || first_time) {
first_time = 0;
if (priv[0].vi->channels == 2) {
ASND_SetVoice(0, VOICE_STEREO_16BIT, priv[0].vi->rate, 0,
(void *) priv[0].pcmout[priv[0].pcmout_pos],
priv[0].pcm_indx << 1, priv[0].volume,
priv[0].volume, ogg_add_callback);
priv[0].pcmout_pos ^= 1;
priv[0].pcm_indx = 0;
priv[0].flag = 0;
} else {
ASND_SetVoice(0, VOICE_MONO_16BIT, priv[0].vi->rate, 0,
(void *) priv[0].pcmout[priv[0].pcmout_pos],
priv[0].pcm_indx << 1, priv[0].volume,
priv[0].volume, ogg_add_callback);
priv[0].pcmout_pos ^= 1;
priv[0].pcm_indx = 0;
priv[0].flag = 0;
}
}
}
usleep(100);
}
ov_clear(&priv[0].vf);
priv[0].fd = -1;
priv[0].pcm_indx = 0;
ogg_thread_running = 0;
return 0;
}
void StopOgg() {
ASND_StopVoice(0);
ogg_thread_running = 0;
if (h_oggplayer != LWP_THREAD_NULL) {
if (oggplayer_queue != LWP_TQUEUE_NULL)
LWP_ThreadSignal(oggplayer_queue);
LWP_JoinThread(h_oggplayer, NULL);
h_oggplayer = LWP_THREAD_NULL;
}
if (oggplayer_queue != LWP_TQUEUE_NULL) {
LWP_CloseQueue(oggplayer_queue);
oggplayer_queue = LWP_TQUEUE_NULL;
}
}
int PlayOgg(int fd, int time_pos, int mode) {
StopOgg();
private_ogg.fd = fd;
private_ogg.mode = mode;
private_ogg.eof = 0;
private_ogg.volume = 127;
private_ogg.flag = 0;
private_ogg.seek_time = -1;
if (time_pos > 0)
private_ogg.seek_time = time_pos;
if (fd < 0) {
private_ogg.fd = -1;
return -1;
}
if (ov_open((void *) &private_ogg.fd, &private_ogg.vf, NULL, 0) < 0) {
mem_close(private_ogg.fd); // mem_close() can too close files from devices
private_ogg.fd = -1;
ogg_thread_running = 0;
return -1;
}
if (LWP_CreateThread(&h_oggplayer, (void *) ogg_player_thread,
&private_ogg, oggplayer_stack, STACKSIZE, 80) == -1) {
ogg_thread_running = 0;
ov_clear(&private_ogg.vf);
private_ogg.fd = -1;
return -1;
}
return 0;
}
int PlayOggFromFile(char * path, int loop) {
StopOgg();
u32 filesize = 0;
char * bufferogg = NULL;
size_t resultogg;
FILE * pFile;
pFile = fopen (path, "rb");
//Check that pFile exist
if (pFile==NULL) {
return -1;
}
// get file size:
fseek (pFile , 0 , SEEK_END);
filesize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
bufferogg = (char*) malloc (sizeof(char)*filesize);
if (bufferogg == NULL) {
fputs (" Memory error",stderr);
exit (2);
}
// copy the file into the buffer:
resultogg = fread (bufferogg,1,filesize,pFile);
if (resultogg != filesize) {
fputs (" Reading error",stderr);
exit (3);
}
fclose (pFile);
if (loop)
return PlayOgg(mem_open((char *)bufferogg, filesize), 0, OGG_INFINITE_TIME);
else
return PlayOgg(mem_open((char *)bufferogg, filesize), 0, OGG_ONE_TIME);
}
void PauseOgg(int pause) {
if (pause) {
private_ogg.flag |= 128;
} else {
if (private_ogg.flag & 128) {
private_ogg.flag |= 64;
private_ogg.flag &= ~128;
if (ogg_thread_running > 0) {
LWP_ThreadSignal(oggplayer_queue);
}
}
}
}
int StatusOgg() {
if (ogg_thread_running == 0)
return -1; // Error
else if (private_ogg.eof)
return 255; // EOF
else if (private_ogg.flag & 128)
return 2; // paused
else
return 1; // running
}
void SetVolumeOgg(int volume) {
private_ogg.volume = volume;
ASND_ChangeVolumeVoice(0, volume, volume);
}
s32 GetTimeOgg() {
int ret;
if (ogg_thread_running == 0 || private_ogg.fd < 0)
return 0;
ret = ((s32) ov_time_tell(&private_ogg.vf));
if (ret < 0)
ret = 0;
return ret;
}
void SetTimeOgg(s32 time_pos) {
if (time_pos >= 0)
private_ogg.seek_time = time_pos;
}
/*
Copyright (c) 2008 Francisco Muñoz 'Hermes' <www.elotrolado.net>
All rights reserved.
Threading modifications/corrections by Tantric, 2009
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "oggplayer.h"
#include <gccore.h>
#include <malloc.h>
#include <stdlib.h>
#include <unistd.h>
/* OGG control */
#define READ_SAMPLES 4096 // samples that it must read before to send
#define MAX_PCMOUT 4096 // minimum size to read ogg samples
typedef struct {
OggVorbis_File vf;
vorbis_info *vi;
int current_section;
// OGG file operation
int fd;
int mode;
int eof;
int flag;
int volume;
int seek_time;
/* OGG buffer control */
short pcmout[2][READ_SAMPLES + MAX_PCMOUT * 2]; /* take 4k out of the data segment, not the stack */
int pcmout_pos;
int pcm_indx;
} private_data_ogg;
static private_data_ogg private_ogg;
// OGG thread control
#define STACKSIZE 8192
static u8 oggplayer_stack[STACKSIZE];
static lwpq_t oggplayer_queue = LWP_THREAD_NULL;
static lwp_t h_oggplayer = LWP_THREAD_NULL;
static int ogg_thread_running = 0;
static void ogg_add_callback(int voice) {
if (!ogg_thread_running) {
ASND_StopVoice(0);
return;
}
if (private_ogg.flag & 128)
return; // Ogg is paused
if (private_ogg.pcm_indx >= READ_SAMPLES) {
if (ASND_AddVoice(0,
(void *) private_ogg.pcmout[private_ogg.pcmout_pos],
private_ogg.pcm_indx << 1) == 0) {
private_ogg.pcmout_pos ^= 1;
private_ogg.pcm_indx = 0;
private_ogg.flag = 0;
LWP_ThreadSignal(oggplayer_queue);
}
} else {
if (private_ogg.flag & 64) {
private_ogg.flag &= ~64;
LWP_ThreadSignal(oggplayer_queue);
}
}
}
static void * ogg_player_thread(private_data_ogg * priv) {
int first_time = 1;
long ret;
ogg_thread_running = 0;
//init
LWP_InitQueue(&oggplayer_queue);
priv[0].vi = ov_info(&priv[0].vf, -1);
ASND_Pause(0);
priv[0].pcm_indx = 0;
priv[0].pcmout_pos = 0;
priv[0].eof = 0;
priv[0].flag = 0;
priv[0].current_section = 0;
ogg_thread_running = 1;
while (!priv[0].eof && ogg_thread_running) {
if (priv[0].flag)
LWP_ThreadSleep(oggplayer_queue); // wait only when i have samples to send
if (priv[0].flag == 0) { // wait to all samples are sended
if (ASND_TestPointer(0, priv[0].pcmout[priv[0].pcmout_pos])
&& ASND_StatusVoice(0) != SND_UNUSED) {
priv[0].flag |= 64;
continue;
}
if (priv[0].pcm_indx < READ_SAMPLES) {
priv[0].flag = 3;
if (priv[0].seek_time >= 0) {
ov_time_seek(&priv[0].vf, priv[0].seek_time);
priv[0].seek_time = -1;
}
ret
= ov_read(
&priv[0].vf,
(void *) &priv[0].pcmout[priv[0].pcmout_pos][priv[0].pcm_indx],
MAX_PCMOUT,/*0,2,1,*/&priv[0].current_section);
priv[0].flag &= 192;
if (ret == 0) {
/* EOF */
if (priv[0].mode & 1)
ov_time_seek(&priv[0].vf, 0); // repeat
else
priv[0].eof = 1; // stops
//
} else if (ret < 0) {
/* error in the stream. Not a problem, just reporting it in
case we (the app) cares. In this case, we don't. */
if (ret != OV_HOLE) {
if (priv[0].mode & 1)
ov_time_seek(&priv[0].vf, 0); // repeat
else
priv[0].eof = 1; // stops
}
} else {
/* we don't bother dealing with sample rate changes, etc, but
you'll have to*/
priv[0].pcm_indx += ret >> 1; //get 16 bits samples
}
} else
priv[0].flag = 1;
}
if (priv[0].flag == 1) {
if (ASND_StatusVoice(0) == SND_UNUSED || first_time) {
first_time = 0;
if (priv[0].vi->channels == 2) {
ASND_SetVoice(0, VOICE_STEREO_16BIT, priv[0].vi->rate, 0,
(void *) priv[0].pcmout[priv[0].pcmout_pos],
priv[0].pcm_indx << 1, priv[0].volume,
priv[0].volume, ogg_add_callback);
priv[0].pcmout_pos ^= 1;
priv[0].pcm_indx = 0;
priv[0].flag = 0;
} else {
ASND_SetVoice(0, VOICE_MONO_16BIT, priv[0].vi->rate, 0,
(void *) priv[0].pcmout[priv[0].pcmout_pos],
priv[0].pcm_indx << 1, priv[0].volume,
priv[0].volume, ogg_add_callback);
priv[0].pcmout_pos ^= 1;
priv[0].pcm_indx = 0;
priv[0].flag = 0;
}
}
}
usleep(100);
}
ov_clear(&priv[0].vf);
priv[0].fd = -1;
priv[0].pcm_indx = 0;
ogg_thread_running = 0;
return 0;
}
void StopOgg() {
ASND_StopVoice(0);
ogg_thread_running = 0;
if (h_oggplayer != LWP_THREAD_NULL) {
if (oggplayer_queue != LWP_TQUEUE_NULL)
LWP_ThreadSignal(oggplayer_queue);
LWP_JoinThread(h_oggplayer, NULL);
h_oggplayer = LWP_THREAD_NULL;
}
if (oggplayer_queue != LWP_TQUEUE_NULL) {
LWP_CloseQueue(oggplayer_queue);
oggplayer_queue = LWP_TQUEUE_NULL;
}
}
int PlayOgg(int fd, int time_pos, int mode) {
StopOgg();
private_ogg.fd = fd;
private_ogg.mode = mode;
private_ogg.eof = 0;
private_ogg.volume = 127;
private_ogg.flag = 0;
private_ogg.seek_time = -1;
if (time_pos > 0)
private_ogg.seek_time = time_pos;
if (fd < 0) {
private_ogg.fd = -1;
return -1;
}
if (ov_open((void *) &private_ogg.fd, &private_ogg.vf, NULL, 0) < 0) {
mem_close(private_ogg.fd); // mem_close() can too close files from devices
private_ogg.fd = -1;
ogg_thread_running = 0;
return -1;
}
if (LWP_CreateThread(&h_oggplayer, (void *) ogg_player_thread,
&private_ogg, oggplayer_stack, STACKSIZE, 80) == -1) {
ogg_thread_running = 0;
ov_clear(&private_ogg.vf);
private_ogg.fd = -1;
return -1;
}
return 0;
}
int PlayOggFromFile(char * path, int loop) {
StopOgg();
u32 filesize = 0;
char * bufferogg = NULL;
size_t resultogg;
FILE * pFile;
pFile = fopen (path, "rb");
//Check that pFile exist
if (pFile==NULL) {
return -1;
}
// get file size:
fseek (pFile , 0 , SEEK_END);
filesize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
bufferogg = (char*) malloc (sizeof(char)*filesize);
if (bufferogg == NULL) {
fputs (" Memory error",stderr);
exit (2);
}
// copy the file into the buffer:
resultogg = fread (bufferogg,1,filesize,pFile);
if (resultogg != filesize) {
fputs (" Reading error",stderr);
exit (3);
}
fclose (pFile);
if (loop)
return PlayOgg(mem_open((char *)bufferogg, filesize), 0, OGG_INFINITE_TIME);
else
return PlayOgg(mem_open((char *)bufferogg, filesize), 0, OGG_ONE_TIME);
}
void PauseOgg(int pause) {
if (pause) {
private_ogg.flag |= 128;
} else {
if (private_ogg.flag & 128) {
private_ogg.flag |= 64;
private_ogg.flag &= ~128;
if (ogg_thread_running > 0) {
LWP_ThreadSignal(oggplayer_queue);
}
}
}
}
int StatusOgg() {
if (ogg_thread_running == 0)
return -1; // Error
else if (private_ogg.eof)
return 255; // EOF
else if (private_ogg.flag & 128)
return 2; // paused
else
return 1; // running
}
void SetVolumeOgg(int volume) {
private_ogg.volume = volume;
ASND_ChangeVolumeVoice(0, volume, volume);
}
s32 GetTimeOgg() {
int ret;
if (ogg_thread_running == 0 || private_ogg.fd < 0)
return 0;
ret = ((s32) ov_time_tell(&private_ogg.vf));
if (ret < 0)
ret = 0;
return ret;
}
void SetTimeOgg(s32 time_pos) {
if (time_pos >= 0)
private_ogg.seek_time = time_pos;
}

View File

@ -1,175 +1,175 @@
/*
Copyright (c) 2008 Francisco Muñoz 'Hermes' <www.elotrolado.net>
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __OGGPLAYER_H__
#define __OGGPLAYER_H__
#include <asndlib.h>
#include "tremor/ivorbiscodec.h"
#include "tremor/ivorbisfile.h"
#ifdef __cplusplus
extern "C" {
#endif
#define OGG_ONE_TIME 0
#define OGG_INFINITE_TIME 1
#define OGG_STATUS_RUNNING 1
#define OGG_STATUS_ERR -1
#define OGG_STATUS_PAUSED 2
#define OGG_STATUS_EOF 255
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* Player OGG functions */
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* int PlayOgg(int fd, int time_pos, int mode);
Play an Ogg file. This file can be loaded from memory (mem_open(void *ogg, int size_ogg)) or from device with open("device:file.ogg",O_RDONLY,0);
NOTE: The file is closed by the player when you call PlayOgg(), StopOgg() or if it fail.
-- Params ---
fd: file descriptor from open() or mem_open()
time_pos: initial time position in the file (in milliseconds). For example, use 30000 to advance 30 seconds
mode: Use OGG_ONE_TIME or OGG_INFINITE_TIME. When you use OGG_ONE_TIME the sound stops and StatusOgg() return OGG_STATUS_EOF
return: 0- Ok, -1 Error
*/
int PlayOgg(int fd, int time_pos, int mode);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* int PlayOgg(char * path, int loop);
Just give the function the full device+path to OGG to play it
loop = 1 for Loop and 0 for one time playing
*/
int PlayOggFromFile(char * path, int loop);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void StopOgg();
Stop an Ogg file.
NOTE: The file is closed and the player thread is released
-- Params ---
*/
void StopOgg();
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void PauseOgg(int pause);
Pause an Ogg file.
-- Params ---
pause: 0 -> continue, 1-> pause
*/
void PauseOgg(int pause);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* int StatusOgg();
Return the Ogg status
-- Params ---
return: OGG_STATUS_RUNNING
OGG_STATUS_ERR -> not initialized?
OGG_STATUS_PAUSED
OGG_STATUS_EOF -> player stopped by End Of File
*/
int StatusOgg();
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void SetVolumeOgg(int volume);
Set the Ogg playing volume.
NOTE: it change the volume of voice 0 (used for the Ogg player)
-- Params ---
volume: 0 to 255 (max)
*/
void SetVolumeOgg(int volume);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* s32 GetTimeOgg();
Return the Ogg time from the starts of the file
-- Params ---
return: 0 -> Ok or error condition (you must ignore this value)
>0 -> time in milliseconds from the starts
*/
s32 GetTimeOgg();
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void SetTimeOgg(s32 time_pos);
Set the time position
NOTE: The file is closed by the player when you call PlayOgg(), StopOgg() or if it fail.
-- Params ---
time_pos: time position in the file (in milliseconds). For example, use 30000 to advance 30 seconds
*/
void SetTimeOgg(s32 time_pos);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
#endif
/*
Copyright (c) 2008 Francisco Muñoz 'Hermes' <www.elotrolado.net>
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __OGGPLAYER_H__
#define __OGGPLAYER_H__
#include <asndlib.h>
#include "tremor/ivorbiscodec.h"
#include "tremor/ivorbisfile.h"
#ifdef __cplusplus
extern "C" {
#endif
#define OGG_ONE_TIME 0
#define OGG_INFINITE_TIME 1
#define OGG_STATUS_RUNNING 1
#define OGG_STATUS_ERR -1
#define OGG_STATUS_PAUSED 2
#define OGG_STATUS_EOF 255
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* Player OGG functions */
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* int PlayOgg(int fd, int time_pos, int mode);
Play an Ogg file. This file can be loaded from memory (mem_open(void *ogg, int size_ogg)) or from device with open("device:file.ogg",O_RDONLY,0);
NOTE: The file is closed by the player when you call PlayOgg(), StopOgg() or if it fail.
-- Params ---
fd: file descriptor from open() or mem_open()
time_pos: initial time position in the file (in milliseconds). For example, use 30000 to advance 30 seconds
mode: Use OGG_ONE_TIME or OGG_INFINITE_TIME. When you use OGG_ONE_TIME the sound stops and StatusOgg() return OGG_STATUS_EOF
return: 0- Ok, -1 Error
*/
int PlayOgg(int fd, int time_pos, int mode);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* int PlayOgg(char * path, int loop);
Just give the function the full device+path to OGG to play it
loop = 1 for Loop and 0 for one time playing
*/
int PlayOggFromFile(char * path, int loop);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void StopOgg();
Stop an Ogg file.
NOTE: The file is closed and the player thread is released
-- Params ---
*/
void StopOgg();
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void PauseOgg(int pause);
Pause an Ogg file.
-- Params ---
pause: 0 -> continue, 1-> pause
*/
void PauseOgg(int pause);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* int StatusOgg();
Return the Ogg status
-- Params ---
return: OGG_STATUS_RUNNING
OGG_STATUS_ERR -> not initialized?
OGG_STATUS_PAUSED
OGG_STATUS_EOF -> player stopped by End Of File
*/
int StatusOgg();
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void SetVolumeOgg(int volume);
Set the Ogg playing volume.
NOTE: it change the volume of voice 0 (used for the Ogg player)
-- Params ---
volume: 0 to 255 (max)
*/
void SetVolumeOgg(int volume);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* s32 GetTimeOgg();
Return the Ogg time from the starts of the file
-- Params ---
return: 0 -> Ok or error condition (you must ignore this value)
>0 -> time in milliseconds from the starts
*/
s32 GetTimeOgg();
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void SetTimeOgg(s32 time_pos);
Set the time position
NOTE: The file is closed by the player when you call PlayOgg(), StopOgg() or if it fail.
-- Params ---
time_pos: time position in the file (in milliseconds). For example, use 30000 to advance 30 seconds
*/
void SetTimeOgg(s32 time_pos);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,53 +1,53 @@
/*
* Copyright (C) 2008 Nuke (wiinuke@gmail.com)
*
* this file is part of GeckoOS for USB Gecko
* http://www.usbgecko.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __DVD_BROADWAY_H__
#define __DVD_BROADWAY_H__
#include <gctypes.h>
#include <ogc/ipc.h>
#include <ogc/dvd.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef void (*dvdcallbacklow)(s32 result);
s32 bwDVD_LowInit();
s32 bwDVD_LowInquiry(dvddrvinfo *info,dvdcallbacklow cb);
s32 bwDVD_LowReadID(dvddiskid *diskID,dvdcallbacklow cb);
s32 bwDVD_LowClosePartition(dvdcallbacklow cb);
s32 bwDVD_LowOpenPartition(u32 offset,void *eticket,u32 certin_len,void *certificate_in,void *certificate_out,dvdcallbacklow cb);
s32 bwDVD_LowUnencryptedRead(void *buf,u32 len,u32 offset,dvdcallbacklow cb);
s32 bwDVD_LowReset(dvdcallbacklow cb);
s32 bwDVD_LowWaitCoverClose(dvdcallbacklow cb);
s32 bwDVD_LowRead(void *buf,u32 len,u32 offset,dvdcallbacklow cb);
s32 bwDVD_EnableVideo(dvdcallbacklow cb);
s32 bwDVD_LowReadVideo(void *buf,u32 len,u32 offset,dvdcallbacklow cb);
s32 bwDVD_SetDecryption(s32 mode, dvdcallbacklow cb);
s32 bwDVD_SetOffset(u32 offset, dvdcallbacklow cb);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
/*
* Copyright (C) 2008 Nuke (wiinuke@gmail.com)
*
* this file is part of GeckoOS for USB Gecko
* http://www.usbgecko.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __DVD_BROADWAY_H__
#define __DVD_BROADWAY_H__
#include <gctypes.h>
#include <ogc/ipc.h>
#include <ogc/dvd.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef void (*dvdcallbacklow)(s32 result);
s32 bwDVD_LowInit();
s32 bwDVD_LowInquiry(dvddrvinfo *info,dvdcallbacklow cb);
s32 bwDVD_LowReadID(dvddiskid *diskID,dvdcallbacklow cb);
s32 bwDVD_LowClosePartition(dvdcallbacklow cb);
s32 bwDVD_LowOpenPartition(u32 offset,void *eticket,u32 certin_len,void *certificate_in,void *certificate_out,dvdcallbacklow cb);
s32 bwDVD_LowUnencryptedRead(void *buf,u32 len,u32 offset,dvdcallbacklow cb);
s32 bwDVD_LowReset(dvdcallbacklow cb);
s32 bwDVD_LowWaitCoverClose(dvdcallbacklow cb);
s32 bwDVD_LowRead(void *buf,u32 len,u32 offset,dvdcallbacklow cb);
s32 bwDVD_EnableVideo(dvdcallbacklow cb);
s32 bwDVD_LowReadVideo(void *buf,u32 len,u32 offset,dvdcallbacklow cb);
s32 bwDVD_SetDecryption(s32 mode, dvdcallbacklow cb);
s32 bwDVD_SetOffset(u32 offset, dvdcallbacklow cb);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@ -1,106 +1,106 @@
/*
* Copyright (C) 2008 Nuke (wiinuke@gmail.com)
*
* this file is part of GeckoOS for USB Gecko
* http://www.usbgecko.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gccore.h>
#include <malloc.h>
#include <sys/unistd.h>
#include <sdcard/wiisd_io.h>
#include <ogc/ipc.h>
#include "settings/cfg.h"
#include "fst.h"
#include "dvd_broadway.h"
#include "wpad.h"
#include "fatmounter.h"
extern struct SSettings Settings;
u32 do_sd_code(char *filename)
{
FILE *fp;
u8 *filebuff;
u32 filesize;
u32 ret;
char filepath[150];
SDCard_Init();
USBDevice_Init();
sprintf(filepath, "%s%s", Settings.Cheatcodespath, filename);
filepath[strlen(Settings.Cheatcodespath)+6] = 0x2E;
filepath[strlen(Settings.Cheatcodespath)+7] = 0x67;
filepath[strlen(Settings.Cheatcodespath)+8] = 0x63;
filepath[strlen(Settings.Cheatcodespath)+9] = 0x74;
filepath[strlen(Settings.Cheatcodespath)+10] = 0;
fp = fopen(filepath, "rb");
if (!fp) {
USBDevice_deInit();
SDCard_deInit();
return 0;
}
fseek(fp, 0, SEEK_END);
filesize = ftell(fp);
if(filesize <= 16){
fclose(fp);
sleep(2);
USBDevice_deInit();
SDCard_deInit();
return 0;
}
fseek(fp, 0, SEEK_SET);
filebuff = (u8*) malloc (filesize);
if(filebuff == 0){
fclose(fp);
sleep(2);
USBDevice_deInit();
SDCard_deInit();
return 0;
}
ret = fread(filebuff, 1, filesize, fp);
if(ret != filesize){
free(filebuff);
fclose(fp);
USBDevice_deInit();
SDCard_deInit();
return 0;
}
memcpy((void*)0x800027E8,filebuff,filesize);
*(vu8*)0x80001807 = 0x01;
free(filebuff);
fclose(fp);
USBDevice_deInit();
SDCard_deInit();
return 1;
}
/*
* Copyright (C) 2008 Nuke (wiinuke@gmail.com)
*
* this file is part of GeckoOS for USB Gecko
* http://www.usbgecko.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gccore.h>
#include <malloc.h>
#include <sys/unistd.h>
#include <sdcard/wiisd_io.h>
#include <ogc/ipc.h>
#include "settings/cfg.h"
#include "fst.h"
#include "dvd_broadway.h"
#include "wpad.h"
#include "fatmounter.h"
extern struct SSettings Settings;
u32 do_sd_code(char *filename)
{
FILE *fp;
u8 *filebuff;
u32 filesize;
u32 ret;
char filepath[150];
SDCard_Init();
USBDevice_Init();
sprintf(filepath, "%s%s", Settings.Cheatcodespath, filename);
filepath[strlen(Settings.Cheatcodespath)+6] = 0x2E;
filepath[strlen(Settings.Cheatcodespath)+7] = 0x67;
filepath[strlen(Settings.Cheatcodespath)+8] = 0x63;
filepath[strlen(Settings.Cheatcodespath)+9] = 0x74;
filepath[strlen(Settings.Cheatcodespath)+10] = 0;
fp = fopen(filepath, "rb");
if (!fp) {
USBDevice_deInit();
SDCard_deInit();
return 0;
}
fseek(fp, 0, SEEK_END);
filesize = ftell(fp);
if(filesize <= 16){
fclose(fp);
sleep(2);
USBDevice_deInit();
SDCard_deInit();
return 0;
}
fseek(fp, 0, SEEK_SET);
filebuff = (u8*) malloc (filesize);
if(filebuff == 0){
fclose(fp);
sleep(2);
USBDevice_deInit();
SDCard_deInit();
return 0;
}
ret = fread(filebuff, 1, filesize, fp);
if(ret != filesize){
free(filebuff);
fclose(fp);
USBDevice_deInit();
SDCard_deInit();
return 0;
}
memcpy((void*)0x800027E8,filebuff,filesize);
*(vu8*)0x80001807 = 0x01;
free(filebuff);
fclose(fp);
USBDevice_deInit();
SDCard_deInit();
return 1;
}

View File

@ -1,38 +1,38 @@
/*
* Copyright (C) 2008 Nuke (wiinuke@gmail.com)
*
* this file is part of GeckoOS for USB Gecko
* http://www.usbgecko.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __FST_H__
#define __FST_H__
#ifdef __cplusplus
extern "C"
{
#endif
//u32 do_fst(u32 fstlocation);
u32 do_sd_code(char *filename);
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (C) 2008 Nuke (wiinuke@gmail.com)
*
* this file is part of GeckoOS for USB Gecko
* http://www.usbgecko.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __FST_H__
#define __FST_H__
#ifdef __cplusplus
extern "C"
{
#endif
//u32 do_fst(u32 fstlocation);
u32 do_sd_code(char *filename);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,60 +1,60 @@
/*
* Copyright (C) 2008 Nuke (wiinuke@gmail.com)
*
* this file is part of GeckoOS for USB Gecko
* http://www.usbgecko.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __GECKOMENU_H__
#define __GECKOMENU_H__
#define ROOTMENU 0
#define ABOUTMENU 1
#define CONFIGMENU 2
#define REBOOTMENU 3
#define root_itemcount 7
#define about_itemcount 4
#define config_itemcount 9
#define rebooter_itemcount 6
u32 currentmenu; // 0 ROOT
u32 rootmenu_item;
u32 menufreeze;
u32 langselect;
u32 langsaved;
u32 pal60select;
u32 pal50select;
u32 viselect;
u32 ntscselect;
u32 hookselect;
u32 ocarinaselect;
u32 recoveryselect;
u32 regionfreeselect;
u32 nocopyselect;
u32 buttonskipselect;
u32 doprogress(u32 progstate, u32 noelements);
void drawmenu(u32 menuid);
void drawselected(u32 menuidpos);
void processwpad();
void clearscreen(u32 *framebuffer, u16 xscreen, u16 yscreen, u16 width, u16 height, u32 color);
void drawicon(u32 *framebuffer, u16 xscreen, u16 yscreen, u16 width, u16 height, u32 gicon);
u32 CvtRGB (u8 r1, u8 g1, u8 b1, u8 r2, u8 g2, u8 b2);
#endif // __GECKOLOAD_H__
/*
* Copyright (C) 2008 Nuke (wiinuke@gmail.com)
*
* this file is part of GeckoOS for USB Gecko
* http://www.usbgecko.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __GECKOMENU_H__
#define __GECKOMENU_H__
#define ROOTMENU 0
#define ABOUTMENU 1
#define CONFIGMENU 2
#define REBOOTMENU 3
#define root_itemcount 7
#define about_itemcount 4
#define config_itemcount 9
#define rebooter_itemcount 6
u32 currentmenu; // 0 ROOT
u32 rootmenu_item;
u32 menufreeze;
u32 langselect;
u32 langsaved;
u32 pal60select;
u32 pal50select;
u32 viselect;
u32 ntscselect;
u32 hookselect;
u32 ocarinaselect;
u32 recoveryselect;
u32 regionfreeselect;
u32 nocopyselect;
u32 buttonskipselect;
u32 doprogress(u32 progstate, u32 noelements);
void drawmenu(u32 menuid);
void drawselected(u32 menuidpos);
void processwpad();
void clearscreen(u32 *framebuffer, u16 xscreen, u16 yscreen, u16 width, u16 height, u32 color);
void drawicon(u32 *framebuffer, u16 xscreen, u16 yscreen, u16 width, u16 height, u32 gicon);
u32 CvtRGB (u8 r1, u8 g1, u8 b1, u8 r2, u8 g2, u8 b2);
#endif // __GECKOLOAD_H__

View File

@ -1,359 +1,359 @@
/*
* Copyright (C) 2008 Nuke (wiinuke@gmail.com)
*
* this file is part of GeckoOS for USB Gecko
* http://www.usbgecko.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gccore.h>
#include "usbloader/apploader.h"
#include "geckomenu.h"
#include "patchcode.h"
#include "fwrite_patch.h"
extern void patchhook(u32 address, u32 len);
extern void patchhook2(u32 address, u32 len);
extern void patchhook3(u32 address, u32 len);
extern void patchhook4(u32 address, u32 len);
extern void multidolpatchone(u32 address, u32 len);
extern void multidolpatchtwo(u32 address, u32 len);
extern void regionfreejap(u32 address, u32 len);
extern void regionfreeusa(u32 address, u32 len);
extern void regionfreepal(u32 address, u32 len);
extern void removehealthcheck(u32 address, u32 len);
extern void copyflagcheck1(u32 address, u32 len);
extern void copyflagcheck2(u32 address, u32 len);
extern void copyflagcheck3(u32 address, u32 len);
extern void copyflagcheck4(u32 address, u32 len);
extern void copyflagcheck5(u32 address, u32 len);
extern void patchupdatecheck(u32 address, u32 len);
extern void movedvdhooks(u32 address, u32 len);
extern void patchhookdol(u32 address, u32 len);
extern void langvipatch(u32 address, u32 len, u8 langbyte);
extern void vipatch(u32 address, u32 len);
extern u32 regionfreeselect;
static const u32 viwiihooks[4] = {
0x7CE33B78,0x38870034,0x38A70038,0x38C7004C
};
static const u32 multidolpatch1[2] = {
0x3C03FFB4,0x28004F43
};
static const u32 healthcheckhook[2] = {
0x41810010,0x881D007D
};
static const u32 updatecheckhook[3] = {
0x80650050,0x80850054,0xA0A50058
};
static const u32 multidolpatch2[2] = {
0x3F608000, 0x807B0018
};
static const u32 recoveryhooks[3] = {
0xA00100AC,0x5400073E,0x2C00000F
};
static const u32 nocopyflag1[3] = {
0x540007FF, 0x4182001C, 0x80630068
};
static const u32 nocopyflag2[3] = {
0x540007FF, 0x41820024, 0x387E12E2
};
// this one is for the GH3 and VC saves
//static const u32 nocopyflag3[5] = {
// 0x2C030000, 0x40820010, 0x88010020, 0x28000002, 0x41820234
//};
static const u32 nocopyflag3[5] = {
0x2C030000, 0x41820200,0x48000058,0x38610100
};
// this removes the display warning for no copy VC and GH3 saves
static const u32 nocopyflag4[4] = {
0x80010008, 0x2C000000, 0x4182000C, 0x3BE00001
};
static const u32 nocopyflag5[3] = {
0x801D0024,0x540007FF,0x41820024
};
static const u32 movedvdpatch[3] = {
0x2C040000, 0x41820120, 0x3C608109
};
static const u32 regionfreehooks[5] = {
0x7C600774, 0x2C000001, 0x41820030,0x40800010,0x2C000000
};
static const u32 fwritepatch[8] = {
0x9421FFD0,0x7C0802A6,0x90010034,0xBF210014,0x7C9B2378,0x7CDC3378,0x7C7A1B78,0x7CB92B78 // bushing fwrite
};
static const u32 kpadhooks[4] = {
0x9A3F005E,0x38AE0080,0x389FFFFC,0x7E0903A6
};
static const u32 kpadoldhooks[6] = {
0x801D0060, 0x901E0060, 0x801D0064, 0x901E0064, 0x801D0068, 0x901E0068
};
static const u32 joypadhooks[4] = {
0x3AB50001, 0x3A73000C, 0x2C150004, 0x3B18000C
};
static const u32 langpatch[3] = {
0x7C600775, 0x40820010, 0x38000000
};
static const u32 vipatchcode[3] = {
0x4182000C,0x4180001C,0x48000018
};
static const u32 wpadlibogc[5] = {
// 0x38A00140, 0x7C095878, 0x7D600078, 0x901F0010,0x913F0014
// 0x7FA00124, 0x8001001C, 0x83810008, 0x83A1000C,0x7C0803A6
0x90A402E0,0x806502E4,0x908502E4,0x2C030000,0x906402E4
};
void dogamehooks(void *addr, u32 len)
{
void *addr_start = addr;
void *addr_end = addr+len;
while(addr_start < addr_end)
{
switch(hooktype)
{
case 0:
break;
case 1:
if(memcmp(addr_start, viwiihooks, sizeof(viwiihooks))==0){
// printf("\n\n\n");
// printf("found at address %x\n", addr_start);
// sleep(2);
patchhook((u32)addr_start, len);
patched = 1;
hooktype = 1;
}
break;
/*
case 2:
if(memcmp(addr_start, kpadhooks, sizeof(kpadhooks))==0){
patchhook((u32)addr_start, len);
patched = 1;
}
if(memcmp(addr_start, kpadoldhooks, sizeof(kpadoldhooks))==0){
patchhook((u32)addr_start, len);
patched = 1;
}
break;
case 3:
if(memcmp(addr_start, joypadhooks, sizeof(joypadhooks))==0){
patchhook((u32)addr_start, len);
patched = 1;
}
break;
case 4:
if(memcmp(addr_start, recoveryhooks, sizeof(recoveryhooks))==0){
patchhook3((u32)addr_start, len);
}
break;
*/
case 2:
if(memcmp(addr_start, viwiihooks, sizeof(viwiihooks))==0){
patchhook2((u32)addr_start, len);
}
break;
/*
case 6:
// jap region free
if(memcmp(addr_start, regionfreehooks, sizeof(regionfreehooks))==0){
regionfreejap((u32)addr_start, len);
}
// usa region free
if(memcmp(addr_start, regionfreehooks, sizeof(regionfreehooks))==0){
regionfreeusa((u32)addr_start, len);
}
// pal region free
if(memcmp(addr_start, regionfreehooks, sizeof(regionfreehooks))==0){
regionfreepal((u32)addr_start, len);
}
// skip disc update
if(memcmp(addr_start, updatecheckhook, sizeof(updatecheckhook))==0){
patchupdatecheck((u32)addr_start, len);
}
break;
case 7:
if(memcmp(addr_start, healthcheckhook, sizeof(healthcheckhook))==0){
removehealthcheck((u32)addr_start, len);
}
break;
// no copy flags
case 8:
// Remove the actual flag so can copy back
if(memcmp(addr_start, nocopyflag5, sizeof(nocopyflag5))==0){
copyflagcheck5((u32)addr_start, len);
}
if(memcmp(addr_start, nocopyflag1, sizeof(nocopyflag1))==0){
copyflagcheck1((u32)addr_start, len);
}
if(memcmp(addr_start, nocopyflag2, sizeof(nocopyflag2))==0){
copyflagcheck2((u32)addr_start, len);
}
// no VC and GH3 save
if(memcmp(addr_start, nocopyflag3, sizeof(nocopyflag2))==0){
copyflagcheck3((u32)addr_start, len);
}
// no VC and GH3 save display remove
if(memcmp(addr_start, nocopyflag4, sizeof(nocopyflag4))==0){
copyflagcheck4((u32)addr_start, len);
}
break;
case 9:
if(memcmp(addr_start, movedvdpatch, sizeof(movedvdpatch))==0){
movedvdhooks((u32)addr_start, len);
}
break;
*/
// multidol
case 3:
if(memcmp(addr_start, multidolpatch1, sizeof(multidolpatch1))==0){
multidolpatchone((u32)addr_start, len);
}
if(memcmp(addr_start, multidolpatch2, sizeof(multidolpatch2))==0){
multidolpatchtwo((u32)addr_start, len);
}
break;
}
addr_start += 4;
}
}
// Not used yet, for patching DOL once loaded into memory and befor execution
void patchdol(void *addr, u32 len)
{
void *addr_start = addr;
void *addr_end = addr+len;
while(addr_start < addr_end)
{
if(memcmp(addr_start, wpadlibogc, sizeof(wpadlibogc))==0) {
// printf("\n\n\n");
// printf("found at address %x\n", addr_start);
// sleep(10);
// patchhookdol((u32)addr_start, len);
patched = 1;
break;
}
addr_start += 4;
}
}
void langpatcher(void *addr, u32 len)
{
void *addr_start = addr;
void *addr_end = addr+len;
while(addr_start < addr_end)
{
if(memcmp(addr_start, langpatch, sizeof(langpatch))==0) {
if(configbytes[0] != 0xCD){
langvipatch((u32)addr_start, len, configbytes[0]);
}
}
addr_start += 4;
}
}
void patchdebug(void *addr, u32 len)
{
void *addr_start = addr;
void *addr_end = addr+len;
while(addr_start < addr_end)
{
if(memcmp(addr_start, fwritepatch, sizeof(fwritepatch))==0) {
memcpy(addr_start,fwrite_patch_bin,fwrite_patch_bin_len);
// apply patch
}
addr_start += 4;
}
}
void vidolpatcher(void *addr, u32 len)
{
void *addr_start = addr;
void *addr_end = addr+len;
while(addr_start < addr_end)
{
if(memcmp(addr_start, vipatchcode, sizeof(vipatchcode))==0) {
vipatch((u32)addr_start, len);
}
addr_start += 4;
}
}
/*
* Copyright (C) 2008 Nuke (wiinuke@gmail.com)
*
* this file is part of GeckoOS for USB Gecko
* http://www.usbgecko.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gccore.h>
#include "usbloader/apploader.h"
#include "geckomenu.h"
#include "patchcode.h"
#include "fwrite_patch.h"
extern void patchhook(u32 address, u32 len);
extern void patchhook2(u32 address, u32 len);
extern void patchhook3(u32 address, u32 len);
extern void patchhook4(u32 address, u32 len);
extern void multidolpatchone(u32 address, u32 len);
extern void multidolpatchtwo(u32 address, u32 len);
extern void regionfreejap(u32 address, u32 len);
extern void regionfreeusa(u32 address, u32 len);
extern void regionfreepal(u32 address, u32 len);
extern void removehealthcheck(u32 address, u32 len);
extern void copyflagcheck1(u32 address, u32 len);
extern void copyflagcheck2(u32 address, u32 len);
extern void copyflagcheck3(u32 address, u32 len);
extern void copyflagcheck4(u32 address, u32 len);
extern void copyflagcheck5(u32 address, u32 len);
extern void patchupdatecheck(u32 address, u32 len);
extern void movedvdhooks(u32 address, u32 len);
extern void patchhookdol(u32 address, u32 len);
extern void langvipatch(u32 address, u32 len, u8 langbyte);
extern void vipatch(u32 address, u32 len);
extern u32 regionfreeselect;
static const u32 viwiihooks[4] = {
0x7CE33B78,0x38870034,0x38A70038,0x38C7004C
};
static const u32 multidolpatch1[2] = {
0x3C03FFB4,0x28004F43
};
static const u32 healthcheckhook[2] = {
0x41810010,0x881D007D
};
static const u32 updatecheckhook[3] = {
0x80650050,0x80850054,0xA0A50058
};
static const u32 multidolpatch2[2] = {
0x3F608000, 0x807B0018
};
static const u32 recoveryhooks[3] = {
0xA00100AC,0x5400073E,0x2C00000F
};
static const u32 nocopyflag1[3] = {
0x540007FF, 0x4182001C, 0x80630068
};
static const u32 nocopyflag2[3] = {
0x540007FF, 0x41820024, 0x387E12E2
};
// this one is for the GH3 and VC saves
//static const u32 nocopyflag3[5] = {
// 0x2C030000, 0x40820010, 0x88010020, 0x28000002, 0x41820234
//};
static const u32 nocopyflag3[5] = {
0x2C030000, 0x41820200,0x48000058,0x38610100
};
// this removes the display warning for no copy VC and GH3 saves
static const u32 nocopyflag4[4] = {
0x80010008, 0x2C000000, 0x4182000C, 0x3BE00001
};
static const u32 nocopyflag5[3] = {
0x801D0024,0x540007FF,0x41820024
};
static const u32 movedvdpatch[3] = {
0x2C040000, 0x41820120, 0x3C608109
};
static const u32 regionfreehooks[5] = {
0x7C600774, 0x2C000001, 0x41820030,0x40800010,0x2C000000
};
static const u32 fwritepatch[8] = {
0x9421FFD0,0x7C0802A6,0x90010034,0xBF210014,0x7C9B2378,0x7CDC3378,0x7C7A1B78,0x7CB92B78 // bushing fwrite
};
static const u32 kpadhooks[4] = {
0x9A3F005E,0x38AE0080,0x389FFFFC,0x7E0903A6
};
static const u32 kpadoldhooks[6] = {
0x801D0060, 0x901E0060, 0x801D0064, 0x901E0064, 0x801D0068, 0x901E0068
};
static const u32 joypadhooks[4] = {
0x3AB50001, 0x3A73000C, 0x2C150004, 0x3B18000C
};
static const u32 langpatch[3] = {
0x7C600775, 0x40820010, 0x38000000
};
static const u32 vipatchcode[3] = {
0x4182000C,0x4180001C,0x48000018
};
static const u32 wpadlibogc[5] = {
// 0x38A00140, 0x7C095878, 0x7D600078, 0x901F0010,0x913F0014
// 0x7FA00124, 0x8001001C, 0x83810008, 0x83A1000C,0x7C0803A6
0x90A402E0,0x806502E4,0x908502E4,0x2C030000,0x906402E4
};
void dogamehooks(void *addr, u32 len)
{
void *addr_start = addr;
void *addr_end = addr+len;
while(addr_start < addr_end)
{
switch(hooktype)
{
case 0:
break;
case 1:
if(memcmp(addr_start, viwiihooks, sizeof(viwiihooks))==0){
// printf("\n\n\n");
// printf("found at address %x\n", addr_start);
// sleep(2);
patchhook((u32)addr_start, len);
patched = 1;
hooktype = 1;
}
break;
/*
case 2:
if(memcmp(addr_start, kpadhooks, sizeof(kpadhooks))==0){
patchhook((u32)addr_start, len);
patched = 1;
}
if(memcmp(addr_start, kpadoldhooks, sizeof(kpadoldhooks))==0){
patchhook((u32)addr_start, len);
patched = 1;
}
break;
case 3:
if(memcmp(addr_start, joypadhooks, sizeof(joypadhooks))==0){
patchhook((u32)addr_start, len);
patched = 1;
}
break;
case 4:
if(memcmp(addr_start, recoveryhooks, sizeof(recoveryhooks))==0){
patchhook3((u32)addr_start, len);
}
break;
*/
case 2:
if(memcmp(addr_start, viwiihooks, sizeof(viwiihooks))==0){
patchhook2((u32)addr_start, len);
}
break;
/*
case 6:
// jap region free
if(memcmp(addr_start, regionfreehooks, sizeof(regionfreehooks))==0){
regionfreejap((u32)addr_start, len);
}
// usa region free
if(memcmp(addr_start, regionfreehooks, sizeof(regionfreehooks))==0){
regionfreeusa((u32)addr_start, len);
}
// pal region free
if(memcmp(addr_start, regionfreehooks, sizeof(regionfreehooks))==0){
regionfreepal((u32)addr_start, len);
}
// skip disc update
if(memcmp(addr_start, updatecheckhook, sizeof(updatecheckhook))==0){
patchupdatecheck((u32)addr_start, len);
}
break;
case 7:
if(memcmp(addr_start, healthcheckhook, sizeof(healthcheckhook))==0){
removehealthcheck((u32)addr_start, len);
}
break;
// no copy flags
case 8:
// Remove the actual flag so can copy back
if(memcmp(addr_start, nocopyflag5, sizeof(nocopyflag5))==0){
copyflagcheck5((u32)addr_start, len);
}
if(memcmp(addr_start, nocopyflag1, sizeof(nocopyflag1))==0){
copyflagcheck1((u32)addr_start, len);
}
if(memcmp(addr_start, nocopyflag2, sizeof(nocopyflag2))==0){
copyflagcheck2((u32)addr_start, len);
}
// no VC and GH3 save
if(memcmp(addr_start, nocopyflag3, sizeof(nocopyflag2))==0){
copyflagcheck3((u32)addr_start, len);
}
// no VC and GH3 save display remove
if(memcmp(addr_start, nocopyflag4, sizeof(nocopyflag4))==0){
copyflagcheck4((u32)addr_start, len);
}
break;
case 9:
if(memcmp(addr_start, movedvdpatch, sizeof(movedvdpatch))==0){
movedvdhooks((u32)addr_start, len);
}
break;
*/
// multidol
case 3:
if(memcmp(addr_start, multidolpatch1, sizeof(multidolpatch1))==0){
multidolpatchone((u32)addr_start, len);
}
if(memcmp(addr_start, multidolpatch2, sizeof(multidolpatch2))==0){
multidolpatchtwo((u32)addr_start, len);
}
break;
}
addr_start += 4;
}
}
// Not used yet, for patching DOL once loaded into memory and befor execution
void patchdol(void *addr, u32 len)
{
void *addr_start = addr;
void *addr_end = addr+len;
while(addr_start < addr_end)
{
if(memcmp(addr_start, wpadlibogc, sizeof(wpadlibogc))==0) {
// printf("\n\n\n");
// printf("found at address %x\n", addr_start);
// sleep(10);
// patchhookdol((u32)addr_start, len);
patched = 1;
break;
}
addr_start += 4;
}
}
void langpatcher(void *addr, u32 len)
{
void *addr_start = addr;
void *addr_end = addr+len;
while(addr_start < addr_end)
{
if(memcmp(addr_start, langpatch, sizeof(langpatch))==0) {
if(configbytes[0] != 0xCD){
langvipatch((u32)addr_start, len, configbytes[0]);
}
}
addr_start += 4;
}
}
void patchdebug(void *addr, u32 len)
{
void *addr_start = addr;
void *addr_end = addr+len;
while(addr_start < addr_end)
{
if(memcmp(addr_start, fwritepatch, sizeof(fwritepatch))==0) {
memcpy(addr_start,fwrite_patch_bin,fwrite_patch_bin_len);
// apply patch
}
addr_start += 4;
}
}
void vidolpatcher(void *addr, u32 len)
{
void *addr_start = addr;
void *addr_end = addr+len;
while(addr_start < addr_end)
{
if(memcmp(addr_start, vipatchcode, sizeof(vipatchcode))==0) {
vipatch((u32)addr_start, len);
}
addr_start += 4;
}
}

View File

@ -1,46 +1,46 @@
/*
* Copyright (C) 2008 Nuke (wiinuke@gmail.com)
*
* this file is part of GeckoOS for USB Gecko
* http://www.usbgecko.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __PATCHCODE_H__
#define __PATCHCODE_H__
#ifdef __cplusplus
extern "C"
{
#endif
// Globals
u32 hooktype;
int patched;
u8 configbytes[2];
u32 regionfree;
// Function prototypes
void dogamehooks(void *addr, u32 len);
void langpatcher(void *addr, u32 len);
void vidolpatcher(void *addr, u32 len);
void patchdebug(void *addr, u32 len);
#ifdef __cplusplus
}
#endif
#endif // __PATCHCODE_H__
/*
* Copyright (C) 2008 Nuke (wiinuke@gmail.com)
*
* this file is part of GeckoOS for USB Gecko
* http://www.usbgecko.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __PATCHCODE_H__
#define __PATCHCODE_H__
#ifdef __cplusplus
extern "C"
{
#endif
// Globals
u32 hooktype;
int patched;
u8 configbytes[2];
u32 regionfree;
// Function prototypes
void dogamehooks(void *addr, u32 len);
void langpatcher(void *addr, u32 len);
void vidolpatcher(void *addr, u32 len);
void patchdebug(void *addr, u32 len);
#ifdef __cplusplus
}
#endif
#endif // __PATCHCODE_H__

File diff suppressed because it is too large Load Diff

View File

@ -1,450 +1,450 @@
/****************************************************************************
* DiscBrowser
* USB Loader GX 2009
*
* DiscBrowser.h
***************************************************************************/
#include "language/gettext.h"
#include "libwiigui/gui.h"
#include "libwiigui/gui_customoptionbrowser.h"
#include "prompts/PromptWindows.h"
#include "filelist.h"
#include "menu.h"
#include "usbloader/disc.h"
#include "usbloader/fstfile.h"
#include "usbloader/wdvd.h"
#include "main.h"
#include "sys.h"
#include "settings/cfg.h"
#include "memory.h"
#include "../wad/title.h"
#include "../patches/dvd_broadway.h"
#define BC 0x0000000100000100ULL
/*** Extern functions ***/
extern void ResumeGui();
extern void HaltGui();
/*** Extern variables ***/
extern GuiWindow * mainWindow;
extern u8 shutdown;
extern u8 reset;
extern u8 dvdMounted;
/********************************************************************************
*Disk Browser
*********************************************************************************/
int DiscBrowse(struct discHdr * header) {
bool exit = false;
int ret, choice;
u64 offset;
HaltGui();
if (!dvdMounted)
{
ret = Disc_SetUSB(header->id);
if (ret < 0) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Could not set USB."), tr("OK"));
return ret;
}
}
ret = Disc_Open();
if (ret < 0) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Could not open disc."), tr("OK"));
return ret;
}
ret = __Disc_FindPartition(&offset);
if (ret < 0) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Could not find a WBFS partition."), tr("OK"));
return ret;
}
ret = WDVD_OpenPartition(offset);
if (ret < 0) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Could not open WBFS partition"), tr("OK"));
return ret;
}
int *buffer = (int*)allocate_memory(0x20);
if (buffer == NULL) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Not enough free memory."), tr("OK"));
return -1;
}
ret = WDVD_Read(buffer, 0x20, 0x420);
if (ret < 0) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Could not read the disc."), tr("OK"));
return ret;
}
void *fstbuffer = allocate_memory(buffer[2]*4);
FST_ENTRY *fst = (FST_ENTRY *)fstbuffer;
if (fst == NULL) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Not enough free memory."), tr("OK"));
free(buffer);
return -1;
}
ret = WDVD_Read(fstbuffer, buffer[2]*4, buffer[1]*4);
if (ret < 0) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Could not read the disc."), tr("OK"));
free(buffer);
free(fstbuffer);
return ret;
}
ResumeGui();
free(buffer);
WDVD_Reset();
//Disc_SetUSB(NULL);
WDVD_ClosePartition();
u32 discfilecount = fst[0].filelen;
u32 dolfilecount = 0;
//int offsetselect[20];
customOptionList options3(discfilecount);
for (u32 i = 0; i < discfilecount; i++) {
//don't add files that aren't .dol to the list
int len = (strlen(fstfiles(fst, i)));
if (fstfiles(fst, i)[len-4] =='.' &&
fstfiles(fst, i)[len-3] =='d' &&
fstfiles(fst, i)[len-2] =='o' &&
fstfiles(fst, i)[len-1] =='l') {
options3.SetName(i, "%i", i);
options3.SetValue(i, fstfiles(fst, i));
//options3.SetName(i, fstfiles(fst, i));
dolfilecount++;
}
}
if (dolfilecount <= 0) {
WindowPrompt(tr("ERROR"), tr("No dol file found on disc."), tr("OK"));
free(fstbuffer);
return -1;
}
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
GuiImageData btnOutline(imgPath, button_dialogue_box_png);
snprintf(imgPath, sizeof(imgPath), "%sgamesettings_background.png", CFG.theme_path);
GuiImageData settingsbg(imgPath, settings_background_png);
GuiTrigger trigA;
trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
GuiTrigger trigHome;
trigHome.SetButtonOnlyTrigger(-1, WPAD_BUTTON_HOME | WPAD_CLASSIC_BUTTON_HOME, 0);
GuiTrigger trigB;
trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B);
GuiText titleTxt(get_title(header), 28, (GXColor) {0, 0, 0, 255});
titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
titleTxt.SetPosition(12,40);
titleTxt.SetMaxWidth(356, GuiText::SCROLL);
GuiImage settingsbackground(&settingsbg);
GuiButton settingsbackgroundbtn(settingsbackground.GetWidth(), settingsbackground.GetHeight());
settingsbackgroundbtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
settingsbackgroundbtn.SetPosition(0, 0);
settingsbackgroundbtn.SetImage(&settingsbackground);
GuiText cancelBtnTxt(tr("Back"), 22, THEME.prompttext);
cancelBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30);
GuiImage cancelBtnImg(&btnOutline);
if (Settings.wsprompt == yes) {
cancelBtnTxt.SetWidescreen(CFG.widescreen);
cancelBtnImg.SetWidescreen(CFG.widescreen);
}
GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, &btnClick,1);
cancelBtn.SetScale(0.9);
cancelBtn.SetLabel(&cancelBtnTxt);
cancelBtn.SetTrigger(&trigB);
u8 scrollbaron = 0;
if (dolfilecount > 9)
scrollbaron = 1;
GuiCustomOptionBrowser optionBrowser3(396, 280, &options3, CFG.theme_path, "bg_options_gamesettings.png", bg_options_settings_png, dolfilecount>9?1:0, 200);
optionBrowser3.SetPosition(0, 90);
optionBrowser3.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
HaltGui();
GuiWindow w(screenwidth, screenheight);
w.Append(&settingsbackgroundbtn);
w.Append(&titleTxt);
w.Append(&cancelBtn);
w.Append(&optionBrowser3);
mainWindow->Append(&w);
ResumeGui();
while (!exit) {
VIDEO_WaitVSync();
if (shutdown == 1)
Sys_Shutdown();
if (reset == 1)
Sys_Reboot();
ret = optionBrowser3.GetClickedOption();
if (ret > 0) {
char temp[100];
strlcpy(temp, fstfiles(fst, ret), sizeof(temp));
choice = WindowPrompt(temp, tr("Load this dol as alternate dol?"), tr("OK"), tr("Cancel"));
if (choice) {
//ret = offsetselect[ret];
strlcpy(alternatedname, temp, sizeof(alternatedname));
exit = true;
}
}
if (cancelBtn.GetState() == STATE_CLICKED) {
ret = 696969;
exit = true;
}
}
HaltGui();
mainWindow->Remove(&w);
ResumeGui();
//free not needed list buffer anymore
free(fstbuffer);
return ret;
}
int autoSelectDol(const char *id, bool force) {
char id4[10];
sprintf(id4,"%c%c%c%c",id[0],id[1],id[2],id[3]);
////// games that can be forced (always need alt dol)
//Boogie
if (strcmp(id,"RBOP69") == 0) return 675;//previous value was 657
if (strcmp(id,"RBOE69") == 0) return 675;//starstremr
//Fifa 08
if (strcmp(id,"RF8E69") == 0) return 439;//from isostar
if (strcmp(id,"RF8P69") == 0) return 463;//from isostar
if (strcmp(id,"RF8X69") == 0) return 464;//from isostar
//Madden NFL07
if (strcmp(id,"RMDP69") == 0) return 39;//from isostar
//Madden NFL08
if (strcmp(id,"RNFP69") == 0) return 1079;//from isostar
//Medal of Honor: Heroes 2
if (strcmp(id,"RM2X69") == 0)return 601;//dj_skual
if (strcmp(id,"RM2P69") == 0)return 517;//MZottel
if (strcmp(id,"RM2E69") == 0) return 492;//Old8oy
//Mortal Kombat
if (strcmp(id,"RKMP5D") == 0) return 290;//from isostar
if (strcmp(id,"RKME5D") == 0) return 290;//starstremr
//NBA 08
if (strcmp(id,"RNBX69") == 0) return 964;//from isostar
//Pangya! Golf with Style
if (strcmp(id,"RPYP9B") == 0) return 12490;//from isostar
//Redsteel
if (strcmp(id,"REDP41") == 0) return 1957;//from isostar
if (strcmp(id,"REDE41") == 0) return 1957;//starstremr
//SSX
if (strcmp(id,"RSXP69") == 0) return 377;//previous value was 337
if (strcmp(id,"RSXE69") == 0) return 377;//previous value was 337
//Wii Sports Resort, needs alt dol one time only, to show the Motion Plus video
//if (strcmp(id,"RZTP01") == 0 && CheckForSave(id4)==0) return 952;//from isostar
//if (strcmp(id,"RZTE01") == 0 && CheckForSave(id4)==0) return 674;//from starstremr
//as well as Grand Slam Tennis, Tiger Woods 10, Virtual Tennis 2009
///// games that can't be forced (alt dol is not always needed)
if (!force) {
//Grand Slam Tennis
if (strcmp(id,"R5TP69") == 0) return 1493;//from isostar
if (strcmp(id,"R5TE69") == 0) return 1493;//starstremr
//Indiana Jones and the Staff of Kings (Fate of Atlantis)
if (strcmp(id,"RJ8P64") == 0) return 8;//from isostar
if (strcmp(id,"RJ8E64") == 0) return 8;//starstremr
//Medal of Honor Heroes
if (strcmp(id,"RMZX69") == 0) return 492;//from isostar
if (strcmp(id,"RMZP69") == 0) return 492;//from isostar
if (strcmp(id,"RMZE69") == 0) return 492;//starstremr
//Metal Slug Anthology
if (strcmp(id,"RMLP7U") == 0) return 56;//from isostar
//The House Of The Dead 2 & 3 Return
if (strcmp(id,"RHDP8P") == 0) return 149;//from isostar
if (strcmp(id,"RHDE8P") == 0) return 149;//starstremr
//Tiger Woods 10
if (strcmp(id,"R9OP69") == 0) return 1991;//from isostar
if (strcmp(id,"R9OE69") == 0) return 1973;//starstremr
//Virtual Tennis 2009
if (strcmp(id,"RVUP8P") == 0) return 16426;//from isostar
if (strcmp(id,"RVUE8P") == 0) return 16405;//from isostar
//Wii Sports Resort
if (strcmp(id,"RZTP01") == 0) return 952;//from isostar
if (strcmp(id,"RZTE01") == 0) return 674;//from starstremr
}
return -1;
}
int autoSelectDolMenu(const char *id, bool force) {
char id4[10];
sprintf(id4,"%c%c%c%c",id[0],id[1],id[2],id[3]);
/*
switch (CheckForSave(id4)) {
case 0:
WindowPrompt("NO save",0,tr("Ok"));
break;
case 1:
WindowPrompt("save",0,tr("Ok"));
break;
default:
char test[10];
sprintf(test,"%d",CheckForSave(id4));
WindowPrompt(test,0,tr("Ok"));
break;
}
return -1;
*/
//Metroid Prime Trilogy
if (strcmp(id,"R3ME01") == 0) {
//do not use any alt dol if there is no save game in the nand
/*
if (CheckForSave(id4)==0 && force) {
WindowPrompt(0,tr("You need to start this game one time to create a save file, then exit and start it again."),tr("Ok"));
return -1;
}
*/
int choice = WindowPrompt(tr("Select a DOL"), 0, "Metroid Prime", "Metroid Prime 2", "Metroid Prime 3", tr("Default"));
switch (choice) {
case 1:
choice = 780;
break;
case 2:
choice = 781;
break;
case 3:
choice = 782;
break;
default: // no alt dol
choice = 0;
break;
}
return choice;
}
if (strcmp(id,"R3MP01") == 0) {
/*
if (CheckForSave(id4)==0 && force) {
WindowPrompt(0,tr("You need to start this game one time to create a save file, then exit and start it again."),tr("Ok"));
return -1;
}
*/
int choice = WindowPrompt(tr("Select a DOL"), 0, "Metroid Prime", "Metroid Prime 2", "Metroid Prime 3", tr("Default"));
switch (choice) {
case 1:
choice = 782;
break;
case 2:
choice = 783;
break;
case 3:
choice = 784;
break;
default: // no alt dol
choice = 0;
break;
}
return choice;
}
return -1;
}
/********************************************************************************
* Mount a DVD, get the type and ID.
*********************************************************************************/
static vu32 dvddone = 0;
static dvddiskid *g_diskID = (dvddiskid*)0x80000000;
void __dvd_readidcb(s32 result)
{
dvddone = result;
}
u8 DiscMount(char *id) {
int ret;
char gameidbuffer[8];
HaltGui();
memset((char*)0x80000000, 0, 6);
ret = bwDVD_LowInit();
dvddone = 0;
ret = bwDVD_LowReset(__dvd_readidcb);
while(ret>=0 && dvddone==0);
dvddone = 0;
ret = bwDVD_LowReadID(g_diskID,__dvd_readidcb);
while(ret>=0 && dvddone==0);
memset(gameidbuffer, 0, 8);
memcpy(gameidbuffer, (char*)0x80000000, 6);
strcpy(id,gameidbuffer);
if(gameidbuffer[1] == 0 &&
gameidbuffer[2] == 0 &&
gameidbuffer[3] == 0 &&
gameidbuffer[4] == 0 &&
gameidbuffer[5] == 0 &&
gameidbuffer[6] == 0)
{
ResumeGui();
return 0;
}
if(*((u32 *) 0x8000001C) == 0xC2339F3D){
ResumeGui();
return 2;
}
ResumeGui();
return 1;
}
/****************************************************************************
* DiscBrowser
* USB Loader GX 2009
*
* DiscBrowser.h
***************************************************************************/
#include "language/gettext.h"
#include "libwiigui/gui.h"
#include "libwiigui/gui_customoptionbrowser.h"
#include "prompts/PromptWindows.h"
#include "filelist.h"
#include "menu.h"
#include "usbloader/disc.h"
#include "usbloader/fstfile.h"
#include "usbloader/wdvd.h"
#include "main.h"
#include "sys.h"
#include "settings/cfg.h"
#include "memory.h"
#include "../wad/title.h"
#include "../patches/dvd_broadway.h"
#define BC 0x0000000100000100ULL
/*** Extern functions ***/
extern void ResumeGui();
extern void HaltGui();
/*** Extern variables ***/
extern GuiWindow * mainWindow;
extern u8 shutdown;
extern u8 reset;
extern u8 dvdMounted;
/********************************************************************************
*Disk Browser
*********************************************************************************/
int DiscBrowse(struct discHdr * header) {
bool exit = false;
int ret, choice;
u64 offset;
HaltGui();
if (!dvdMounted)
{
ret = Disc_SetUSB(header->id);
if (ret < 0) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Could not set USB."), tr("OK"));
return ret;
}
}
ret = Disc_Open();
if (ret < 0) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Could not open disc."), tr("OK"));
return ret;
}
ret = __Disc_FindPartition(&offset);
if (ret < 0) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Could not find a WBFS partition."), tr("OK"));
return ret;
}
ret = WDVD_OpenPartition(offset);
if (ret < 0) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Could not open WBFS partition"), tr("OK"));
return ret;
}
int *buffer = (int*)allocate_memory(0x20);
if (buffer == NULL) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Not enough free memory."), tr("OK"));
return -1;
}
ret = WDVD_Read(buffer, 0x20, 0x420);
if (ret < 0) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Could not read the disc."), tr("OK"));
return ret;
}
void *fstbuffer = allocate_memory(buffer[2]*4);
FST_ENTRY *fst = (FST_ENTRY *)fstbuffer;
if (fst == NULL) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Not enough free memory."), tr("OK"));
free(buffer);
return -1;
}
ret = WDVD_Read(fstbuffer, buffer[2]*4, buffer[1]*4);
if (ret < 0) {
ResumeGui();
WindowPrompt(tr("ERROR:"), tr("Could not read the disc."), tr("OK"));
free(buffer);
free(fstbuffer);
return ret;
}
ResumeGui();
free(buffer);
WDVD_Reset();
//Disc_SetUSB(NULL);
WDVD_ClosePartition();
u32 discfilecount = fst[0].filelen;
u32 dolfilecount = 0;
//int offsetselect[20];
customOptionList options3(discfilecount);
for (u32 i = 0; i < discfilecount; i++) {
//don't add files that aren't .dol to the list
int len = (strlen(fstfiles(fst, i)));
if (fstfiles(fst, i)[len-4] =='.' &&
fstfiles(fst, i)[len-3] =='d' &&
fstfiles(fst, i)[len-2] =='o' &&
fstfiles(fst, i)[len-1] =='l') {
options3.SetName(i, "%i", i);
options3.SetValue(i, fstfiles(fst, i));
//options3.SetName(i, fstfiles(fst, i));
dolfilecount++;
}
}
if (dolfilecount <= 0) {
WindowPrompt(tr("ERROR"), tr("No dol file found on disc."), tr("OK"));
free(fstbuffer);
return -1;
}
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
GuiImageData btnOutline(imgPath, button_dialogue_box_png);
snprintf(imgPath, sizeof(imgPath), "%sgamesettings_background.png", CFG.theme_path);
GuiImageData settingsbg(imgPath, settings_background_png);
GuiTrigger trigA;
trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
GuiTrigger trigHome;
trigHome.SetButtonOnlyTrigger(-1, WPAD_BUTTON_HOME | WPAD_CLASSIC_BUTTON_HOME, 0);
GuiTrigger trigB;
trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B);
GuiText titleTxt(get_title(header), 28, (GXColor) {0, 0, 0, 255});
titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
titleTxt.SetPosition(12,40);
titleTxt.SetMaxWidth(356, GuiText::SCROLL);
GuiImage settingsbackground(&settingsbg);
GuiButton settingsbackgroundbtn(settingsbackground.GetWidth(), settingsbackground.GetHeight());
settingsbackgroundbtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
settingsbackgroundbtn.SetPosition(0, 0);
settingsbackgroundbtn.SetImage(&settingsbackground);
GuiText cancelBtnTxt(tr("Back"), 22, THEME.prompttext);
cancelBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30);
GuiImage cancelBtnImg(&btnOutline);
if (Settings.wsprompt == yes) {
cancelBtnTxt.SetWidescreen(CFG.widescreen);
cancelBtnImg.SetWidescreen(CFG.widescreen);
}
GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, &btnClick,1);
cancelBtn.SetScale(0.9);
cancelBtn.SetLabel(&cancelBtnTxt);
cancelBtn.SetTrigger(&trigB);
u8 scrollbaron = 0;
if (dolfilecount > 9)
scrollbaron = 1;
GuiCustomOptionBrowser optionBrowser3(396, 280, &options3, CFG.theme_path, "bg_options_gamesettings.png", bg_options_settings_png, dolfilecount>9?1:0, 200);
optionBrowser3.SetPosition(0, 90);
optionBrowser3.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
HaltGui();
GuiWindow w(screenwidth, screenheight);
w.Append(&settingsbackgroundbtn);
w.Append(&titleTxt);
w.Append(&cancelBtn);
w.Append(&optionBrowser3);
mainWindow->Append(&w);
ResumeGui();
while (!exit) {
VIDEO_WaitVSync();
if (shutdown == 1)
Sys_Shutdown();
if (reset == 1)
Sys_Reboot();
ret = optionBrowser3.GetClickedOption();
if (ret > 0) {
char temp[100];
strlcpy(temp, fstfiles(fst, ret), sizeof(temp));
choice = WindowPrompt(temp, tr("Load this dol as alternate dol?"), tr("OK"), tr("Cancel"));
if (choice) {
//ret = offsetselect[ret];
strlcpy(alternatedname, temp, sizeof(alternatedname));
exit = true;
}
}
if (cancelBtn.GetState() == STATE_CLICKED) {
ret = 696969;
exit = true;
}
}
HaltGui();
mainWindow->Remove(&w);
ResumeGui();
//free not needed list buffer anymore
free(fstbuffer);
return ret;
}
int autoSelectDol(const char *id, bool force) {
char id4[10];
sprintf(id4,"%c%c%c%c",id[0],id[1],id[2],id[3]);
////// games that can be forced (always need alt dol)
//Boogie
if (strcmp(id,"RBOP69") == 0) return 675;//previous value was 657
if (strcmp(id,"RBOE69") == 0) return 675;//starstremr
//Fifa 08
if (strcmp(id,"RF8E69") == 0) return 439;//from isostar
if (strcmp(id,"RF8P69") == 0) return 463;//from isostar
if (strcmp(id,"RF8X69") == 0) return 464;//from isostar
//Madden NFL07
if (strcmp(id,"RMDP69") == 0) return 39;//from isostar
//Madden NFL08
if (strcmp(id,"RNFP69") == 0) return 1079;//from isostar
//Medal of Honor: Heroes 2
if (strcmp(id,"RM2X69") == 0)return 601;//dj_skual
if (strcmp(id,"RM2P69") == 0)return 517;//MZottel
if (strcmp(id,"RM2E69") == 0) return 492;//Old8oy
//Mortal Kombat
if (strcmp(id,"RKMP5D") == 0) return 290;//from isostar
if (strcmp(id,"RKME5D") == 0) return 290;//starstremr
//NBA 08
if (strcmp(id,"RNBX69") == 0) return 964;//from isostar
//Pangya! Golf with Style
if (strcmp(id,"RPYP9B") == 0) return 12490;//from isostar
//Redsteel
if (strcmp(id,"REDP41") == 0) return 1957;//from isostar
if (strcmp(id,"REDE41") == 0) return 1957;//starstremr
//SSX
if (strcmp(id,"RSXP69") == 0) return 377;//previous value was 337
if (strcmp(id,"RSXE69") == 0) return 377;//previous value was 337
//Wii Sports Resort, needs alt dol one time only, to show the Motion Plus video
//if (strcmp(id,"RZTP01") == 0 && CheckForSave(id4)==0) return 952;//from isostar
//if (strcmp(id,"RZTE01") == 0 && CheckForSave(id4)==0) return 674;//from starstremr
//as well as Grand Slam Tennis, Tiger Woods 10, Virtual Tennis 2009
///// games that can't be forced (alt dol is not always needed)
if (!force) {
//Grand Slam Tennis
if (strcmp(id,"R5TP69") == 0) return 1493;//from isostar
if (strcmp(id,"R5TE69") == 0) return 1493;//starstremr
//Indiana Jones and the Staff of Kings (Fate of Atlantis)
if (strcmp(id,"RJ8P64") == 0) return 8;//from isostar
if (strcmp(id,"RJ8E64") == 0) return 8;//starstremr
//Medal of Honor Heroes
if (strcmp(id,"RMZX69") == 0) return 492;//from isostar
if (strcmp(id,"RMZP69") == 0) return 492;//from isostar
if (strcmp(id,"RMZE69") == 0) return 492;//starstremr
//Metal Slug Anthology
if (strcmp(id,"RMLP7U") == 0) return 56;//from isostar
//The House Of The Dead 2 & 3 Return
if (strcmp(id,"RHDP8P") == 0) return 149;//from isostar
if (strcmp(id,"RHDE8P") == 0) return 149;//starstremr
//Tiger Woods 10
if (strcmp(id,"R9OP69") == 0) return 1991;//from isostar
if (strcmp(id,"R9OE69") == 0) return 1973;//starstremr
//Virtual Tennis 2009
if (strcmp(id,"RVUP8P") == 0) return 16426;//from isostar
if (strcmp(id,"RVUE8P") == 0) return 16405;//from isostar
//Wii Sports Resort
if (strcmp(id,"RZTP01") == 0) return 952;//from isostar
if (strcmp(id,"RZTE01") == 0) return 674;//from starstremr
}
return -1;
}
int autoSelectDolMenu(const char *id, bool force) {
char id4[10];
sprintf(id4,"%c%c%c%c",id[0],id[1],id[2],id[3]);
/*
switch (CheckForSave(id4)) {
case 0:
WindowPrompt("NO save",0,tr("Ok"));
break;
case 1:
WindowPrompt("save",0,tr("Ok"));
break;
default:
char test[10];
sprintf(test,"%d",CheckForSave(id4));
WindowPrompt(test,0,tr("Ok"));
break;
}
return -1;
*/
//Metroid Prime Trilogy
if (strcmp(id,"R3ME01") == 0) {
//do not use any alt dol if there is no save game in the nand
/*
if (CheckForSave(id4)==0 && force) {
WindowPrompt(0,tr("You need to start this game one time to create a save file, then exit and start it again."),tr("Ok"));
return -1;
}
*/
int choice = WindowPrompt(tr("Select a DOL"), 0, "Metroid Prime", "Metroid Prime 2", "Metroid Prime 3", tr("Default"));
switch (choice) {
case 1:
choice = 780;
break;
case 2:
choice = 781;
break;
case 3:
choice = 782;
break;
default: // no alt dol
choice = 0;
break;
}
return choice;
}
if (strcmp(id,"R3MP01") == 0) {
/*
if (CheckForSave(id4)==0 && force) {
WindowPrompt(0,tr("You need to start this game one time to create a save file, then exit and start it again."),tr("Ok"));
return -1;
}
*/
int choice = WindowPrompt(tr("Select a DOL"), 0, "Metroid Prime", "Metroid Prime 2", "Metroid Prime 3", tr("Default"));
switch (choice) {
case 1:
choice = 782;
break;
case 2:
choice = 783;
break;
case 3:
choice = 784;
break;
default: // no alt dol
choice = 0;
break;
}
return choice;
}
return -1;
}
/********************************************************************************
* Mount a DVD, get the type and ID.
*********************************************************************************/
static vu32 dvddone = 0;
static dvddiskid *g_diskID = (dvddiskid*)0x80000000;
void __dvd_readidcb(s32 result)
{
dvddone = result;
}
u8 DiscMount(char *id) {
int ret;
char gameidbuffer[8];
HaltGui();
memset((char*)0x80000000, 0, 6);
ret = bwDVD_LowInit();
dvddone = 0;
ret = bwDVD_LowReset(__dvd_readidcb);
while(ret>=0 && dvddone==0);
dvddone = 0;
ret = bwDVD_LowReadID(g_diskID,__dvd_readidcb);
while(ret>=0 && dvddone==0);
memset(gameidbuffer, 0, 8);
memcpy(gameidbuffer, (char*)0x80000000, 6);
strcpy(id,gameidbuffer);
if(gameidbuffer[1] == 0 &&
gameidbuffer[2] == 0 &&
gameidbuffer[3] == 0 &&
gameidbuffer[4] == 0 &&
gameidbuffer[5] == 0 &&
gameidbuffer[6] == 0)
{
ResumeGui();
return 0;
}
if(*((u32 *) 0x8000001C) == 0xC2339F3D){
ResumeGui();
return 2;
}
ResumeGui();
return 1;
}

View File

@ -1,16 +1,16 @@
/****************************************************************************
* DiscBrowser
* USB Loader GX 2009
*
* DiscBrowser.h
***************************************************************************/
#ifndef _DISCBROWSER_H_
#define _DISCBROWSER_H_
int DiscBrowse(struct discHdr * header);
int autoSelectDol(const char *id, bool force);
int autoSelectDolMenu(const char *id, bool force);
u8 DiscMount(char *id);
#endif
/****************************************************************************
* DiscBrowser
* USB Loader GX 2009
*
* DiscBrowser.h
***************************************************************************/
#ifndef _DISCBROWSER_H_
#define _DISCBROWSER_H_
int DiscBrowse(struct discHdr * header);
int autoSelectDol(const char *id, bool force);
int autoSelectDolMenu(const char *id, bool force);
u8 DiscMount(char *id);
#endif

View File

@ -1,398 +1,398 @@
/****************************************************************************
* ProgressWindow
* USB Loader GX 2009
*
* ProgressWindow.cpp
***************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "menu.h"
#include "language/gettext.h"
#include "libwiigui/gui.h"
#include "prompts/ProgressWindow.h"
#include "usbloader/wbfs.h"
/*** Variables used only in this file ***/
static lwp_t progressthread = LWP_THREAD_NULL;
static char progressTitle[100];
static char progressMsg1[150];
static char progressMsg2[150];
static char progressTime[80];
static char progressSizeLeft[80];
static char progressSpeed[15];
static char *dyn_message;
static int showProgress = 0;
static f32 progressDone = 0.0;
static bool showTime = false;
static bool showSize = false;
static s32 gameinstalldone = 0;
static s32 gameinstalltotal = -1;
static time_t start;
/*** Extern variables ***/
extern GuiWindow * mainWindow;
extern float gamesize;
/*** Extern functions ***/
extern void ResumeGui();
extern void HaltGui();
/****************************************************************************
* GameInstallProgress
* GameInstallValue updating function
***************************************************************************/
static void GameInstallProgress() {
if (gameinstalltotal <= 0)
return;
GetProgressValue(&gameinstalldone, &gameinstalltotal);
if (gameinstalldone > gameinstalltotal)
gameinstalldone = gameinstalltotal;
static u32 expected = 300;
u32 elapsed, h, m, s;
f32 speed = 0;
//Elapsed time
elapsed = time(0) - start;
//Calculate speed in MB/s
if (elapsed > 0)
speed = KBSIZE * gamesize * gameinstalldone/(gameinstalltotal*elapsed);
if (gameinstalldone != gameinstalltotal) {
//Expected time
if (elapsed)
expected = (expected * 3 + elapsed * gameinstalltotal / gameinstalldone) / 4;
//Remaining time
elapsed = (expected > elapsed) ? (expected - elapsed) : 0;
}
//Calculate time values
h = elapsed / 3600;
m = (elapsed / 60) % 60;
s = elapsed % 60;
progressDone = 100.0*gameinstalldone/gameinstalltotal;
snprintf(progressTime, sizeof(progressTime), "%s %d:%02d:%02d",tr("Time left:"),h,m,s);
snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%.2fGB/%.2fGB", gamesize * gameinstalldone/gameinstalltotal, gamesize);
snprintf(progressSpeed, sizeof(progressSpeed), "%.1fMB/s", speed);
}
/****************************************************************************
* SetupGameInstallProgress
***************************************************************************/
void SetupGameInstallProgress(char * title, char * game) {
strlcpy(progressTitle, title, sizeof(progressTitle));
strlcpy(progressMsg1, game, sizeof(progressMsg1));
gameinstalltotal = 1;
showProgress = 1;
showSize = true;
showTime = true;
LWP_ResumeThread(progressthread);
start = time(0);
}
/****************************************************************************
* ProgressWindow
*
* Opens a window, which displays progress to the user. Can either display a
* progress bar showing % completion, or a throbber that only shows that an
* action is in progress.
***************************************************************************/
static void ProgressWindow(const char *title, const char *msg1, const char *msg2) {
GuiWindow promptWindow(472,320);
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
promptWindow.SetPosition(0, -10);
char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
GuiImageData btnOutline(imgPath, button_dialogue_box_png);
snprintf(imgPath, sizeof(imgPath), "%sdialogue_box.png", CFG.theme_path);
GuiImageData dialogBox(imgPath, dialogue_box_png);
GuiTrigger trigA;
trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
GuiImage dialogBoxImg(&dialogBox);
if (Settings.wsprompt == yes) {
dialogBoxImg.SetWidescreen(CFG.widescreen);
}
snprintf(imgPath, sizeof(imgPath), "%sprogressbar_outline.png", CFG.theme_path);
GuiImageData progressbarOutline(imgPath, progressbar_outline_png);
GuiImage progressbarOutlineImg(&progressbarOutline);
if (Settings.wsprompt == yes) {
progressbarOutlineImg.SetWidescreen(CFG.widescreen);
}
progressbarOutlineImg.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
progressbarOutlineImg.SetPosition(25, 40);
snprintf(imgPath, sizeof(imgPath), "%sprogressbar_empty.png", CFG.theme_path);
GuiImageData progressbarEmpty(imgPath, progressbar_empty_png);
GuiImage progressbarEmptyImg(&progressbarEmpty);
progressbarEmptyImg.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
progressbarEmptyImg.SetPosition(25, 40);
progressbarEmptyImg.SetTile(100);
snprintf(imgPath, sizeof(imgPath), "%sprogressbar.png", CFG.theme_path);
GuiImageData progressbar(imgPath, progressbar_png);
GuiImage progressbarImg(&progressbar);
progressbarImg.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
progressbarImg.SetPosition(25, 40);
GuiText titleTxt(title, 26, THEME.prompttext);
titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
titleTxt.SetPosition(0,60);
GuiText msg1Txt(msg1, 22, THEME.prompttext );
msg1Txt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
if (msg2)
msg1Txt.SetPosition(0,120);
else
msg1Txt.SetPosition(0,100);
msg1Txt.SetMaxWidth(430, GuiText::DOTTED);
GuiText msg2Txt(msg2, 22, THEME.prompttext );
msg2Txt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
msg2Txt.SetPosition(0,125);
msg2Txt.SetMaxWidth(430, GuiText::DOTTED);
GuiText prsTxt("%", 22, THEME.prompttext);
prsTxt.SetAlignment(ALIGN_RIGHT, ALIGN_MIDDLE);
prsTxt.SetPosition(-188,40);
GuiText timeTxt(NULL, 22, THEME.prompttext);
timeTxt.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
timeTxt.SetPosition(280,-50);
GuiText sizeTxt(NULL, 22, THEME.prompttext);
sizeTxt.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
sizeTxt.SetPosition(50, -50);
GuiText speedTxt(NULL, 22, THEME.prompttext);
speedTxt.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
speedTxt.SetPosition(50, -74);
GuiText prTxt(NULL, 26, THEME.prompttext);
prTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
prTxt.SetPosition(200, 40);
if ((Settings.wsprompt == yes) && (CFG.widescreen)) {/////////////adjust for widescreen
progressbarOutlineImg.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
progressbarOutlineImg.SetPosition(0, 40);
progressbarEmptyImg.SetPosition(80,40);
progressbarEmptyImg.SetTile(78);
progressbarImg.SetPosition(80, 40);
msg1Txt.SetMaxWidth(380, GuiText::DOTTED);
msg2Txt.SetMaxWidth(380, GuiText::DOTTED);
timeTxt.SetPosition(250,-50);
timeTxt.SetFontSize(20);
speedTxt.SetPosition(90,-74);
speedTxt.SetFontSize(20);
sizeTxt.SetPosition(90, -50);
sizeTxt.SetFontSize(20);
}
usleep(400000); // wait to see if progress flag changes soon
if (!showProgress)
return;
promptWindow.Append(&dialogBoxImg);
promptWindow.Append(&progressbarEmptyImg);
promptWindow.Append(&progressbarImg);
promptWindow.Append(&progressbarOutlineImg);
promptWindow.Append(&prTxt);
promptWindow.Append(&prsTxt);
if (title)
promptWindow.Append(&titleTxt);
if (msg1)
promptWindow.Append(&msg1Txt);
if (msg2)
promptWindow.Append(&msg2Txt);
if (showTime)
promptWindow.Append(&timeTxt);
if (showSize) {
promptWindow.Append(&sizeTxt);
promptWindow.Append(&speedTxt);
}
HaltGui();
promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_IN, 50);
mainWindow->SetState(STATE_DISABLED);
mainWindow->Append(&promptWindow);
mainWindow->ChangeFocus(&promptWindow);
ResumeGui();
while (promptWindow.GetEffect() > 0) usleep(100);
int tmp;
while (showProgress) {
VIDEO_WaitVSync ();
usleep(20000);
GameInstallProgress();
tmp = static_cast<int>(progressbarImg.GetWidth()*progressDone);
if (CFG.widescreen && Settings.wsprompt == yes)
progressbarImg.SetSkew(0,0,static_cast<int>(progressbarImg.GetWidth()*progressDone*0.8)-progressbarImg.GetWidth(),0,static_cast<int>(progressbarImg.GetWidth()*progressDone*0.8)-progressbarImg.GetWidth(),0,0,0);
else
progressbarImg.SetSkew(0,0,static_cast<int>(progressbarImg.GetWidth()*progressDone)-progressbarImg.GetWidth(),0,static_cast<int>(progressbarImg.GetWidth()*progressDone)-progressbarImg.GetWidth(),0,0,0);
prTxt.SetTextf("%.2f", progressDone);
if (showSize) {
sizeTxt.SetText(progressSizeLeft);
speedTxt.SetText(progressSpeed);
}
if (showTime)
timeTxt.SetText(progressTime);
if (msg2)
msg2Txt.SetText(dyn_message);
}
promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_OUT, 50);
while (promptWindow.GetEffect() > 0) usleep(100);
HaltGui();
mainWindow->Remove(&promptWindow);
mainWindow->SetState(STATE_DEFAULT);
ResumeGui();
}
/****************************************************************************
* ProgressThread
***************************************************************************/
static void * ProgressThread (void *arg) {
while (1) {
if (!showProgress)
LWP_SuspendThread (progressthread);
ProgressWindow(progressTitle, progressMsg1, progressMsg2);
usleep(100);
}
return NULL;
}
/****************************************************************************
* ProgressStop
***************************************************************************/
void ProgressStop() {
showProgress = 0;
gameinstalltotal = -1;
// wait for thread to finish
while (!LWP_ThreadIsSuspended(progressthread))
usleep(100);
}
/****************************************************************************
* ShowProgress
*
* Callbackfunction for updating the progress values
* Use this function as standard callback
***************************************************************************/
void ShowProgress(const char *title, const char *msg1, char *dynmsg2, f32 done, f32 total, bool swSize, bool swTime) {
if (total <= 0)
return;
else if (done > total)
done = total;
showSize = swSize;
showTime = swTime;
if (title)
strlcpy(progressTitle, title, sizeof(progressTitle));
if (msg1)
strlcpy(progressMsg1, msg1, sizeof(progressMsg1));
if (dynmsg2)
dyn_message = dynmsg2;
if (swTime == true) {
static u32 expected;
u32 elapsed, h, m, s, speed = 0;
if (!done) {
start = time(0);
expected = 300;
}
//Elapsed time
elapsed = time(0) - start;
//Calculate speed in KB/s
if (elapsed > 0)
speed = done/(elapsed*KBSIZE);
if (done != total) {
//Expected time
if (elapsed)
expected = (expected * 3 + elapsed * total / done) / 4;
//Remaining time
elapsed = (expected > elapsed) ? (expected - elapsed) : 0;
}
//Calculate time values
h = elapsed / 3600;
m = (elapsed / 60) % 60;
s = elapsed % 60;
snprintf(progressTime, sizeof(progressTime), "%s %d:%02d:%02d",tr("Time left:"),h,m,s);
}
if (swSize == true) {
if (total < MBSIZE)
snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fKB/%0.2fKB", done * done/total / KBSIZE, total/KBSIZE);
else if (total > MBSIZE && total < GBSIZE)
snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fMB/%0.2fMB", done * done/total / MBSIZE, total/MBSIZE);
else
snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fGB/%0.2fGB", done * done/total / GBSIZE, total/GBSIZE);
}
showProgress = 1;
progressDone = 100.0*done/total;
LWP_ResumeThread(progressthread);
}
/****************************************************************************
* InitProgressThread
*
* Startup Progressthread in idle prio
***************************************************************************/
void InitProgressThread() {
LWP_CreateThread(&progressthread, ProgressThread, NULL, NULL, 0, 0);
}
/****************************************************************************
* ExitProgressThread
*
* Shutdown Progressthread
***************************************************************************/
void ExitProgressThread() {
LWP_JoinThread(progressthread, NULL);
progressthread = LWP_THREAD_NULL;
}
/****************************************************************************
* ProgressWindow
* USB Loader GX 2009
*
* ProgressWindow.cpp
***************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "menu.h"
#include "language/gettext.h"
#include "libwiigui/gui.h"
#include "prompts/ProgressWindow.h"
#include "usbloader/wbfs.h"
/*** Variables used only in this file ***/
static lwp_t progressthread = LWP_THREAD_NULL;
static char progressTitle[100];
static char progressMsg1[150];
static char progressMsg2[150];
static char progressTime[80];
static char progressSizeLeft[80];
static char progressSpeed[15];
static char *dyn_message;
static int showProgress = 0;
static f32 progressDone = 0.0;
static bool showTime = false;
static bool showSize = false;
static s32 gameinstalldone = 0;
static s32 gameinstalltotal = -1;
static time_t start;
/*** Extern variables ***/
extern GuiWindow * mainWindow;
extern float gamesize;
/*** Extern functions ***/
extern void ResumeGui();
extern void HaltGui();
/****************************************************************************
* GameInstallProgress
* GameInstallValue updating function
***************************************************************************/
static void GameInstallProgress() {
if (gameinstalltotal <= 0)
return;
GetProgressValue(&gameinstalldone, &gameinstalltotal);
if (gameinstalldone > gameinstalltotal)
gameinstalldone = gameinstalltotal;
static u32 expected = 300;
u32 elapsed, h, m, s;
f32 speed = 0;
//Elapsed time
elapsed = time(0) - start;
//Calculate speed in MB/s
if (elapsed > 0)
speed = KBSIZE * gamesize * gameinstalldone/(gameinstalltotal*elapsed);
if (gameinstalldone != gameinstalltotal) {
//Expected time
if (elapsed)
expected = (expected * 3 + elapsed * gameinstalltotal / gameinstalldone) / 4;
//Remaining time
elapsed = (expected > elapsed) ? (expected - elapsed) : 0;
}
//Calculate time values
h = elapsed / 3600;
m = (elapsed / 60) % 60;
s = elapsed % 60;
progressDone = 100.0*gameinstalldone/gameinstalltotal;
snprintf(progressTime, sizeof(progressTime), "%s %d:%02d:%02d",tr("Time left:"),h,m,s);
snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%.2fGB/%.2fGB", gamesize * gameinstalldone/gameinstalltotal, gamesize);
snprintf(progressSpeed, sizeof(progressSpeed), "%.1fMB/s", speed);
}
/****************************************************************************
* SetupGameInstallProgress
***************************************************************************/
void SetupGameInstallProgress(char * title, char * game) {
strlcpy(progressTitle, title, sizeof(progressTitle));
strlcpy(progressMsg1, game, sizeof(progressMsg1));
gameinstalltotal = 1;
showProgress = 1;
showSize = true;
showTime = true;
LWP_ResumeThread(progressthread);
start = time(0);
}
/****************************************************************************
* ProgressWindow
*
* Opens a window, which displays progress to the user. Can either display a
* progress bar showing % completion, or a throbber that only shows that an
* action is in progress.
***************************************************************************/
static void ProgressWindow(const char *title, const char *msg1, const char *msg2) {
GuiWindow promptWindow(472,320);
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
promptWindow.SetPosition(0, -10);
char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
GuiImageData btnOutline(imgPath, button_dialogue_box_png);
snprintf(imgPath, sizeof(imgPath), "%sdialogue_box.png", CFG.theme_path);
GuiImageData dialogBox(imgPath, dialogue_box_png);
GuiTrigger trigA;
trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
GuiImage dialogBoxImg(&dialogBox);
if (Settings.wsprompt == yes) {
dialogBoxImg.SetWidescreen(CFG.widescreen);
}
snprintf(imgPath, sizeof(imgPath), "%sprogressbar_outline.png", CFG.theme_path);
GuiImageData progressbarOutline(imgPath, progressbar_outline_png);
GuiImage progressbarOutlineImg(&progressbarOutline);
if (Settings.wsprompt == yes) {
progressbarOutlineImg.SetWidescreen(CFG.widescreen);
}
progressbarOutlineImg.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
progressbarOutlineImg.SetPosition(25, 40);
snprintf(imgPath, sizeof(imgPath), "%sprogressbar_empty.png", CFG.theme_path);
GuiImageData progressbarEmpty(imgPath, progressbar_empty_png);
GuiImage progressbarEmptyImg(&progressbarEmpty);
progressbarEmptyImg.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
progressbarEmptyImg.SetPosition(25, 40);
progressbarEmptyImg.SetTile(100);
snprintf(imgPath, sizeof(imgPath), "%sprogressbar.png", CFG.theme_path);
GuiImageData progressbar(imgPath, progressbar_png);
GuiImage progressbarImg(&progressbar);
progressbarImg.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
progressbarImg.SetPosition(25, 40);
GuiText titleTxt(title, 26, THEME.prompttext);
titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
titleTxt.SetPosition(0,60);
GuiText msg1Txt(msg1, 22, THEME.prompttext );
msg1Txt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
if (msg2)
msg1Txt.SetPosition(0,120);
else
msg1Txt.SetPosition(0,100);
msg1Txt.SetMaxWidth(430, GuiText::DOTTED);
GuiText msg2Txt(msg2, 22, THEME.prompttext );
msg2Txt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
msg2Txt.SetPosition(0,125);
msg2Txt.SetMaxWidth(430, GuiText::DOTTED);
GuiText prsTxt("%", 22, THEME.prompttext);
prsTxt.SetAlignment(ALIGN_RIGHT, ALIGN_MIDDLE);
prsTxt.SetPosition(-188,40);
GuiText timeTxt(NULL, 22, THEME.prompttext);
timeTxt.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
timeTxt.SetPosition(280,-50);
GuiText sizeTxt(NULL, 22, THEME.prompttext);
sizeTxt.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
sizeTxt.SetPosition(50, -50);
GuiText speedTxt(NULL, 22, THEME.prompttext);
speedTxt.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
speedTxt.SetPosition(50, -74);
GuiText prTxt(NULL, 26, THEME.prompttext);
prTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
prTxt.SetPosition(200, 40);
if ((Settings.wsprompt == yes) && (CFG.widescreen)) {/////////////adjust for widescreen
progressbarOutlineImg.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
progressbarOutlineImg.SetPosition(0, 40);
progressbarEmptyImg.SetPosition(80,40);
progressbarEmptyImg.SetTile(78);
progressbarImg.SetPosition(80, 40);
msg1Txt.SetMaxWidth(380, GuiText::DOTTED);
msg2Txt.SetMaxWidth(380, GuiText::DOTTED);
timeTxt.SetPosition(250,-50);
timeTxt.SetFontSize(20);
speedTxt.SetPosition(90,-74);
speedTxt.SetFontSize(20);
sizeTxt.SetPosition(90, -50);
sizeTxt.SetFontSize(20);
}
usleep(400000); // wait to see if progress flag changes soon
if (!showProgress)
return;
promptWindow.Append(&dialogBoxImg);
promptWindow.Append(&progressbarEmptyImg);
promptWindow.Append(&progressbarImg);
promptWindow.Append(&progressbarOutlineImg);
promptWindow.Append(&prTxt);
promptWindow.Append(&prsTxt);
if (title)
promptWindow.Append(&titleTxt);
if (msg1)
promptWindow.Append(&msg1Txt);
if (msg2)
promptWindow.Append(&msg2Txt);
if (showTime)
promptWindow.Append(&timeTxt);
if (showSize) {
promptWindow.Append(&sizeTxt);
promptWindow.Append(&speedTxt);
}
HaltGui();
promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_IN, 50);
mainWindow->SetState(STATE_DISABLED);
mainWindow->Append(&promptWindow);
mainWindow->ChangeFocus(&promptWindow);
ResumeGui();
while (promptWindow.GetEffect() > 0) usleep(100);
int tmp;
while (showProgress) {
VIDEO_WaitVSync ();
usleep(20000);
GameInstallProgress();
tmp = static_cast<int>(progressbarImg.GetWidth()*progressDone);
if (CFG.widescreen && Settings.wsprompt == yes)
progressbarImg.SetSkew(0,0,static_cast<int>(progressbarImg.GetWidth()*progressDone*0.8)-progressbarImg.GetWidth(),0,static_cast<int>(progressbarImg.GetWidth()*progressDone*0.8)-progressbarImg.GetWidth(),0,0,0);
else
progressbarImg.SetSkew(0,0,static_cast<int>(progressbarImg.GetWidth()*progressDone)-progressbarImg.GetWidth(),0,static_cast<int>(progressbarImg.GetWidth()*progressDone)-progressbarImg.GetWidth(),0,0,0);
prTxt.SetTextf("%.2f", progressDone);
if (showSize) {
sizeTxt.SetText(progressSizeLeft);
speedTxt.SetText(progressSpeed);
}
if (showTime)
timeTxt.SetText(progressTime);
if (msg2)
msg2Txt.SetText(dyn_message);
}
promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_OUT, 50);
while (promptWindow.GetEffect() > 0) usleep(100);
HaltGui();
mainWindow->Remove(&promptWindow);
mainWindow->SetState(STATE_DEFAULT);
ResumeGui();
}
/****************************************************************************
* ProgressThread
***************************************************************************/
static void * ProgressThread (void *arg) {
while (1) {
if (!showProgress)
LWP_SuspendThread (progressthread);
ProgressWindow(progressTitle, progressMsg1, progressMsg2);
usleep(100);
}
return NULL;
}
/****************************************************************************
* ProgressStop
***************************************************************************/
void ProgressStop() {
showProgress = 0;
gameinstalltotal = -1;
// wait for thread to finish
while (!LWP_ThreadIsSuspended(progressthread))
usleep(100);
}
/****************************************************************************
* ShowProgress
*
* Callbackfunction for updating the progress values
* Use this function as standard callback
***************************************************************************/
void ShowProgress(const char *title, const char *msg1, char *dynmsg2, f32 done, f32 total, bool swSize, bool swTime) {
if (total <= 0)
return;
else if (done > total)
done = total;
showSize = swSize;
showTime = swTime;
if (title)
strlcpy(progressTitle, title, sizeof(progressTitle));
if (msg1)
strlcpy(progressMsg1, msg1, sizeof(progressMsg1));
if (dynmsg2)
dyn_message = dynmsg2;
if (swTime == true) {
static u32 expected;
u32 elapsed, h, m, s, speed = 0;
if (!done) {
start = time(0);
expected = 300;
}
//Elapsed time
elapsed = time(0) - start;
//Calculate speed in KB/s
if (elapsed > 0)
speed = done/(elapsed*KBSIZE);
if (done != total) {
//Expected time
if (elapsed)
expected = (expected * 3 + elapsed * total / done) / 4;
//Remaining time
elapsed = (expected > elapsed) ? (expected - elapsed) : 0;
}
//Calculate time values
h = elapsed / 3600;
m = (elapsed / 60) % 60;
s = elapsed % 60;
snprintf(progressTime, sizeof(progressTime), "%s %d:%02d:%02d",tr("Time left:"),h,m,s);
}
if (swSize == true) {
if (total < MBSIZE)
snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fKB/%0.2fKB", done * done/total / KBSIZE, total/KBSIZE);
else if (total > MBSIZE && total < GBSIZE)
snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fMB/%0.2fMB", done * done/total / MBSIZE, total/MBSIZE);
else
snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fGB/%0.2fGB", done * done/total / GBSIZE, total/GBSIZE);
}
showProgress = 1;
progressDone = 100.0*done/total;
LWP_ResumeThread(progressthread);
}
/****************************************************************************
* InitProgressThread
*
* Startup Progressthread in idle prio
***************************************************************************/
void InitProgressThread() {
LWP_CreateThread(&progressthread, ProgressThread, NULL, NULL, 0, 0);
}
/****************************************************************************
* ExitProgressThread
*
* Shutdown Progressthread
***************************************************************************/
void ExitProgressThread() {
LWP_JoinThread(progressthread, NULL);
progressthread = LWP_THREAD_NULL;
}

View File

@ -1,22 +1,22 @@
/****************************************************************************
* ProgressWindow
* USB Loader GX 2009
*
* ProgressWindow.h
***************************************************************************/
#ifndef _PROGRESSWINDOW_H_
#define _PROGRESSWINDOW_H_
#define KBSIZE 1024.0
#define MBSIZE 1048576.0
#define GBSIZE 1073741824.0
void InitProgressThread();
void ExitProgressThread();
void SetupGameInstallProgress(char * titl, char * game);
void ShowProgress (const char *title, const char *msg1, char *dynmsg2,
f32 done, f32 total, bool swSize = false, bool swTime = false);
void ProgressStop();
#endif
/****************************************************************************
* ProgressWindow
* USB Loader GX 2009
*
* ProgressWindow.h
***************************************************************************/
#ifndef _PROGRESSWINDOW_H_
#define _PROGRESSWINDOW_H_
#define KBSIZE 1024.0
#define MBSIZE 1048576.0
#define GBSIZE 1073741824.0
void InitProgressThread();
void ExitProgressThread();
void SetupGameInstallProgress(char * titl, char * game);
void ShowProgress (const char *title, const char *msg1, char *dynmsg2,
f32 done, f32 total, bool swSize = false, bool swTime = false);
void ProgressStop();
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,36 +1,36 @@
/****************************************************************************
* PromptWindows
* USB Loader GX 2009
*
* PromptWindows.h
***************************************************************************/
#ifndef _PROMPTWINDOWS_H_
#define _PROMPTWINDOWS_H_
#include "usbloader/partition.h"
#define NOTFULLCHANNEL
int WindowPrompt(const char *title, const char *msg = NULL, const char *btn1Label = NULL,
const char *btn2Label = NULL, const char *btn3Label = NULL,
const char *btn4Label = NULL, int wait = -1);
void WindowCredits();
int OnScreenKeyboard(char * var, u32 maxlen, int min);
int WindowExitPrompt(const char *title, const char *msg, const char *btn1Label, const char *btn2Label, const char *btn3Label, const char *btn4Label);
int GameWindowPrompt();
int DiscWait(const char *title, const char *msg, const char *btn1Label, const char *btn2Label, int IsDeviceWait);
int FormatingPartition(const char *title, partitionEntry *entry);
bool SearchMissingImages(int choice2);
int ProgressDownloadWindow(int choice2);
int ProgressUpdateWindow();
bool NetworkInitPrompt();
char * GetMissingFiles();
int WindowScreensaver();
int CodeDownload(const char *id);
int HBCWindowPrompt(const char *name, const char *coder, const char *version,
const char *release_date, const char *long_description,
const char *iconPath, u64 filesize);
#endif
/****************************************************************************
* PromptWindows
* USB Loader GX 2009
*
* PromptWindows.h
***************************************************************************/
#ifndef _PROMPTWINDOWS_H_
#define _PROMPTWINDOWS_H_
#include "usbloader/partition.h"
#define NOTFULLCHANNEL
int WindowPrompt(const char *title, const char *msg = NULL, const char *btn1Label = NULL,
const char *btn2Label = NULL, const char *btn3Label = NULL,
const char *btn4Label = NULL, int wait = -1);
void WindowCredits();
int OnScreenKeyboard(char * var, u32 maxlen, int min);
int WindowExitPrompt(const char *title, const char *msg, const char *btn1Label, const char *btn2Label, const char *btn3Label, const char *btn4Label);
int GameWindowPrompt();
int DiscWait(const char *title, const char *msg, const char *btn1Label, const char *btn2Label, int IsDeviceWait);
int FormatingPartition(const char *title, partitionEntry *entry);
bool SearchMissingImages(int choice2);
int ProgressDownloadWindow(int choice2);
int ProgressUpdateWindow();
bool NetworkInitPrompt();
char * GetMissingFiles();
int WindowScreensaver();
int CodeDownload(const char *id);
int HBCWindowPrompt(const char *name, const char *coder, const char *version,
const char *release_date, const char *long_description,
const char *iconPath, u64 filesize);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,15 @@
/****************************************************************************
* TitleBrowser
* USB Loader GX 2009
*
* TitleBrowser.h
***************************************************************************/
#ifndef _TITLEBROWSER_H_
#define _TITLEBROWSER_H_
///opens a window with a custom option browser in it populated with
//! type is the type of chnnel to put in the list
int TitleBrowser(u32 type);
#endif
/****************************************************************************
* TitleBrowser
* USB Loader GX 2009
*
* TitleBrowser.h
***************************************************************************/
#ifndef _TITLEBROWSER_H_
#define _TITLEBROWSER_H_
///opens a window with a custom option browser in it populated with
//! type is the type of chnnel to put in the list
int TitleBrowser(u32 type);
#endif

View File

@ -1,455 +1,455 @@
/****************************************************************************
* libwiigui Template
* Tantric 2009
*
* modified by dimok
*
* filebrowser.cpp
*
* Generic file routines - reading, writing, browsing
***************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiiuse/wpad.h>
#include <sys/dir.h>
#include <malloc.h>
#include "filebrowser.h"
#include "menu.h"
#include "listfiles.h"
#include "language/gettext.h"
#include "PromptWindows.h"
#include "libwiigui/gui.h"
#include "sys.h"
/*** Extern variables ***/
extern GuiWindow * mainWindow;
extern u8 shutdown;
extern u8 reset;
/*** Extern functions ***/
extern void ResumeGui();
extern void HaltGui();
BROWSERINFO browser;
BROWSERENTRY * browserList = NULL; // list of files/folders in browser
/****************************************************************************
* ResetBrowser()
* Clears the file browser memory, and allocates one initial entry
***************************************************************************/
void ResetBrowser() {
browser.numEntries = 0;
browser.selIndex = 0;
browser.pageIndex = 0;
// Clear any existing values
if (browserList != NULL) {
free(browserList);
browserList = NULL;
}
// set aside space for 1 entry
browserList = (BROWSERENTRY *)malloc(sizeof(BROWSERENTRY));
memset(browserList, 0, sizeof(BROWSERENTRY));
}
/****************************************************************************
* UpdateDirName()
* Update curent directory name for file browser
***************************************************************************/
int UpdateDirName() {
int size=0;
char * test;
char temp[1024];
/* current directory doesn't change */
if (strcmp(browserList[browser.selIndex].filename,".") == 0) {
return 0;
}
/* go up to parent directory */
else if (strcmp(browserList[browser.selIndex].filename,"..") == 0) {
/* determine last subdirectory namelength */
sprintf(temp,"%s",browser.dir);
test = strtok(temp,"/");
while (test != NULL) {
size = strlen(test);
test = strtok(NULL,"/");
}
/* remove last subdirectory name */
size = strlen(browser.dir) - size - 1;
browser.dir[size] = 0;
return 1;
}
/* Open a directory */
else {
/* test new directory namelength */
if ((strlen(browser.dir)+1+strlen(browserList[browser.selIndex].filename)) < MAXPATHLEN) {
/* update current directory name */
sprintf(browser.dir, "%s/%s",browser.dir, browserList[browser.selIndex].filename);
return 1;
} else {
return -1;
}
}
}
/****************************************************************************
* FileSortCallback
*
* Quick sort callback to sort file entries with the following order:
* .
* ..
* <dirs>
* <files>
***************************************************************************/
int FileSortCallback(const void *f1, const void *f2) {
/* Special case for implicit directories */
if (((BROWSERENTRY *)f1)->filename[0] == '.' || ((BROWSERENTRY *)f2)->filename[0] == '.') {
if (strcmp(((BROWSERENTRY *)f1)->filename, ".") == 0) {
return -1;
}
if (strcmp(((BROWSERENTRY *)f2)->filename, ".") == 0) {
return 1;
}
if (strcmp(((BROWSERENTRY *)f1)->filename, "..") == 0) {
return -1;
}
if (strcmp(((BROWSERENTRY *)f2)->filename, "..") == 0) {
return 1;
}
}
/* If one is a file and one is a directory the directory is first. */
if (((BROWSERENTRY *)f1)->isdir && !(((BROWSERENTRY *)f2)->isdir)) return -1;
if (!(((BROWSERENTRY *)f1)->isdir) && ((BROWSERENTRY *)f2)->isdir) return 1;
return stricmp(((BROWSERENTRY *)f1)->filename, ((BROWSERENTRY *)f2)->filename);
}
/***************************************************************************
* Browse subdirectories
**************************************************************************/
int
ParseDirectory() {
DIR_ITER *dir = NULL;
char fulldir[MAXPATHLEN];
char filename[MAXPATHLEN];
struct stat filestat;
// reset browser
ResetBrowser();
// open the directory
sprintf(fulldir, "%s%s", browser.rootdir, browser.dir); // add currentDevice to path
dir = diropen(fulldir);
// if we can't open the dir, try opening the root dir
if (dir == NULL) {
sprintf(browser.dir,"/");
dir = diropen(browser.rootdir);
if (dir == NULL) {
return -1;
}
}
// index files/folders
int entryNum = 0;
while (dirnext(dir,filename,&filestat) == 0) {
if (strcmp(filename,".") != 0) {
BROWSERENTRY * newBrowserList = (BROWSERENTRY *)realloc(browserList, (entryNum+1) * sizeof(BROWSERENTRY));
if (!newBrowserList) { // failed to allocate required memory
ResetBrowser();
entryNum = -1;
break;
} else {
browserList = newBrowserList;
}
memset(&(browserList[entryNum]), 0, sizeof(BROWSERENTRY)); // clear the new entry
strncpy(browserList[entryNum].filename, filename, MAXJOLIET);
if (strcmp(filename,"..") == 0) {
sprintf(browserList[entryNum].displayname, "..");
} else {
strcpy(browserList[entryNum].displayname, filename); // crop name for display
}
browserList[entryNum].length = filestat.st_size;
browserList[entryNum].isdir = (filestat.st_mode & _IFDIR) == 0 ? 0 : 1; // flag this as a dir
entryNum++;
}
}
// close directory
dirclose(dir);
// Sort the file list
qsort(browserList, entryNum, sizeof(BROWSERENTRY), FileSortCallback);
browser.numEntries = entryNum;
return entryNum;
}
/****************************************************************************
* BrowserChangeFolder
*
* Update current directory and set new entry list if directory has changed
***************************************************************************/
int BrowserChangeFolder() {
if (!UpdateDirName())
return -1;
ParseDirectory();
return browser.numEntries;
}
/****************************************************************************
* BrowseDevice
* Displays a list of files on the selected device
***************************************************************************/
int BrowseDevice(int device) {
sprintf(browser.dir, "/");
switch (device) {
case SD:
sprintf(browser.rootdir, "SD:");
break;
case USB:
sprintf(browser.rootdir, "USB:");
break;
}
ParseDirectory(); // Parse root directory
return browser.numEntries;
}
/****************************************************************************
* MenuBrowseDevice
***************************************************************************/
int BrowseDevice(char * var, int force) {
int result=-1;
int i;
char currentdir[90];
int curDivice = -1;
int forced =force;
if (forced>-1) {
if (BrowseDevice(forced) > 0) {
curDivice = forced;
goto main;
}
}
else if ((!strcasecmp(bootDevice, "USB:"))&&(BrowseDevice(USB) > 0)) {
curDivice = USB;
goto main;
} else if ((!strcasecmp(bootDevice, "SD:"))&&(BrowseDevice(SD) > 0)) {
curDivice = SD;
goto main;
} else {
WindowPrompt(tr("Error"),0,tr("Ok"));
return -1;
}
main:
int menu = MENU_NONE;
/*
GuiText titleTxt("Browse Files", 28, (GXColor){0, 0, 0, 230});
titleTxt.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
titleTxt.SetPosition(70,20);
*/
GuiTrigger trigA;
trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
GuiTrigger trigB;
trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
GuiImageData folderImgData(folder_png);
GuiImage folderImg(&folderImgData);
GuiButton folderBtn(folderImg.GetWidth(), folderImg.GetHeight());
folderBtn.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
folderBtn.SetPosition(-210, -145);
folderBtn.SetImage(&folderImg);
folderBtn.SetTrigger(&trigA);
folderBtn.SetEffectGrow();
char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
GuiImageData btnOutline(imgPath, button_dialogue_box_png);
GuiText ExitBtnTxt(tr("Cancel"), 24, (GXColor) {0, 0, 0, 255});
GuiImage ExitBtnImg(&btnOutline);
if (Settings.wsprompt == yes) {
ExitBtnTxt.SetWidescreen(CFG.widescreen);
ExitBtnImg.SetWidescreen(CFG.widescreen);
}
GuiButton ExitBtn(btnOutline.GetWidth(), btnOutline.GetHeight());
ExitBtn.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
ExitBtn.SetPosition(-40, -35);
ExitBtn.SetLabel(&ExitBtnTxt);
ExitBtn.SetImage(&ExitBtnImg);
ExitBtn.SetTrigger(&trigA);
ExitBtn.SetTrigger(&trigB);
ExitBtn.SetEffectGrow();
GuiText usbBtnTxt((curDivice==SD?"USB":"SD"), 24, (GXColor) {0, 0, 0, 255});
GuiImage usbBtnImg(&btnOutline);
if (Settings.wsprompt == yes) {
usbBtnTxt.SetWidescreen(CFG.widescreen);
usbBtnImg.SetWidescreen(CFG.widescreen);
}
GuiButton usbBtn(btnOutline.GetWidth(), btnOutline.GetHeight());
usbBtn.SetAlignment(ALIGN_CENTRE, ALIGN_BOTTOM);
usbBtn.SetPosition(0, -35);
usbBtn.SetLabel(&usbBtnTxt);
usbBtn.SetImage(&usbBtnImg);
usbBtn.SetTrigger(&trigA);
usbBtn.SetEffectGrow();
GuiText okBtnTxt(tr("Ok"), 22, THEME.prompttext);
GuiImage okBtnImg(&btnOutline);
if (Settings.wsprompt == yes) {
okBtnTxt.SetWidescreen(CFG.widescreen);
okBtnImg.SetWidescreen(CFG.widescreen);
}
GuiButton okBtn(&okBtnImg,&okBtnImg, 0, 4, 40, -35, &trigA, &btnSoundOver, &btnClick,1);
okBtn.SetLabel(&okBtnTxt);
GuiFileBrowser fileBrowser(396, 248);
fileBrowser.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
fileBrowser.SetPosition(0, 120);
GuiImageData Address(addressbar_textbox_png);
snprintf(currentdir, sizeof(currentdir), "%s%s", browser.rootdir, browser.dir);
GuiText AdressText(currentdir, 20, (GXColor) { 0, 0, 0, 255});
AdressText.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
AdressText.SetPosition(20, 0);
AdressText.SetMaxWidth(Address.GetWidth()-40, GuiText::SCROLL);
GuiImage AdressbarImg(&Address);
GuiButton Adressbar(Address.GetWidth(), Address.GetHeight());
Adressbar.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
Adressbar.SetPosition(0, fileBrowser.GetTop()-45);
Adressbar.SetImage(&AdressbarImg);
Adressbar.SetLabel(&AdressText);
//save var in case they cancel and return it to them
snprintf(currentdir, sizeof(currentdir), "%s", var);
sprintf(var,"%s", browser.rootdir);
HaltGui();
GuiWindow w(screenwidth, screenheight);
w.Append(&ExitBtn);
// w.Append(&titleTxt);
w.Append(&fileBrowser);
w.Append(&Adressbar);
w.Append(&okBtn);
w.Append(&folderBtn);
w.Append(&usbBtn);
mainWindow->Append(&w);
ResumeGui();
while (menu == MENU_NONE) {
VIDEO_WaitVSync();
if (shutdown == 1)
Sys_Shutdown();
if (reset == 1)
Sys_Reboot();
for (i=0; i<PAGESIZE; i++) {
if (fileBrowser.fileList[i]->GetState() == STATE_CLICKED) {
fileBrowser.fileList[i]->ResetState();
// check corresponding browser entry
if (browserList[browser.selIndex].isdir) {
if (BrowserChangeFolder()) {
fileBrowser.ResetState();
fileBrowser.fileList[0]->SetState(STATE_SELECTED);
fileBrowser.TriggerUpdate();
sprintf(var,"%s", browser.rootdir);
int len=strlen(browser.rootdir);
for (unsigned int i=len;i<strlen(browser.rootdir)+strlen(browser.dir);i++) {
var[i]=browser.dir[i-(len-1)];
}
AdressText.SetTextf("%s", var);
} else {
menu = MENU_DISCLIST;
break;
}
} else {
mainWindow->SetState(STATE_DISABLED);
mainWindow->SetState(STATE_DEFAULT);
}
}
}
if (ExitBtn.GetState() == STATE_CLICKED) {
snprintf(var,sizeof(currentdir),"%s", currentdir);
break;
}
if (okBtn.GetState() == STATE_CLICKED) {
result = 1;
break;
} else if (usbBtn.GetState() == STATE_CLICKED) {
HaltGui();
mainWindow->Remove(&w);
ResumeGui();
result = BrowseDevice(var, (curDivice==SD?USB:SD));
break;
} else if (folderBtn.GetState() == STATE_CLICKED) {
HaltGui();
mainWindow->Remove(&w);
ResumeGui();
char newfolder[100];
char oldfolder[100];
sprintf(newfolder,"%s/",var);
strcpy(oldfolder,newfolder);
int result = OnScreenKeyboard(newfolder,100,0);
if ( result == 1 ) {
int len = (strlen(newfolder)-1);
if (newfolder[len] !='/')
strncat (newfolder, "/", 1);
char* pos = newfolder;
char root[6];
sprintf(root,"%s/",browser.rootdir);
if (len > 0 && strcmp(oldfolder,newfolder)!=0 && strstr(newfolder,root) == pos && strstr(newfolder,"//") == NULL) {
struct stat st;
if (stat(newfolder, &st) != 0) {
if (subfoldercreate(newfolder) != 1) {
WindowPrompt(tr("Error !"),tr("Can't create directory"),tr("OK"));
break;
}
} else {
break;
}
}
}
result = BrowseDevice(var, (curDivice==SD?SD:USB));
break;
}
}
HaltGui();
mainWindow->Remove(&w);
ResumeGui();
//}
return result;
}
/****************************************************************************
* libwiigui Template
* Tantric 2009
*
* modified by dimok
*
* filebrowser.cpp
*
* Generic file routines - reading, writing, browsing
***************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiiuse/wpad.h>
#include <sys/dir.h>
#include <malloc.h>
#include "filebrowser.h"
#include "menu.h"
#include "listfiles.h"
#include "language/gettext.h"
#include "PromptWindows.h"
#include "libwiigui/gui.h"
#include "sys.h"
/*** Extern variables ***/
extern GuiWindow * mainWindow;
extern u8 shutdown;
extern u8 reset;
/*** Extern functions ***/
extern void ResumeGui();
extern void HaltGui();
BROWSERINFO browser;
BROWSERENTRY * browserList = NULL; // list of files/folders in browser
/****************************************************************************
* ResetBrowser()
* Clears the file browser memory, and allocates one initial entry
***************************************************************************/
void ResetBrowser() {
browser.numEntries = 0;
browser.selIndex = 0;
browser.pageIndex = 0;
// Clear any existing values
if (browserList != NULL) {
free(browserList);
browserList = NULL;
}
// set aside space for 1 entry
browserList = (BROWSERENTRY *)malloc(sizeof(BROWSERENTRY));
memset(browserList, 0, sizeof(BROWSERENTRY));
}
/****************************************************************************
* UpdateDirName()
* Update curent directory name for file browser
***************************************************************************/
int UpdateDirName() {
int size=0;
char * test;
char temp[1024];
/* current directory doesn't change */
if (strcmp(browserList[browser.selIndex].filename,".") == 0) {
return 0;
}
/* go up to parent directory */
else if (strcmp(browserList[browser.selIndex].filename,"..") == 0) {
/* determine last subdirectory namelength */
sprintf(temp,"%s",browser.dir);
test = strtok(temp,"/");
while (test != NULL) {
size = strlen(test);
test = strtok(NULL,"/");
}
/* remove last subdirectory name */
size = strlen(browser.dir) - size - 1;
browser.dir[size] = 0;
return 1;
}
/* Open a directory */
else {
/* test new directory namelength */
if ((strlen(browser.dir)+1+strlen(browserList[browser.selIndex].filename)) < MAXPATHLEN) {
/* update current directory name */
sprintf(browser.dir, "%s/%s",browser.dir, browserList[browser.selIndex].filename);
return 1;
} else {
return -1;
}
}
}
/****************************************************************************
* FileSortCallback
*
* Quick sort callback to sort file entries with the following order:
* .
* ..
* <dirs>
* <files>
***************************************************************************/
int FileSortCallback(const void *f1, const void *f2) {
/* Special case for implicit directories */
if (((BROWSERENTRY *)f1)->filename[0] == '.' || ((BROWSERENTRY *)f2)->filename[0] == '.') {
if (strcmp(((BROWSERENTRY *)f1)->filename, ".") == 0) {
return -1;
}
if (strcmp(((BROWSERENTRY *)f2)->filename, ".") == 0) {
return 1;
}
if (strcmp(((BROWSERENTRY *)f1)->filename, "..") == 0) {
return -1;
}
if (strcmp(((BROWSERENTRY *)f2)->filename, "..") == 0) {
return 1;
}
}
/* If one is a file and one is a directory the directory is first. */
if (((BROWSERENTRY *)f1)->isdir && !(((BROWSERENTRY *)f2)->isdir)) return -1;
if (!(((BROWSERENTRY *)f1)->isdir) && ((BROWSERENTRY *)f2)->isdir) return 1;
return stricmp(((BROWSERENTRY *)f1)->filename, ((BROWSERENTRY *)f2)->filename);
}
/***************************************************************************
* Browse subdirectories
**************************************************************************/
int
ParseDirectory() {
DIR_ITER *dir = NULL;
char fulldir[MAXPATHLEN];
char filename[MAXPATHLEN];
struct stat filestat;
// reset browser
ResetBrowser();
// open the directory
sprintf(fulldir, "%s%s", browser.rootdir, browser.dir); // add currentDevice to path
dir = diropen(fulldir);
// if we can't open the dir, try opening the root dir
if (dir == NULL) {
sprintf(browser.dir,"/");
dir = diropen(browser.rootdir);
if (dir == NULL) {
return -1;
}
}
// index files/folders
int entryNum = 0;
while (dirnext(dir,filename,&filestat) == 0) {
if (strcmp(filename,".") != 0) {
BROWSERENTRY * newBrowserList = (BROWSERENTRY *)realloc(browserList, (entryNum+1) * sizeof(BROWSERENTRY));
if (!newBrowserList) { // failed to allocate required memory
ResetBrowser();
entryNum = -1;
break;
} else {
browserList = newBrowserList;
}
memset(&(browserList[entryNum]), 0, sizeof(BROWSERENTRY)); // clear the new entry
strncpy(browserList[entryNum].filename, filename, MAXJOLIET);
if (strcmp(filename,"..") == 0) {
sprintf(browserList[entryNum].displayname, "..");
} else {
strcpy(browserList[entryNum].displayname, filename); // crop name for display
}
browserList[entryNum].length = filestat.st_size;
browserList[entryNum].isdir = (filestat.st_mode & _IFDIR) == 0 ? 0 : 1; // flag this as a dir
entryNum++;
}
}
// close directory
dirclose(dir);
// Sort the file list
qsort(browserList, entryNum, sizeof(BROWSERENTRY), FileSortCallback);
browser.numEntries = entryNum;
return entryNum;
}
/****************************************************************************
* BrowserChangeFolder
*
* Update current directory and set new entry list if directory has changed
***************************************************************************/
int BrowserChangeFolder() {
if (!UpdateDirName())
return -1;
ParseDirectory();
return browser.numEntries;
}
/****************************************************************************
* BrowseDevice
* Displays a list of files on the selected device
***************************************************************************/
int BrowseDevice(int device) {
sprintf(browser.dir, "/");
switch (device) {
case SD:
sprintf(browser.rootdir, "SD:");
break;
case USB:
sprintf(browser.rootdir, "USB:");
break;
}
ParseDirectory(); // Parse root directory
return browser.numEntries;
}
/****************************************************************************
* MenuBrowseDevice
***************************************************************************/
int BrowseDevice(char * var, int force) {
int result=-1;
int i;
char currentdir[90];
int curDivice = -1;
int forced =force;
if (forced>-1) {
if (BrowseDevice(forced) > 0) {
curDivice = forced;
goto main;
}
}
else if ((!strcasecmp(bootDevice, "USB:"))&&(BrowseDevice(USB) > 0)) {
curDivice = USB;
goto main;
} else if ((!strcasecmp(bootDevice, "SD:"))&&(BrowseDevice(SD) > 0)) {
curDivice = SD;
goto main;
} else {
WindowPrompt(tr("Error"),0,tr("Ok"));
return -1;
}
main:
int menu = MENU_NONE;
/*
GuiText titleTxt("Browse Files", 28, (GXColor){0, 0, 0, 230});
titleTxt.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
titleTxt.SetPosition(70,20);
*/
GuiTrigger trigA;
trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
GuiTrigger trigB;
trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
GuiImageData folderImgData(folder_png);
GuiImage folderImg(&folderImgData);
GuiButton folderBtn(folderImg.GetWidth(), folderImg.GetHeight());
folderBtn.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
folderBtn.SetPosition(-210, -145);
folderBtn.SetImage(&folderImg);
folderBtn.SetTrigger(&trigA);
folderBtn.SetEffectGrow();
char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
GuiImageData btnOutline(imgPath, button_dialogue_box_png);
GuiText ExitBtnTxt(tr("Cancel"), 24, (GXColor) {0, 0, 0, 255});
GuiImage ExitBtnImg(&btnOutline);
if (Settings.wsprompt == yes) {
ExitBtnTxt.SetWidescreen(CFG.widescreen);
ExitBtnImg.SetWidescreen(CFG.widescreen);
}
GuiButton ExitBtn(btnOutline.GetWidth(), btnOutline.GetHeight());
ExitBtn.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
ExitBtn.SetPosition(-40, -35);
ExitBtn.SetLabel(&ExitBtnTxt);
ExitBtn.SetImage(&ExitBtnImg);
ExitBtn.SetTrigger(&trigA);
ExitBtn.SetTrigger(&trigB);
ExitBtn.SetEffectGrow();
GuiText usbBtnTxt((curDivice==SD?"USB":"SD"), 24, (GXColor) {0, 0, 0, 255});
GuiImage usbBtnImg(&btnOutline);
if (Settings.wsprompt == yes) {
usbBtnTxt.SetWidescreen(CFG.widescreen);
usbBtnImg.SetWidescreen(CFG.widescreen);
}
GuiButton usbBtn(btnOutline.GetWidth(), btnOutline.GetHeight());
usbBtn.SetAlignment(ALIGN_CENTRE, ALIGN_BOTTOM);
usbBtn.SetPosition(0, -35);
usbBtn.SetLabel(&usbBtnTxt);
usbBtn.SetImage(&usbBtnImg);
usbBtn.SetTrigger(&trigA);
usbBtn.SetEffectGrow();
GuiText okBtnTxt(tr("Ok"), 22, THEME.prompttext);
GuiImage okBtnImg(&btnOutline);
if (Settings.wsprompt == yes) {
okBtnTxt.SetWidescreen(CFG.widescreen);
okBtnImg.SetWidescreen(CFG.widescreen);
}
GuiButton okBtn(&okBtnImg,&okBtnImg, 0, 4, 40, -35, &trigA, &btnSoundOver, &btnClick,1);
okBtn.SetLabel(&okBtnTxt);
GuiFileBrowser fileBrowser(396, 248);
fileBrowser.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
fileBrowser.SetPosition(0, 120);
GuiImageData Address(addressbar_textbox_png);
snprintf(currentdir, sizeof(currentdir), "%s%s", browser.rootdir, browser.dir);
GuiText AdressText(currentdir, 20, (GXColor) { 0, 0, 0, 255});
AdressText.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
AdressText.SetPosition(20, 0);
AdressText.SetMaxWidth(Address.GetWidth()-40, GuiText::SCROLL);
GuiImage AdressbarImg(&Address);
GuiButton Adressbar(Address.GetWidth(), Address.GetHeight());
Adressbar.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
Adressbar.SetPosition(0, fileBrowser.GetTop()-45);
Adressbar.SetImage(&AdressbarImg);
Adressbar.SetLabel(&AdressText);
//save var in case they cancel and return it to them
snprintf(currentdir, sizeof(currentdir), "%s", var);
sprintf(var,"%s", browser.rootdir);
HaltGui();
GuiWindow w(screenwidth, screenheight);
w.Append(&ExitBtn);
// w.Append(&titleTxt);
w.Append(&fileBrowser);
w.Append(&Adressbar);
w.Append(&okBtn);
w.Append(&folderBtn);
w.Append(&usbBtn);
mainWindow->Append(&w);
ResumeGui();
while (menu == MENU_NONE) {
VIDEO_WaitVSync();
if (shutdown == 1)
Sys_Shutdown();
if (reset == 1)
Sys_Reboot();
for (i=0; i<PAGESIZE; i++) {
if (fileBrowser.fileList[i]->GetState() == STATE_CLICKED) {
fileBrowser.fileList[i]->ResetState();
// check corresponding browser entry
if (browserList[browser.selIndex].isdir) {
if (BrowserChangeFolder()) {
fileBrowser.ResetState();
fileBrowser.fileList[0]->SetState(STATE_SELECTED);
fileBrowser.TriggerUpdate();
sprintf(var,"%s", browser.rootdir);
int len=strlen(browser.rootdir);
for (unsigned int i=len;i<strlen(browser.rootdir)+strlen(browser.dir);i++) {
var[i]=browser.dir[i-(len-1)];
}
AdressText.SetTextf("%s", var);
} else {
menu = MENU_DISCLIST;
break;
}
} else {
mainWindow->SetState(STATE_DISABLED);
mainWindow->SetState(STATE_DEFAULT);
}
}
}
if (ExitBtn.GetState() == STATE_CLICKED) {
snprintf(var,sizeof(currentdir),"%s", currentdir);
break;
}
if (okBtn.GetState() == STATE_CLICKED) {
result = 1;
break;
} else if (usbBtn.GetState() == STATE_CLICKED) {
HaltGui();
mainWindow->Remove(&w);
ResumeGui();
result = BrowseDevice(var, (curDivice==SD?USB:SD));
break;
} else if (folderBtn.GetState() == STATE_CLICKED) {
HaltGui();
mainWindow->Remove(&w);
ResumeGui();
char newfolder[100];
char oldfolder[100];
sprintf(newfolder,"%s/",var);
strcpy(oldfolder,newfolder);
int result = OnScreenKeyboard(newfolder,100,0);
if ( result == 1 ) {
int len = (strlen(newfolder)-1);
if (newfolder[len] !='/')
strncat (newfolder, "/", 1);
char* pos = newfolder;
char root[6];
sprintf(root,"%s/",browser.rootdir);
if (len > 0 && strcmp(oldfolder,newfolder)!=0 && strstr(newfolder,root) == pos && strstr(newfolder,"//") == NULL) {
struct stat st;
if (stat(newfolder, &st) != 0) {
if (subfoldercreate(newfolder) != 1) {
WindowPrompt(tr("Error !"),tr("Can't create directory"),tr("OK"));
break;
}
} else {
break;
}
}
}
result = BrowseDevice(var, (curDivice==SD?SD:USB));
break;
}
}
HaltGui();
mainWindow->Remove(&w);
ResumeGui();
//}
return result;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,15 @@
/****************************************************************************
* PromptWindows
* USB Loader GX 2009
*
* PromptWindows.h
***************************************************************************/
#ifndef _GAMEINFO_H_
#define _GAMEINFO_H_
int showGameInfo(char *ID);
bool save_XML_URL();
bool save_gamelist(int txt);
void MemInfoPrompt();
#endif
/****************************************************************************
* PromptWindows
* USB Loader GX 2009
*
* PromptWindows.h
***************************************************************************/
#ifndef _GAMEINFO_H_
#define _GAMEINFO_H_
int showGameInfo(char *ID);
bool save_XML_URL();
bool save_gamelist(int txt);
void MemInfoPrompt();
#endif

Some files were not shown because too many files have changed in this diff Show More