Merged develop into default for release 0.7.1 beta.

This commit is contained in:
Pieter Hulshoff
2016-05-14 13:28:27 +02:00
42 changed files with 1550 additions and 1420 deletions

View File

@@ -6,6 +6,10 @@ pageUp = A
pageDown = B pageDown = B
letterUp = N letterUp = N
letterDown = M letterDown = M
nextPlaylist = P
addPlaylist = I
removePlaylist = O
random = R
select = Space select = Space
back = Escape back = Escape
quit = Q quit = Q

View File

@@ -12,7 +12,7 @@
<!-----------------MAIN MENU Section-----------------> <!-----------------MAIN MENU Section----------------->
<!-- This is the title text that shows at the bottom of the main menu list. --> <!-- This is the title text that shows at the bottom of the main menu list. -->
<reloadableText type="title" x="center" y="center" xOrigin="center" yOrigin="center" yOffset="394" fontSize="48" layer="5"> <reloadableText type="playlist" x="center" y="center" xOrigin="center" yOrigin="center" yOffset="394" fontSize="48" layer="5">
<onMenuEnter menuIndex="0"> <onMenuEnter menuIndex="0">
<set duration=".2"> <set duration=".2">
<animate type="alpha" from="0" to="1" algorithm="easeinquadratic"/> <animate type="alpha" from="0" to="1" algorithm="easeinquadratic"/>
@@ -367,4 +367,4 @@
</onHighlightExit> </onHighlightExit>
</reloadableVideo> </reloadableVideo>
</layout> </layout>

View File

@@ -76,7 +76,7 @@
</reloadableVideo> </reloadableVideo>
<reloadableImage type="titleshot" x="397" y="520" xOrigin="center" yOrigin="center" height="360" maxWidth="400" layer="2"> <reloadableImage type="screentitle" x="397" y="520" xOrigin="center" yOrigin="center" height="360" maxWidth="400" layer="2">
<onMenuEnter menuIndex="1"> <onMenuEnter menuIndex="1">
<set duration=".1"> <set duration=".1">
<animate type="alpha" from="0" to="1" algorithm="easeinquadratic"/> <animate type="alpha" from="0" to="1" algorithm="easeinquadratic"/>

View File

@@ -90,7 +90,7 @@
</reloadableVideo> </reloadableVideo>
<reloadableImage type="titleshot" x="397" y="520" xOrigin="center" yOrigin="center" height="360" maxWidth="400" layer="2"> <reloadableImage type="screentitle" x="397" y="520" xOrigin="center" yOrigin="center" height="360" maxWidth="400" layer="2">
<onMenuEnter menuIndex="1"> <onMenuEnter menuIndex="1">
<set duration=".1"> <set duration=".1">
<animate type="alpha" from="0" to="1" algorithm="easeinquadratic"/> <animate type="alpha" from="0" to="1" algorithm="easeinquadratic"/>

View File

@@ -1227,7 +1227,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Chi Chi&apos;s Pro Challenge Golf (USA)" index="" image=""> <game name="Chi Chi&apos;s Pro Challenge Golf (USA)" index="" image="">
<description>Chi Chi\&apos;s Pro Challenge Golf (USA)</description> <description>Chi Chi&apos;s Pro Challenge Golf (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>9c3973a4</crc> <crc>9c3973a4</crc>
<manufacturer>Coconuts Japan</manufacturer> <manufacturer>Coconuts Japan</manufacturer>
@@ -1337,7 +1337,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="College Football&apos;s National Championship (USA)" index="" image=""> <game name="College Football&apos;s National Championship (USA)" index="" image="">
<description>College Football\&apos;s National Championship (USA)</description> <description>College Football&apos;s National Championship (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>172c5dbb</crc> <crc>172c5dbb</crc>
<manufacturer>Bluesky Innovations</manufacturer> <manufacturer>Bluesky Innovations</manufacturer>
@@ -1347,7 +1347,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="College Football&apos;s National Championship II (USA)" index="" image=""> <game name="College Football&apos;s National Championship II (USA)" index="" image="">
<description>College Football\&apos;s National Championship II (USA)</description> <description>College Football&apos;s National Championship II (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>65b64413</crc> <crc>65b64413</crc>
<manufacturer>Bluesky Innovations</manufacturer> <manufacturer>Bluesky Innovations</manufacturer>
@@ -1477,7 +1477,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Crystal&apos;s Pony Tale (USA)" index="" image=""> <game name="Crystal&apos;s Pony Tale (USA)" index="" image="">
<description>Crystal\&apos;s Pony Tale (USA)</description> <description>Crystal&apos;s Pony Tale (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>6cf7a4df</crc> <crc>6cf7a4df</crc>
<manufacturer>Artech Studios</manufacturer> <manufacturer>Artech Studios</manufacturer>
@@ -1547,7 +1547,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Dashin&apos; Desperadoes (USA)" index="" image=""> <game name="Dashin&apos; Desperadoes (USA)" index="" image="">
<description>Dashin\&apos; Desperadoes (USA)</description> <description>Dashin&apos; Desperadoes (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>dcb76fb7</crc> <crc>dcb76fb7</crc>
<manufacturer>Data East</manufacturer> <manufacturer>Data East</manufacturer>
@@ -1557,7 +1557,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="David Crane&apos;s Amazing Tennis (USA)" index="" image=""> <game name="David Crane&apos;s Amazing Tennis (USA)" index="" image="">
<description>David Crane\&apos;s Amazing Tennis (USA)</description> <description>David Crane&apos;s Amazing Tennis (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>9177088c</crc> <crc>9177088c</crc>
<manufacturer>Absolute Entertainment</manufacturer> <manufacturer>Absolute Entertainment</manufacturer>
@@ -1567,7 +1567,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="David Robinson&apos;s Supreme Court (USA, Europe)" index="" image=""> <game name="David Robinson&apos;s Supreme Court (USA, Europe)" index="" image="">
<description>David Robinson\&apos;s Supreme Court (USA, Europe)</description> <description>David Robinson&apos;s Supreme Court (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>512b7599</crc> <crc>512b7599</crc>
<manufacturer>Sega</manufacturer> <manufacturer>Sega</manufacturer>
@@ -1677,7 +1677,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Dick Vitale&apos;s &apos;Awesome, Baby!&apos; College Hoops (USA)" index="" image=""> <game name="Dick Vitale&apos;s &apos;Awesome, Baby!&apos; College Hoops (USA)" index="" image="">
<description>Dick Vitale\&apos;s \&apos;Awesome, Baby!\&apos; College Hoops (USA)</description> <description>Dick Vitale&apos;s &apos;Awesome, Baby!&apos; College Hoops (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>1312cf22</crc> <crc>1312cf22</crc>
<manufacturer>Time Warner Interactive</manufacturer> <manufacturer>Time Warner Interactive</manufacturer>
@@ -1687,7 +1687,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Dino Dini&apos;s Soccer (Europe)" index="" image=""> <game name="Dino Dini&apos;s Soccer (Europe)" index="" image="">
<description>Dino Dini\&apos;s Soccer (Europe)</description> <description>Dino Dini&apos;s Soccer (Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>4608f53a</crc> <crc>4608f53a</crc>
<manufacturer>Dini and Dini Productions</manufacturer> <manufacturer>Dini and Dini Productions</manufacturer>
@@ -1717,7 +1717,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Dinosaur&apos;s Tale, A (USA)" index="" image=""> <game name="Dinosaur&apos;s Tale, A (USA)" index="" image="">
<description>Dinosaur\&apos;s Tale, A (USA)</description> <description>Dinosaur&apos;s Tale, A (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>70155b5b</crc> <crc>70155b5b</crc>
<manufacturer>Malibu</manufacturer> <manufacturer>Malibu</manufacturer>
@@ -1817,7 +1817,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Dr. Robotnik&apos;s Mean Bean Machine (USA)" index="" image=""> <game name="Dr. Robotnik&apos;s Mean Bean Machine (USA)" index="" image="">
<description>Dr. Robotnik\&apos;s Mean Bean Machine (USA)</description> <description>Dr. Robotnik&apos;s Mean Bean Machine (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>c7ca517f</crc> <crc>c7ca517f</crc>
<manufacturer>Sega</manufacturer> <manufacturer>Sega</manufacturer>
@@ -1837,7 +1837,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Dragon&apos;s Fury (USA, Europe)" index="" image=""> <game name="Dragon&apos;s Fury (USA, Europe)" index="" image="">
<description>Dragon\&apos;s Fury (USA, Europe)</description> <description>Dragon&apos;s Fury (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>58037bc6</crc> <crc>58037bc6</crc>
<manufacturer>TechnoSoft</manufacturer> <manufacturer>TechnoSoft</manufacturer>
@@ -1847,7 +1847,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Dragon&apos;s Revenge (USA, Europe)" index="" image=""> <game name="Dragon&apos;s Revenge (USA, Europe)" index="" image="">
<description>Dragon\&apos;s Revenge (USA, Europe)</description> <description>Dragon&apos;s Revenge (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>841edbc0</crc> <crc>841edbc0</crc>
<manufacturer>Tengen</manufacturer> <manufacturer>Tengen</manufacturer>
@@ -2057,7 +2057,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Evander Holyfield&apos;s &apos;Real Deal&apos; Boxing (World)" index="" image=""> <game name="Evander Holyfield&apos;s &apos;Real Deal&apos; Boxing (World)" index="" image="">
<description>Evander Holyfield\&apos;s \&apos;Real Deal\&apos; Boxing (World)</description> <description>Evander Holyfield&apos;s &apos;Real Deal&apos; Boxing (World)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>4fef37c8</crc> <crc>4fef37c8</crc>
<manufacturer>ACME Interactive</manufacturer> <manufacturer>ACME Interactive</manufacturer>
@@ -2407,7 +2407,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Fun &apos;N&apos; Games (USA)" index="" image=""> <game name="Fun &apos;N&apos; Games (USA)" index="" image="">
<description>Fun \&apos;N\&apos; Games (USA)</description> <description>Fun &apos;N&apos; Games (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>b5ae351d</crc> <crc>b5ae351d</crc>
<manufacturer>Leland Interactive Media</manufacturer> <manufacturer>Leland Interactive Media</manufacturer>
@@ -2547,7 +2547,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="George Foreman&apos;s KO Boxing (USA)" index="" image=""> <game name="George Foreman&apos;s KO Boxing (USA)" index="" image="">
<description>George Foreman\&apos;s KO Boxing (USA)</description> <description>George Foreman&apos;s KO Boxing (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>e1fdc787</crc> <crc>e1fdc787</crc>
<manufacturer>Beam Software</manufacturer> <manufacturer>Beam Software</manufacturer>
@@ -2567,7 +2567,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Ghouls &apos;n Ghosts (USA, Europe) (Rev A)" index="" image=""> <game name="Ghouls &apos;n Ghosts (USA, Europe) (Rev A)" index="" image="">
<description>Ghouls \&apos;n Ghosts (USA, Europe) (Rev A)</description> <description>Ghouls &apos;n Ghosts (USA, Europe) (Rev A)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>4f2561d5</crc> <crc>4f2561d5</crc>
<manufacturer>AM8</manufacturer> <manufacturer>AM8</manufacturer>
@@ -2607,7 +2607,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Goofy&apos;s Hysterical History Tour (USA)" index="" image=""> <game name="Goofy&apos;s Hysterical History Tour (USA)" index="" image="">
<description>Goofy\&apos;s Hysterical History Tour (USA)</description> <description>Goofy&apos;s Hysterical History Tour (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>4e1cc833</crc> <crc>4e1cc833</crc>
<manufacturer>Imagineering</manufacturer> <manufacturer>Imagineering</manufacturer>
@@ -2707,7 +2707,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Hard Drivin&apos; (World)" index="true" image="h"> <game name="Hard Drivin&apos; (World)" index="true" image="h">
<description>Hard Drivin\&apos; (World)</description> <description>Hard Drivin&apos; (World)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>3225baaf</crc> <crc>3225baaf</crc>
<manufacturer>Sterling Silver Software</manufacturer> <manufacturer>Sterling Silver Software</manufacturer>
@@ -2727,7 +2727,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="HardBall &apos;94 (USA, Europe)" index="" image=""> <game name="HardBall &apos;94 (USA, Europe)" index="" image="">
<description>HardBall \&apos;94 (USA, Europe)</description> <description>HardBall &apos;94 (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>ea9c4878</crc> <crc>ea9c4878</crc>
<manufacturer>MindSpan</manufacturer> <manufacturer>MindSpan</manufacturer>
@@ -2737,7 +2737,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="HardBall &apos;95 (USA)" index="" image=""> <game name="HardBall &apos;95 (USA)" index="" image="">
<description>HardBall \&apos;95 (USA)</description> <description>HardBall &apos;95 (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>ed10bc9e</crc> <crc>ed10bc9e</crc>
<manufacturer>MindSpan</manufacturer> <manufacturer>MindSpan</manufacturer>
@@ -2977,7 +2977,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Izzy&apos;s Quest for the Olympic Rings (USA, Europe)" index="" image=""> <game name="Izzy&apos;s Quest for the Olympic Rings (USA, Europe)" index="" image="">
<description>Izzy\&apos;s Quest for the Olympic Rings (USA, Europe)</description> <description>Izzy&apos;s Quest for the Olympic Rings (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>77b416e4</crc> <crc>77b416e4</crc>
<manufacturer>Alexandria</manufacturer> <manufacturer>Alexandria</manufacturer>
@@ -2987,7 +2987,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Jack Nicklaus&apos; Power Challenge Golf (USA, Europe)" index="true" image="j"> <game name="Jack Nicklaus&apos; Power Challenge Golf (USA, Europe)" index="true" image="j">
<description>Jack Nicklaus\&apos; Power Challenge Golf (USA, Europe)</description> <description>Jack Nicklaus&apos; Power Challenge Golf (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>5545e909</crc> <crc>5545e909</crc>
<manufacturer>Accolade</manufacturer> <manufacturer>Accolade</manufacturer>
@@ -3037,7 +3037,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="James &apos;Buster&apos; Douglas Knockout Boxing (USA, Europe)" index="" image=""> <game name="James &apos;Buster&apos; Douglas Knockout Boxing (USA, Europe)" index="" image="">
<description>James \&apos;Buster\&apos; Douglas Knockout Boxing (USA, Europe)</description> <description>James &apos;Buster&apos; Douglas Knockout Boxing (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>87bbcf2a</crc> <crc>87bbcf2a</crc>
<manufacturer>Domark</manufacturer> <manufacturer>Domark</manufacturer>
@@ -3097,7 +3097,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Jerry Glanville&apos;s Pigskin Footbrawl (USA)" index="" image=""> <game name="Jerry Glanville&apos;s Pigskin Footbrawl (USA)" index="" image="">
<description>Jerry Glanville\&apos;s Pigskin Footbrawl (USA)</description> <description>Jerry Glanville&apos;s Pigskin Footbrawl (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>e7f48d30</crc> <crc>e7f48d30</crc>
<manufacturer>Developer Resources</manufacturer> <manufacturer>Developer Resources</manufacturer>
@@ -3117,7 +3117,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Jimmy White&apos;s Whirlwind Snooker (Europe)" index="" image=""> <game name="Jimmy White&apos;s Whirlwind Snooker (Europe)" index="" image="">
<description>Jimmy White\&apos;s Whirlwind Snooker (Europe)</description> <description>Jimmy White&apos;s Whirlwind Snooker (Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>0aef5b1f</crc> <crc>0aef5b1f</crc>
<manufacturer>Virgin Interactive</manufacturer> <manufacturer>Virgin Interactive</manufacturer>
@@ -3177,7 +3177,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="John Madden Football &apos;92 (USA, Europe)" index="" image=""> <game name="John Madden Football &apos;92 (USA, Europe)" index="" image="">
<description>John Madden Football \&apos;92 (USA, Europe)</description> <description>John Madden Football &apos;92 (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>046e3945</crc> <crc>046e3945</crc>
<manufacturer>Park Place Productions</manufacturer> <manufacturer>Park Place Productions</manufacturer>
@@ -3187,7 +3187,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="John Madden Football &apos;93 (USA, Europe)" index="" image=""> <game name="John Madden Football &apos;93 (USA, Europe)" index="" image="">
<description>John Madden Football \&apos;93 (USA, Europe)</description> <description>John Madden Football &apos;93 (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>ca323b3e</crc> <crc>ca323b3e</crc>
<manufacturer>Park Place Productions</manufacturer> <manufacturer>Park Place Productions</manufacturer>
@@ -3357,7 +3357,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="King&apos;s Bounty - The Conqueror&apos;s Quest (USA, Europe)" index="" image=""> <game name="King&apos;s Bounty - The Conqueror&apos;s Quest (USA, Europe)" index="" image="">
<description>King\&apos;s Bounty - The Conqueror\&apos;s Quest (USA, Europe)</description> <description>King&apos;s Bounty - The Conqueror&apos;s Quest (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>aa68a92e</crc> <crc>aa68a92e</crc>
<manufacturer>New World Computing</manufacturer> <manufacturer>New World Computing</manufacturer>
@@ -3377,7 +3377,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Krusty&apos;s Super Fun House (USA, Europe) (v1.1)" index="" image=""> <game name="Krusty&apos;s Super Fun House (USA, Europe) (v1.1)" index="" image="">
<description>Krusty\&apos;s Super Fun House (USA, Europe) (v1.1)</description> <description>Krusty&apos;s Super Fun House (USA, Europe) (v1.1)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>56976261</crc> <crc>56976261</crc>
<manufacturer>Audiogenic</manufacturer> <manufacturer>Audiogenic</manufacturer>
@@ -3637,7 +3637,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Madden NFL &apos;94 (USA, Europe)" index="" image=""> <game name="Madden NFL &apos;94 (USA, Europe)" index="" image="">
<description>Madden NFL \&apos;94 (USA, Europe)</description> <description>Madden NFL &apos;94 (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>d14b811b</crc> <crc>d14b811b</crc>
<manufacturer>High Score Productions</manufacturer> <manufacturer>High Score Productions</manufacturer>
@@ -3727,7 +3727,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Mary Shelley&apos;s Frankenstein (USA)" index="" image=""> <game name="Mary Shelley&apos;s Frankenstein (USA)" index="" image="">
<description>Mary Shelley\&apos;s Frankenstein (USA)</description> <description>Mary Shelley&apos;s Frankenstein (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>48993dc3</crc> <crc>48993dc3</crc>
<manufacturer>Bits Studios</manufacturer> <manufacturer>Bits Studios</manufacturer>
@@ -3767,7 +3767,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="McDonald&apos;s Treasure Land Adventure (USA)" index="" image=""> <game name="McDonald&apos;s Treasure Land Adventure (USA)" index="" image="">
<description>McDonald\&apos;s Treasure Land Adventure (USA)</description> <description>McDonald&apos;s Treasure Land Adventure (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>04ef4899</crc> <crc>04ef4899</crc>
<manufacturer>Treasure</manufacturer> <manufacturer>Treasure</manufacturer>
@@ -3897,7 +3897,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Michael Jackson&apos;s Moonwalker (World) (Rev A)" index="" image=""> <game name="Michael Jackson&apos;s Moonwalker (World) (Rev A)" index="" image="">
<description>Michael Jackson\&apos;s Moonwalker (World) (Rev A)</description> <description>Michael Jackson&apos;s Moonwalker (World) (Rev A)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>11ce1f9e</crc> <crc>11ce1f9e</crc>
<manufacturer>Ultimate Productions</manufacturer> <manufacturer>Ultimate Productions</manufacturer>
@@ -3927,7 +3927,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Mickey&apos;s Ultimate Challenge (USA)" index="" image=""> <game name="Mickey&apos;s Ultimate Challenge (USA)" index="" image="">
<description>Mickey\&apos;s Ultimate Challenge (USA)</description> <description>Mickey&apos;s Ultimate Challenge (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>30b512ee</crc> <crc>30b512ee</crc>
<manufacturer>Designer Software</manufacturer> <manufacturer>Designer Software</manufacturer>
@@ -4177,7 +4177,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="NBA Action &apos;94 (USA)" index="true" image="n"> <game name="NBA Action &apos;94 (USA)" index="true" image="n">
<description>NBA Action \&apos;94 (USA)</description> <description>NBA Action &apos;94 (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>99c348ba</crc> <crc>99c348ba</crc>
<manufacturer>Sega</manufacturer> <manufacturer>Sega</manufacturer>
@@ -4187,7 +4187,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="NBA Action &apos;95 Starring David Robinson (USA, Europe)" index="" image=""> <game name="NBA Action &apos;95 Starring David Robinson (USA, Europe)" index="" image="">
<description>NBA Action \&apos;95 Starring David Robinson (USA, Europe)</description> <description>NBA Action &apos;95 Starring David Robinson (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>aa7006d6</crc> <crc>aa7006d6</crc>
<manufacturer>Sega</manufacturer> <manufacturer>Sega</manufacturer>
@@ -4277,7 +4277,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="NBA Showdown &apos;94 (USA, Europe)" index="" image=""> <game name="NBA Showdown &apos;94 (USA, Europe)" index="" image="">
<description>NBA Showdown \&apos;94 (USA, Europe)</description> <description>NBA Showdown &apos;94 (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>160b7090</crc> <crc>160b7090</crc>
<manufacturer>Electronic Arts</manufacturer> <manufacturer>Electronic Arts</manufacturer>
@@ -4337,7 +4337,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="NFL Football &apos;94 Starring Joe Montana (USA)" index="" image=""> <game name="NFL Football &apos;94 Starring Joe Montana (USA)" index="" image="">
<description>NFL Football \&apos;94 Starring Joe Montana (USA)</description> <description>NFL Football &apos;94 Starring Joe Montana (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>0d486ed5</crc> <crc>0d486ed5</crc>
<manufacturer>Bluesky Innovations</manufacturer> <manufacturer>Bluesky Innovations</manufacturer>
@@ -4367,7 +4367,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="NFL Sports Talk Football &apos;93 Starring Joe Montana (USA, Europe)" index="" image=""> <game name="NFL Sports Talk Football &apos;93 Starring Joe Montana (USA, Europe)" index="" image="">
<description>NFL Sports Talk Football \&apos;93 Starring Joe Montana (USA, Europe)</description> <description>NFL Sports Talk Football &apos;93 Starring Joe Montana (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>ce0b1fe1</crc> <crc>ce0b1fe1</crc>
<manufacturer>Bluesky Innovations</manufacturer> <manufacturer>Bluesky Innovations</manufacturer>
@@ -4377,7 +4377,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="NFL &apos;95 (USA, Europe)" index="" image=""> <game name="NFL &apos;95 (USA, Europe)" index="" image="">
<description>NFL \&apos;95 (USA, Europe)</description> <description>NFL &apos;95 (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>b58e4a81</crc> <crc>b58e4a81</crc>
<manufacturer>Sega</manufacturer> <manufacturer>Sega</manufacturer>
@@ -4427,7 +4427,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="NHL All-Star Hockey &apos;95 (USA)" index="" image=""> <game name="NHL All-Star Hockey &apos;95 (USA)" index="" image="">
<description>NHL All-Star Hockey \&apos;95 (USA)</description> <description>NHL All-Star Hockey &apos;95 (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>e6c0218b</crc> <crc>e6c0218b</crc>
<manufacturer>Sega</manufacturer> <manufacturer>Sega</manufacturer>
@@ -4447,7 +4447,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="NHL &apos;94 (USA, Europe)" index="" image=""> <game name="NHL &apos;94 (USA, Europe)" index="" image="">
<description>NHL \&apos;94 (USA, Europe)</description> <description>NHL &apos;94 (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>9438f5dd</crc> <crc>9438f5dd</crc>
<manufacturer>High Score Productions</manufacturer> <manufacturer>High Score Productions</manufacturer>
@@ -4467,7 +4467,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Nigel Mansell&apos;s World Championship Racing (USA)" index="" image=""> <game name="Nigel Mansell&apos;s World Championship Racing (USA)" index="" image="">
<description>Nigel Mansell\&apos;s World Championship Racing (USA)</description> <description>Nigel Mansell&apos;s World Championship Racing (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>6bc57b2c</crc> <crc>6bc57b2c</crc>
<manufacturer>Gremlin Interactive</manufacturer> <manufacturer>Gremlin Interactive</manufacturer>
@@ -4487,7 +4487,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Nobunaga&apos;s Ambition (USA)" index="" image=""> <game name="Nobunaga&apos;s Ambition (USA)" index="" image="">
<description>Nobunaga\&apos;s Ambition (USA)</description> <description>Nobunaga&apos;s Ambition (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>b9bc07bc</crc> <crc>b9bc07bc</crc>
<manufacturer>Koei</manufacturer> <manufacturer>Koei</manufacturer>
@@ -4497,7 +4497,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Normy&apos;s Beach Babe-O-Rama (USA, Europe)" index="" image=""> <game name="Normy&apos;s Beach Babe-O-Rama (USA, Europe)" index="" image="">
<description>Normy\&apos;s Beach Babe-O-Rama (USA, Europe)</description> <description>Normy&apos;s Beach Babe-O-Rama (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>b56a8220</crc> <crc>b56a8220</crc>
<manufacturer>Realtime Associates</manufacturer> <manufacturer>Realtime Associates</manufacturer>
@@ -5087,7 +5087,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="R.B.I. Baseball &apos;93 (USA)" index="" image=""> <game name="R.B.I. Baseball &apos;93 (USA)" index="" image="">
<description>R.B.I. Baseball \&apos;93 (USA)</description> <description>R.B.I. Baseball &apos;93 (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>beafce84</crc> <crc>beafce84</crc>
<manufacturer>Tengen</manufacturer> <manufacturer>Tengen</manufacturer>
@@ -5097,7 +5097,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="R.B.I. Baseball &apos;94 (USA, Europe)" index="" image=""> <game name="R.B.I. Baseball &apos;94 (USA, Europe)" index="" image="">
<description>R.B.I. Baseball \&apos;94 (USA, Europe)</description> <description>R.B.I. Baseball &apos;94 (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>4eb4d5e4</crc> <crc>4eb4d5e4</crc>
<manufacturer>Tengen</manufacturer> <manufacturer>Tengen</manufacturer>
@@ -5107,7 +5107,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Race Drivin&apos; (USA)" index="" image=""> <game name="Race Drivin&apos; (USA)" index="" image="">
<description>Race Drivin\&apos; (USA)</description> <description>Race Drivin&apos; (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>d737cf3d</crc> <crc>d737cf3d</crc>
<manufacturer>Polygames</manufacturer> <manufacturer>Polygames</manufacturer>
@@ -5187,7 +5187,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Ren &amp; Stimpy Show Presents Stimpy&apos;s Invention, The (USA)" index="" image=""> <game name="Ren &amp; Stimpy Show Presents Stimpy&apos;s Invention, The (USA)" index="" image="">
<description>Ren &amp; Stimpy Show Presents Stimpy\&apos;s Invention, The (USA)</description> <description>Ren &amp; Stimpy Show Presents Stimpy&apos;s Invention, The (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>d9503ba5</crc> <crc>d9503ba5</crc>
<manufacturer>Blue Sky Software</manufacturer> <manufacturer>Blue Sky Software</manufacturer>
@@ -5217,7 +5217,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Richard Scarry&apos;s BusyTown (USA)" index="" image=""> <game name="Richard Scarry&apos;s BusyTown (USA)" index="" image="">
<description>Richard Scarry\&apos;s BusyTown (USA)</description> <description>Richard Scarry&apos;s BusyTown (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>7bb60c3f</crc> <crc>7bb60c3f</crc>
<manufacturer>Novotrade</manufacturer> <manufacturer>Novotrade</manufacturer>
@@ -5337,7 +5337,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Rock n&apos; Roll Racing (USA)" index="" image=""> <game name="Rock n&apos; Roll Racing (USA)" index="" image="">
<description>Rock n\&apos; Roll Racing (USA)</description> <description>Rock n&apos; Roll Racing (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>6abab577</crc> <crc>6abab577</crc>
<manufacturer>Blizzard Entertainment</manufacturer> <manufacturer>Blizzard Entertainment</manufacturer>
@@ -5597,7 +5597,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Shanghai II - Dragon&apos;s Eye (USA)" index="" image=""> <game name="Shanghai II - Dragon&apos;s Eye (USA)" index="" image="">
<description>Shanghai II - Dragon\&apos;s Eye (USA)</description> <description>Shanghai II - Dragon&apos;s Eye (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>ebe9e840</crc> <crc>ebe9e840</crc>
<manufacturer>Activision</manufacturer> <manufacturer>Activision</manufacturer>
@@ -5687,7 +5687,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Simpsons, The - Bart&apos;s Nightmare (USA, Europe)" index="" image=""> <game name="Simpsons, The - Bart&apos;s Nightmare (USA, Europe)" index="" image="">
<description>Simpsons, The - Bart\&apos;s Nightmare (USA, Europe)</description> <description>Simpsons, The - Bart&apos;s Nightmare (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>24d7507c</crc> <crc>24d7507c</crc>
<manufacturer>Sculptured Software</manufacturer> <manufacturer>Sculptured Software</manufacturer>
@@ -5707,7 +5707,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Skitchin&apos; (USA, Europe)" index="" image=""> <game name="Skitchin&apos; (USA, Europe)" index="" image="">
<description>Skitchin\&apos; (USA, Europe)</description> <description>Skitchin&apos; (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>f785f9d7</crc> <crc>f785f9d7</crc>
<manufacturer>Electronic Arts</manufacturer> <manufacturer>Electronic Arts</manufacturer>
@@ -5887,7 +5887,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Sorcerer&apos;s Kingdom (USA) (v1.1)" index="" image=""> <game name="Sorcerer&apos;s Kingdom (USA) (v1.1)" index="" image="">
<description>Sorcerer\&apos;s Kingdom (USA) (v1.1)</description> <description>Sorcerer&apos;s Kingdom (USA) (v1.1)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>bb1fc9ce</crc> <crc>bb1fc9ce</crc>
<manufacturer>Treco</manufacturer> <manufacturer>Treco</manufacturer>
@@ -5907,7 +5907,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Space Invaders &apos;91 (USA)" index="" image=""> <game name="Space Invaders &apos;91 (USA)" index="" image="">
<description>Space Invaders \&apos;91 (USA)</description> <description>Space Invaders &apos;91 (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>bb83b528</crc> <crc>bb83b528</crc>
<manufacturer>Taito</manufacturer> <manufacturer>Taito</manufacturer>
@@ -5977,7 +5977,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Spider-Man and X-Men - Arcade&apos;s Revenge (USA, Europe)" index="" image=""> <game name="Spider-Man and X-Men - Arcade&apos;s Revenge (USA, Europe)" index="" image="">
<description>Spider-Man and X-Men - Arcade\&apos;s Revenge (USA, Europe)</description> <description>Spider-Man and X-Men - Arcade&apos;s Revenge (USA, Europe)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>4a4414ea</crc> <crc>4a4414ea</crc>
<manufacturer>Software Creations</manufacturer> <manufacturer>Software Creations</manufacturer>
@@ -6127,7 +6127,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Street Fighter II&apos; - Special Champion Edition (USA)" index="" image=""> <game name="Street Fighter II&apos; - Special Champion Edition (USA)" index="" image="">
<description>Street Fighter II\&apos; - Special Champion Edition (USA)</description> <description>Street Fighter II&apos; - Special Champion Edition (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>13fe08a1</crc> <crc>13fe08a1</crc>
<manufacturer>Capcom</manufacturer> <manufacturer>Capcom</manufacturer>
@@ -6767,7 +6767,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Tiny Toon Adventures - Buster&apos;s Hidden Treasure (USA)" index="" image=""> <game name="Tiny Toon Adventures - Buster&apos;s Hidden Treasure (USA)" index="" image="">
<description>Tiny Toon Adventures - Buster\&apos;s Hidden Treasure (USA)</description> <description>Tiny Toon Adventures - Buster&apos;s Hidden Treasure (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>a26d3ae0</crc> <crc>a26d3ae0</crc>
<manufacturer>Konami</manufacturer> <manufacturer>Konami</manufacturer>
@@ -6787,7 +6787,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="TNN Outdoors Bass Tournament &apos;96 (USA)" index="" image=""> <game name="TNN Outdoors Bass Tournament &apos;96 (USA)" index="" image="">
<description>TNN Outdoors Bass Tournament \&apos;96 (USA)</description> <description>TNN Outdoors Bass Tournament &apos;96 (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>5c523c0b</crc> <crc>5c523c0b</crc>
<manufacturer>Imagitec Design</manufacturer> <manufacturer>Imagitec Design</manufacturer>
@@ -6797,7 +6797,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Todd&apos;s Adventures in Slime World (USA)" index="" image=""> <game name="Todd&apos;s Adventures in Slime World (USA)" index="" image="">
<description>Todd\&apos;s Adventures in Slime World (USA)</description> <description>Todd&apos;s Adventures in Slime World (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>652e8b7d</crc> <crc>652e8b7d</crc>
<manufacturer>Epyx</manufacturer> <manufacturer>Epyx</manufacturer>
@@ -7127,7 +7127,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Unnecessary Roughness &apos;95 (USA)" index="" image=""> <game name="Unnecessary Roughness &apos;95 (USA)" index="" image="">
<description>Unnecessary Roughness \&apos;95 (USA)</description> <description>Unnecessary Roughness &apos;95 (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>9920e7b7</crc> <crc>9920e7b7</crc>
<manufacturer>Accolade</manufacturer> <manufacturer>Accolade</manufacturer>
@@ -7337,7 +7337,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Wayne&apos;s World (USA)" index="" image=""> <game name="Wayne&apos;s World (USA)" index="" image="">
<description>Wayne\&apos;s World (USA)</description> <description>Wayne&apos;s World (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>d2cf6ebe</crc> <crc>d2cf6ebe</crc>
<manufacturer>Gray Matter</manufacturer> <manufacturer>Gray Matter</manufacturer>
@@ -7407,7 +7407,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Williams Arcade&apos;s Greatest Hits (USA)" index="" image=""> <game name="Williams Arcade&apos;s Greatest Hits (USA)" index="" image="">
<description>Williams Arcade\&apos;s Greatest Hits (USA)</description> <description>Williams Arcade&apos;s Greatest Hits (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>d68e9c00</crc> <crc>d68e9c00</crc>
<manufacturer>Digital Eclipse</manufacturer> <manufacturer>Digital Eclipse</manufacturer>
@@ -7457,7 +7457,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Wiz&apos;n&apos;Liz (USA)" index="" image=""> <game name="Wiz&apos;n&apos;Liz (USA)" index="" image="">
<description>Wiz\&apos;n\&apos;Liz (USA)</description> <description>Wiz&apos;n&apos;Liz (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>df036b62</crc> <crc>df036b62</crc>
<manufacturer>Raising Hell</manufacturer> <manufacturer>Raising Hell</manufacturer>
@@ -7587,7 +7587,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="World Series Baseball &apos;95 (USA)" index="" image=""> <game name="World Series Baseball &apos;95 (USA)" index="" image="">
<description>World Series Baseball \&apos;95 (USA)</description> <description>World Series Baseball &apos;95 (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>25130077</crc> <crc>25130077</crc>
<manufacturer>Blue Sky Software</manufacturer> <manufacturer>Blue Sky Software</manufacturer>
@@ -7597,7 +7597,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="World Series Baseball &apos;96 (USA)" index="" image=""> <game name="World Series Baseball &apos;96 (USA)" index="" image="">
<description>World Series Baseball \&apos;96 (USA)</description> <description>World Series Baseball &apos;96 (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>04ee8272</crc> <crc>04ee8272</crc>
<manufacturer>Blue Sky Software</manufacturer> <manufacturer>Blue Sky Software</manufacturer>
@@ -7787,7 +7787,7 @@
<enabled>Yes</enabled> <enabled>Yes</enabled>
</game> </game>
<game name="Zool - Ninja of the &apos;Nth&apos; Dimension (USA)" index="" image=""> <game name="Zool - Ninja of the &apos;Nth&apos; Dimension (USA)" index="" image="">
<description>Zool - Ninja of the \&apos;Nth\&apos; Dimension (USA)</description> <description>Zool - Ninja of the &apos;Nth&apos; Dimension (USA)</description>
<cloneof></cloneof> <cloneof></cloneof>
<crc>cb2939f1</crc> <crc>cb2939f1</crc>
<manufacturer>Gremlin Interactive</manufacturer> <manufacturer>Gremlin Interactive</manufacturer>

View File

@@ -22,6 +22,9 @@ showSquareBrackets = yes
# specify the name of the first collection to load on start # specify the name of the first collection to load on start
firstCollection = Main firstCollection = Main
# specify whether RetroFE should switch to Favorites list if it exists.
autoFavorites = true
####################################### #######################################
# Video playback settings # Video playback settings
####################################### #######################################

View File

@@ -17,8 +17,22 @@
#include "Item.h" #include "Item.h"
#include "../Database/Configuration.h" #include "../Database/Configuration.h"
#include "../Utility/Utils.h" #include "../Utility/Utils.h"
#include "../Utility/Log.h"
#include <sstream> #include <sstream>
#include <fstream>
#include <algorithm> #include <algorithm>
#include <exception>
#include <sys/stat.h>
#include <sys/types.h>
#ifdef _WIN32
#include <Windows.h>
#endif
#ifdef __linux
#include <errno.h>
#include <cstring>
#endif
CollectionInfo::CollectionInfo(std::string name, CollectionInfo::CollectionInfo(std::string name,
std::string listPath, std::string listPath,
@@ -27,6 +41,7 @@ CollectionInfo::CollectionInfo(std::string name,
std::string metadataPath) std::string metadataPath)
: name(name) : name(name)
, listpath(listPath) , listpath(listPath)
, saveRequest(false)
, metadataType(metadataType) , metadataType(metadataType)
, menusort(true) , menusort(true)
, metadataPath_(metadataPath) , metadataPath_(metadataPath)
@@ -39,13 +54,25 @@ CollectionInfo::~CollectionInfo()
// remove items from the subcollections so their destructors do not // remove items from the subcollections so their destructors do not
// delete the items since the parent collection will delete them. // delete the items since the parent collection will delete them.
std::vector<CollectionInfo *>::iterator subit; std::vector<CollectionInfo *>::iterator subit;
for (subit != subcollections_.begin(); subit != subcollections_.end(); subit++) for (subit = subcollections_.begin(); subit != subcollections_.end(); subit++)
{ {
CollectionInfo *info = *subit; CollectionInfo *info = *subit;
info->items.clear(); info->items.clear();
} }
Playlists_T::iterator pit = playlists.begin();
while(pit != playlists.end())
{
if(pit->second != &items)
{
delete pit->second;
}
playlists.erase(pit);
pit = playlists.begin();
}
std::vector<Item *>::iterator it = items.begin(); std::vector<Item *>::iterator it = items.begin();
while(it != items.end()) while(it != items.end())
{ {
@@ -55,6 +82,68 @@ CollectionInfo::~CollectionInfo()
} }
} }
bool CollectionInfo::Save()
{
bool retval = true;
if(saveRequest)
{
std::string dir = Utils::combinePath(Configuration::absolutePath, "collections", name, "playlists");
std::string file = Utils::combinePath(Configuration::absolutePath, "collections", name, "playlists/favorites.txt");
Logger::write(Logger::ZONE_INFO, "Collection", "Saving " + file);
std::ofstream filestream;
try
{
// Create playlists directory if it does not exist yet.
struct stat info;
if ( stat( dir.c_str(), &info ) != 0 )
{
#if defined(_WIN32) && !defined(__GNUC__)
if(!CreateDirectory(dir.c_str(), NULL))
{
if(ERROR_ALREADY_EXISTS != GetLastError())
{
Logger::write(Logger::ZONE_WARNING, "Collection", "Could not create directory " + dir);
return false;
}
}
#else
#if defined(__MINGW32__)
if(mkdir(dir.c_str()) == -1)
#else
if(mkdir(dir.c_str(), 0755) == -1)
#endif
{
Logger::write(Logger::ZONE_WARNING, "Collection", "Could not create directory " + dir);
return false;
}
#endif
}
else if ( !(info.st_mode & S_IFDIR) )
{
Logger::write(Logger::ZONE_WARNING, "Collection", dir + " exists, but is not a directory.");
return false;
}
filestream.open(file.c_str());
std::vector<Item *> *saveitems = playlists["favorites"];
for(std::vector<Item *>::iterator it = saveitems->begin(); it != saveitems->end(); it++)
{
filestream << (*it)->name << std::endl;
}
filestream.close();
}
catch(std::exception &)
{
Logger::write(Logger::ZONE_ERROR, "Collection", "Save failed: " + file);
retval = false;
}
}
return retval;
}
std::string CollectionInfo::settingsPath() const std::string CollectionInfo::settingsPath() const
{ {
return Utils::combinePath(Configuration::absolutePath, "collections", name); return Utils::combinePath(Configuration::absolutePath, "collections", name);
@@ -95,5 +184,8 @@ bool CollectionInfo::itemIsLess(Item *lhs, Item *rhs)
void CollectionInfo::sortItems() void CollectionInfo::sortItems()
{ {
std::sort(items.begin(), items.end(), itemIsLess); for(Playlists_T::iterator it = playlists.begin(); it != playlists.end(); it++)
{
std::sort(it->second->begin(), it->second->end(), itemIsLess);
}
} }

View File

@@ -17,6 +17,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <map>
class Item; class Item;
@@ -26,15 +27,21 @@ public:
CollectionInfo(std::string name, std::string listPath, std::string extensions, std::string metadataType, std::string metadataPath); CollectionInfo(std::string name, std::string listPath, std::string extensions, std::string metadataType, std::string metadataPath);
virtual ~CollectionInfo(); virtual ~CollectionInfo();
std::string settingsPath() const; std::string settingsPath() const;
bool Save();
void sortItems(); void sortItems();
void addSubcollection(CollectionInfo *info); void addSubcollection(CollectionInfo *info);
bool hasSubcollections(); bool hasSubcollections();
void extensionList(std::vector<std::string> &extensions); void extensionList(std::vector<std::string> &extensions);
std::string name; std::string name;
std::string listpath; std::string listpath;
bool saveRequest;
std::string metadataType; std::string metadataType;
std::string launcher; std::string launcher;
std::vector<Item *> items; std::vector<Item *> items;
typedef std::map<std::string, std::vector <Item *> *> Playlists_T;
Playlists_T playlists;
bool menusort; bool menusort;
private: private:
std::vector<CollectionInfo *> subcollections_; std::vector<CollectionInfo *> subcollections_;

View File

@@ -81,7 +81,7 @@ bool CollectionInfoBuilder::createCollectionDirectory(std::string name)
#if defined(__MINGW32__) #if defined(__MINGW32__)
if(mkdir(it->c_str()) == -1) if(mkdir(it->c_str()) == -1)
#else #else
if(mkdir(it->c_str(), 0744) == -1) if(mkdir(it->c_str(), 0755) == -1)
#endif #endif
{ {
std::cout << "Could not create folder \"" << *it << "\":" << errno << std::endl; std::cout << "Could not create folder \"" << *it << "\":" << errno << std::endl;
@@ -119,18 +119,23 @@ bool CollectionInfoBuilder::createCollectionDirectory(std::string name)
settingsFile << "list.menuSort = yes" << std::endl; settingsFile << "list.menuSort = yes" << std::endl;
settingsFile << std::endl; settingsFile << std::endl;
settingsFile << "launcher = mame" << std::endl; settingsFile << "launcher = mame" << std::endl;
settingsFile << "metadata.type = MAME" << std::endl; settingsFile << "#metadata.type = MAME" << std::endl;
settingsFile << std::endl; settingsFile << std::endl;
settingsFile << "#media.screenshot = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screenshot") << std::endl; settingsFile << "#manufacturer = " << std::endl;
settingsFile << "#media.screentitle = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screentitle") << std::endl; settingsFile << "#year = " << std::endl;
settingsFile << "#media.artwork_back = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "artwork_back") << std::endl; settingsFile << "#genre = " << std::endl;
settingsFile << "#media.artwork_front = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "artwork_front") << std::endl; settingsFile << std::endl;
settingsFile << "#media.logo = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "logo") << std::endl; settingsFile << "#media.screenshot = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screenshot") << std::endl;
settingsFile << "#media.medium_back = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "medium_back") << std::endl; settingsFile << "#media.screentitle = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screentitle") << std::endl;
settingsFile << "#media.medium_front = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "medium_front") << std::endl; settingsFile << "#media.artwork_back = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "artwork_back") << std::endl;
settingsFile << "#media.screenshot = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screenshot") << std::endl; settingsFile << "#media.artwork_front = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "artwork_front") << std::endl;
settingsFile << "#media.screentitle = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screentitle") << std::endl; settingsFile << "#media.logo = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "logo") << std::endl;
settingsFile << "#media.video = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "video") << std::endl; settingsFile << "#media.medium_back = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "medium_back") << std::endl;
settingsFile << "#media.medium_front = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "medium_front") << std::endl;
settingsFile << "#media.screenshot = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screenshot") << std::endl;
settingsFile << "#media.screentitle = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "screentitle") << std::endl;
settingsFile << "#media.video = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "medium_artwork", "video") << std::endl;
settingsFile << "#media.system_artwork = " << Utils::combinePath("%BASE_MEDIA_PATH%", "%ITEM_COLLECTION_NAME%", "system_artwork") << std::endl;
settingsFile.close(); settingsFile.close();
filename = Utils::combinePath(collectionPath, "menu.txt"); filename = Utils::combinePath(collectionPath, "menu.txt");
@@ -230,9 +235,12 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me
DIR *dp; DIR *dp;
struct dirent *dirp; struct dirent *dirp;
std::string path = info->listpath; std::string path = info->listpath;
std::map<std::string, Item *> allMap;
std::map<std::string, Item *> includeFilter; std::map<std::string, Item *> includeFilter;
std::map<std::string, Item *> favoritesFilter;
std::map<std::string, Item *> excludeFilter; std::map<std::string, Item *> excludeFilter;
std::string includeFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "include.txt"); std::string includeFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "include.txt");
std::string favoritesFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "playlists/favorites.txt");
std::string excludeFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "exclude.txt"); std::string excludeFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "exclude.txt");
std::string launcher; std::string launcher;
@@ -266,14 +274,12 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me
info->extensionList(extensions); info->extensionList(extensions);
dp = opendir(path.c_str()); dp = opendir(path.c_str());
Logger::write(Logger::ZONE_INFO, "CollectionInfoBuilder", "Scanning directory \"" + path + "\""); Logger::write(Logger::ZONE_INFO, "CollectionInfoBuilder", "Scanning directory \"" + path + "\"");
if(dp == NULL) if(dp == NULL)
{ {
Logger::write(Logger::ZONE_INFO, "CollectionInfoBuilder", "Could not read directory \"" + path + "\". Ignore if this is a menu."); Logger::write(Logger::ZONE_INFO, "CollectionInfoBuilder", "Could not read directory \"" + path + "\". Ignore if this is a menu.");
return false;
} }
if(showMissing) if(showMissing)
@@ -287,7 +293,7 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me
} }
} }
while((dirp = readdir(dp)) != NULL) while(dp != NULL && (dirp = readdir(dp)) != NULL)
{ {
std::string file = dirp->d_name; std::string file = dirp->d_name;
@@ -322,7 +328,10 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me
} }
} }
closedir(dp); if(dp != NULL)
{
closedir(dp);
}
while(includeFilter.size() > 0) while(includeFilter.size() > 0)
{ {
@@ -341,6 +350,27 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me
excludeFilter.erase(it); excludeFilter.erase(it);
} }
for(std::vector<Item *>::iterator it = info->items.begin(); it != info->items.end(); it++) {
allMap[(*it)->fullTitle] = *it;
}
ImportBasicList(info, favoritesFile, favoritesFilter);
info->playlists["all"] = &info->items;
info->playlists["favorites"] = new std::vector<Item *>();
// add the favorites list
for(std::map<std::string, Item *>::iterator it = favoritesFilter.begin(); it != favoritesFilter.end(); it++)
{
std::map<std::string, Item *>::iterator itemit = allMap.find(it->first);
if(itemit != allMap.end())
{
info->playlists["favorites"]->push_back(itemit->second);
}
}
metaDB_.injectMetadata(info); metaDB_.injectMetadata(info);
return true; return true;

View File

@@ -30,6 +30,7 @@ UserInput::UserInput(Configuration &c)
for(unsigned int i = 0; i < KeyCodeMax; ++i) for(unsigned int i = 0; i < KeyCodeMax; ++i)
{ {
keyHandlers_[i] = NULL; keyHandlers_[i] = NULL;
currentKeyState_[i] = false;
lastKeyState_[i] = false; lastKeyState_[i] = false;
} }
} }
@@ -66,13 +67,18 @@ bool UserInput::initialize()
retVal = MapKey("down", KeyCodeRight) && retVal; retVal = MapKey("down", KeyCodeRight) && retVal;
} }
retVal = MapKey("pageDown", KeyCodePageDown) && retVal;
retVal = MapKey("pageUp", KeyCodePageUp) && retVal;
MapKey("letterDown", KeyCodeLetterDown);
MapKey("letterUp", KeyCodeLetterUp);
retVal = MapKey("select", KeyCodeSelect) && retVal; retVal = MapKey("select", KeyCodeSelect) && retVal;
retVal = MapKey("back", KeyCodeBack) && retVal; retVal = MapKey("back", KeyCodeBack) && retVal;
retVal = MapKey("quit", KeyCodeQuit) && retVal; retVal = MapKey("quit", KeyCodeQuit) && retVal;
retVal = MapKey("pageDown", KeyCodePageDown);
retVal = MapKey("pageUp", KeyCodePageUp);
MapKey("letterDown", KeyCodeLetterDown, false);
MapKey("letterUp", KeyCodeLetterUp, false);
MapKey("nextPlaylist", KeyCodeNextPlaylist, false);
MapKey("addPlaylist", KeyCodeAddPlaylist, false);
MapKey("removePlaylist", KeyCodeRemovePlaylist, false);
MapKey("random", KeyCodeRandom, false);
// these features will need to be implemented at a later time // these features will need to be implemented at a later time
// retVal = MapKey("admin", KeyCodeAdminMode) && retVal; // retVal = MapKey("admin", KeyCodeAdminMode) && retVal;
// retVal = MapKey("remove", KeyCodeHideItem) && retVal; // retVal = MapKey("remove", KeyCodeHideItem) && retVal;
@@ -87,6 +93,11 @@ bool UserInput::initialize()
} }
bool UserInput::MapKey(std::string keyDescription, KeyCode_E key) bool UserInput::MapKey(std::string keyDescription, KeyCode_E key)
{
return MapKey(keyDescription, key, true);
}
bool UserInput::MapKey(std::string keyDescription, KeyCode_E key, bool required)
{ {
SDL_Scancode scanCode; SDL_Scancode scanCode;
std::string description; std::string description;
@@ -95,7 +106,8 @@ bool UserInput::MapKey(std::string keyDescription, KeyCode_E key)
if(!config_.getProperty(configKey, description)) if(!config_.getProperty(configKey, description))
{ {
Logger::write(Logger::ZONE_ERROR, "Input", "Missing property " + configKey); Logger::Zone zone = (required) ? Logger::ZONE_ERROR : Logger::ZONE_INFO;
Logger::write(zone, "Input", "Missing property " + configKey);
return false; return false;
} }
@@ -223,6 +235,9 @@ void UserInput::resetStates()
bool UserInput::update(SDL_Event &e) bool UserInput::update(SDL_Event &e)
{ {
bool updated = false; bool updated = false;
memcpy(lastKeyState_, currentKeyState_, sizeof(lastKeyState_));
for(unsigned int i = 0; i < KeyCodeMax; ++i) for(unsigned int i = 0; i < KeyCodeMax; ++i)
{ {
InputHandler *h = keyHandlers_[i]; InputHandler *h = keyHandlers_[i];
@@ -230,7 +245,7 @@ bool UserInput::update(SDL_Event &e)
{ {
if(h->update(e)) updated = true; if(h->update(e)) updated = true;
lastKeyState_[i] = h->pressed(); currentKeyState_[i] = h->pressed();
} }
} }
@@ -239,5 +254,11 @@ bool UserInput::update(SDL_Event &e)
bool UserInput::keystate(KeyCode_E code) bool UserInput::keystate(KeyCode_E code)
{ {
return lastKeyState_[code]; return currentKeyState_[code];
} }
bool UserInput::newKeyPressed(KeyCode_E code)
{
return currentKeyState_[code] && !lastKeyState_[code];
}

View File

@@ -39,6 +39,10 @@ public:
KeyCodePageUp, KeyCodePageUp,
KeyCodeLetterDown, KeyCodeLetterDown,
KeyCodeLetterUp, KeyCodeLetterUp,
KeyCodeNextPlaylist,
KeyCodeRandom,
KeyCodeAddPlaylist,
KeyCodeRemovePlaylist,
KeyCodeAdminMode, KeyCodeAdminMode,
KeyCodeHideItem, KeyCodeHideItem,
KeyCodeQuit, KeyCodeQuit,
@@ -51,12 +55,14 @@ public:
void resetStates(); void resetStates();
bool update(SDL_Event &e); bool update(SDL_Event &e);
bool keystate(KeyCode_E); bool keystate(KeyCode_E);
bool newKeyPressed(KeyCode_E code);
private: private:
bool MapKey(std::string keyDescription, KeyCode_E key); bool MapKey(std::string keyDescription, KeyCode_E key);
bool MapKey(std::string keyDescription, KeyCode_E key, bool required);
Configuration &config_; Configuration &config_;
std::vector<SDL_Joystick *> joysticks_; std::vector<SDL_Joystick *> joysticks_;
InputHandler *keyHandlers_[KeyCodeMax]; InputHandler *keyHandlers_[KeyCodeMax];
bool lastKeyState_[KeyCodeMax]; bool lastKeyState_[KeyCodeMax];
bool currentKeyState_[KeyCodeMax];
}; };

View File

@@ -130,15 +130,14 @@ bool Configuration::parseLine(std::string collection, std::string keyPrefix, std
key = trimEnds(key); key = trimEnds(key);
value = line.substr(position + delimiter.length(), line.length()); value = line.substr(position + delimiter.length(), line.length());
value = trimEnds(value); value = trimEnds(value);
// only overwrite the collection name if we know it. We could be parsing a launcher configuration
if(collection != "") if(collection != "")
{ {
value = Utils::replace(value, "%ITEM_COLLECTION_NAME%", collection); value = Utils::replace(value, "%ITEM_COLLECTION_NAME%", collection);
} }
properties_.insert(PropertiesPair(key, value)); properties_.insert(PropertiesPair(key, value));
std::stringstream ss; std::stringstream ss;
@@ -305,11 +304,9 @@ std::string Configuration::convertToAbsolutePath(std::string prefix, std::string
} }
// check to see if it is already an absolute path // check to see if it is already an absolute path
#ifdef WIN32 if((first != Utils::pathSeparator) &&
if((first != '\\') && (first != '/') && (second != ':')) //(first != '.') &&
#else (second != ':'))
if(first != Utils::pathSeparator)
#endif
{ {
path = Utils::combinePath(prefix, path); path = Utils::combinePath(prefix, path);
} }
@@ -338,6 +335,10 @@ void Configuration::getMediaPropertyAbsolutePath(std::string collectionName, std
void Configuration::getMediaPropertyAbsolutePath(std::string collectionName, std::string mediaType, bool system, std::string &value) void Configuration::getMediaPropertyAbsolutePath(std::string collectionName, std::string mediaType, bool system, std::string &value)
{ {
std::string key = "collections." + collectionName + ".media." + mediaType; std::string key = "collections." + collectionName + ".media." + mediaType;
if (system)
{
key = "collections." + collectionName + ".media.system_artwork";
}
// use user-overridden setting if it exists // use user-overridden setting if it exists
if(getPropertyAbsolutePath(key, value)) if(getPropertyAbsolutePath(key, value))

View File

@@ -417,7 +417,14 @@ bool MetadataDatabase::importMamelist(std::string filename, std::string collecti
} }
sqlite3_exec(handle, "BEGIN IMMEDIATE TRANSACTION;", NULL, NULL, &error); sqlite3_exec(handle, "BEGIN IMMEDIATE TRANSACTION;", NULL, NULL, &error);
for (rapidxml::xml_node<> * game = rootNode->first_node("game"); game; game = game->next_sibling()) std::string gameNodeName = "game";
// support new mame formats
if(rootNode->first_node(gameNodeName.c_str()) == NULL) {
gameNodeName = "machine";
}
for (rapidxml::xml_node<> * game = rootNode->first_node(gameNodeName.c_str()); game; game = game->next_sibling())
{ {
rapidxml::xml_attribute<> *nameNode = game->first_attribute("name"); rapidxml::xml_attribute<> *nameNode = game->first_attribute("name");
rapidxml::xml_attribute<> *cloneOfXml = game->first_attribute("cloneof"); rapidxml::xml_attribute<> *cloneOfXml = game->first_attribute("cloneof");

View File

@@ -67,29 +67,28 @@ bool Launcher::run(std::string collection, Item *collectionItem)
Logger::write(Logger::ZONE_ERROR, "Launcher", "No launcher arguments specified for launcher " + launcherName); Logger::write(Logger::ZONE_ERROR, "Launcher", "No launcher arguments specified for launcher " + launcherName);
return false; return false;
} }
if(!findFile(selectedItemsPath, matchedExtension, selectedItemsDirectory, collectionItem->name, extensionstr))
{ // It is ok to continue if the file could not be found. We could be launching a merged romset
// FindFile() prints out diagnostic messages for us, no need to print anything here findFile(selectedItemsPath, matchedExtension, selectedItemsDirectory, collectionItem->name, extensionstr);
return false;
}
args = replaceVariables(args, args = replaceVariables(args,
selectedItemsPath, selectedItemsPath,
collectionItem->name, collectionItem->name,
collectionItem->filename(), Utils::getFileName(selectedItemsPath),
selectedItemsDirectory, selectedItemsDirectory,
collection); collection);
executablePath = replaceVariables(executablePath, executablePath = replaceVariables(executablePath,
selectedItemsPath, selectedItemsPath,
collectionItem->name, collectionItem->name,
collectionItem->filename(), Utils::getFileName(selectedItemsPath),
selectedItemsDirectory, selectedItemsDirectory,
collection); collection);
currentDirectory = replaceVariables(currentDirectory, currentDirectory = replaceVariables(currentDirectory,
selectedItemsPath, selectedItemsPath,
collectionItem->name, collectionItem->name,
collectionItem->filename(), Utils::getFileName(selectedItemsPath),
selectedItemsDirectory, selectedItemsDirectory,
collection); collection);
@@ -329,7 +328,7 @@ bool Launcher::findFile(std::string &foundFilePath, std::string &foundFilename,
<< filenameWithoutExtension << "\" in folder \"" << filenameWithoutExtension << "\" in folder \""
<< directory; << directory;
Logger::write(Logger::ZONE_ERROR, "Launcher", ss.str()); Logger::write(Logger::ZONE_WARNING, "Launcher", ss.str());
} }

View File

@@ -1,460 +1,460 @@
/* This file is part of RetroFE. /* This file is part of RetroFE.
* *
* RetroFE is free software: you can redistribute it and/or modify * RetroFE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* RetroFE is distributed in the hope that it will be useful, * RetroFE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with RetroFE. If not, see <http://www.gnu.org/licenses/>. * along with RetroFE. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "Component.h" #include "Component.h"
#include "../Animate/Tween.h" #include "../Animate/Tween.h"
#include "../../Graphics/ViewInfo.h" #include "../../Graphics/ViewInfo.h"
#include "../../Utility/Log.h" #include "../../Utility/Log.h"
#include "../../SDL.h" #include "../../SDL.h"
Component::Component() Component::Component(Page &p)
{ : page(p)
tweens_ = NULL; {
selectedItem_ = NULL; tweens_ = NULL;
newItemSelectedSinceEnter = false; newItemSelectedSinceEnter = false;
backgroundTexture_ = NULL; backgroundTexture_ = NULL;
freeGraphicsMemory(); freeGraphicsMemory();
} }
Component::Component(const Component &copy) Component::Component(const Component &copy)
{ : page(copy.page)
tweens_ = NULL; {
selectedItem_ = NULL; tweens_ = NULL;
newItemSelectedSinceEnter = false; newItemSelectedSinceEnter = false;
backgroundTexture_ = NULL; backgroundTexture_ = NULL;
freeGraphicsMemory(); freeGraphicsMemory();
if(copy.tweens_) if(copy.tweens_)
{ {
AnimationEvents *tweens = new AnimationEvents(*copy.tweens_); AnimationEvents *tweens = new AnimationEvents(*copy.tweens_);
setTweens(tweens); setTweens(tweens);
} }
} }
Component::~Component() Component::~Component()
{ {
freeGraphicsMemory(); freeGraphicsMemory();
} }
void Component::freeGraphicsMemory() void Component::freeGraphicsMemory()
{ {
currentAnimationState = HIDDEN; currentAnimationState = HIDDEN;
enterRequested = false; enterRequested = false;
exitRequested = false; exitRequested = false;
menuEnterRequested = false; menuEnterRequested = false;
menuEnterIndex = -1; menuEnterIndex = -1;
menuScrollRequested = false; menuScrollRequested = false;
menuExitRequested = false; menuExitRequested = false;
menuExitIndex = -1; menuExitIndex = -1;
newItemSelected = false; newItemSelected = false;
highlightExitComplete = false; playlistChanged = false;
currentTweens_ = NULL; highlightExitComplete = false;
currentTweenIndex_ = 0; currentTweens_ = NULL;
currentTweenComplete_ = false; currentTweenIndex_ = 0;
elapsedTweenTime_ = 0; currentTweenComplete_ = false;
scrollActive = false; elapsedTweenTime_ = 0;
scrollActive = false;
if(backgroundTexture_)
{ if(backgroundTexture_)
SDL_LockMutex(SDL::getMutex()); {
SDL_DestroyTexture(backgroundTexture_); SDL_LockMutex(SDL::getMutex());
SDL_UnlockMutex(SDL::getMutex()); SDL_DestroyTexture(backgroundTexture_);
SDL_UnlockMutex(SDL::getMutex());
backgroundTexture_ = NULL;
} backgroundTexture_ = NULL;
} }
void Component::allocateGraphicsMemory() }
{ void Component::allocateGraphicsMemory()
if(!backgroundTexture_) {
{ if(!backgroundTexture_)
// make a 4x4 pixel wide surface to be stretched during rendering, make it a white background so we can use {
// color later // make a 4x4 pixel wide surface to be stretched during rendering, make it a white background so we can use
SDL_Surface *surface = SDL_CreateRGBSurface(0, 4, 4, 32, 0, 0, 0, 0); // color later
SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 255, 255, 255)); SDL_Surface *surface = SDL_CreateRGBSurface(0, 4, 4, 32, 0, 0, 0, 0);
SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 255, 255, 255));
SDL_LockMutex(SDL::getMutex());
backgroundTexture_ = SDL_CreateTextureFromSurface(SDL::getRenderer(), surface); SDL_LockMutex(SDL::getMutex());
SDL_UnlockMutex(SDL::getMutex()); backgroundTexture_ = SDL_CreateTextureFromSurface(SDL::getRenderer(), surface);
SDL_UnlockMutex(SDL::getMutex());
SDL_FreeSurface(surface);
SDL_SetTextureBlendMode(backgroundTexture_, SDL_BLENDMODE_BLEND); SDL_FreeSurface(surface);
} SDL_SetTextureBlendMode(backgroundTexture_, SDL_BLENDMODE_BLEND);
} }
}
Item *Component::getSelectedItem()
{ void Component::triggerEnterEvent()
return selectedItem_; {
} enterRequested = true;
}
void Component::triggerEnterEvent()
{ void Component::triggerExitEvent()
enterRequested = true; {
} exitRequested = true;
}
void Component::triggerExitEvent()
{
exitRequested = true;
} void Component::triggerMenuEnterEvent(int menuIndex)
{
menuEnterRequested = true;
menuEnterIndex = menuIndex;
void Component::triggerMenuEnterEvent(int menuIndex) }
{
menuEnterRequested = true; void Component::triggerMenuScrollEvent()
menuEnterIndex = menuIndex; {
} menuScrollRequested = true;
}
void Component::triggerMenuScrollEvent()
{
menuScrollRequested = true; void Component::triggerMenuExitEvent(int menuIndex)
} {
menuExitRequested = true;
menuExitIndex = menuIndex;
void Component::triggerMenuExitEvent(int menuIndex) }
{ void Component::triggerHighlightEvent()
menuExitRequested = true; {
menuExitIndex = menuIndex; newItemSelected = true;
} }
void Component::triggerHighlightEvent(Item *selectedItem)
{ void Component::triggerPlaylistChangeEvent(std::string name)
newItemSelected = true; {
this->selectedItem_ = selectedItem; playlistChanged = true;
} this->playlistName = name;
}
bool Component::isIdle() bool Component::isIdle()
{ {
return (currentAnimationState == IDLE); return (currentAnimationState == IDLE);
} }
bool Component::isHidden() bool Component::isHidden()
{ {
return (currentAnimationState == HIDDEN); return (currentAnimationState == HIDDEN);
} }
bool Component::isWaiting() bool Component::isWaiting()
{ {
return (currentAnimationState == HIGHLIGHT_WAIT); return (currentAnimationState == HIGHLIGHT_WAIT);
} }
bool Component::isMenuScrolling() bool Component::isMenuScrolling()
{ {
return (currentAnimationState == MENU_ENTER || currentAnimationState == MENU_SCROLL || currentAnimationState == MENU_EXIT || menuScrollRequested); return (currentAnimationState == MENU_ENTER || currentAnimationState == MENU_SCROLL || currentAnimationState == MENU_EXIT || menuScrollRequested);
} }
void Component::setTweens(AnimationEvents *set) void Component::setTweens(AnimationEvents *set)
{ {
tweens_ = set; tweens_ = set;
forceIdle(); forceIdle();
} }
void Component::forceIdle() void Component::forceIdle()
{ {
currentAnimationState = IDLE; currentAnimationState = IDLE;
currentTweenIndex_ = 0; currentTweenIndex_ = 0;
currentTweenComplete_ = false; currentTweenComplete_ = false;
elapsedTweenTime_ = 0; elapsedTweenTime_ = 0;
currentTweens_ = NULL; currentTweens_ = NULL;
} }
void Component::update(float dt) void Component::update(float dt)
{ {
elapsedTweenTime_ += dt; elapsedTweenTime_ += dt;
highlightExitComplete = false; highlightExitComplete = false;
if(isHidden() || isWaiting() || (isIdle() && exitRequested)) if(isHidden() || isWaiting() || (isIdle() && exitRequested))
{ {
currentTweenComplete_ = true; currentTweenComplete_ = true;
} }
if(currentTweenComplete_) if(currentTweenComplete_)
{ {
currentTweens_ = NULL; currentTweens_ = NULL;
// There was no request to override our state path. Continue on as normal. // There was no request to override our state path. Continue on as normal.
std::stringstream ss; std::stringstream ss;
switch(currentAnimationState) switch(currentAnimationState)
{ {
case MENU_ENTER: case MENU_ENTER:
currentTweens_ = NULL; currentTweens_ = NULL;
currentAnimationState = IDLE; currentAnimationState = IDLE;
break; break;
case MENU_SCROLL: case MENU_SCROLL:
currentTweens_ = NULL; currentTweens_ = NULL;
currentAnimationState = IDLE; currentAnimationState = IDLE;
break; break;
case MENU_EXIT: case MENU_EXIT:
currentTweens_ = NULL; currentTweens_ = NULL;
currentAnimationState = IDLE; currentAnimationState = IDLE;
break; break;
case ENTER: case ENTER:
currentTweens_ = tweens_->getAnimation("enter", menuEnterIndex); currentTweens_ = tweens_->getAnimation("enter", menuEnterIndex);
currentAnimationState = HIGHLIGHT_ENTER; currentAnimationState = HIGHLIGHT_ENTER;
break; break;
case EXIT: case EXIT:
currentTweens_ = NULL; currentTweens_ = NULL;
currentAnimationState = HIDDEN; currentAnimationState = HIDDEN;
break; break;
case HIGHLIGHT_ENTER: case HIGHLIGHT_ENTER:
currentTweens_ = tweens_->getAnimation("idle", menuEnterIndex); currentTweens_ = tweens_->getAnimation("idle", menuEnterIndex);
currentAnimationState = IDLE; currentAnimationState = IDLE;
break; break;
case IDLE: case IDLE:
// prevent us from automatically jumping to the exit tween upon enter // prevent us from automatically jumping to the exit tween upon enter
if(enterRequested) if(enterRequested)
{ {
enterRequested = false; enterRequested = false;
newItemSelected = false; newItemSelected = false;
} }
else if(menuExitRequested && (!menuEnterRequested || menuExitRequested <= menuEnterRequested)) else if(menuExitRequested && (!menuEnterRequested || menuExitRequested <= menuEnterRequested))
{ {
currentTweens_ = tweens_->getAnimation("menuExit", menuExitIndex); currentTweens_ = tweens_->getAnimation("menuExit", menuExitIndex);
currentAnimationState = MENU_EXIT; currentAnimationState = MENU_EXIT;
menuExitRequested = false; menuExitRequested = false;
} }
else if(menuEnterRequested && (!menuExitRequested || menuExitRequested > menuEnterRequested)) else if(menuEnterRequested && (!menuExitRequested || menuExitRequested > menuEnterRequested))
{ {
currentTweens_ = tweens_->getAnimation("menuEnter", menuEnterIndex); currentTweens_ = tweens_->getAnimation("menuEnter", menuEnterIndex);
currentAnimationState = MENU_ENTER; currentAnimationState = MENU_ENTER;
menuEnterRequested = false; menuEnterRequested = false;
} }
else if(menuScrollRequested) else if(menuScrollRequested)
{ {
menuScrollRequested = false; menuScrollRequested = false;
currentTweens_ = tweens_->getAnimation("menuScroll", menuEnterIndex); currentTweens_ = tweens_->getAnimation("menuScroll", menuEnterIndex);
currentAnimationState = MENU_SCROLL; currentAnimationState = MENU_SCROLL;
} }
else if(scrollActive || newItemSelected || exitRequested) else if(scrollActive || newItemSelected || exitRequested)
{ {
currentTweens_ = tweens_->getAnimation("highlightExit", menuEnterIndex); currentTweens_ = tweens_->getAnimation("highlightExit", menuEnterIndex);
currentAnimationState = HIGHLIGHT_EXIT; currentAnimationState = HIGHLIGHT_EXIT;
} }
else else
{ {
currentTweens_ = tweens_->getAnimation("idle", menuEnterIndex); currentTweens_ = tweens_->getAnimation("idle", menuEnterIndex);
currentAnimationState = IDLE; currentAnimationState = IDLE;
} }
break; break;
case HIGHLIGHT_EXIT: case HIGHLIGHT_EXIT:
// intentionally break down // intentionally break down
case HIGHLIGHT_WAIT: case HIGHLIGHT_WAIT:
if(exitRequested && (currentAnimationState == HIGHLIGHT_WAIT)) if(exitRequested && (currentAnimationState == HIGHLIGHT_WAIT))
{ {
currentTweens_ = tweens_->getAnimation("highlightExit", menuEnterIndex); currentTweens_ = tweens_->getAnimation("highlightExit", menuEnterIndex);
currentAnimationState = HIGHLIGHT_EXIT; currentAnimationState = HIGHLIGHT_EXIT;
} }
else if(exitRequested && (currentAnimationState == HIGHLIGHT_EXIT)) else if(exitRequested && (currentAnimationState == HIGHLIGHT_EXIT))
{ {
currentTweens_ = tweens_->getAnimation("exit", menuEnterIndex); currentTweens_ = tweens_->getAnimation("exit", menuEnterIndex);
currentAnimationState = EXIT; currentAnimationState = EXIT;
exitRequested = false; exitRequested = false;
} }
else if(scrollActive) else if(scrollActive)
{ {
currentTweens_ = NULL; currentTweens_ = NULL;
currentAnimationState = HIGHLIGHT_WAIT; currentAnimationState = HIGHLIGHT_WAIT;
} }
else if(newItemSelected) else if(newItemSelected)
{ {
currentTweens_ = tweens_->getAnimation("highlightEnter", menuEnterIndex); currentTweens_ = tweens_->getAnimation("highlightEnter", menuEnterIndex);
currentAnimationState = HIGHLIGHT_ENTER; currentAnimationState = HIGHLIGHT_ENTER;
highlightExitComplete = true; highlightExitComplete = true;
newItemSelected = false; newItemSelected = false;
} }
else else
{ {
currentTweens_ = NULL; currentTweens_ = NULL;
currentAnimationState = HIGHLIGHT_WAIT; currentAnimationState = HIGHLIGHT_WAIT;
} }
break; break;
case HIDDEN: case HIDDEN:
if(enterRequested || exitRequested) if(enterRequested || exitRequested)
{ {
currentTweens_ = tweens_->getAnimation("enter", menuEnterIndex); currentTweens_ = tweens_->getAnimation("enter", menuEnterIndex);
currentAnimationState = ENTER; currentAnimationState = ENTER;
} }
else if(menuExitRequested && (!menuEnterRequested || menuExitRequested <= menuEnterRequested)) else if(menuExitRequested && (!menuEnterRequested || menuExitRequested <= menuEnterRequested))
{ {
currentTweens_ = tweens_->getAnimation("menuExit", menuExitIndex); currentTweens_ = tweens_->getAnimation("menuExit", menuExitIndex);
currentAnimationState = MENU_EXIT; currentAnimationState = MENU_EXIT;
menuExitRequested = false; menuExitRequested = false;
} }
else if(menuEnterRequested && (!menuExitRequested || menuExitRequested > menuEnterRequested)) else if(menuEnterRequested && (!menuExitRequested || menuExitRequested > menuEnterRequested))
{ {
currentTweens_ = tweens_->getAnimation("menuEnter", menuEnterIndex); currentTweens_ = tweens_->getAnimation("menuEnter", menuEnterIndex);
currentAnimationState = MENU_ENTER; currentAnimationState = MENU_ENTER;
menuEnterRequested = false; menuEnterRequested = false;
} }
else if(menuScrollRequested) else if(menuScrollRequested)
{ {
menuScrollRequested = false; menuScrollRequested = false;
currentTweens_ = tweens_->getAnimation("menuScroll", menuEnterIndex); currentTweens_ = tweens_->getAnimation("menuScroll", menuEnterIndex);
currentAnimationState = MENU_SCROLL; currentAnimationState = MENU_SCROLL;
} }
else else
{ {
currentTweens_ = NULL; currentTweens_ = NULL;
currentAnimationState = HIDDEN; currentAnimationState = HIDDEN;
} }
} }
currentTweenIndex_ = 0; currentTweenIndex_ = 0;
currentTweenComplete_ = false; currentTweenComplete_ = false;
elapsedTweenTime_ = 0; elapsedTweenTime_ = 0;
} }
currentTweenComplete_ = animate(isIdle()); currentTweenComplete_ = animate(isIdle());
} }
void Component::draw() void Component::draw()
{ {
if(backgroundTexture_) if(backgroundTexture_)
{ {
SDL_Rect rect; SDL_Rect rect;
rect.h = static_cast<int>(baseViewInfo.ScaledHeight()); rect.h = static_cast<int>(baseViewInfo.ScaledHeight());
rect.w = static_cast<int>(baseViewInfo.ScaledWidth()); rect.w = static_cast<int>(baseViewInfo.ScaledWidth());
rect.x = static_cast<int>(baseViewInfo.XRelativeToOrigin()); rect.x = static_cast<int>(baseViewInfo.XRelativeToOrigin());
rect.y = static_cast<int>(baseViewInfo.YRelativeToOrigin()); rect.y = static_cast<int>(baseViewInfo.YRelativeToOrigin());
SDL_SetTextureColorMod(backgroundTexture_, SDL_SetTextureColorMod(backgroundTexture_,
static_cast<char>(baseViewInfo.BackgroundRed*255), static_cast<char>(baseViewInfo.BackgroundRed*255),
static_cast<char>(baseViewInfo.BackgroundGreen*255), static_cast<char>(baseViewInfo.BackgroundGreen*255),
static_cast<char>(baseViewInfo.BackgroundBlue*255)); static_cast<char>(baseViewInfo.BackgroundBlue*255));
SDL::renderCopy(backgroundTexture_, static_cast<char>(baseViewInfo.BackgroundAlpha*255), NULL, &rect, baseViewInfo.Angle); SDL::renderCopy(backgroundTexture_, static_cast<char>(baseViewInfo.BackgroundAlpha*255), NULL, &rect, baseViewInfo.Angle);
} }
} }
bool Component::animate(bool loop) bool Component::animate(bool loop)
{ {
bool completeDone = false; bool completeDone = false;
if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->size()) if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->size())
{ {
completeDone = true; completeDone = true;
} }
else if(currentTweens_) else if(currentTweens_)
{ {
bool currentDone = true; bool currentDone = true;
TweenSet *tweens = currentTweens_->tweenSet(currentTweenIndex_); TweenSet *tweens = currentTweens_->tweenSet(currentTweenIndex_);
for(unsigned int i = 0; i < tweens->size(); i++) for(unsigned int i = 0; i < tweens->size(); i++)
{ {
Tween *tween = tweens->tweens()->at(i); Tween *tween = tweens->tweens()->at(i);
double elapsedTime = elapsedTweenTime_; double elapsedTime = elapsedTweenTime_;
//todo: too many levels of nesting //todo: too many levels of nesting
if(elapsedTime < tween->duration) if(elapsedTime < tween->duration)
{ {
currentDone = false; currentDone = false;
} }
else else
{ {
elapsedTime = static_cast<float>(tween->duration); elapsedTime = static_cast<float>(tween->duration);
} }
float value = tween->animate(elapsedTime); float value = tween->animate(elapsedTime);
switch(tween->property) switch(tween->property)
{ {
case TWEEN_PROPERTY_X: case TWEEN_PROPERTY_X:
baseViewInfo.X = value; baseViewInfo.X = value;
break; break;
case TWEEN_PROPERTY_Y: case TWEEN_PROPERTY_Y:
baseViewInfo.Y = value; baseViewInfo.Y = value;
break; break;
case TWEEN_PROPERTY_HEIGHT: case TWEEN_PROPERTY_HEIGHT:
baseViewInfo.Height = value; baseViewInfo.Height = value;
break; break;
case TWEEN_PROPERTY_WIDTH: case TWEEN_PROPERTY_WIDTH:
baseViewInfo.Width = value; baseViewInfo.Width = value;
break; break;
case TWEEN_PROPERTY_ANGLE: case TWEEN_PROPERTY_ANGLE:
baseViewInfo.Angle = value; baseViewInfo.Angle = value;
break; break;
case TWEEN_PROPERTY_ALPHA: case TWEEN_PROPERTY_ALPHA:
baseViewInfo.Alpha = value; baseViewInfo.Alpha = value;
break; break;
case TWEEN_PROPERTY_X_ORIGIN: case TWEEN_PROPERTY_X_ORIGIN:
baseViewInfo.XOrigin = value; baseViewInfo.XOrigin = value;
break; break;
case TWEEN_PROPERTY_Y_ORIGIN: case TWEEN_PROPERTY_Y_ORIGIN:
baseViewInfo.YOrigin = value; baseViewInfo.YOrigin = value;
break; break;
case TWEEN_PROPERTY_X_OFFSET: case TWEEN_PROPERTY_X_OFFSET:
baseViewInfo.XOffset = value; baseViewInfo.XOffset = value;
break; break;
case TWEEN_PROPERTY_Y_OFFSET: case TWEEN_PROPERTY_Y_OFFSET:
baseViewInfo.YOffset = value; baseViewInfo.YOffset = value;
break; break;
case TWEEN_PROPERTY_FONT_SIZE: case TWEEN_PROPERTY_FONT_SIZE:
baseViewInfo.FontSize = value; baseViewInfo.FontSize = value;
break; break;
case TWEEN_PROPERTY_BACKGROUND_ALPHA: case TWEEN_PROPERTY_BACKGROUND_ALPHA:
baseViewInfo.BackgroundAlpha = value; baseViewInfo.BackgroundAlpha = value;
break; break;
} }
} }
if(currentDone) if(currentDone)
{ {
currentTweenIndex_++; currentTweenIndex_++;
elapsedTweenTime_ = 0; elapsedTweenTime_ = 0;
} }
} }
if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->tweenSets()->size()) if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->tweenSets()->size())
{ {
if(loop) if(loop)
{ {
currentTweenIndex_ = 0; currentTweenIndex_ = 0;
} }
completeDone = true; completeDone = true;
} }
return completeDone; return completeDone;
} }

View File

@@ -19,15 +19,15 @@
#include "../../SDL.h" #include "../../SDL.h"
#include "../MenuNotifierInterface.h" #include "../MenuNotifierInterface.h"
#include "../Page.h"
#include "../ViewInfo.h" #include "../ViewInfo.h"
#include "../Animate/Tween.h" #include "../Animate/Tween.h"
#include "../Animate/AnimationEvents.h" #include "../Animate/AnimationEvents.h"
#include "../../Collection/Item.h" #include "../../Collection/Item.h"
class Component class Component
{ {
public: public:
Component(); Component(Page &p);
Component(const Component &copy); Component(const Component &copy);
virtual ~Component(); virtual ~Component();
virtual void freeGraphicsMemory(); virtual void freeGraphicsMemory();
@@ -39,7 +39,8 @@ public:
void triggerMenuEnterEvent(int menuIndex = -1); void triggerMenuEnterEvent(int menuIndex = -1);
void triggerMenuExitEvent(int menuIndex = -1); void triggerMenuExitEvent(int menuIndex = -1);
void triggerMenuScrollEvent(); void triggerMenuScrollEvent();
void triggerHighlightEvent(Item *selectedItem); void triggerHighlightEvent();
void triggerPlaylistChangeEvent(std::string name);
bool isIdle(); bool isIdle();
bool isHidden(); bool isHidden();
bool isWaiting(); bool isWaiting();
@@ -54,7 +55,8 @@ public:
bool scrollActive; bool scrollActive;
protected: protected:
Item *getSelectedItem(); Page &page;
enum AnimationState enum AnimationState
{ {
IDLE, IDLE,
@@ -78,6 +80,8 @@ protected:
bool menuExitRequested; bool menuExitRequested;
int menuExitIndex; int menuExitIndex;
bool newItemSelected; bool newItemSelected;
bool playlistChanged;
std::string playlistName;
bool highlightExitComplete; bool highlightExitComplete;
bool newItemSelectedSinceEnter; bool newItemSelectedSinceEnter;
private: private:
@@ -87,7 +91,6 @@ private:
AnimationEvents *tweens_; AnimationEvents *tweens_;
Animation *currentTweens_; Animation *currentTweens_;
Item *selectedItem_;
SDL_Texture *backgroundTexture_; SDL_Texture *backgroundTexture_;
unsigned int currentTweenIndex_; unsigned int currentTweenIndex_;

View File

@@ -18,7 +18,8 @@
#include "../ViewInfo.h" #include "../ViewInfo.h"
#include "../../SDL.h" #include "../../SDL.h"
Container::Container() Container::Container(Page &p)
: Component(p)
{ {
allocateGraphicsMemory(); allocateGraphicsMemory();
} }

View File

@@ -22,7 +22,7 @@
class Container : public Component class Container : public Component
{ {
public: public:
Container(); Container(Page &p);
virtual ~Container(); virtual ~Container();
void freeGraphicsMemory(); void freeGraphicsMemory();
void allocateGraphicsMemory(); void allocateGraphicsMemory();

View File

@@ -19,8 +19,9 @@
#include "../../Utility/Log.h" #include "../../Utility/Log.h"
#include <SDL2/SDL_image.h> #include <SDL2/SDL_image.h>
Image::Image(std::string file, float scaleX, float scaleY) Image::Image(std::string file, Page &p, float scaleX, float scaleY)
: texture_(NULL) : Component(p)
, texture_(NULL)
, file_(file) , file_(file)
, scaleX_(scaleX) , scaleX_(scaleX)
, scaleY_(scaleY) , scaleY_(scaleY)

View File

@@ -22,7 +22,7 @@
class Image : public Component class Image : public Component
{ {
public: public:
Image(std::string file, float scaleX, float scaleY); Image(std::string file, Page &p, float scaleX, float scaleY);
virtual ~Image(); virtual ~Image();
void freeGraphicsMemory(); void freeGraphicsMemory();
void allocateGraphicsMemory(); void allocateGraphicsMemory();

View File

@@ -18,7 +18,7 @@
#include "../../Utility/Log.h" #include "../../Utility/Log.h"
#include <fstream> #include <fstream>
Image * ImageBuilder::CreateImage(std::string path, std::string name, float scaleX, float scaleY) Image * ImageBuilder::CreateImage(std::string path, Page &p, std::string name, float scaleX, float scaleY)
{ {
Image *image = NULL; Image *image = NULL;
std::vector<std::string> extensions; std::vector<std::string> extensions;
@@ -35,7 +35,7 @@ Image * ImageBuilder::CreateImage(std::string path, std::string name, float scal
if(Utils::findMatchingFile(prefix, extensions, file)) if(Utils::findMatchingFile(prefix, extensions, file))
{ {
image = new Image(file, scaleX, scaleY); image = new Image(file, p, scaleX, scaleY);
} }
return image; return image;

View File

@@ -15,6 +15,7 @@
*/ */
#pragma once #pragma once
#include "../Page.h"
#include "Image.h" #include "Image.h"
#include "VideoComponent.h" #include "VideoComponent.h"
#include "../../Video/VideoFactory.h" #include "../../Video/VideoFactory.h"
@@ -23,5 +24,5 @@
class ImageBuilder class ImageBuilder
{ {
public: public:
Image * CreateImage(std::string path, std::string name, float scaleX, float scaleY); Image * CreateImage(std::string path, Page &p, std::string name, float scaleX, float scaleY);
}; };

View File

@@ -28,8 +28,9 @@
#include <vector> #include <vector>
#include <iostream> #include <iostream>
ReloadableMedia::ReloadableMedia(Configuration &config, bool systemMode, std::string type, bool isVideo, Font *font, float scaleX, float scaleY) ReloadableMedia::ReloadableMedia(Configuration &config, bool systemMode, std::string type, Page &p, int displayOffset, bool isVideo, Font *font, float scaleX, float scaleY)
: config_(config) : Component(p)
, config_(config)
, systemMode_(systemMode) , systemMode_(systemMode)
, loadedComponent_(NULL) , loadedComponent_(NULL)
, reloadRequested_(false) , reloadRequested_(false)
@@ -41,6 +42,8 @@ ReloadableMedia::ReloadableMedia(Configuration &config, bool systemMode, std::st
, type_(type) , type_(type)
, scaleX_(scaleX) , scaleX_(scaleX)
, scaleY_(scaleY) , scaleY_(scaleY)
, displayOffset_(displayOffset)
{ {
allocateGraphicsMemory(); allocateGraphicsMemory();
} }
@@ -145,7 +148,7 @@ void ReloadableMedia::reloadTexture()
loadedComponent_ = NULL; loadedComponent_ = NULL;
} }
Item *selectedItem = getSelectedItem(); Item *selectedItem = page.getSelectedItem(displayOffset_);
if(!selectedItem) return; if(!selectedItem) return;
config_.getProperty("currentCollection", currentCollection_); config_.getProperty("currentCollection", currentCollection_);
@@ -252,7 +255,10 @@ void ReloadableMedia::reloadTexture()
} }
else if(typeLC == "manufacturer") else if(typeLC == "manufacturer")
{ {
if ( selectedItem->leaf ) // item is a leaf
basename = selectedItem->manufacturer; basename = selectedItem->manufacturer;
else // item is a collection
(void)config_.getProperty("collections." + selectedItem->name + ".manufacturer", basename );
} }
else if(typeLC == "genre") else if(typeLC == "genre")
{ {
@@ -324,7 +330,7 @@ void ReloadableMedia::reloadTexture()
// if image and artwork was not specified, fall back to displaying text // if image and artwork was not specified, fall back to displaying text
if(!loadedComponent_ && textFallback_) if(!loadedComponent_ && textFallback_)
{ {
loadedComponent_ = new Text(selectedItem->fullTitle, FfntInst_, scaleX_, scaleY_); loadedComponent_ = new Text(selectedItem->fullTitle, page, FfntInst_, scaleX_, scaleY_);
baseViewInfo.ImageWidth = loadedComponent_->baseViewInfo.ImageWidth; baseViewInfo.ImageWidth = loadedComponent_->baseViewInfo.ImageWidth;
baseViewInfo.ImageHeight = loadedComponent_->baseViewInfo.ImageHeight; baseViewInfo.ImageHeight = loadedComponent_->baseViewInfo.ImageHeight;
} }
@@ -343,11 +349,11 @@ Component *ReloadableMedia::findComponent(std::string collection, std::string ty
if(type == "video") if(type == "video")
{ {
component = videoBuild.createVideo(imagePath, basename, scaleX_, scaleY_); component = videoBuild.createVideo(imagePath, page, basename, scaleX_, scaleY_);
} }
else else
{ {
component = imageBuild.CreateImage(imagePath, basename, scaleX_, scaleY_); component = imageBuild.CreateImage(imagePath, page, basename, scaleX_, scaleY_);
} }
return component; return component;

View File

@@ -27,7 +27,7 @@ class Image;
class ReloadableMedia : public Component class ReloadableMedia : public Component
{ {
public: public:
ReloadableMedia(Configuration &config, bool systemMode, std::string type, bool isVideo, Font *font, float scaleX, float scaleY); ReloadableMedia(Configuration &config, bool systemMode, std::string type, Page &page, int displayOffset, bool isVideo, Font *font, float scaleX, float scaleY);
virtual ~ReloadableMedia(); virtual ~ReloadableMedia();
void update(float dt); void update(float dt);
void draw(); void draw();
@@ -54,4 +54,6 @@ private:
float scaleX_; float scaleX_;
float scaleY_; float scaleY_;
std::string currentCollection_; std::string currentCollection_;
Page *page_;
int displayOffset_;
}; };

View File

@@ -23,8 +23,10 @@
#include <vector> #include <vector>
#include <iostream> #include <iostream>
ReloadableText::ReloadableText(std::string type, Font *font, std::string layoutKey, float scaleX, float scaleY) ReloadableText::ReloadableText(std::string type, Page &page, Configuration &config, Font *font, std::string layoutKey, float scaleX, float scaleY)
: imageInst_(NULL) : Component(page)
, config_(config)
, imageInst_(NULL)
, layoutKey_(layoutKey) , layoutKey_(layoutKey)
, reloadRequested_(false) , reloadRequested_(false)
, firstLoad_(true) , firstLoad_(true)
@@ -59,7 +61,22 @@ ReloadableText::ReloadableText(std::string type, Font *font, std::string layoutK
{ {
type_ = TextTypeGenre; type_ = TextTypeGenre;
} }
else if(type == "playlist")
{
type_ = TextTypePlaylist;
}
else if(type == "collectionName")
{
type_ = TextTypeCollectionName;
}
else if(type == "collectionSize")
{
type_ = TextTypeCollectionSize;
}
else if(type == "collectionIndex")
{
type_ = TextTypeCollectionIndex;
}
allocateGraphicsMemory(); allocateGraphicsMemory();
} }
@@ -75,7 +92,8 @@ ReloadableText::~ReloadableText()
void ReloadableText::update(float dt) void ReloadableText::update(float dt)
{ {
if(newItemSelected) if((type_ != TextTypePlaylist && newItemSelected) ||
(type_ == TextTypePlaylist && playlistChanged))
{ {
reloadRequested_ = true; reloadRequested_ = true;
} }
@@ -128,7 +146,7 @@ void ReloadableText::ReloadTexture()
imageInst_ = NULL; imageInst_ = NULL;
} }
Item *selectedItem = getSelectedItem(); Item *selectedItem = page.getSelectedItem();
if (selectedItem != NULL) if (selectedItem != NULL)
{ {
@@ -143,22 +161,47 @@ void ReloadableText::ReloadTexture()
ss << selectedItem->numberPlayers; ss << selectedItem->numberPlayers;
break; break;
case TextTypeYear: case TextTypeYear:
ss << selectedItem->year; if (selectedItem->leaf) // item is a leaf
text = selectedItem->year;
else // item is a collection
(void)config_.getProperty("collections." + selectedItem->name + ".year", text );
ss << text;
break; break;
case TextTypeTitle: case TextTypeTitle:
ss << selectedItem->title; ss << selectedItem->title;
break; break;
case TextTypeManufacturer: case TextTypeManufacturer:
ss << selectedItem->manufacturer; if (selectedItem->leaf) // item is a leaf
text = selectedItem->manufacturer;
else // item is a collection
(void)config_.getProperty("collections." + selectedItem->name + ".manufacturer", text );
ss << text;
break; break;
case TextTypeGenre: case TextTypeGenre:
ss << selectedItem->genre; if (selectedItem->leaf) // item is a leaf
text = selectedItem->genre;
else // item is a collection
(void)config_.getProperty("collections." + selectedItem->name + ".genre", text );
ss << text;
break; break;
case TextTypePlaylist:
ss << playlistName;
break;
case TextTypeCollectionName:
ss << page.getCollectionName();
break;
case TextTypeCollectionSize:
ss << page.getCollectionSize();
break;
case TextTypeCollectionIndex:
ss << (1+page.getSelectedIndex());
break;
default: default:
break; break;
} }
imageInst_ = new Text(ss.str(), fontInst_, scaleX_, scaleY_); imageInst_ = new Text(ss.str(), page, fontInst_, scaleX_, scaleY_);
} }
} }

View File

@@ -17,6 +17,7 @@
#include "Component.h" #include "Component.h"
#include "Text.h" #include "Text.h"
#include "../Font.h" #include "../Font.h"
#include "../Page.h"
#include "../../Collection/Item.h" #include "../../Collection/Item.h"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <string> #include <string>
@@ -24,7 +25,7 @@
class ReloadableText : public Component class ReloadableText : public Component
{ {
public: public:
ReloadableText(std::string type, Font *font, std::string layoutKey, float scaleX, float scaleY); ReloadableText(std::string type, Page &page, Configuration &config, Font *font, std::string layoutKey, float scaleX, float scaleY);
virtual ~ReloadableText(); virtual ~ReloadableText();
void update(float dt); void update(float dt);
void draw(); void draw();
@@ -43,10 +44,15 @@ private:
TextTypeTitle, TextTypeTitle,
TextTypeManufacturer, TextTypeManufacturer,
TextTypeGenre, TextTypeGenre,
TextTypePlaylist,
TextTypeCollectionName,
TextTypeCollectionSize,
TextTypeCollectionIndex
}; };
void ReloadTexture(); void ReloadTexture();
Configuration &config_;
Text *imageInst_; Text *imageInst_;
TextType type_; TextType type_;
std::string layoutKey_; std::string layoutKey_;

File diff suppressed because it is too large Load Diff

View File

@@ -1,136 +1,139 @@
/* This file is part of RetroFE. /* This file is part of RetroFE.
* *
* RetroFE is free software: you can redistribute it and/or modify * RetroFE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* RetroFE is distributed in the hope that it will be useful, * RetroFE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with RetroFE. If not, see <http://www.gnu.org/licenses/>. * along with RetroFE. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include <vector> #include <vector>
#include "Component.h" #include "Component.h"
#include "../Animate/Tween.h" #include "../Animate/Tween.h"
#include "../ComponentItemBinding.h" #include "../Page.h"
#include "../MenuNotifierInterface.h" #include "../MenuNotifierInterface.h"
#include "../ViewInfo.h" #include "../ViewInfo.h"
#include "../../Database/Configuration.h" #include "../../Database/Configuration.h"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
//todo: This scrolling implementation needs to be overhauled //todo: This scrolling implementation needs to be overhauled
// It needs to have a common interface to support different menu types // It needs to have a common interface to support different menu types
// (It was originally sandbox code that creeped into here) // (It was originally sandbox code that creeped into here)
class Configuration; class Configuration;
class Font; class Font;
class ScrollingList : public Component class ScrollingList : public Component
{ {
public: public:
enum ScrollDirection enum ScrollDirection
{ {
ScrollDirectionBack, ScrollDirectionBack,
ScrollDirectionForward, ScrollDirectionForward,
ScrollDirectionIdle, ScrollDirectionIdle,
}; };
ScrollingList(Configuration &c, ScrollingList(Configuration &c,
float scaleX, Page &p,
float scaleY, float scaleX,
Font *font, float scaleY,
std::string layoutKey, Font *font,
std::string imageType); std::string layoutKey,
std::string imageType);
ScrollingList(const ScrollingList &copy);
virtual ~ScrollingList(); ScrollingList(const ScrollingList &copy);
void triggerMenuEnterEvent(); virtual ~ScrollingList();
void triggerMenuExitEvent(); void triggerMenuEnterEvent();
void triggerMenuExitEvent();
bool allocateTexture(ComponentItemBinding *s);
void deallocateTexture(ComponentItemBinding *s); bool allocateTexture(unsigned int index, Item *i);
void setItems(std::vector<ComponentItemBinding *> *spriteList); void deallocateTexture(unsigned int index);
void destroyItems(); void setItems(std::vector<Item *> *items);
void setPoints(std::vector<ViewInfo *> *scrollPoints, std::vector<AnimationEvents *> *tweenPoints); void destroyItems();
void setScrollDirection(ScrollDirection direction); void setPoints(std::vector<ViewInfo *> *scrollPoints, std::vector<AnimationEvents *> *tweenPoints);
void pageUp(); void setScrollDirection(ScrollDirection direction);
void pageDown(); unsigned int getSelectedIndex();
void letterUp(); unsigned int getSize();
void letterDown(); void pageUp();
bool isIdle(); void pageDown();
void letterUp();
void letterDown();
void letterChange(bool increment);
void random();
bool isIdle();
unsigned int getScrollOffsetIndex(); unsigned int getScrollOffsetIndex();
void setScrollOffsetIndex(unsigned int index); void setScrollOffsetIndex(unsigned int index);
void setSelectedIndex(int selectedIndex); void setSelectedIndex(int selectedIndex);
ComponentItemBinding *getSelectedCollectionItemSprite(); Item *getItemByOffset(int offset);
ComponentItemBinding *getPendingCollectionItemSprite(); void addComponentForNotifications(MenuNotifierInterface *c);
ComponentItemBinding *getPendingSelectedCollectionItemSprite(); void removeComponentForNotifications(MenuNotifierInterface *c);
void addComponentForNotifications(MenuNotifierInterface *c); void freeGraphicsMemory();
void removeComponentForNotifications(MenuNotifierInterface *c); void update(float dt);
std::vector<ComponentItemBinding *> *getCollectionItemSprites(); void draw();
void removeSelectedItem(); void draw(unsigned int layer);
void freeGraphicsMemory(); void setScrollAcceleration(float value);
void update(float dt); void setStartScrollTime(float value);
void draw(); bool horizontalScroll;
void draw(unsigned int layer); void deallocateSpritePoints();
void setScrollAcceleration(float value); void allocateSpritePoints();
void setStartScrollTime(float value);
bool horizontalScroll;
private:
private: void click(double nextScrollTime);
void click(double nextScrollTime); void resetTweens(Component *c, AnimationEvents *sets, ViewInfo *currentViewInfo, ViewInfo *nextViewInfo, double scrollTime);
void deallocateSpritePoints(); unsigned int loopIncrement(unsigned int offset, unsigned int i, unsigned int size);
void allocateSpritePoints(); unsigned int loopDecrement(unsigned int offset, unsigned int i, unsigned int size);
void updateSprite(unsigned int spriteIndex, unsigned int pointIndex, bool newScroll, float dt, double nextScrollTime);
unsigned int getNextTween(unsigned int currentIndex, std::vector<ViewInfo *> *list); enum ScrollState
void resetTweens(Component *c, AnimationEvents *sets, ViewInfo *currentViewInfo, ViewInfo *nextViewInfo, double scrollTime); {
ScrollStateActive,
enum ScrollState ScrollStatePageChange,
{ ScrollStateStopping,
ScrollStateActive, ScrollStateIdle
ScrollStatePageChange, };
ScrollStateStopping,
ScrollStateIdle std::vector<Component *> *spriteList_;
}; std::vector<ViewInfo *> *scrollPoints_;
std::vector<AnimationEvents *> *tweenPoints_;
std::vector<ComponentItemBinding *> *spriteList_; std::vector<MenuNotifierInterface *> notificationComponents_;
std::vector<ViewInfo *> *scrollPoints_; bool focus_;
std::vector<AnimationEvents *> *tweenPoints_;
std::vector<MenuNotifierInterface *> notificationComponents_; unsigned int itemIndex_;
float tweenEnterTime_; unsigned int componentIndex_;
bool focus_; unsigned int selectedOffsetIndex_;
unsigned int firstSpriteIndex_; bool scrollStopRequested_;
unsigned int selectedSpriteListIndex_; bool notifyAllRequested_;
bool scrollStopRequested_;
bool notifyAllRequested_; ScrollDirection currentScrollDirection_;
ScrollDirection currentScrollDirection_; ScrollDirection requestedScrollDirection_;
ScrollDirection requestedScrollDirection_; ScrollState currentScrollState_;
ScrollState currentScrollState_;
float scrollAcceleration_; float scrollAcceleration_;
float startScrollTime_; float startScrollTime_;
float scrollPeriod_; float scrollPeriod_;
int circularIncrement(unsigned int index, unsigned int offset, std::vector<ComponentItemBinding *> *list); Configuration &config_;
void circularIncrement(unsigned &index, std::vector<ComponentItemBinding *> *list); float scaleX_;
void circularDecrement(unsigned &index, std::vector<ComponentItemBinding *> *list); float scaleY_;
void circularIncrement(unsigned &index, std::vector<ViewInfo *> *list); Font *fontInst_;
void circularDecrement(unsigned &index, std::vector<ViewInfo *> *list); std::string layoutKey_;
void updateOffset(float dt); std::string imageType_;
std::string collection_;
Configuration &config_; std::vector<Item *> *items_;
float scaleX_; std::vector<Component *> components_;
float scaleY_;
Font *fontInst_;
std::string layoutKey_; };
std::string imageType_;
};

View File

@@ -20,8 +20,9 @@
#include "../Font.h" #include "../Font.h"
#include <sstream> #include <sstream>
Text::Text(std::string text, Font *font, float scaleX, float scaleY) Text::Text(std::string text, Page &p, Font *font, float scaleX, float scaleY)
: textData_(text) : Component(p)
, textData_(text)
, fontInst_(font) , fontInst_(font)
, scaleX_(scaleX) , scaleX_(scaleX)
, scaleY_(scaleY) , scaleY_(scaleY)

View File

@@ -16,7 +16,7 @@
#pragma once #pragma once
#include "Component.h" #include "Component.h"
#include "../Page.h"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <vector> #include <vector>
@@ -26,7 +26,7 @@ class Text : public Component
{ {
public: public:
//todo: should have a Font flass that references fontcache, pass that in as an argument //todo: should have a Font flass that references fontcache, pass that in as an argument
Text(std::string text, Font *font, float scaleX, float scaleY); Text(std::string text, Page &p, Font *font, float scaleX, float scaleY);
virtual ~Text(); virtual ~Text();
void setText(std::string text); void setText(std::string text);
void allocateGraphicsMemory(); void allocateGraphicsMemory();

View File

@@ -21,7 +21,7 @@
#include <fstream> #include <fstream>
VideoComponent * VideoBuilder::createVideo(std::string path, std::string name, float scaleX, float scaleY) VideoComponent * VideoBuilder::createVideo(std::string path, Page &page, std::string name, float scaleX, float scaleY)
{ {
VideoComponent *component = NULL; VideoComponent *component = NULL;
std::vector<std::string> extensions; std::vector<std::string> extensions;
@@ -40,7 +40,7 @@ VideoComponent * VideoBuilder::createVideo(std::string path, std::string name, f
if(video) if(video)
{ {
component = new VideoComponent(video, file, scaleX, scaleY); component = new VideoComponent(video, page, file, scaleX, scaleY);
} }
} }

View File

@@ -17,13 +17,14 @@
#include "Image.h" #include "Image.h"
#include "VideoComponent.h" #include "VideoComponent.h"
#include "../Page.h"
#include "../../Video/VideoFactory.h" #include "../../Video/VideoFactory.h"
//todo: this is more of a factory than a builder //todo: this is more of a factory than a builder
class VideoBuilder class VideoBuilder
{ {
public: public:
VideoComponent * createVideo(std::string path, std::string name, float scaleX, float scaleY); VideoComponent * createVideo(std::string path, Page &page, std::string name, float scaleX, float scaleY);
private: private:
VideoFactory factory_; VideoFactory factory_;

View File

@@ -20,8 +20,9 @@
#include "../../Utility/Log.h" #include "../../Utility/Log.h"
#include "../../SDL.h" #include "../../SDL.h"
VideoComponent::VideoComponent(IVideo *videoInst, std::string videoFile, float scaleX, float scaleY) VideoComponent::VideoComponent(IVideo *videoInst, Page &p, std::string videoFile, float scaleX, float scaleY)
: videoFile_(videoFile) : Component(p)
, videoFile_(videoFile)
, videoInst_(videoInst) , videoInst_(videoInst)
, scaleX_(scaleX) , scaleX_(scaleX)
, scaleY_(scaleY) , scaleY_(scaleY)

View File

@@ -16,6 +16,7 @@
#pragma once #pragma once
#include "Component.h" #include "Component.h"
#include "Image.h" #include "Image.h"
#include "../Page.h"
#include "../../Collection/Item.h" #include "../../Collection/Item.h"
#include "../../Video/IVideo.h" #include "../../Video/IVideo.h"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
@@ -24,7 +25,7 @@
class VideoComponent : public Component class VideoComponent : public Component
{ {
public: public:
VideoComponent(IVideo *videoInst, std::string videoFile, float scaleX, float scaleY); VideoComponent(IVideo *videoInst, Page &p, std::string videoFile, float scaleX, float scaleY);
virtual ~VideoComponent(); virtual ~VideoComponent();
void update(float dt); void update(float dt);
void draw(); void draw();

View File

@@ -145,7 +145,7 @@ bool Font::initialize(std::string fontPath, int fontSize, SDL_Color color)
SDL_LockMutex(SDL::getMutex()); SDL_LockMutex(SDL::getMutex());
texture = SDL_CreateTextureFromSurface(SDL::getRenderer(), atlasSurface); texture = SDL_CreateTextureFromSurface(SDL::getRenderer(), atlasSurface);
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_ADD); SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
SDL_FreeSurface(atlasSurface); SDL_FreeSurface(atlasSurface);
SDL_UnlockMutex(SDL::getMutex()); SDL_UnlockMutex(SDL::getMutex());

View File

@@ -23,17 +23,18 @@
#include "Component/ScrollingList.h" #include "Component/ScrollingList.h"
#include "../Sound/Sound.h" #include "../Sound/Sound.h"
#include "ComponentItemBindingBuilder.h" #include "ComponentItemBindingBuilder.h"
#include <algorithm>
#include <sstream> #include <sstream>
Page::Page(Configuration &config) Page::Page(Configuration &config)
: config_(config) : config_(config)
, activeMenu_(NULL) , activeMenu_(NULL)
, menuDepth_(0) , menuDepth_(0)
, items_(NULL)
, scrollActive_(false) , scrollActive_(false)
, selectedItem_(NULL) , selectedItem_(NULL)
, textStatusComponent_(NULL) , textStatusComponent_(NULL)
, selectedItemChanged_(false) , selectedItemChanged_(false)
, playlistChanged_(false)
, loadSoundChunk_(NULL) , loadSoundChunk_(NULL)
, unloadSoundChunk_(NULL) , unloadSoundChunk_(NULL)
, highlightSoundChunk_(NULL) , highlightSoundChunk_(NULL)
@@ -43,6 +44,11 @@ Page::Page(Configuration &config)
} }
Page::~Page() Page::~Page()
{
}
void Page::DeInitialize()
{ {
MenuVector_T::iterator it = menus_.begin(); MenuVector_T::iterator it = menus_.begin();
while(it != menus_.end()) while(it != menus_.end())
@@ -89,6 +95,19 @@ Page::~Page()
delete selectSoundChunk_; delete selectSoundChunk_;
selectSoundChunk_ = NULL; selectSoundChunk_ = NULL;
} }
CollectionVector_T::iterator itc = collections_.begin();
while(itc != collections_.end())
{
itc->collection->Save();
if(itc->collection)
{
delete itc->collection;
}
collections_.erase(itc);
itc = collections_.begin();
}
} }
@@ -278,6 +297,12 @@ Item *Page::getSelectedItem()
return selectedItem_; return selectedItem_;
} }
Item *Page::getSelectedItem(int offset)
{
return activeMenu_->getItemByOffset(offset);
}
void Page::removeSelectedItem() void Page::removeSelectedItem()
{ {
/* /*
@@ -315,25 +340,39 @@ float Page::getMinShowTime()
return minShowTime_; return minShowTime_;
} }
void Page::playlistChange()
{
if(activeMenu_)
{
activeMenu_->triggerPlaylistChangeEvent(playlist_->first);
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->triggerPlaylistChangeEvent(playlist_->first);
}
}
}
void Page::highlight() void Page::highlight()
{ {
Item *item = selectedItem_; Item *item = selectedItem_;
if(item) if(!item) return;
if(activeMenu_)
{ {
if(activeMenu_) activeMenu_->triggerHighlightEvent();
{ activeMenu_->scrollActive = scrollActive_;
activeMenu_->triggerHighlightEvent(item); }
activeMenu_->scrollActive = scrollActive_;
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i) for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{ {
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) (*it)->triggerHighlightEvent();
{ (*it)->scrollActive = scrollActive_;
(*it)->triggerHighlightEvent(item);
(*it)->scrollActive = scrollActive_;
}
} }
} }
} }
@@ -392,6 +431,11 @@ void Page::pageScroll(ScrollDirection direction)
} }
} }
void Page::selectRandom()
{
if(activeMenu_) activeMenu_->random();
}
void Page::letterScroll(ScrollDirection direction) void Page::letterScroll(ScrollDirection direction)
{ {
if(activeMenu_) if(activeMenu_)
@@ -407,11 +451,19 @@ void Page::letterScroll(ScrollDirection direction)
} }
} }
unsigned int Page::getCollectionSize()
{
return activeMenu_->getSize();
}
unsigned int Page::getSelectedIndex()
{
return activeMenu_->getSelectedIndex();
}
bool Page::pushCollection(CollectionInfo *collection) bool Page::pushCollection(CollectionInfo *collection)
{ {
collections_.push_back(collection);
std::vector<ComponentItemBinding *> *sprites = ComponentItemBindingBuilder::buildCollectionItems(&collection->items);
int menuExitIndex = -1; int menuExitIndex = -1;
int menuEnterIndex = -1; int menuEnterIndex = -1;
@@ -426,19 +478,31 @@ bool Page::pushCollection(CollectionInfo *collection)
menuExitIndex = menuDepth_ - 1; menuExitIndex = menuDepth_ - 1;
} }
// grow the menu as needed
if(menus_.size() >= menuDepth_ && activeMenu_) if(menus_.size() >= menuDepth_ && activeMenu_)
{ {
ScrollingList *newList = new ScrollingList(*activeMenu_); activeMenu_ = new ScrollingList(*activeMenu_);
newList->forceIdle(); activeMenu_->forceIdle();
pushMenu(newList); pushMenu(activeMenu_);
} }
activeMenu_ = menus_[menuDepth_]; activeMenu_ = menus_[menuDepth_];
activeMenu_->collectionName = collection->name; activeMenu_->collectionName = collection->name;
activeMenu_->destroyItems(); activeMenu_->setItems(&collection->items);
activeMenu_->setItems(sprites);
activeMenu_->triggerMenuEnterEvent(); activeMenu_->triggerMenuEnterEvent();
// build the collection info instance
MenuInfo_S info;
info.collection = collection;
info.menu = activeMenu_;
info.playlist = collection->playlists.begin();
info.queueDelete = false;
collections_.push_back(info);
playlist_ = info.playlist;
playlistChanged_ = true;
if(menuDepth_ < menus_.size()) if(menuDepth_ < menus_.size())
{ {
menuEnterIndex = menuDepth_; menuEnterIndex = menuDepth_;
@@ -469,22 +533,26 @@ bool Page::popCollection()
{ {
int menuExitIndex = -1; int menuExitIndex = -1;
int menuEnterIndex = -1; int menuEnterIndex = -1;
CollectionInfo *collection = NULL;
if(menuDepth_ <= 1)
{
return false;
}
if(collections_.size() <= 1)
{
return false;
}
if(!activeMenu_) return false;
if(menuDepth_ <= 1) return false;
if(collections_.size() <= 1) return false;
// queue the collection for deletion
MenuInfo_S *info = &collections_.back();
info->queueDelete = true;
deleteCollections_.push_back(*info);
// get the next collection off of the stack
collections_.pop_back(); collections_.pop_back();
collection = collections_.back(); info = &collections_.back();
playlist_ = info->playlist;
playlistChanged_ = true;
if(activeMenu_) if(activeMenu_)
{ {
activeMenu_->triggerMenuExitEvent(); activeMenu_->triggerMenuExitEvent();
} }
menuDepth_--; menuDepth_--;
@@ -500,7 +568,7 @@ bool Page::popCollection()
{ {
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{ {
(*it)->collectionName = collection->name; (*it)->collectionName = info->collection->name;
if(menuEnterIndex >= 0) if(menuEnterIndex >= 0)
{ {
@@ -517,6 +585,54 @@ bool Page::popCollection()
return true; return true;
} }
void Page::nextPlaylist()
{
MenuInfo_S &info = collections_.back();
info.collection->Save();
unsigned int numlists = info.collection->playlists.size();
for(unsigned int i = 0; i <= numlists; ++i)
{
playlist_++;
// wrap
if(playlist_ == info.collection->playlists.end()) playlist_ = info.collection->playlists.begin();
// find the first playlist
if(playlist_->second->size() != 0) break;
}
activeMenu_->setItems(playlist_->second);
activeMenu_->triggerMenuEnterEvent();
playlistChanged_ = true;
}
void Page::favPlaylist()
{
MenuInfo_S &info = collections_.back();
info.collection->Save();
unsigned int numlists = info.collection->playlists.size();
// Store current playlist
CollectionInfo::Playlists_T::iterator playlist_store = playlist_;
for(unsigned int i = 0; i <= numlists; ++i)
{
playlist_++;
// wrap
if(playlist_ == info.collection->playlists.end()) playlist_ = info.collection->playlists.begin();
// find the first playlist
if(playlist_->second->size() != 0 && playlist_->first == "favorites") break;
}
// Do not change playlist if favorites does not exist or if it's empty
if ( playlist_->second->size() == 0 || playlist_->first != "favorites")
playlist_ = playlist_store;
activeMenu_->setItems(playlist_->second);
activeMenu_->triggerMenuEnterEvent();
playlistChanged_ = true;
}
void Page::update(float dt) void Page::update(float dt)
{ {
@@ -526,6 +642,12 @@ void Page::update(float dt)
menu->update(dt); menu->update(dt);
} }
if(playlistChanged_)
{
playlistChange();
playlistChanged_ = false;
}
if(selectedItemChanged_ && !scrollActive_) if(selectedItemChanged_ && !scrollActive_)
{ {
@@ -544,7 +666,33 @@ void Page::update(float dt)
{ {
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{ {
(*it)->update(dt); if(*it) (*it)->update(dt);
}
}
// many nodes still have handles on the collection info. We need to delete
// them once everything is done using them
std::list<MenuInfo_S>::iterator del = deleteCollections_.begin();
while(del != deleteCollections_.end())
{
MenuInfo_S &info = *del;
if(info.queueDelete && info.menu && info.menu->isIdle())
{
std::list<MenuInfo_S>::iterator next = del;
++next;
if(info.collection)
{
info.collection->Save();
delete info.collection;
}
deleteCollections_.erase(del);
del = next;
}
else
{
++del;
} }
} }
} }
@@ -555,7 +703,7 @@ void Page::draw()
{ {
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{ {
(*it)->draw(); if(*it && (*it)->baseViewInfo.Layer == i) (*it)->draw();
} }
for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++) for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++)
@@ -567,16 +715,58 @@ void Page::draw()
} }
void Page::removePlaylist()
{
if(!selectedItem_) return;
if(!selectedItem_->leaf) return;
MenuInfo_S &info = collections_.back();
CollectionInfo *collection = info.collection;
std::vector<Item *> *items = collection->playlists["favorites"];
std::vector<Item *>::iterator it = std::find(items->begin(), items->end(), selectedItem_);
if(it != items->end())
{
items->erase(it);
collection->saveRequest = true;
if(activeMenu_)
{
activeMenu_->deallocateSpritePoints();
activeMenu_->allocateSpritePoints();
}
}
}
void Page::addPlaylist()
{
if(!selectedItem_) return;
if(!selectedItem_->leaf) return;
MenuInfo_S &info = collections_.back();
CollectionInfo *collection = info.collection;
std::vector<Item *> *items = collection->playlists["favorites"];
if(playlist_->first != "favorites" && std::find(items->begin(), items->end(), selectedItem_) == items->end())
{
items->push_back(selectedItem_);
collection->saveRequest = true;
if(activeMenu_)
{
activeMenu_->deallocateSpritePoints();
activeMenu_->allocateSpritePoints();
}
}
}
std::string Page::getCollectionName() std::string Page::getCollectionName()
{ {
CollectionInfo *info = collections_.back(); if(collections_.size() == 0) return "";
if(info) MenuInfo_S &info = collections_.back();
{ return info.collection->name;
return info->name;
}
return "";
} }
void Page::freeGraphicsMemory() void Page::freeGraphicsMemory()

View File

@@ -16,13 +16,13 @@
#pragma once #pragma once
#include "MenuNotifierInterface.h" #include "MenuNotifierInterface.h"
#include "../Collection/CollectionInfo.h"
#include <map> #include <map>
#include <string> #include <string>
#include <list> #include <list>
#include <vector> #include <vector>
class CollectionInfo;
class Component; class Component;
class Configuration; class Configuration;
class ScrollingList; class ScrollingList;
@@ -43,9 +43,12 @@ public:
Page(Configuration &c); Page(Configuration &c);
virtual ~Page(); virtual ~Page();
void DeInitialize();
virtual void onNewItemSelected(Item *); virtual void onNewItemSelected(Item *);
bool pushCollection(CollectionInfo *collection); bool pushCollection(CollectionInfo *collection);
bool popCollection(); bool popCollection();
void nextPlaylist();
void favPlaylist();
void pushMenu(ScrollingList *s); void pushMenu(ScrollingList *s);
bool isMenusFull(); bool isMenusFull();
void setLoadSound(Sound *chunk); void setLoadSound(Sound *chunk);
@@ -55,6 +58,9 @@ public:
bool addComponent(Component *c); bool addComponent(Component *c);
void pageScroll(ScrollDirection direction); void pageScroll(ScrollDirection direction);
void letterScroll(ScrollDirection direction); void letterScroll(ScrollDirection direction);
unsigned int getCollectionSize();
unsigned int getSelectedIndex();
void selectRandom();
void start(); void start();
void startComponents(); void startComponents();
void stop(); void stop();
@@ -62,6 +68,7 @@ public:
bool isHorizontalScroll(); bool isHorizontalScroll();
unsigned int getMenuDepth(); unsigned int getMenuDepth();
Item *getSelectedItem(); Item *getSelectedItem();
Item *getSelectedItem(int offset);
void removeSelectedItem(); void removeSelectedItem();
void setScrollOffsetIndex(unsigned int i); void setScrollOffsetIndex(unsigned int i);
unsigned int getScrollOffsetIndex(); unsigned int getScrollOffsetIndex();
@@ -78,33 +85,50 @@ public:
std::string getCollectionName(); std::string getCollectionName();
void setMinShowTime(float value); void setMinShowTime(float value);
float getMinShowTime(); float getMinShowTime();
void addPlaylist();
void removePlaylist();
private: private:
void highlight(); void highlight();
void playlistChange();
std::string collectionName_; std::string collectionName_;
Configuration &config_; Configuration &config_;
struct MenuInfo_S
{
CollectionInfo *collection;
ScrollingList *menu;
CollectionInfo::Playlists_T::iterator playlist;
bool queueDelete;
};
typedef std::vector<ScrollingList *> MenuVector_T; typedef std::vector<ScrollingList *> MenuVector_T;
typedef std::vector<CollectionInfo *> CollectionInfo_T; typedef std::list<MenuInfo_S> CollectionVector_T;
ScrollingList *activeMenu_; ScrollingList *activeMenu_;
unsigned int menuDepth_; unsigned int menuDepth_;
MenuVector_T menus_; MenuVector_T menus_;
CollectionInfo_T collections_; CollectionVector_T collections_;
CollectionVector_T deleteCollections_;
static const unsigned int NUM_LAYERS = 8; static const unsigned int NUM_LAYERS = 20;
std::vector<Component *> LayerComponents[NUM_LAYERS]; std::vector<Component *> LayerComponents[NUM_LAYERS];
std::vector<Item *> *items_; std::list<ScrollingList *> deleteMenuList_;
std::list<CollectionInfo *> deleteCollectionList_;
bool scrollActive_; bool scrollActive_;
Item *selectedItem_; Item *selectedItem_;
Text *textStatusComponent_; Text *textStatusComponent_;
bool selectedItemChanged_; bool selectedItemChanged_;
bool playlistChanged_;
Sound *loadSoundChunk_; Sound *loadSoundChunk_;
Sound *unloadSoundChunk_; Sound *unloadSoundChunk_;
Sound *highlightSoundChunk_; Sound *highlightSoundChunk_;
Sound *selectSoundChunk_; Sound *selectSoundChunk_;
float minShowTime_; float minShowTime_;
float elapsedTime_; float elapsedTime_;
CollectionInfo::Playlists_T::iterator playlist_;
}; };

View File

@@ -320,13 +320,13 @@ bool PageBuilder::buildComponents(xml_node<> *layout, Page *page)
{ {
for(xml_node<> *componentXml = layout->first_node("menu"); componentXml; componentXml = componentXml->next_sibling("menu")) for(xml_node<> *componentXml = layout->first_node("menu"); componentXml; componentXml = componentXml->next_sibling("menu"))
{ {
ScrollingList *scrollingList = buildMenu(componentXml); ScrollingList *scrollingList = buildMenu(componentXml,*page);
page->pushMenu(scrollingList); page->pushMenu(scrollingList);
} }
for(xml_node<> *componentXml = layout->first_node("container"); componentXml; componentXml = componentXml->next_sibling("container")) for(xml_node<> *componentXml = layout->first_node("container"); componentXml; componentXml = componentXml->next_sibling("container"))
{ {
Container *c = new Container(); Container *c = new Container(*page);
buildViewInfo(componentXml, c->baseViewInfo); buildViewInfo(componentXml, c->baseViewInfo);
loadTweens(c, componentXml); loadTweens(c, componentXml);
page->addComponent(c); page->addComponent(c);
@@ -346,7 +346,7 @@ bool PageBuilder::buildComponents(xml_node<> *layout, Page *page)
std::string imagePath; std::string imagePath;
imagePath = Utils::combinePath(Configuration::convertToAbsolutePath(layoutPath, imagePath), std::string(src->value())); imagePath = Utils::combinePath(Configuration::convertToAbsolutePath(layoutPath, imagePath), std::string(src->value()));
Image *c = new Image(imagePath, scaleX_, scaleY_); Image *c = new Image(imagePath, *page, scaleX_, scaleY_);
buildViewInfo(componentXml, c->baseViewInfo); buildViewInfo(componentXml, c->baseViewInfo);
loadTweens(c, componentXml); loadTweens(c, componentXml);
page->addComponent(c); page->addComponent(c);
@@ -365,7 +365,7 @@ bool PageBuilder::buildComponents(xml_node<> *layout, Page *page)
else else
{ {
Font *font = addFont(componentXml, NULL); Font *font = addFont(componentXml, NULL);
Text *c = new Text(value->value(), font, scaleX_, scaleY_); Text *c = new Text(value->value(), *page, font, scaleX_, scaleY_);
buildViewInfo(componentXml, c->baseViewInfo); buildViewInfo(componentXml, c->baseViewInfo);
@@ -377,7 +377,7 @@ bool PageBuilder::buildComponents(xml_node<> *layout, Page *page)
for(xml_node<> *componentXml = layout->first_node("statusText"); componentXml; componentXml = componentXml->next_sibling("statusText")) for(xml_node<> *componentXml = layout->first_node("statusText"); componentXml; componentXml = componentXml->next_sibling("statusText"))
{ {
Font *font = addFont(componentXml, NULL); Font *font = addFont(componentXml, NULL);
Text *c = new Text("", font, scaleX_, scaleY_); Text *c = new Text("", *page, font, scaleX_, scaleY_);
buildViewInfo(componentXml, c->baseViewInfo); buildViewInfo(componentXml, c->baseViewInfo);
@@ -403,8 +403,9 @@ void PageBuilder::loadReloadableImages(xml_node<> *layout, std::string tagName,
std::string reloadableVideoPath; std::string reloadableVideoPath;
xml_attribute<> *type = componentXml->first_attribute("type"); xml_attribute<> *type = componentXml->first_attribute("type");
xml_attribute<> *mode = componentXml->first_attribute("mode"); xml_attribute<> *mode = componentXml->first_attribute("mode");
xml_attribute<> *selectedOffsetXml = componentXml->first_attribute("selectedOffset");
bool systemMode = false; bool systemMode = false;
int selectedOffset = 0;
if(tagName == "reloadableVideo") if(tagName == "reloadableVideo")
{ {
type = componentXml->first_attribute("imageType"); type = componentXml->first_attribute("imageType");
@@ -430,6 +431,13 @@ void PageBuilder::loadReloadableImages(xml_node<> *layout, std::string tagName,
} }
} }
if(selectedOffsetXml)
{
std::stringstream ss;
ss << selectedOffsetXml->value();
ss >> selectedOffset;
}
Component *c = NULL; Component *c = NULL;
@@ -438,13 +446,13 @@ void PageBuilder::loadReloadableImages(xml_node<> *layout, std::string tagName,
if(type) if(type)
{ {
Font *font = addFont(componentXml, NULL); Font *font = addFont(componentXml, NULL);
c = new ReloadableText(type->value(), font, layoutKey, scaleX_, scaleY_); c = new ReloadableText(type->value(), *page, config_, font, layoutKey, scaleX_, scaleY_);
} }
} }
else else
{ {
Font *font = addFont(componentXml, NULL); Font *font = addFont(componentXml, NULL);
c = new ReloadableMedia(config_, systemMode, type->value(), (tagName == "reloadableVideo"), font, scaleX_, scaleY_); c = new ReloadableMedia(config_, systemMode, type->value(), *page, selectedOffset, (tagName == "reloadableVideo"), font, scaleX_, scaleY_);
xml_attribute<> *textFallback = componentXml->first_attribute("textFallback"); xml_attribute<> *textFallback = componentXml->first_attribute("textFallback");
if(textFallback && Utils::toLower(textFallback->value()) == "true") if(textFallback && Utils::toLower(textFallback->value()) == "true")
@@ -564,7 +572,7 @@ void PageBuilder::buildTweenSet(AnimationEvents *tweens, xml_node<> *componentXm
} }
ScrollingList * PageBuilder::buildMenu(xml_node<> *menuXml) ScrollingList * PageBuilder::buildMenu(xml_node<> *menuXml, Page &page)
{ {
ScrollingList *menu = NULL; ScrollingList *menu = NULL;
std::string menuType = "vertical"; std::string menuType = "vertical";
@@ -596,7 +604,7 @@ ScrollingList * PageBuilder::buildMenu(xml_node<> *menuXml)
// on default, text will be rendered to the menu. Preload it into cache. // on default, text will be rendered to the menu. Preload it into cache.
Font *font = addFont(itemDefaults, NULL); Font *font = addFont(itemDefaults, NULL);
menu = new ScrollingList(config_, scaleX_, scaleY_, font, layoutKey, imageType); menu = new ScrollingList(config_, page, scaleX_, scaleY_, font, layoutKey, imageType);
if(scrollTimeXml) if(scrollTimeXml)
{ {

View File

@@ -58,7 +58,7 @@ private:
void loadTweens(Component *c, rapidxml::xml_node<> *componentXml); void loadTweens(Component *c, rapidxml::xml_node<> *componentXml);
AnimationEvents *createTweenInstance(rapidxml::xml_node<> *componentXml); AnimationEvents *createTweenInstance(rapidxml::xml_node<> *componentXml);
void buildTweenSet(AnimationEvents *tweens, rapidxml::xml_node<> *componentXml, std::string tagName, std::string tweenName); void buildTweenSet(AnimationEvents *tweens, rapidxml::xml_node<> *componentXml, std::string tagName, std::string tweenName);
ScrollingList * buildMenu(rapidxml::xml_node<> *menuXml); ScrollingList * buildMenu(rapidxml::xml_node<> *menuXml, Page &p);
void buildCustomMenu(ScrollingList *menu, rapidxml::xml_node<> *menuXml, rapidxml::xml_node<> *itemDefaults); void buildCustomMenu(ScrollingList *menu, rapidxml::xml_node<> *menuXml, rapidxml::xml_node<> *itemDefaults);
void buildVerticalMenu(ScrollingList *menu, rapidxml::xml_node<> *menuXml, rapidxml::xml_node<> *itemDefaults); void buildVerticalMenu(ScrollingList *menu, rapidxml::xml_node<> *menuXml, rapidxml::xml_node<> *itemDefaults);
int parseMenuPosition(std::string strIndex); int parseMenuPosition(std::string strIndex);

View File

@@ -24,12 +24,16 @@
#include <cstdlib> #include <cstdlib>
#include <fstream> #include <fstream>
#include <dirent.h> #include <dirent.h>
#include <time.h>
static bool ImportConfiguration(Configuration *c); static bool ImportConfiguration(Configuration *c);
static bool StartLogging(); static bool StartLogging();
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
// Initialize random seed
srand(static_cast<unsigned int>(time(0)));
Configuration::initialize(); Configuration::initialize();
Configuration config; Configuration config;

View File

@@ -178,6 +178,7 @@ bool RetroFE::deInitialize()
if(currentPage_) if(currentPage_)
{ {
currentPage_->DeInitialize();
delete currentPage_; delete currentPage_;
currentPage_ = NULL; currentPage_ = NULL;
} }
@@ -288,6 +289,7 @@ void RetroFE::run()
} }
// delete the splash screen and use the standard menu // delete the splash screen and use the standard menu
currentPage_->DeInitialize();
delete currentPage_; delete currentPage_;
currentPage_ = loadPage(); currentPage_ = loadPage();
@@ -389,7 +391,6 @@ void RetroFE::run()
render(); render();
} }
} }
} }
@@ -447,7 +448,11 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page)
if (!input_.keystate(UserInput::KeyCodePageUp) && if (!input_.keystate(UserInput::KeyCodePageUp) &&
!input_.keystate(UserInput::KeyCodePageDown) && !input_.keystate(UserInput::KeyCodePageDown) &&
!input_.keystate(UserInput::KeyCodeLetterUp) && !input_.keystate(UserInput::KeyCodeLetterUp) &&
!input_.keystate(UserInput::KeyCodeLetterDown)) !input_.keystate(UserInput::KeyCodeLetterDown) &&
!input_.keystate(UserInput::KeyCodeNextPlaylist) &&
!input_.keystate(UserInput::KeyCodeAddPlaylist) &&
!input_.keystate(UserInput::KeyCodeRemovePlaylist) &&
!input_.keystate(UserInput::KeyCodeRandom))
{ {
keyLastTime_ = 0; keyLastTime_ = 0;
keyDelayTime_= 0.3f; keyDelayTime_= 0.3f;
@@ -475,6 +480,22 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page)
{ {
page->letterScroll(Page::ScrollDirectionForward); page->letterScroll(Page::ScrollDirectionForward);
} }
if(input_.newKeyPressed(UserInput::KeyCodeNextPlaylist))
{
page->nextPlaylist();
}
if(input_.newKeyPressed(UserInput::KeyCodeRemovePlaylist))
{
page->removePlaylist();
}
if(input_.newKeyPressed(UserInput::KeyCodeAddPlaylist))
{
page->addPlaylist();
}
if(input_.keystate(UserInput::KeyCodeRandom))
{
page->selectRandom();
}
} }
if (input_.keystate(UserInput::KeyCodeAdminMode)) if (input_.keystate(UserInput::KeyCodeAdminMode))
@@ -508,6 +529,12 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page)
page->setScrollOffsetIndex(lastMenuOffsets_[nextPageItem_->name]); page->setScrollOffsetIndex(lastMenuOffsets_[nextPageItem_->name]);
} }
bool autoFavorites = true;
config_.getProperty("autoFavorites", autoFavorites);
if (autoFavorites)
page->favPlaylist(); // Switch to favorites if it exists
state = RETROFE_NEXT_PAGE_REQUEST; state = RETROFE_NEXT_PAGE_REQUEST;
} }
} }

View File

@@ -194,11 +194,8 @@ void Utils::replaceSlashesWithUnderscores(std::string &content)
std::string Utils::getDirectory(std::string filePath) std::string Utils::getDirectory(std::string filePath)
{ {
#ifdef WIN32
filePath = Utils::replace(filePath, "/", "\\");
#endif
std::string directory = filePath; std::string directory = filePath;
const size_t last_slash_idx = filePath.rfind(pathSeparator); const size_t last_slash_idx = filePath.rfind(pathSeparator);
if (std::string::npos != last_slash_idx) if (std::string::npos != last_slash_idx)
{ {
@@ -210,9 +207,6 @@ std::string Utils::getDirectory(std::string filePath)
std::string Utils::getParentDirectory(std::string directory) std::string Utils::getParentDirectory(std::string directory)
{ {
#ifdef WIN32
directory = Utils::replace(directory, "/", "\\");
#endif
size_t last_slash_idx = directory.find_last_of(pathSeparator); size_t last_slash_idx = directory.find_last_of(pathSeparator);
if(directory.length() - 1 == last_slash_idx) if(directory.length() - 1 == last_slash_idx)
{ {
@@ -231,9 +225,6 @@ std::string Utils::getParentDirectory(std::string directory)
std::string Utils::getFileName(std::string filePath) std::string Utils::getFileName(std::string filePath)
{ {
#ifdef WIN32
filePath = Utils::replace(filePath, "/", "\\");
#endif
std::string filename = filePath; std::string filename = filePath;