Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Kartik Thakore July 25, 2011
file 4604 lines (3358 sloc) 155.094 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603
<h1>Preface</h1>

<p><a name="libsdl"> </p>

<p><i>Simple DirectMedia Layer</i> (or <i>libsdl</i>) is a cross-platform C
library that provides access to several input and output devices. Its most
popular usage is to provide access to the video framebuffer and input
devices for games. SDL also has several extension libraries to provide
features such as text display, sound mixing, image handling, and graphics
effects.</p>

<p> </p>

<p>SDL Perl binds several of these libraries together in the
<code>SDL::*</code> namespace. Moreover, SDL Perl provides several
high-level libraries in the <code>SDLx::*</code> namespace that encapsulate
valuable game-writing abstractions.</p>

<p></p>

<h2><code>SDL</code> and <code>SDLx</code></h2>

<p>The main purpose of the <code>SDLx::*</code> layer is to smooth out the
drudgery of using the <code>SDL::*</code> layer directly.</p>

<p></p>

<blockquote>

<p>Don't worry about understanding the details of this code right now.
Compare the complexity and size of the code listings.</p>

</blockquote>

<p>Using the <code>SDL::*</code> layer to draw a blue rectangle looks
something like:</p>

<pre><code> use SDL;
    use SDL::Video;
    use SDL::Surface;
    use SDL::Rect;

    # the size of the window box or the screen resolution if fullscreen
    my $screen_width = 800;
    my $screen_height = 600;

    SDL::init(SDL_INIT_VIDEO);

    # setting video mode
    my $screen_surface = SDL::Video::set_video_mode($screen_width,
                                                    $screen_height,
                                                    32,
                                                    SDL_ANYFORMAT);

    # drawing a rectangle with the blue color
    my $mapped_color = SDL::Video::map_RGB($screen_surface-&gt;format(),
                                              0, 0, 255);
    SDL::Video::fill_rect($screen_surface,
                          SDL::Rect-&gt;new($screen_width / 4, $screen_height / 4,
                                         $screen_width / 2, $screen_height / 2),
                          $mapped_color);

    # update an area on the screen so it&#39;s visible
    SDL::Video::update_rect($screen_surface, 0, 0,
                            $screen_width, $screen_height);

    # just to have time to see it
    sleep(5);</code></pre>

<p>... while drawing a blue rectangle in the <code>SDLx::*</code> layer is
as simple as:</p>

<pre><code> use strict;
    use warnings;

    use SDL;
    use SDLx::App;

    my $app = SDLx::App-&gt;new( width=&gt; 800, height =&gt; 600 );

    $app-&gt;draw_rect([ $app-&gt;width / 4, $app-&gt;height / 4,
                      $app-&gt;width / 2, $app-&gt;height / 2, ],
                      [ 0, 0, 255, 255] );

    $app-&gt;update();

    sleep(5);</code></pre>

<p>The <code>SDLx::*</code> modules also provide and manage higher-level
concerns for users, such as layers and game loops.</p>

<h2>About the Book</h2>

<p>This book has a two-fold purpose: first, to introduce game development
to Perl programmers, and second, to introduce Modern Perl concepts through
game development. While the examples assume some experience with Perl, no
experience with SDL in Perl or as <code>libsdl</code> itself is
necessary.</p>

<p>The book presents a progression from simple to intermediate examples and
provides suggestions for more advanced endeavors. The chapters of this book
increase progressively in complexity, but each chapter has a singular goal
(such as chapter five's <i>Making Pong</i>) which stands alone as an
individual tutorial. Sources and data files are all available from
http://sdl.perl.org/.</p>

<h2>Installing SDL Perl</h2>

<p></p>

<p>We assume the presence of a recent version of the Perl language (at
least Perl 5.10) and supporting packages. We also assume that you can
install packages from the CPAN, including SDL Perl itself.</p>

<h3>Windows</h3>

<p> </p>

<p><code>Alien::SDL</code> will install binaries for 32bit and 64bit so
there is no need to compile anything.</p>

<h3>Mac OS X</h3>

<p> </p>

<p>Fink has packages for SDL Perl available. However, they do not support
Pango, a library which provides internalization support for text
handling.</p>

<p>Installing <code>Alien::SDL</code> from the CPAN will compile SDL and
its dependencies, provided you have installed severan necessary
dependencies. We recommend that you install <code>libfreetype6</code>,
<code>libX11</code>, <code>libvorbis</code>, <code>libogg</code>,
<code>libpng</code>, and their headers.</p>

<h3>GNU/Linux</h3>

<p> </p>

<p>Most current GNU/Linux distributions include all the parts needed for
this tutorial in the default install and in their package management
system. It is also always possible to install on GNU/Linux using the
available open source code from the proper repositories. The
<code>Alien::SDL</code> perl module automates much of downloading,
compiling, and installing the needed libraries.</p>

<p>You can probably use your distribution's packages. On Ubuntu and Debian
try:</p>

<pre><code> $ sudo apt-get install libsdl-net1.2-dev libsdl-mixer1.2-dev \
    libsdl1.2-dev libsdl-image1.2-dev libsdl-ttf2.0-dev \
    libsdl-gfx1.2-dev libsdl-pango-dev</code></pre>

<p>To compile from scratch, you must install a compiler, system header
packages, and some libraries are required.</p>

<pre><code> $ sudo apt-get install build-essential xorg-dev libx11-dev libxv-dev \
    libpango1.0-dev libfreetype6-dev libvorbis-dev libpng12-dev \
    libogg-dev</code></pre>

<h3>CPAN install</h3>

<p></p>

<p>Before installing SDL Perl, ensure that you have the most recent
versions of the modules necessary to build SDL:</p>

<pre><code> $ sudo cpan CPAN
    $ sudo cpan YAML Module::Build</code></pre>

<p>After these two steps CPAN will be able to install SDL:</p>

<pre><code> $ sudo cpan SDL</code></pre>

<p>For most platforms a CPAN install will suffice. Supported and tested
platforms are listed at http://pass.cpantesters.org/distro/S/SDL.html.</p>

<h2>Contact</h2>

<p></p>

<p>Hopefully this book answers most of your questions. For additional
assistance, contact the project via:</p>

<ul>

<li><i>the web</i>, by visiting the SDL Perl homepage at
http://sdl.perl.org/.</li>

<li><i>IRC</i>, in the <code>#sdl</code> channel on
<code>irc.perl.org</code>. This is a very active and helpful resource.</li>

<li><i>email</i>, through the <code>sdl-devel@perl.org</code> mailing
list.</li>

</ul>

<h2>Examples</h2>

<p></p>

<p>The code examples in this book are available from
https://github.com/PerlGameDev/SDL_Manual/tree/master/code_listings.</p>

<h2>Acknowledgements</h2>

<p>Thanks to contributors and reviewers from the <code>#sdl</code> channel,
including:</p>

<ul>

<li>Alias

<li>bobross

<li>Blaizer

<li>cfedde

<li>chromatic

<li>FROGGS

<li>garu

<li>jamesw

<li>perlpilot

<li>PerlJam

<li>Pip

<li>waxhead

<li>and many more

<pre><code> (Apologies if I have missed you; let me know and I will add you.)</code></pre>

</ul>

<h1>The Screen</h1>

<p> </p>

<p>SDL's primary purpose is to display graphics. It does so by providing an
abstraction called a <i>screen</i>, which represents a <i>video device</i>.
This video device is an interface provided by your operating system, such
as X11 or DirectX. Before you can display anything, you must create a
screen. The <code>SDLx::App</code> class does so for you:</p>

<pre><code> use strict;
    use warnings;
    use SDL;
    use SDLx::App;

    my $app = SDLx::App-&gt;new();

    sleep( 2 );</code></pre>

<p>This example causes an empty window to appear on the desktop. Most
systems will fill that window with the color black. Other systems might
display a transparent window. SDL's default behavior is to fill the screen
with black. To enforce this behavior on all systems, you must
<code>update()</code> the app to draw to the window:</p>

<pre><code> $app-&gt;update();</code></pre>

<h2><code>SDLx::App</code> Options</h2>

<p> </p>

<p><code>SDLx::App</code> allows you to specify several options for the
screen and your application. First are the physical dimensions of the
screen itself. To make the screen of the <code>SDLx::App</code> window a
400×400 pixel square, change the initialization line to:</p>

<pre><code> my $app = SDLx::App-&gt;new( width =&gt; 400, height =&gt; 400 );</code></pre>

<p>Another important option is the window's title. Some systems display the
path to the running program. Others leave the title blank. You can change
the displayed title with another argument to the <code>SDLx::App</code>
constructor:</p>

<p></p>

<pre><code> my $app = SDLx::App-&gt;new( width =&gt; 400,
                              height =&gt; 400,
                              title =&gt; &#39;Pong - A clone&#39; );</code></pre>

<p>At this point your screen will be:</p>

<p>\includegraphics[width=0.5\textwidth]{../src/images/first.png}
\caption{Your first SDL screen!} \label{fig:first_screen}</p>



<h3>Shortcuts</h3>

<p></p>

<p>Abbreviations for these parameters are available. Instead of
<code>width</code>, <code>height</code>, and <code>title</code>, you may
use <code>w</code>, <code>h</code>, and <code>t</code> respectively. The
previous example could also be written:</p>

<pre><code> my $app = SDLx::App-&gt;new( w =&gt; 400,
                              h =&gt; 400,
                              t =&gt; &#39;Pong - A clone&#39; );</code></pre>

<h1>Drawing</h1>

<p></p>

<p>SDL provides several ways to draw graphical elements on the screen in
three general categories: primitives, images, and text. All drawing occurs
on a surface, represented by the <code>SDLx::Surface</code> class. Even the
<code>SDLx::App</code> is an <code>SDLx::Surface</code>. Though this means
it's possible to draw directly to the app's surface, there are several
advantages to drawing on multiple surfaces.</p>

<h2>Coordinates</h2>

<p></p>

<p>SDL's surface coordinate system has its origin (where both the x and y
coordinates have the value of zero) in the upper left corner. As the value
of x increases, the position moves to the right of the origin. As the value
of y increases, the position moves downward from the origin. The API always
lists coordinates in x, y order.</p>

<blockquote>

<p>The SDL library documentation has an extended discussion on coordinates:
http://sdltutorials.com/sdl-coordinates-and-blitting.</p>

</blockquote>

<p></p>

<h2>Drawing with SDL</h2>

<p>You can produce original pictures knowing little more than how to draw
to a surface with SDL:</p>

<p>\includegraphics[width=0.5\textwidth]{../src/images/flower.png}
\caption{A field of flowers} \label{fig:flowers}</p>



<h3>Surface Drawing Methods</h3>

<p>As mentioned earlier, all drawing in SDL requires a surface. The
<code>SDLx::Surface</code> object provides access to methods in the form
of:</p>

<pre><code> $surface-&gt;draw_{something}( .... );</code></pre>

<p>Parameters to these methods are generally coordinates and colors,
provided as array references.</p>

<p></p>

<h4>Rectangular Parameters</h4>

<p>Some parameters are sets of coordinate positions and dimensions. For
example, parameters to describe a rectangle of <code>40x40</code> pixels
placed at <code>(20, 20)</code> pixel units on the screen make a
four-element array reference of x, y, width, height:</p>

<pre><code> my $rect = [20, 20, 40, 40];</code></pre>

<p></p>

<h4>Color</h4>

<p></p>

<p>Need to document what the magnitude of the color and transparency values
mean.</p>

<p>SDL color parameters require four-element array references. The first
three numbers define the Red, Green, and Blue intensity of the color. The
final number defines the transparency of the color.</p>

<pre><code> my $color = [255, 255, 255, 255];</code></pre>

<p>The magnitude of each color value determines how much of that color
component will be mixed into the resulting color. A 0 value specifies that
none of the color channel should be used while 255 specifies a maximum
intensity for a particular channel. The first value corresponds with the
Red channel, so a higher number there means more red will be mixed into the
resulting color. It is a common practice to achieve a grayscale of varying
intensity by specifying the same value for each of the Red, Green, and Blue
color channels. The fourth and final value designates the transparency (or
Alpha channel) where a 0 value makes the resulting color fully transparent
and 255 makes it entirely opaque. A transparency value somewhere in between
will allow underlying (pixel data of surfaces below the current one) colors
to be blended with the specified RGB values into the final color
output.</p>

<p>You may also represent a color as hexadecimal values, where the values
of the numbers range from 0-255 for 32 bit depth in RGBA format:</p>

<pre><code> my $color = 0xFFFFFFFF;
    my $white = 0xFFFFFFFF;
    my $black = 0x000000FF;
    my $red = 0xFF0000FF;
    my $green = 0x00FF00FF;
    my $blue = 0x0000FFFF;</code></pre>

<p>... or as four-byte hexadecimal values, where each two-digit byte
encodes the same RGBA values:</p>

<pre><code> my $goldenrod = 0xDAA520FF;</code></pre>

<blockquote>

<h5>NOTE: Depth of Surface</h5>

<p></p>

<p>The color depth of the surface--how many bits are available to describe
colors--is a property of the relevant <code>SDLx::Surface</code> or
<code>SDLx::App</code>. Set it in its constructor:</p>

<pre><code> my $app = SDLx::App-&gt;new( depth =&gt; 32 );</code></pre>

<p>The default bit depth is 32, such that each color component has 256
possible values. Other options are 24, 16, and 8.</p>

</blockquote>

<h3>Pixels</h3>

<p></p>

<p>All <code>SDLx::Surface</code>s are collections of pixels. You can read
from and write to these pixels by treating the surface as an array
reference:</p>

<pre><code> $app-&gt;[$x][$y] = $color;</code></pre>

<p>... where <code>$color</code> is an unsigned integer value using the
hexadecimal format (<code>0xRRGGBBAA</code>) <i>or</i> an anonymous array
of the form <code>[$red, $green, $blue, $alpha]</code>.</p>

<h3>Primitives</h3>

<p></p>

<p>Drawing primitives are simple shapes that SDL supports natively.</p>

<p>\includegraphics[width=0.5\textwidth]{../src/images/draw-1.png}
\caption{Drawing a line} \label{fig:draw_line}</p>



<h4>Lines</h4>

<p></p>

<p>A line is a series of contiguous pixels between two points. The
<code>draw_line</code> method causes SDL to draw a line to a surface:</p>

<pre><code> $app-&gt;draw_line( [200, 20], [20, 200], [255, 255, 0, 255] );</code></pre>

<p>This will draw a yellow line from positions <code>(200, 20)</code> to
<code>(20, 200)</code>.</p>

<p>\includegraphics[width=0.5\textwidth]{../src/images/draw-2.png}
\caption{Drawing a Rectangle} \label{fig:draw_rect}</p>



<h4>Rectangles</h4>

<p></p>

<p>A rectangle is a four-sided, filled polygon. Rectangles are a common
building block for games. In SDL, rectangles are the most cost effective of
the primitives to draw. The <code>draw_rect</code> method draws a rectangle
on a surface:</p>

<pre><code> $app-&gt;draw_rect( [10, 20, 40, 40 ], [255, 255, 255,255] );</code></pre>

<p>This draws a white square of size <code>40x40</code> onto the screen at
the position <code>(10,20)</code>.</p>

<p>\includegraphics[width=0.5\textwidth]{../src/images/draw-3.png}
\caption{Drawing a Circle} \label{fig:draw_circle}</p>



<p>\includegraphics[width=0.5\textwidth]{../src/images/draw-4.png}
\caption{Drawing a filled Circle} \label{fig:draw_filled_circle}</p>



<h4>Circles</h4>

<p></p>

<p>A circle is a primitive a fixed radius around a given point. Circles may
be filled or unfilled. The <code>draw_circle</code> and
<code>draw_circle_filled</code> methods draw these to a surface:</p>

<pre><code> $app-&gt;draw_circle( [100, 100], 20, [255, 0, 0, 255] );
    $app-&gt;draw_circle_filled( [100, 100], 19, [0, 0, 255, 255] );</code></pre>

<p>These draw an unfilled red circle and a filled blue circle.</p>

<p>SDL provides more complex primitives in
<code>SDL::GFX::Primitives</code>.</p>

<h3>Drawing with Primitives</h3>

<p></p>

<p>It's easy to combine several primitives to draw an interesting
images.</p>

<pre><code> use strict;
    use warnings;
    use SDL;
    use SDLx::App;

    my $app = SDLx::App-&gt;new(
        w =&gt; 500,
        h =&gt; 500,
        d =&gt; 32,
        title =&gt; &#39;Pretty Flowers&#39;
    );

    # Add the blue skies
    $app-&gt;draw_rect( [ 0, 0, 500, 500 ], [ 20, 50, 170, 255 ] );

    # Draw a green field
    $app-&gt;draw_rect( [ 0, 400, 500, 100 ], [ 50, 170, 20, 100 ] );

    # Make a surface for the flower
    my $flower = SDLx::Surface-&gt;new( width =&gt; 50, height =&gt; 100 );

    # With a black background
    $flower-&gt;draw_rect( [ 0, 0, 50, 100 ], [ 0, 0, 0, 0 ] );

    # Draw a pretty green stem
    $flower-&gt;draw_rect( [ 23, 30, 4, 100 ], [ 0, 255, 0, 255 ] );

    # And a simple flower bud
    $flower-&gt;draw_circle_filled( [ 25, 25 ], 10, [ 150, 0, 0, 255 ] );
    $flower-&gt;draw_circle( [ 25, 25 ], 10, [ 255, 0, 0, 255 ] );

    # Draw flower on $app
    $flower-&gt;blit( $app, [ 0, 0, 50, 100 ] );

    $app-&gt;update();

    sleep(1);</code></pre>

<p>\includegraphics[width=0.5\textwidth]{../src/images/flower-1.png}
\caption{Looks so lonely there all alone} \label{fig:draw_flower_lone}</p>



<h2>Drawing on Multiple Surfaces</h2>

<p></p>

<p>The examples so far have drawn on only a single surface, the display.
SDL makes it possible to write on multiple surfaces. These other surfaces
exist only in memory until you draw them to the display.</p>

<h3>Creating Surfaces</h3>

<p></p>

<p>There are several ways to create an <code>SDLx::Surface</code> for use.
The most common is to create one manually with a constructor call:</p>

<pre><code> $surface = SDLx::Surface-&gt;new( width =&gt; $width, height =&gt; $height );</code></pre>

<p><code>SDL::Image</code> and <code>SDL::Video</code> can load images as
surfaces too. <code>SDL::Image</code> provides support for all types of
images, provided that the underlying <code>SDL_image</code> library
supports the image type you want to load. For example,
<code>SDL_image</code> must support PNG images to use:</p>

<pre><code> $surface = SDL::Image::load( &#39;picture.png&#39; );</code></pre>

<p></p>

<p>In the event that the desired <code>SDL_image</code> library is
unavailable, you can fallback to the built-in support for the
<code>.bmp</code> format.</p>

<pre><code> $surface = SDL::Video::load_BMP( &#39;picture.bmp&#39; );</code></pre>

<p>The <code>SDLx::Sprite</code> module provides another option to
manipulate surfaces.</p>

<h2>Lots of Flowers but One Seed</h2>

<p>The flower example used a method called <code>blit</code> to draw a
surface to the display. This method copies data from one surface to
another. It's a fundamental operation, but it's a low level operation.
<code>SDLx::Sprite</code> provides higher level options. Besides making
drawing simpler, <code>SDLx::Sprite</code> adds several other features
useful for moving images. Here's a revised example using
<code>SDLx::Sprite</code> for flowers:</p>

<p></p>

<pre><code> use strict;
    use warnings;
    use SDL;
    use SDLx::App;
    use SDLx::Sprite;

    my $app = SDLx::App-&gt;new(
        w =&gt; 500,
        h =&gt; 500,
        d =&gt; 32,
        title =&gt; &#39;Pretty Flowers&#39;
    );

    # Adding blue skies
    $app-&gt;draw_rect( [ 0, 0, 500, 500 ], [ 20, 50, 170, 255 ] );

    # Draw a green field
    $app-&gt;draw_rect( [ 0, 400, 500, 100 ], [ 50, 170, 20, 100 ] );

    my $flower = SDLx::Sprite-&gt;new( width =&gt; 50, height =&gt; 100 );

    # Use -&gt;surface() to access a sprite&#39;s SDLx::Surface

    # Make the background black
    $flower-&gt;surface-&gt;draw_rect( [ 0, 0, 50, 100 ], [ 0, 0, 0, 0 ] );

    # Now for a pretty green stem
    $flower-&gt;surface-&gt;draw_rect( [ 23, 30, 4, 100 ], [ 0, 255, 0, 255 ] );

    # Add the simple flower bud
    $flower-&gt;surface-&gt;draw_circle_filled( [ 25, 25 ], 10, [ 150, 0, 0, 255 ] );
    $flower-&gt;surface-&gt;draw_circle( [ 25, 25 ], 10, [ 255, 0, 0, 255 ] );

    $flower-&gt;draw_xy( $app, 0, 0 );

    $app-&gt;update();

    sleep(1);</code></pre>

<p>Flowers usually don't grow in the sky. Flowers make more sense on the
ground. It's easy to insert plenty of identical flowers from a single
sprite. Replace the line:</p>

<pre><code> $flower-&gt;draw_xy( $app, 0, 0 );</code></pre>

<p>... with:</p>

<pre><code> for (0 .. 500) {
        my $y = 425 - rand( 50);
        $flower-&gt;draw_xy( $app, rand(500) - 20, $y );
    }</code></pre>

<p>... to make an entire field of flowers.</p>

<p>Probably don't need this.</p>

<h1>Handling Events</h1>

<p></p>

<p>The cornerstone of an SDL application is event handling. The user
presses a key or moves the mouse. The operating system switches the focus
of the active window. The user selects the quit option from the menu or the
operating system. These are all events. How do you handle them?</p>

<p> </p>

<p>SDL provides an event queue which holds all events that occur until they
are removed. Every time an event occurs, SDL places it into the queue. The
<code>SDL::Event</code> object represents this queue in Perl, allowing you
to add and remove events constantly:</p>

<pre><code> use strict;
        use warnings;
        use SDL;
        use SDL::Event;
        use SDL::Events;
        use SDLx::App;

        my $app = SDLx::App-&gt;new( w =&gt; 200, h =&gt; 200 );
        my $event = SDL::Event-&gt;new();
        
        my $quit = 0;

        while (!$quit) {
        # Updates the queue to recent events
        SDL::Events::pump_events();

                # process all available events
                while ( SDL::Events::poll_event($event) ) {

                        # check by Event type
                        do_key() if $event-&gt;type == SDL_KEYDOWN;
                }
        }

        sub do_key { $quit = 1 }</code></pre>

<p> </p>

<p>Every event has an associated type which represents the category of the
event. The previous example looks for a keypress event (footnote: SDL
separates the event of pressing a key from the event of releasing a key,
which allows you to identify combinations of keypresses, such as Ctrl + P
to print.). The SDL library defines several types of events, and SDL_perl
makes them available as constants with names such as
<code>SDL_KEYDOWN</code> and <code>SDL_QUIT</code>. See <code>perldoc
SDL::Events</code> for a list of all event types.</p>

<p></p>

<p>Checking for every possible event type within that event loop can be
tedious. The <code>SDLx::Controller</code> available from the
<code>SDLx::App</code> offers the use of event callbacks with which to
handle events. Processing events is a matter of setting up the appropriate
callbacks and letting SDL do the heavy work.</p>

<blockquote>

<p><b>SDL Events Types</b></p>

<p>Additional Event types that can be captured by SDL are:</p>

<ul>

<li>Keyboard

<p><code>SDL_KEYDOWN</code> <code>SDL_KEYUP</code> - Keyboard button
pressed</p>

<li>Mouse

<p><code>SDL_MOUSEMOTION</code> - Mouse motion occured</p>

<p><code>SDL_MOUSEBUTTONDOWN</code> <code>SDL_MOUSEBUTTONUP</code> - Mouse
button pressed</p>

<li>Joystick

<p><code>SDL_JOYAXISMOTION</code> - Joystick axis motion</p>

<p><code>SDL_JOYBALLMOTION</code> - Joystick trackball motion</p>

<p><code>SDL_JOYHATMOTION</code> - Joystick hat position change</p>

<p><code>SDL_JOYBUTTONDOWN</code> <code>SDL_JOYBUTTONUP</code> - Joystick
button pressed</p>

<li>Window & System

<p><code>SDL_ACTIVEEVENT</code> - Application visibility</p>

<p><code>SDL_VIDEORESIZE</code> - Window resized</p>

<p><code>SDL_VIDEOEXPOSE</code> - Window exposed</p>

<p><code>SDL_QUIT</code> - Quit requested</p>

<p><code>SDL_USEREVENT</code> - A user-defined event type</p>

<p><code>SDL_SYSWMEVENT</code> - Platform-dependent window manager
event</p>

</ul>

<p>For more information look at:</p>

<pre><code> perldoc SDL::Event </code></pre>

</blockquote>

<h2>Quitting with Grace</h2>

<p>The example applications so far have not exited cleanly. Handling quit
events is much better:</p>

<pre><code> use strict;
    use warnings;
    use SDL;
    use SDL::Event;
    use SDLx::App;

    my $app = SDLx::App-&gt;new(
        w =&gt; 200,
        h =&gt; 200,
        d =&gt; 32,
        title =&gt; &quot;Quit Events&quot;
    );

    $app-&gt;add_event_handler( \&amp;quit_event );
    $app-&gt;run();

    sub quit_event
    {
        # the callback receives the appropriate SDL::Event
            my $event = shift;

            # ... as well as the calling SDLx::Controller
            my $controller = shift;

        # stopping the controller will exit $app-&gt;run() for us
            $controller-&gt;stop if $event-&gt;type == SDL_QUIT;
    }</code></pre>

<p><code>SDLx::App</code> calls the event_handlers, from an internal
<code>SDLx::Controller</code>. When this event handler receives a quit
event, it calls <code>SDLx::Controller::stop()</code> which causes
<code>SDLx::App</code> to exit gracefully.</p>

<h3>Exit on Quit</h3>

<p>Exiting on receiving the <code>SDL_QUIT</code> event is such a common
operation that <code>SDLx::App</code> provides it as a constructor
option:</p>

<pre><code> use strict;
    use warnings;
    use SDL;
    use SDLx::App;

    my $app = SDLx::App-&gt;new(
        w =&gt; 200,
        h =&gt; 200,
        d =&gt; 32,
        title =&gt; &quot;Quit Events&quot;,
        exit_on_quit =&gt; 1
    );

    $app-&gt;run();</code></pre>

<h2>Small Paint: Input Devices</h2>

<p>SDL events also allow input handling. Consider a simple paint program.
It will provide a small black window. Moving the mouse draws on this
window. Pressing a number key chooses a paint color. Pressing
<code>q</code> or <code>Q</code> exits the program. Pressing <code>c</code>
or <code>C</code> clears the screen. Pressing <code>Ctrl-S</code> saves the
image to a file named <i>painted.bmp</i>.</p>

<p>\includegraphics[width=0.5\textwidth]{../src/images/painted.png}
\caption{Simple Paint: Smile} \label{fig:Smile}</p>



<h3>Saving the image</h3>

<p>Start by defining the saving function:</p>

<pre><code> sub save_image {
        if (SDL::Video::save_BMP( $app, &#39;painted.bmp&#39; ) == 0
        &amp;&amp; -e &#39;painted.bmp&#39;)
        {
             warn &#39;Saved painted.bmp to &#39; . cwd();
        }
        else
        {
            warn &#39;Could not save painted.bmp: &#39; . SDL::get_errors();
        }
    }</code></pre>

<h3>Keyboard</h3>

<p>Keyboard handling requires some color data as well as a keypress
callback:</p>

<pre><code> my $brush_color = 0;

    sub keyboard_event
    {
        my $event = shift;

        if ( $event-&gt;type == SDL_KEYDOWN )
        {
            # convert the key_symbol (integer) to a keyname
            my $key_name = SDL::Events::get_key_name( $event-&gt;key_sym );

            # if $key_name is a digit, use it as a color
            $brush_color = $key_name if $key_name =~ /^\d$/;

            # get the keyboard modifier (see perldoc SDL::Events)
            my $mod_state = SDL::Events::get_mod_state();

            # we are using any CTRL so KMOD_CTRL is fine
            save_image() if $key_name =~ /^s$/ &amp;&amp; ($mod_state &amp; KMOD_CTRL);

            # clear the screen
            $app-&gt;draw_rect( [ 0, 0, $app-&gt;w, $app-&gt;h ], 0 )
                if $key_name =~ /^c$/;

            # exit
            $app-&gt;stop() if $key_name =~ /^q$/;
        }

        $app-&gt;update();
    }

    $app-&gt;add_event_handler(\&amp;quit_event);
    $app-&gt;add_event_handler(\&amp;keyboard_event);</code></pre>

<blockquote>

<p><b>NOTE: </b> When adding a callback to <code>SDLx::App</code> which
uses variables declared outside of the function (<code>$brush_color</code>
and <code>@colors</code> in this case), be sure to define them before
declaring the subroutine. Normal Perl scoping and initialization rules
apply.</p>

</blockquote>

<h3>Mouse</h3>

<p>Handling mouse events is almost as straightforward as keyboard events:
=begin programlisting</p>

<pre><code> # track the drawing status
    my $drawing = 0;

    sub mouse_event {
        my $event = shift;

        # detect Mouse Button events and check if user is currently drawing
        if ($event-&gt;type == SDL_MOUSEBUTTONDOWN || $drawing)
        {
            # set drawing to 1
            $drawing = 1;

            # get the X and Y values of the mouse
            my $x = $event-&gt;button_x;
            my $y = $event-&gt;button_y;

            # draw a rectangle at the specified position
            $app-&gt;draw_rect( [ $x, $y, 2, 2 ], $colors[$brush_color] );

            $app-&gt;update();
        }

        # disable drawing when user releases mouse button
        $drawing = 0 if ($event-&gt;type == SDL_MOUSEBUTTONUP );
    }

    $app-&gt;add_event_handler( \&amp;mouse_event );</code></pre>

<p>This is all of the code necessary to make a simple drawing
application.</p>

<p>Take note of two things. First, SDL_perl invokes the event handlers in
the order of attachment. If the user presses <code>Q</code> and then moves
the mouse, the application will quit before processing the mouse
movement.</p>

<p>Second, the application makes no distinction between right, middle, or
left mouse clicks. SDL provides this information. See the
<code>button_button()</code> method in <code>SDL::Event</code>.</p>

<h2>POD ERRORS</h2>

<p>Hey! <b>The above document had some coding errors, which are explained
below:</b></p>

<ul>

<li>Around line 317:

<p>=end programlisting without matching =begin. (Stack: [empty])</p>

</ul>

<h1>The Game Loop</h1>

<p></p>

<p>Just as an interactive SDL app builds around an event loop, a game
builds around a game loop. The simplest game loop is something like:</p>

<pre><code> while (!$quit)
    {
       get_events();
       calculate_next_positions();
       render();
    }</code></pre>

<p>The names of the functions called in this loop hint at their purposes,
but the subtleties of even this simple code are important.
<code>get_events()</code> obviously processes events from the relevant
input devices (keyboard, mouse, joystick). Processing events at the start
of every game loop iteration helps to prevent lag.</p>

<p><code>calculate_next_positions</code> updates the game state according
to user input as well as any active animations (a player walking, an
explosion, a cut scene). <code>render()</code> finally updates and displays
the screen.</p>

<h2>A Practical Game Loop</h2>

<p>Consider a game with a moving laser bolt:</p>

<pre><code> use strict;
    use warnings;
    use SDL;
    use SDL::Event;
    use SDL::Events;
    use SDLx::App;

    my $app = SDLx::App-&gt;new(
        width =&gt; 200,
        height =&gt; 200,
        title =&gt; &#39;Pew Pew&#39;
    );

    my $quit = 0;

    # start laser on the left
    my $laser = 0;

    sub get_events {
        my $event = SDL::Event-&gt;new();

        SDL::Events::pump_events;

        while( SDL::Events::poll_event($event) )
        {
            $quit = 1 if $event-&gt;type == SDL_QUIT
        }
    }

    sub calculate_next_positions {
            # move the laser
        $laser++;

            # if the laser goes off the screen, bring it back
        $laser = 0 if $laser &gt; $app-&gt;w();
    }

    sub render {
        # draw the background first
        $app-&gt;draw_rect( [ 0, 0, $app-&gt;w, $app-&gt;h ], 0 );

        # draw the laser halfway up the screen
        $app-&gt;draw_rect( [ $laser, $app-&gt;h / 2, 10, 2 ], [ 255, 0, 0, 255 ]);

        $app-&gt;update();
    }

    while (!$quit)
    {
         get_events();
         calculate_next_positions();
         render();
    }</code></pre>

<p>This game loop works very well for consoles and other devices where you
know exactly how much CPU time the game will get for every loop iteration.
That hardware stability is easy to predict: each animation and calculation
will happen at the same time for each machine. Unfortunately, this is
<i>not</i> true for modern operating systems and general purpose computing
hardware. CPU speeds and workloads vary, so for this game to play
consistently across multiple machines and myriad configurations, the game
loop itself needs to regulate its updates.</p>

<h3>Fixed FPS</h3>

<p> </p>

<p>One way to solve this problem is to regulate the number of frames per
second the game will produce. A <i>frame</i> is a complete redraw of the
screen representing the updated game state. If each iteration of the game
loop draws one frame, the more frames per second, the faster the game is
running. If the game loop limits the number of frames per second, the game
will perform consistently on all machines fast enough to draw that many
frames per second.</p>

<p>You can see this with the example program <i>game_fixed.pl</i>. When run
with no arguments:</p>

<pre><code> $ <b>perl game_fixed.pl</b></code></pre>

<p>.... the FPS rate will be erratic. The laser seems to change its speed
randomly. When run with a single argument, the game sets an upper bound on
the number of frames per second:</p>

<pre><code> $ <b>perl game_fixed.pl 1</b></code></pre>

<p>This will prevent the laser from going faster than 60 frames per second.
When run with a second argument, the game will set a lower bound of frames
per second:</p>

<pre><code> $ <b>perl game_fixed.pl 1 1</b></code></pre>

<p>At this point the FPS should hold steady at 60 frames per second.</p>

<pre><code> use strict;
        use warnings;
        use SDL;
        use SDL::Event;
        use SDL::Events;
        use SDLx::App;

        my $app = SDLx::App-&gt;new(
                        width =&gt; 200,
                        height =&gt; 200,
                        title =&gt; &#39;Pew Pew&#39;
        );

        my ( $start, $end, $delta_time, $FPS, $frames ) = ( 0, 0, 0, 0, 0 );

        # aim for a rate of 60 frames per second
        my $fixed_rate = 60;

        # compensate for times stored in microseconds
        my $fps_check = (1000 / $fixed_rate );

        my $quit = 0;

        # start laser on the left
        my $laser = 0;

        sub get_events {
                my $event = SDL::Event-&gt;new();

                SDL::Events::pump_events;

                while ( SDL::Events::poll_event($event) ) {
                        $quit = 1 if $event-&gt;type == SDL_QUIT;
                }
        }

        sub calculate_next_positions {
                $laser++;

                $laser = 0 if $laser &gt; $app-&gt;w;
        }

        sub render {
                # draw the background first
                $app-&gt;draw_rect( [ 0, 0, $app-&gt;w, $app-&gt;h ], 0 );

                # draw the laser
                $app-&gt;draw_rect( [ $laser, $app-&gt;h / 2, 10, 2 ], [ 255, 0, 0, 255 ] );

                # draw the FPS
                $app-&gt;draw_gfx_text( [ 10, 10 ], [ 255, 0, 255, 255 ], &quot;FPS: $FPS&quot; );

                $app-&gt;update();
        }

        # Called at the end of each frame, whether we draw or not
        sub calculate_fps_at_frame_end
        {
                # Ticks are microseconds since load time
                $end = SDL::get_ticks();

        # smooth the frame rate by averaging over 10 frames
                if ( $frames &lt; 10 ) {
                        $frames++;
                        $delta_time += $end - $start;
                }
                else {
                        # frame rate is Frames * 100 / Time Elapsed in us
            $FPS = int( ( $frames * 100 ) / $delta_time )
                        if $delta_time != 0;

                        # reset metrics
                        $frames = 0;
                        $delta_time = 0;
                }
        }

        while ( !$quit ) {
                # Get the time for the starting of the frame
                $start = SDL::get_ticks();

                get_events();

                # if fixing the lower bounds of the frame rate
                if( $ARGV[1] )
                {
                        # if delta time is going too slow for frame check
                        if ( $delta_time &gt; $fps_check ) {

                                calculate_fps_at_frame_end();

                # skip rendering and collision detections
                # (heavy functions in the game loop)
                                next;
                        }
                }

                calculate_next_positions();
                render();

                # a normal frame with rendering actually performed
                calculate_fps_at_frame_end();

                # if fixing the upper bounds of the frame rate
                if ( $ARGV[0] ) {
                        
                        # if delta time is going too fast compared to the frame check
                        if ( $delta_time &lt; $fps_check ) {

                                # delay for the difference
                                SDL::delay( $fps_check - $delta_time );
                        }
                }
        }</code></pre>

<p>This method is generally sufficient for most computers. The animations
will be smooth enough to provide the same gameplay even on machines with
different hardware.</p>

<p>However, this method still has some serious problems. First, if a
computer is too slow to sustain a rate of 60 FPS, the game will skip
rendering some frames, leading to sparse and jittery animation.it will skip
a lot of rendering, and the animation will look sparse and jittery. It
might be better to set a lower bounds of 30 FPS, though it's difficult to
predict the best frame rate for a user.</p>

<p>The worst problem is that this technique still ties rendering speed to
the CPU speed: a very fast computer will waste CPU cycles delaying.</p>

<h3>Variable FPS</h3>

<p>To fix the problem of a computer being consistently too fast or too slow
for the hard-coded FPS rate is to adjust the FPS rate accordingly. A slow
CPU may limit itself to 30 FPS, while a fast CPU might run at 300 FPS.
Although you may achieve a consistent rate this way (consistent for any one
particular computer), this technique still presents the problem of
differing animation speeds between different computers.</p>

<p>Better solutions are available.</p>

<h2>Integrating Physics</h2>

<p>Describe movement and show handlers.</p>

<p>The problem caused by coupling rendering to the CPU speed has a
convenient solution. Instead of updating object positions based on how fast
the computer can get through the game loop, derive their positions from a
physical model based on the passage of time. Objects moving according to
real world time will have consistent behavior at all CPU speeds and smooth
interpolation between frames. <code>SDLx::App</code> provides this behavior
through movement and show handlers.</p>

<p>Consider a simple physics model for the laser has a consistent
horizontal velocity in pixels per time step at the window's mid-point:</p>

<pre><code> X = Velocity * time step,
    Y = 100</code></pre>

<p>Assuming a velocity of 10, the laser will pass through the
coordinates:</p>

<pre><code> 0, 100
     10, 100
     20, 100
     30, 100
    ...
    200, 100</code></pre>

<p>Note that the speed of processing the game loop no longer matters. The
position of the laser depends instead on the passage of real time.</p>

<p>The biggest problem with this approach is the required bookkeeping for
the many objects and callbacks. The implementation of such complex models
is non-trivial; see the lengthy discussion in the documentation of the
<code>SDLx::Controller</code> module.</p>

<p><code>SDLx::App</code> using the <code>SDLx::Controller</code> module
provide callbacks to handle both aspects of this type of game loop. One is
the the movement handler, which is a callback where calculations of the
next step for each relevant data point is calculated. In the above example
the movement handler would calculate the <code>X</code> and <code>Y</code>
values, for each time step between the frames of animations.</p>

<p>When we are ready to render the frame it is handled by the show handler.
In the above example that would mean the show handler would print or render
the <code>X, Y</code> values.</p>

<h3>Laser in Real Time</h3>

<p>This version of the laser example demonstrates the use of movement, show
handlers, and a simple physics model. This example also shows how
<code>SDLx::App</code> can do more of the work, even providing the entire
game loop:</p>

<pre><code> use strict;
        use warnings;
        use SDL;
        use SDL::Event;
        use SDLx::App;

        my $app = SDLx::App-&gt;new(
            width =&gt; 200,
            height =&gt; 200,
            title =&gt; &#39;Pew Pew&#39;
        );

        my $laser = 0;
        my $velocity = 10;

        $app-&gt;add_event_handler( \&amp;quit_event );

        # tell app to handle the appropriate times to
        # call both rendering and physics calculation

        $app-&gt;add_move_handler( \&amp;calculate_laser );
        $app-&gt;add_show_handler( \&amp;render_laser );

        $app-&gt;run();

        sub quit_event {
            my $event = shift;
            my $controller = shift;

            $controller-&gt;stop if $event-&gt;type == SDL_QUIT;
        }

        sub calculate_laser {

            # The step is the difference in Time calculated for the next jump
            my ( $step, $app, $t ) = @_;
            $laser += $velocity * $step;
            $laser = 0 if $laser &gt; $app-&gt;w;
        }

        sub render_laser {
            my ( $delta, $app ) = @_;

            # The delta can be used to render blurred frames

            # draw the background first
            $app-&gt;draw_rect( [ 0, 0, $app-&gt;w, $app-&gt;h ], 0 );

            # draw the laser
            $app-&gt;draw_rect( [ $laser, $app-&gt;h / 2, 10, 2 ], [ 255, 0, 0, 255 ] );
            $app-&gt;update();
        }</code></pre>

<p>To learn more about this topic please, see an excellent blog post by
<b>GafferOnGames.com</b>:
HTTP://GafferOnGames.Com/game-physics/fix-your-timestep.</p>

<h1>Pong!</h1>

<p> </p>

<p>Pong is one of the first popular video games in the world. Allan Alcorn
created it for Atari, Inc. Its release in 1972 was both Atari's first game
ever and the spark which began the video game industry.</p>

<p>Pong simulates a table tennis match ("ping pong"). Each player controls
a paddle which moves vertically on the screen to hit a ball bouncing back
and forth between the players. You earn a point if your opponent is unable
to return the ball to your side of the screen.</p>

<p>You can recreate Pong yourself with Perl and SDL.</p>

<h2>The Basic Screen</h2>

<p>Start by making a simple screen for Pong. Open a file in your favourite
text editor and type:</p>

<pre><code> #!/usr/bin/perl
    use strict;
    use warnings;

    use SDL;
    use SDLx::App;

    # create the main screen
    my $app = SDLx::App-&gt;new(
        width =&gt; 500,
        height =&gt; 500,
        title =&gt; &#39;My Pong Clone!&#39;,
        dt =&gt; 0.02,
        exit_on_quit =&gt; 1,
    );

    # let&#39;s roll!
    $app-&gt;run;</code></pre>

<p>Save this file as <i>pong.pl</i> and run it by typing on the command
line:</p>

<pre><code> $ <b>perl pong.pl</b></code></pre>

<p>You should see a 500x500 black window entitled <i>"My Pong Clone!"</i>.
The only new feature you might not have seen before is the <code>dt</code>
parameter to the <code>SDLx::App</code> constructor. This represents the
length, in seconds, of a movement step as managed by an
<code>SDLx::Controller</code> object. Because the <code>SDLx::App</code>
object is also an <code>SDLx::Controller</code> object, it can handle
<code>SDL_QUIT</code> events.</p>

<blockquote>

<p><b>Game Loop Granularity</b></p>

<p>The game loop runs using a process that performs calculus on the time
progression. To do this it uses the <code>dt</code> parameter of
<code>SDLx::App</code>. <code>dt</code> by default is set to
<code>0.01</code> granularity. In simple terms <code>dt</code> determines
how many small steps in movement ( calls to the move handler ) should be
made per each render ( call to the show handler ).</p>

<p>What is important to remember is that the <code>dt</code> granularity
must never be set so big that it fails to capture collisions and
interaction between moving objects. This can especially happen with fast
moving objects such as bullets, but the principle applies to many
situation. On the other hand having a too fine granularity taxes the CPU
resources.</p>

</blockquote>

<h2>Game Objects</h2>

<p>There are three main game objects in Pong: two player paddles and the
bouncing ball. Paddles are rectangles moving which move vertically. They're
easy to represent with SDLx::Rect objects. First, put
<code>SDLx::Rect</code> in your module's declarations:</p>

<pre><code> use SDL;
    use SDLx::App;
    <b>use SDLx::Rect;</b></code></pre>

<p>Next, add a hash reference to store the first player's paddle. Using a
hash reference allows the possibility of adding more information later. In
a more complex game, consider using an actual object which <i>contains</i>
an <code>SDLx::Rect</code>. For now, this will suffice:</p>

<pre><code> <b>my $player1 = {</b>
          <b>paddle =&gt; SDLx::Rect-&gt;new( 10, $app-&gt;h / 2, 10, 40 ),</b>
    <b>};</b>

    # let&#39;s roll!
    $app-&gt;run;</code></pre>

<p>This creates a 10x40 paddle rect for the first player on the left side
of the screen (<code>x = 10</code>) and somewhat in the center (<code>y =
$app->h / 2</code>). The second player's paddle is similar:</p>

<pre><code> <b>my $player2 = {</b>
         <b>paddle =&gt; SDLx::Rect-&gt;new( $app-&gt;w - 20, $app-&gt;h / 2, 10, 40),</b>
    <b>};</b>

    # let&#39;s roll!
    $app-&gt;run;</code></pre>

<p>The second paddle needs to appear on the right side of the screen, so
its <code>x</code> position is the screen's width minus 20. As the paddle
has a width of 10 and the <code>x</code> position refers to the rect's
top-left corner, the paddle has a 10 pixel margin from the right edge of
the screen.</p>

<p>Finally, the bouncing ball is a 10x10 rect in the middle of the
screen:</p>

<pre><code> <b>my $ball = {</b>
        <b>rect =&gt; SDLx::Rect-&gt;new( $app-&gt;w / 2, $app-&gt;h / 2, 10, 10 ),</b>
    <b>};

    # let&#39;s roll!
    $app-</b>run;</code></pre>

<p>Just like the original Pong, this ball is square.</p>

<h3>Show it Off</h3>

<p>With the game objects created, add a show handler to render them to the
screen:</p>

<pre><code> <b>$app-</b>add_show_handler(&gt;
        <b>sub {</b>
            <b># first, clear the screen</b>
            <b>$app-&gt;draw_rect( [ 0, 0, $app-&gt;w, $app-&gt;h ], 0x000000FF );</b>

            <b># then render the ball</b>
            <b>$app-&gt;draw_rect( $ball-&gt;{rect}, 0xFF0000FF );</b>

            <b># ... and each paddle</b>
            <b>$app-&gt;draw_rect( $player1-&gt;{paddle}, 0xFF0000FF );</b>
            <b>$app-&gt;draw_rect( $player2-&gt;{paddle}, 0xFF0000FF );</b>

            <b># finally, update the screen</b>
            <b>$app-&gt;update;</b>
        <b>}</b>
    <b>);</b>

    # let&#39;s roll!
    $app-&gt;run;</code></pre>

<p>This approach is rather simple. The code clears the screen by painting a
black rectangle the size of the screen, then painting opaque red
(<code>0xFF0000FF</code>) rectangles in each object's position.</p>

<p>The result can be seen on the screenshot:</p>

<p>\includegraphics[width=0.5\textwidth]{../src/images/pong1.png}
\caption{First view of our Pong clone} \label{fig:pong1}</p>



<h2>Moving the Player's Paddle</h2>

<p></p>

<p>It's time to let the player move the left paddle! Remember that motion
is merely changing an object's position with respect to time. If this
motion is, in the game, a magical teleportation, you can change the (x, y)
coordinates and be done with it. If the motion needs to represent some sort
of realistic physics, the object needs to move at an understood speed. Pong
paddles have a constant speed, so there's no need to model acceleration.
Also, as paddles move only vertically, the game only needs to track
vertical velocity. Add a <code>v_y</code> element to each paddle
structure:</p>

<pre><code> my $player1 = {
           paddle =&gt; SDLx::Rect-&gt;new( 10, $app-&gt;h / 2, 10, 40 ),
           <b>v_y =&gt; 0,</b>
      };</code></pre>

<p> </p>

<p>Now what? How does this new attribute help modify the position of a
paddle? Velocity represents the <i>displacement</i> how much displacement
happens in a unit of time, as in 20 km/h or 4 m/s. In this Pong clone, the
unit of time is the app's <code>dt</code>. The velocity of a paddle is
<code>v_y</code> pixels per <code>dt</code>. Here is where the motion
handlers come in handy:</p>

<pre><code> <b># handles the player&#39;s paddle movement</b>
    <b>$app-&gt;add_move_handler( sub {</b>
        <b>my ( $step, $app ) = @_;</b>
        <b>my $paddle = $player1-&gt;{paddle};</b>
        <b>my $v_y = $player1-&gt;{v_y};</b>

        <b>$paddle-&gt;y( $paddle-&gt;y ( $v_y * $step ) );</b>
    <b>});</b></code></pre>

<p>If you recall previous chapters, the code should be straightforward.
When <code>v_y</code> is 0 at any given run cycle, the paddle won't change
its <code>y</code> position. If, however, there is a vertical velocity, the
code updates the <code>y</code> position based on how much of the expected
cycle time (the app's <code>dt</code>) has passed. A value of 1 in
<code>$step</code> indicates a full cycle has occurred, so that <code>$v_y
* $step</code> is the same as <code>$v_y * 1</code>, which simplifies to
<code>$v_y</code> -- the desired speed for one cycle. If the handler gets
called more frequently, the paddle will move a relatively shorter
amount.</p>

<h3>Rinse and Repeat</h3>

<p>The second player's paddle will use the same motion mechanics, so it
won't hurt to prepare for its motion:</p>

<pre><code> my $player2 = {
           paddle =&gt; SDLx::Rect-&gt;new( $app-&gt;w - 20, $app-&gt;h / 2, 10, 40),
           <b>v_y =&gt; 0,</b>
      };</code></pre>

<p>And add another motion handler, just like our player's:</p>

<pre><code> <b># handles AI&#39;s paddle movement</b>
    <b>$app-&gt;add_move_handler( sub {</b>
        <b>my ( $step, $app ) = @_;</b>
        <b>my $paddle = $player2-&gt;{paddle};</b>
        <b>my $v_y = $player2-&gt;{v_y};</b>

        <b>$paddle-&gt;y( $paddle-&gt;y ( $v_y * $step ) );</b>
    <b>});</b></code></pre>

<blockquote>

<p>For the sake of simplicity of explanation, this code has repetition a
real program would not want. This repetition could go away in several ways.
You could use an array to hold all moving elements. You could use a helper
function to create a new closure for each paddle. You could turn the game
object hash references into real objects and add a <code>move()</code> or
<code>update_position()</code> method.</p>

</blockquote>

<h3>Move that Paddle!</h3>

<p>Paddle velocity <code>v_y</code> has a default value of zero, so paddles
begin by not moving. That's good, until the player wants to move the
paddle. To divine the player's intent, the program must bind the up and
down arrow keys of the keyboard to manipulate the positive and negative
velocity of the paddle through an event hook. This means loading the
SDL::Events module:</p>

<pre><code> use SDL;
     <b>use SDL::Events;</b>
     use SDLx::App;
     use SDLx::Rect;</code></pre>

<p>... and creating an event hook:</p>

<pre><code> <b># handles keyboard events</b>
   <b>$app-</b>add_event_handler(&gt;
       <b>sub {</b>
           <b>my ( $event, $app ) = @_;</b>

           <b># user pressing a key</b>
           <b>if ( $event-&gt;type == SDL_KEYDOWN ) {</b>

               <b># up arrow key means going up (negative velocity)</b>
               <b>if ( $event-&gt;key_sym == SDLK_UP ) {</b>
                   <b>$player1-&gt;{v_y} = -2;</b>
               <b>}</b>

               <b># down arrow key means going down (positive velocity)</b>
               <b>elsif ( $event-&gt;key_sym == SDLK_DOWN ) {</b>
                   <b>$player1-&gt;{v_y} = 2;</b>
               <b>}</b>
           <b>}</b>
           <b># user releasing a key</b>
           <b>elsif ( $event-&gt;type == SDL_KEYUP ) {</b>

               <b># up or down arrow keys released, stop the paddle</b>
               <b>if (</b>
                       <b>$event-&gt;key_sym == SDLK_UP</b>
                    <b>or $event-&gt;key_sym == SDLK_DOWN</b>
               <b>) {</b>
                   <b>$player1-&gt;{v_y} = 0;</b>
               <b>}</b>
           <b>}</b>
       <b>}</b>
   <b>);</b></code></pre>

<p>Again, there's nothing new. Whenever the user presses the up arrow key,
the paddle should move up. Keep in mind that the origin point of 0, 0 in
SDL is the top-left corner, so a negative <code>v_y</code> will decrease
the paddle's <code>y</code> and send it <b>up</b> the screen. Similarly,
adding a positive value to <code>v_y</code> whenever the user presses the
down arrow key will move the paddle down. When the user releases either
arrow key, assigning zero to <code>v_y</code> stops the motion.</p>

<h2>A Bouncing Ball</h2>

<p>The ball's movement is similar to that of either paddle, except that it
also has a horizontal velocity component of <code>v_x</code>. Add that to
the ball structure:</p>

<pre><code> my $ball = {
         rect =&gt; SDLx::Rect-&gt;new( $app-&gt;w / 2, $app-&gt;h / 2, 10, 10 ),
         <b>v_x =&gt; -2.7,</b>
         <b>v_y =&gt; 1.8,</b>
     };</code></pre>

<p>The ball will have an initial velocity of -2.7 horizontally and 1.8
vertically. Just as a negative vertical velocity moves the object up, a
negative horizontal velocity moves it towards the left side of the screen.
The ball also needs a motion handler to update its position according to
its velocity:</p>

<pre><code> # handles the ball movement
   $app-&gt;add_move_handler( sub {
       my ( $step, $app ) = @_;
       my $ball_rect = $ball-&gt;{rect};

       $ball_rect-&gt;x( $ball_rect-&gt;x + ($ball-&gt;{v_x} * $step) );
       $ball_rect-&gt;y( $ball_rect-&gt;y + ($ball-&gt;{v_y} * $step) );
   });</code></pre>

<p>All of these motion handlers look similar so far, but if you're paying
close attention, you can probably spot a bug caused by missing code. Try
running the game. You'll see the ball going, going, and gone!</p>

<p>This handler needs to confine the ball to the screen. Whenever the ball
reaches a top or bottom edge of the screen, it needs to bounce. That's easy
enough to add:</p>

<pre><code> # handles the ball movement
     $app-&gt;add_move_handler( sub {
         my ( $step, $app ) = @_;
         my $ball_rect = $ball-&gt;{rect};

         $ball_rect-&gt;x( $ball_rect-&gt;x + ($ball-&gt;{v_x} * $step) );
         $ball_rect-&gt;y( $ball_rect-&gt;y + ($ball-&gt;{v_y} * $step) );

         <b># collision to the bottom of the screen</b>
         <b>if ( $ball_rect-&gt;bottom &gt;= $app-&gt;h ) {</b>
             <b>$ball_rect-&gt;bottom( $app-&gt;h );</b>
             <b>$ball-&gt;{v_y} *= -1;</b>
         <b>}</b>

         <b># collision to the top of the screen</b>
         <b>elsif ( $ball_rect-&gt;top &lt;= 0 ) {</b>
             <b>$ball_rect-&gt;top( 0 );</b>
             <b>$ball-&gt;{v_y} *= -1;</b>
         <b>}</b>
     });</code></pre>

<p>If the new y (<code>"bottom"</code> or <code>"top"</code>) value would
take the ball off the screen in part or in whole, the handler updates the
ball's position with the furthest position possible while remaining on the
screen, so that the ball will only ever <i>touch</i> that edge. The handler
also reverses <code>y_y</code> so that the ball will bounce back onto the
screen going the opposite direction at the same speed.</p>

<h3>He shoots... and scores!!</h3>

<p>That fixes one bug, but what should happen when the ball hits the left
or right edges of the screen? According to the rules of Pong, this means
the player on the opposite side scored a point, and the ball should go back
to the center of the screen. Start by adding a <code>score</code> attribute
for each player:</p>

<pre><code> my $player1 = {
           paddle =&gt; SDLx::Rect-&gt;new( 10, $app-&gt;h / 2, 10, 40),
           v_y =&gt; 0,
           <b>score =&gt; 0,</b>
      };

      my $player2 = {
           paddle =&gt; SDLx::Rect-&gt;new( $app-&gt;w - 20, $app-&gt;h / 2, 10, 40),
           v_y =&gt; 0,
           <b>score =&gt; 0,</b>
      };</code></pre>

<p>Then update the ball's motion handler to handle the out of bounds
condition for the left and right borders:</p>

<pre><code> # handles the ball movement
     $app-&gt;add_move_handler( sub {
         my ( $step, $app ) = @_;
         my $ball_rect = $ball-&gt;{rect};

         $ball_rect-&gt;x( $ball_rect-&gt;x + ($ball-&gt;{v_x} * $step) );
         $ball_rect-&gt;y( $ball_rect-&gt;y + ($ball-&gt;{v_y} * $step) );

         # collision to the bottom of the screen
         if ( $ball_rect-&gt;bottom &gt;= $app-&gt;h ) {
             $ball_rect-&gt;bottom( $app-&gt;h );
             $ball-&gt;{v_y} *= -1;
         }

         # collision to the top of the screen
         elsif ( $ball_rect-&gt;top &lt;= 0 ) {
             $ball_rect-&gt;top( 0 );
             $ball-&gt;{v_y} *= -1;
         }

         <b># collision to the right: player 1 score!</b>
         <b>elsif ( $ball_rect-&gt;right &gt;= $app-&gt;w ) {</b>
             <b>$player1-&gt;{score}++;</b>
             <b>reset_game();</b>
             <b>return;</b>
         <b>}</b>

         <b># collision to the left: player 2 score!</b>
         <b>elsif ( $ball_rect-&gt;left &lt;= 0 ) {</b>
             <b>$player2-&gt;{score}++;</b>
             <b>reset_game();</b>
             <b>return;</b>
         <b>}</b>
     });</code></pre>

<p>If the ball hits the right edge of the screen (the app's width), we
increase player 1's score, call <code>reset_game()</code>, and return
without updating the ball's position. If the ball hits the left edge of the
screen, do the same for player 2.</p>

<p>The <code>reset_game()</code> function must return the ball to the
center of the screen:</p>

<pre><code> <b>sub reset_game {</b>
         <b>$ball-&gt;{rect}-&gt;x( $app-&gt;w / 2 );</b>
         <b>$ball-&gt;{rect}-&gt;y( $app-&gt;h / 2 );</b>
     <b>}</b></code></pre>

<h2>Collision Detection: The Ball and The Paddle</h2>

<p>The game's existing collision detection is very simple because the
paddles and ball can only collide with the fixed edges of the screen. The
game gets more interesting when it can detect whether the ball and a paddle
collide--or rather, intersect.</p>

<p></p>

<p>The Separating Axis Theorem roughly states that two convex shapes in a
2D plane <i> do not</i> intersect if and only you can place a line which
separates them. Because the paddles and the ball are rectangular <i>and</i>
aligned along one axis, detecting a collision means choosing one item and
testing its top, right, bottom, and left lines for intersection. If any
other object is on one side or the other of those four lines, there is no
collision. Otherwise, there is a collision.</p>

<p>In more general terms, given two rects A and B, you can establish
several conditions:</p>

<p>\includegraphics[width=0.9\textwidth]{../src/images/collision.png}
\caption{if B is completely to the left, right, top or bottom of A, they do
NOT intersect} \label{fig:pong1}</p>



<ul>

<li>if A's bottom side is above B's top side, then A is completely above B
(fig. 6.2.1).</li>

<li>if A's top side is below B's bottom side, then A is completely below B
(fig. 6.2.2).</li>

<li>if A's right side is to the left of B's left side, then A is completely
to the left of B (fig. 6.2.3).</li>

<li>if A's left side is to the right of B's right side, then A is
completely to the right of B (fig 6.2.4).</li>

</ul>

<p>Keep in mind that SDL's origin point of 0, 0 is always the top left
corner. This produces a simple generic <code>check_collision()</code>
function which returns true of two rect objects have collided:</p>

<pre><code> sub check_collision {
         my ($A, $B) = @_;

         return if $A-&gt;bottom &lt; $B-&gt;top;
         return if $A-&gt;top &gt; $B-&gt;bottom;
         return if $A-&gt;right &lt; $B-&gt;left;
         return if $A-&gt;left &gt; $B-&gt;right;

         # we have a collision!
         return 1;
     }</code></pre>

<p>The ball motion handler can now test to see if the ball has hit either
paddle:</p>

<pre><code> # handles the ball movement
     $app-&gt;add_move_handler( sub {
         my ( $step, $app ) = @_;
         my $ball_rect = $ball-&gt;{rect};

         $ball_rect-&gt;x( $ball_rect-&gt;x + ($ball-&gt;{v_x} * $step) );
         $ball_rect-&gt;y( $ball_rect-&gt;y + ($ball-&gt;{v_y} * $step) );

         # collision to the bottom of the screen
         if ( $ball_rect-&gt;bottom &gt;= $app-&gt;h ) {
             $ball_rect-&gt;bottom( $app-&gt;h );
             $ball-&gt;{v_y} *= -1;
         }

         # collision to the top of the screen
         elsif ( $ball_rect-&gt;top &lt;= 0 ) {
             $ball_rect-&gt;top( 0 );
             $ball-&gt;{v_y} *= -1;
         }

         # collision to the right: player 1 score!
         elsif ( $ball_rect-&gt;right &gt;= $app-&gt;w ) {
             $player1-&gt;{score}++;
             reset_game();
             return;
         }

         # collision to the left: player 2 score!
         elsif ( $ball_rect-&gt;left &lt;= 0 ) {
             $player2-&gt;{score}++;
             reset_game();
             return;
         }

         <b># collision with player1&#39;s paddle</b>
         <b>elsif ( check_collision( $ball_rect, $player1-&gt;{paddle} )) {</b>
             <b>$ball_rect-&gt;left( $player1-&gt;{paddle}-&gt;right );</b>
             <b>$ball-&gt;{v_x} *= -1;</b>
         <b>}</b>

         <b># collision with player2&#39;s paddle</b>
         <b>elsif ( check_collision( $ball_rect, $player2-&gt;{paddle} )) {</b>
             <b>$ball-&gt;{v_x} *= -1;</b>
             <b>$ball_rect-&gt;right( $player2-&gt;{paddle}-&gt;left );</b>
         <b>}</b>
     });</code></pre>

<p>That's it! If the ball hits the first player's paddle, the handler
reverses its horizontal velocity (<code>v_x</code>) to make it bounce back,
and set its left edge to the paddle's right so they don't overlap. The
logic is similar for the second player's paddle, except that the ball's
right edge now must be at the same position as the paddle's left, as the
ball has hit the other side of the paddle.</p>

<h2>Artificial Stupidity</h2>

<p>This Pong game is almost done. With scoring, ball movement, and paddle
movement, it's playable--but dull, unless the second player can move. It's
easy enough to bind a secondary set of keys to move the second paddle, but
what if you want a quick game on your own without a friend around?</p>

<p>Artificial intelligence for games is a complex field of study, with many
algorithms. Fortunately, the easiest approach is simple to model for Pong:
the second player's paddle should follow the ball as it moves. All that
takes is some new code in the second player's motion handler:</p>

<pre><code> # handles AI&#39;s paddle movement
      $app-&gt;add_move_handler( sub {
          my ( $step, $app ) = @_;
          my $paddle = $player2-&gt;{paddle};
          my $v_y = $player2-&gt;{v_y};

          <b>if ( $ball-&gt;{rect}-&gt;y &gt; $paddle-&gt;y ) {</b>
              <b>$player2-&gt;{v_y} = 1.5;</b>
          <b>}</b>
          <b>elsif ( $ball-&gt;{rect}-&gt;y &lt; $paddle-&gt;y ) {</b>
              <b>$player2-&gt;{v_y} = -1.5;</b>
          <b>}</b>
          <b>else {</b>
              <b>$player2-&gt;{v_y} = 0;</b>
          <b>}</b>

          $paddle-&gt;y( $paddle-&gt;y + ( $v_y * $step ) );
      });</code></pre>

<p>If the ball is below the paddle (if its <code>y</code> value is greater
than the <code>y</code> value of the paddle), the paddle needs a positive
velocity to go downwards. If, otherwise, the ball has a lower
<code>y</code> value, the paddle's <code>v_y</code> gets a negative value.
If the ball is somewhere in between those two values, the paddle stays in
place.</p>

<h2>Cosmetics: Displaying the Score</h2>

<p></p>

<p>All that's left is polish. Displaying the score means drawing text to
the screen. That's the purpose of the <code>SDLx::Text</code> module:</p>

<pre><code> use SDL;
     use SDL::Events;
     use SDLx::App;
     use SDLx::Rect;
     <b>use SDLx::Text;</b></code></pre>

<p>Create an object to represent the display of the score:</p>

<pre><code> <b>my $score = SDLx::Text-&gt;new( font =&gt; &#39;font.ttf&#39;, h_align =&gt; &#39;center&#39; );</b></code></pre>

<p>The optional <code>font</code> parameter specifies the path to a
TrueType Font. Feel free to change <i>font.ttf</i> as you like. Otherwise,
leave out this parameter and SDL will use the bundled default font. The
other parameter, <code>h_align</code>, allows you to specify the horizontal
alignment of rendered text. The default is left alignment.</p>

<p>Add the score object to the show handler to display it:</p>

<pre><code> $app-&gt;add_show_handler(
          sub {
              # first clear the screen
              $app-&gt;draw_rect( [0, 0, $app-&gt;w, $app-&gt;h], 0x000000FF );

              # then render the ball
              $app-&gt;draw_rect( $ball-&gt;{rect}, 0xFF0000FF );

              # ... and each paddle
              $app-&gt;draw_rect( $player1-&gt;{paddle}, 0xFF0000FF );
              $app-&gt;draw_rect( $player2-&gt;{paddle}, 0xFF0000FF );

              <b># ... and each player&#39;s score!</b>
              <b>$score-&gt;write_to(</b>
                  <b>$app,</b>
                  <b>$player1-&gt;{score} . &#39; x &#39; . $player2-&gt;{score}</b>
              <b>);</b>

              # finally, update the screen
              $app-&gt;update;
          }
      );</code></pre>

<p>The <code>write_to()</code> call will write to any surface passed as the
first argument--in this case, the app itself. The second argument is the
string to render. Note that the string's when rendered is relative to the
surface to which it writes. The default position is (0, 0). Because the
<code>$score</code> object has horizontal centering, the text will write to
the top and center of the screen--not the top and left.</p>

<p>The result is:</p>

<p>\includegraphics[width=0.5\textwidth]{../src/images/pong2.png}
\caption{our finished Pong clone, in all its glory} \label{fig:pong2}</p>



<h2>Exercises</h2>

<p>Pong is a simple game, but there's plenty of room for polish. Here's
your chance to add some features. Of course, there's always more than one
way to do things:</p>

<ul>

<li>1 Every time a player scores, the ball goes back to the middle but has
the same sense and direction as before. See if you can make it restart at a
random direction instead.

<li>2 Red is boring. How about a psychedelic Pong? Pick three different
colors and make each paddle oscillate between them every time the ball hits
it.

</ul>

<h3>Answers</h3>

<ul>

<li>1 To make the ball restart at a random direction, update
<code>reset_game()</code> function to set the ball's <code>v_x</code> and
<code>v_y</code> to a random value between. Anything between positive 1.5
and 2.5 works well:

<pre><code> sub reset_game {
         $ball-&gt;{rect}-&gt;x( $app-&gt;w / 2 );
         $ball-&gt;{rect}-&gt;y( $app-&gt;h / 2 );

         <b>$ball-&gt;{v_x} = (1.5 + int rand 1) * (rand 2 &gt; 1 ? 1 : -1);</b>
         <b>$ball-&gt;{v_y} = (1.5 + int rand 1) * (rand 2 &gt; 1 ? 1 : -1);</b>
     }</code></pre>

<li>2 Start by representing the available colors. You could use separate
colors or hues for each player, but for simplicity this code uses a single
group of colors. Each player's hash will contain the index into this array:

<pre><code> <b>my @colors = qw( 0xFF0000FF 0x00FF00FF 0x0000FFFF 0xFFFF00FF );</b>

      my $player1 = {
           paddle =&gt; SDLx::Rect-&gt;new( 10, $app-&gt;h / 2, 10, 40),
           v_y =&gt; 0,
           score =&gt; 0,
           <b>color =&gt; 0,</b>
      };

      my $player2 = {
           paddle =&gt; SDLx::Rect-&gt;new( $app-&gt;w - 20, $app-&gt;h / 2, 10, 40),
           v_y =&gt; 0,
           score =&gt; 0,
           <b>color =&gt; 0,</b>
      };</code></pre>

<p>Now make the ball's color change every time a paddle hits it:</p>

<pre><code> # handles the ball movement
     $app-&gt;add_move_handler( sub {

        ...

         # collision with player1&#39;s paddle
         elsif ( check_collision( $ball_rect, $player1-&gt;{paddle} )) {
             $ball_rect-&gt;left( $player1-&gt;{paddle}-&gt;right );
             $ball-&gt;{v_x} *= -1;
             <b>$player1-&gt;{color} = ($player1-&gt;{color} + 1) % @colors;</b>
         }

         # collision with player2&#39;s paddle
         elsif ( check_collision( $ball_rect, $player2-&gt;{paddle} )) {
             $ball-&gt;{v_x} *= -1;
             $ball_rect-&gt;right( $player2-&gt;{paddle}-&gt;left );
             <b>$player2-&gt;{color} = ($player2-&gt;{color} + 1) % @colors;</b>
         }
     });</code></pre>

<p>Finally, change the show handler to use the current color referenced by
<code>color</code>, instead of the previously hardcoded value:</p>

<pre><code> $app-&gt;add_show_handler(
          sub {
              # first clear the screen
              $app-&gt;draw_rect( [0, 0, $app-&gt;w, $app-&gt;h], 0x000000FF );

              # then render the ball
              $app-&gt;draw_rect( $ball-&gt;{rect}, 0xFF0000FF );

              # ... and each paddle
              <b>$app-&gt;draw_rect( $player1-&gt;{paddle}, $colors[ $player1-&gt;{color} ] );</b>
              <b>$app-&gt;draw_rect( $player2-&gt;{paddle}, $colors[ $player2-&gt;{color} ] );</b>
              ...

              # finally update the screen
              $app-&gt;update;
          }
      );</code></pre>

</ul>

<h2>Author</h2>

<p>This chapter's content graciously provided by Breno G. de Oliveira
(<code>garu</code>).</p>

<h2>POD ERRORS</h2>

<p>Hey! <b>The above document had some coding errors, which are explained
below:</b></p>

<ul>

<li>Around line 822:

<p>You forgot a '=back' before '=head1'</p>

</ul>

<h1>Tetris</h1>

<p>Pong is an important milestone in gaming history. If you can write it,
you understand the basics of game programming. The next step in mastery
comes from writing something like Tetris, with better animation and more
complex scoring.</p>

<p>\includegraphics[width=0.5\textwidth]{../src/images/tetris.png}
\caption{Tetris using SDLx Perl} \label{fig:tetris}</p>



<p>To follow along, download the sample code from
https://github.com/PerlGameDev/SDL_Manual/raw/master/games/tetris.zip. To
start the game, extract this Zip file and run:</p>

<pre><code> $ <b>perl tetris.pl</b></code></pre>

<h2>The Game Window</h2>

<p>The game starts out as you should expect by now:</p>

<pre><code> use strict;
    use warnings;

    use SDL;
    use SDL::Event;
    use SDL::Events;
    use SDLx::App;

    # create the main screen
    my $app = SDLx::App-&gt;new(
       w =&gt; 400,
       h =&gt; 512,
       exit_on_quit =&gt; 1,
       dt =&gt; 0.2,
       title =&gt; &#39;SDLx Tetris&#39;
    );</code></pre>

<p>This game requires several pieces of artwork, and so the program must
manage and store them somehow. The <code>SDLx::Surface</code> module
handles the conversion of files from their storage on disk into a format
SDL can use, and an array will hold them:</p>

<pre><code> use SDL;
     <b>use SDLx::Surface;</b>
        
        ...
                
     <b>my $back = SDLx::Surface-&gt;load( &#39;data/tetris_back.png&#39; );</b>
     <b>my @piece = (undef);</b>
     <b>push @piece, SDLx::Surface-&gt;load( &quot;data/tetris_$_.png&quot; ) for 1..7;</b></code></pre>

<p>The <code>$back</code> variable holds one special surface: the
background image. Everything else is in the <code>@piece</code> array.</p>

<h2>Managing Blocks</h2>

<p>Blocks are critical to the success of a Tetris game. The program must
represent them in a sensible way: they must be easy to access and they must
be easy to manipulate and calculate. A hash fulfills the ease of
access:</p>

<pre><code> my %pieces = (
      I =&gt; [0, 5, 0, 0,
            0, 5, 0, 0,
            0, 5, 0, 0,
            0, 5, 0, 0],
      J =&gt; [0, 0, 0, 0,
            0, 0, 6, 0,
            0, 0, 6, 0,
            0, 6, 6, 0],
      L =&gt; [0, 0, 0, 0,
            0, 2, 0, 0,
            0, 2, 0, 0,
            0, 2, 2, 0],
      O =&gt; [0, 0, 0, 0,
            0, 3, 3, 0,
            0, 3, 3, 0,
            0, 0, 0, 0],
      S =&gt; [0, 0, 0, 0,
            0, 4, 4, 0,
            4, 4, 0, 0,
            0, 0, 0, 0],
      T =&gt; [0, 0, 0, 0,
            0, 7, 0, 0,
            7, 7, 7, 0,
            0, 0, 0, 0],
      Z =&gt; [0, 0, 0, 0,
            1, 1, 0, 0,
            0, 1, 1, 0,
            0, 0, 0, 0],
    );</code></pre>

<p>Each hash entry holds a four-element array reference which represents a
grid of the piece. Each item in the array corresponds to an image in the
<code>@piece</code> array. Drawing a piece means blitting one element of
<code>@piece</code> for each non-zero entry in the piece's array.</p>

<pre><code> use strict;
     use warnings;

    <b>use List::Util qw(shuffle min max);</b></code></pre>

<p></p>

<p>Selecting pieces needs some randomness. The core <code>List::Util</code>
module can help:</p>

<pre><code> Z =&gt; [0,0,0,0,
               1,1,0,0,
               0,1,1,0,
               0,0,0,0],
     );

     <b>my $next_tile = get_next_tile();</b>
     <b>my $curr_tile = [ undef, 4, 0 ];</b>
        <b>@{ $curr_tile-&gt;[0] } = @{ $pieces{$next_tile} };</b>
        <b>$next_tile = get_next_tile()</b>

        <b>sub get_next_tile { shuffle keys %pieces };</b></code></pre>

<p>This code randomly chooses a <code>$next_tile</code>, then sets the
piece data for the first piece in <code>$curr_tile</code>.</p>

<h2>Piece Collisions</h2>

<p>Collision detection is both easier (because only one piece at a time
moves) and more difficult (because the screen continues to fill up with
pieces). One solution is to treat the screen as two overlapping grids. The
first grid represents the moving piece. The second grid represents the
pieces already in place. When a moving piece collides with a piece in the
fixed grid, the moving piece becomes stationary and joins the fixed grid.
When that action clears one or more lines, the stationary grid changes.</p>

<p>Start by defining these grids:</p>

<pre><code> push @piece, SDLx::Surface-&gt;load( &quot;data/tetris_$_.png&quot; ) for 1..7;

     <b># compare the position of the moving piece with non-moving pieces</b>
     <b>my $grid = []; # moving piece</b>
     <b>my $store = []; # non-moving pieces</b>

     my %pieces = (
          I =&gt; [0,5,0,0,</code></pre>

<p>Rotating a piece means transforming each of its elements:</p>

<p>This math needs some explanation for everyone who hasn't done linear
algebra in a while.</p>

<pre><code> sub rotate_piece {
        my $_piece = shift;
        my $_rotated = [];
        my $_i = 0;

        for (@{$_piece}) {
            $_rotated-&gt;[ $_i + (($_i % 4 + 1 ) * 3)
                             - ( 5 * int( $_i / 4 ))] = $_;
            $_i++;
        }

        return $_rotated;
    }</code></pre>

<p>Collision detection requires checking both grids for a piece overlap in
the direction the user wants to move the piece:</p>

<p>The math concern applies here too. A diagram might help.</p>

<pre><code> sub can_move_piece {
        my $direction = shift;
        my $amount = shift || 1;

        for my $y (0 .. 3) {

            for my $x (0 . .3) {
                if ($curr_tile-&gt;[0]-&gt;[ $x + 4 * $y ]) {
                    return if $direction eq &#39;left&#39;
                             &amp;&amp; $x - $amount + $curr_tile-&gt;[1] &lt; 0;
                    return if $direction eq &#39;right&#39;
                             &amp;&amp; $x + $amount + $curr_tile-&gt;[1] &gt; 9;
                    return if $direction eq &#39;down&#39;
                             &amp;&amp; int($y + $amount + $curr_tile-&gt;[2]) &gt; 22;
    
                    return if $direction eq &#39;right&#39;
                             &amp;&amp; $store-&gt;[ $x + $amount +
                                           $curr_tile-&gt;[1] +
                                           10 * int($y + $curr_tile-&gt;[2]) ];
                    return if $direction eq &#39;left&#39;
                             &amp;&amp; $store-&gt;[ $x - $amount +
                                           $curr_tile-&gt;[1] +
                                           10 * int($y + $curr_tile-&gt;[2]) ];
                    return if $direction eq &#39;down&#39;
                             &amp;&amp; $store-&gt;[ $x +
                                           $curr_tile-&gt;[1]
                                           + 10 * int($y + $amount +
                                           $curr_tile-&gt;[2]) ];
                }
            }
        }

        return 1;
    }</code></pre>

<p>All of the pieces are in place to move the piece: make the collision
check, then place the piece into the appropriate grid for its next
position:</p>

<pre><code> sub move_piece {
        my $direction = shift;
        my $amount = shift || 1;

        if ($direction eq &#39;right&#39;) {
            $curr_tile-&gt;[1] += $amount;
        }
        elsif ($direction eq &#39;left&#39;) {
            $curr_tile-&gt;[1] -= $amount;
        }
        elsif ($direction eq &#39;down&#39;) {
            $curr_tile-&gt;[2] += $amount;
        }

        @{$grid} = ();

        for my $y (0..3) {
            for my $x (0..3) {
                if ($curr_tile-&gt;[0]-&gt;[$x + 4 * $y]) {
                    $grid-&gt;[ $x + $curr_tile-&gt;[1] +
                             10 * ($y + int($curr_tile-&gt;[2])) ]
                              = $curr_tile-&gt;[0]-&gt;[$x + 4 * $y];
                }
            }
        }
    }

    sub store_piece {
        for my $y (0..3) {
            for my $x (0..3) {
                if ($curr_tile-&gt;[0]-&gt;[$x + 4 * $y]) {
                    $store-&gt;[ $x + $curr_tile-&gt;[1] + 10 *
                             ($y + int($curr_tile-&gt;[2])) ]
                              = $curr_tile-&gt;[0]-&gt;[$x + 4 * $y];
                }
            }
        }
    }</code></pre>

<p>Of course this all needs an event handler to attempt to move the pieces
appropriately:</p>

<pre><code> sub trigger_move_event_handler {
        my ( $event, $app ) = @_;

        if ( $event-&gt;type == SDL_KEYDOWN ) {
            my $key = $event-&gt;key_sym;

            if ( $event-&gt;key_sym &amp; (SDLK_LEFT|SDLK_RIGHT|SDLK_UP|SDLK_DOWN) ) {
                if ($key == SDLK_LEFT &amp;&amp; can_move_piece(&#39;left&#39;)) {
                    move_piece(&#39;left&#39;);
                }
                elsif ($key == SDLK_RIGHT &amp;&amp; can_move_piece(&#39;right&#39;)) {
                    move_piece(&#39;right&#39;);
                }
                elsif ($key == SDLK_DOWN &amp;&amp; can_move_piece(&#39;down&#39;)) {
                    move_piece(&#39;down&#39;)
                }
                elsif ($key == SDLK_UP) {
                    $curr_tile-&gt;[0] = rotate_piece($curr_tile-&gt;[0]);
                }
            }
        }
    }

    $app-&gt;add_event_handler( \&amp;trigger_move_event_handler );</code></pre>

<h3>Score and Game State</h3>

<p>First we keep hold a variable to keep the game score and set the
<code>SDLx::Text</code> font and options to draw the text on the screen
later on.</p>

<pre><code> use SDLx::App;
        <b>use SDLx::Text;</b>
        use SDLx::Rect;

        ...
        
        # create our game objects
        <b>my $score_text = SDLx::Text-&gt;new( font =&gt; &#39;font.ttf&#39;,</b>
                                        <b>h_align =&gt; &#39;left&#39;,</b>
                                        <b>color =&gt; [255,255,255,255] );</b>
        <b>my $score = 0;</b>
        my $back = SDLx::Surface-&gt;load( &#39;data/tetris_back.png&#39; );</code></pre>

<p>The game state in Tetris is the combination of the fixed placement grid,
the current piece, and the current score. The move handler can update all
of these:</p>

<pre><code> $app-&gt;add_move_handler( sub {
        my ( $step, $app ) = @_;</code></pre>

<p>Start by updating the current piece's state as movable or fixed:</p>

<pre><code> if (can_move_piece(&#39;down&#39;, $step / 2)) {
            # still movable
            move_piece(&#39;down&#39;, $step / 2);
        }
        else {
            # place the tile
            store_piece($curr_tile);</code></pre>

<p>Then update the state of the grid and check for lines to remove:</p>

<p>Why count backwards? This seems like it could be <code>for my $y (0 ..
22)</code>. Maybe the question is whether to remove rows from the bottom up
or the top down.</p>

<pre><code> # checking for lines to delete
            my $y;
            my @to_delete);

            for($y = 22; $y &gt;= 0; $y--) {
                # if the min value of this row is 0,
                # it contains at least one open space
                if (min( @{$store}[ ($y * 10)..((( $y + 1) *10 ) -1 )])) {
                    push @to_delete, $y;
                }
            }</code></pre>

<p>Deleting a line should increment the user's score:</p>

<pre><code> # deleting lines
            foreach (@to_delete) {
                splice @{$store}, $_ * 10, 10;
                $score++;
            }</code></pre>

<p>... and should clear that line off of the fixed grid:</p>

<p>These loops should merge.</p>

<pre><code> # adding blank rows to the top
            foreach (@to_delete) {
                splice @{$store}, 0, 0, (0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
            }
    </code></pre>

<p>... and the game should launch a new tile.</p>

<pre><code> # launching new tile
            @{$curr_tile-&gt;[0]} = @{ $pieces{$next_tile} };
            $curr_tile-&gt;[1] = 4;
            $curr_tile-&gt;[2] = 0;
            $next_tile = shuffle keys %pieces;
        }
    });</code></pre>

<h3>Drawing the Game</h3>

<p>Those are the mechanics. How about displaying the game? The show handler
needs to iterate through all of the elements in both grids and draw the
appropriate tile:</p>

<pre><code> $app-&gt;add_show_handler(
        sub {
            # first clear the screen
            $app-&gt;draw_rect( [ 0, 0, $app-&gt;w, $app-&gt;h ], 0x000000 );

            # and draw the background image
            $back-&gt;blit( $app );
            my $x = 0;
            my $y = 0;

            # draw the fixed tiles
            foreach (@{$store}) {
                $piece[$_]-&gt;blit( $app,
                                   undef,
                                  [ 28 + $x%10 * 20, 28 + $y * 20 ]
                                ) if $_;
                $x++;
                $y++ unless $x % 10;
            }

            $x = 0;
            $y = 0;

            # draw the moving tile
            foreach (@{$grid}) {
                $piece[$_]-&gt;blit( $app, undef,
                    [ 28 + $x % 10 * 20, 28 + $y * 20 ] ) if $_;
                $x++;
                $y++ unless $x % 10;
            }

            # the next tile will be...
            my $next_tile_index = max( @{$pieces{$next_tile}} );
            for $y (0..3) {
                for $x (0..3) {
                    if ($pieces{$next_tile}-&gt;[$x + 4 * $y]) {
                        $piece[$next_tile_index]-&gt;blit( $app, undef,
                                                        [ 264 + $x * 20,
                                                           48 + $y * 20 ]
                                                      );
                    }
                }
            }</code></pre>

<p>... and should draw the score:</p>

<pre><code> $score_text-&gt;write_xy( $app, 248, 20, &quot;Next Piece&quot; );
            $score_text-&gt;write_xy( $app, 248, 240, &quot;Score: $score&quot; );

            # finally, update the screen
            $app-&gt;update;
        }
    );

    # all is set, run the app!
    $app-&gt;run();</code></pre>

<h2>Author</h2>

<p>Code for this chapter was provided by Tobias Leich "FROGGS".</p>

<h1>Puzz! A puzzle game</h1>

<h2>Abstract</h2>

<p>We are now ready to write another complete game. Instead of listing the
code and then explaining it, I will go through the process of how I might
write it.</p>

<p>Puzz is a simple rearrangment puzzle. A random image from the folder
Puzz is in is chosen and broken into a 4x4 grid. The top left corner piece
is then taken away, and every other piece is then moved to a random
position, scrambling the image up. The goal is then to move pieces which
are in the 4 squares adjacent to the empty square on to the empty square,
and eventually restore the image.</p>

<p>\includegraphics[width=0.5\textwidth]{../src/images/puzz1.png}
\caption{Credits to Sebastian Riedel (kraih.com) for the Perl6 logo used
with permission in the application.} \label{fig:puzz}</p>



<h2>The Window</h2>

<p>So, first thing we do is create the window. I've decided I want each
piece to be 100x100, so the window needs to be 400x400.</p>

<pre><code> use strict;
       use warnings;

       use SDL;
       use SDLx::App;

       my $App = SDLx::App-&gt;new(w =&gt; 400, h =&gt; 400, t =&gt; &#39;Puzz&#39;);</code></pre>

<p>Next thing we usually do is figure out what global vars we will be
needing. As with $App, I like to name my globals with title case, so they
are easily distinguishable from lexical vars. The globals we need are the
grid (the positions of the pieces), the images we have to use, the current
image, and a construct that will give us piece movement, along with an
animation.</p>

<pre><code> my @Grid;
    my @Img;
    my $CurrentImg;
    my %Move;</code></pre>

<p>For now, lets fill in @Grid with what it's going to look like:</p>

<pre><code> @Grid = (
       [0, 1, 2, 3],
       [4, 5, 6, 7],
       [8, 9, 10, 11],
       [12, 13, 14, 15],
    );</code></pre>

<p><code>0</code> will be our blank piece, but we could have chosen it to
be any other number. When the grid looks like this, it's solved, so
eventually we will need a way to scramble it. It's good enough for now,
though.</p>

<h2>Loading the images</h2>

<p>To load the images, we would normally use <code>SDLx::Surface</code>,
but we're going to do it the libsdl way with <code>SDL::Image</code>
because we need to do our own error handling.</p>

<pre><code> use SDL::Image;
    use SDL::GFX::Rotozoom &#39;SMOOTHING_ON&#39;;

    while(&lt;./*&gt;) {
        if(-f and my $i = SDL::Image::load($_)) {
            $i = SDL::GFX::Rotozoom::surface_xy($i, 0, 400 / $i-&gt;w, 400 / $i-&gt;h, SMOOTHING_ON);
            push @Img, $i;
        }
        else
        {
            warn &quot;Cannot Load $_: &quot; . SDL::get_error() if $_ =~ /jpg|png|bmp/;
        }
    }
    $CurrentImg = $Img[rand @Img];
    
    die &quot;Please place images in the Current Folder&quot; if $#Img &lt; 0;</code></pre>

<p>We just go through every file in the current directory, and try to load
it as an image. <code>SDL::Image::load</code> will return false if there
was an error, so we want to discard it when that happens. If we used
<code>SDLx::Surface</code> to load the images, we would get a warning every
time a file fails to load as an image, which we don't want. The <code>my $i
= SDL::Image::load($_)</code> is just an idiom for setting a var and
checking it for truth at the same time.</p>

<p>We want the image to be 400x400, and <code>SDL::GFX::Rotozoom</code>
makes this possible. The two Rotozoom functions that are the most useful
are <code>surface</code> and <code>surface_xy</code>. They work like
this:</p>

<pre><code> $zoomed_src = SDL::GFX::Rotozoom::surface($src, $angle, $zoom, $smoothing)
    $zoomed_src = SDL::GFX::Rotozoom::surface_xy($src, $angle, $x_zoom, $y_zoom, $smoothing)</code></pre>

<p>The zoom values are the multiplier for that component, or for both
components at once as with <code>$zoom</code>. <code>$angle</code> is an
angle of rotation in degrees. <code>$smoothing</code> should be
<code>SMOOTHING_ON</code> or <code>SMOOTHING_OFF</code> (which can be
exported by <code>SDL::GFX::Rotozoom</code>) or just 1 or 0.</p>

<p>Once the image is zoomed, it is added to the image array. The current
image is then set to a random value of the array.</p>

<h2>Handling Events</h2>

<p>The next part I like to write is the events. We're going to make Escape
quit, and left click will move the pieces around. We <code>use
SDL::Events</code> for the constants.</p>

<pre><code> use SDL::Events;

    sub on_event {
        my ($e) = @_;
        if($e-&gt;type == SDL_QUIT or $e-&gt;type == SDL_KEYDOWN and $e-&gt;key_sym == SDLK_ESCAPE) {
            $App-&gt;stop;
        }
        elsif($e-&gt;type == SDL_MOUSEBUTTONDOWN and $e-&gt;button_button == SDL_BUTTON_LEFT) {
            ...
        }
    }

    $App-&gt;add_event_handler(\&amp;on_event);
    # $App-&gt;add_move_handler(\&amp;on_move);
    # $App-&gt;add_show_handler(\&amp;on_show);
    $App-&gt;run;</code></pre>

<h2>Filling the Grid</h2>

<p>Once we have something like this, it's a good time to put some
<code>warn</code> messages in to make sure the inputs are working
correctly. Once they are, it's time to fill it in.</p>

<pre><code> my $x = int($e-&gt;button_x / 100);
    my $y = int($e-&gt;button_y / 100);
    if(!%Move and $Grid[$y][$x]) {`
        ...
    }</code></pre>

<p>From the pixel coordinates of the click (0 to 399), we want to find out
the grid coordinates (0 to 3), so we divide both components by 100 and
round them down. Then, we only want to continue on to see if that piece can
move if no other piece is moving (<code>%Move</code> is false), and the
piece clicked isn't the blank piece (0).</p>

<pre><code> for([-1, 0], [0, -1], [1, 0], [0, 1]) {
        my $nx = $x + $_-&gt;[0];
        my $ny = $y + $_-&gt;[1];
        if($nx &gt;= 0 and $nx &lt; 4 and $ny &gt;= 0 and $ny &lt; 4 and !$Grid[$ny][$nx]) {
            ...
        }
    }</code></pre>

<h2>Moving the Pieces</h2>

<p>We check that the blank piece is in the 4 surrounding places by
constructing 4 vectors. These will take us to those squares. The
<code>x</code> component is first and the second is <code>y</code>. We
iterate through them, setting <code>$nx</code> and <code>$ny</code> to the
new position. Then if both <code>$nx</code> and <code>$ny</code> are within
the grid (0 to 3), and that position in the grid is 0, we can move the
piece to the blank square.</p>

<pre><code> %Move = (
        x =&gt; $x,
        y =&gt; $y,
        x_dir =&gt; $_-&gt;[0],
        y_dir =&gt; $_-&gt;[1],
        offset =&gt; 0,
    );</code></pre>

<p>To make a piece move, we construct the move hash with all the
information it needs to move the piece. The <code>x</code> and
<code>y</code> positions of the piece, the <code>x</code> and
<code>y</code> directions it will be moving (the vector), and it's current
pixel offset from it's position (for the moving animation), which starts at
0.</p>

<h3>The Move Handler Callback</h3>

<p>Next we will write the move handler. All it needs to do is move any
moving piece along by updating the offset, and click it in to where it's
being moved to when it has moved the whole way (offset is 100 or more).</p>

<pre><code> sub on_move {
        if(%Move) {
            $Move{offset} += 30 * $_[0];
            if($Move{offset} &gt;= 100) {
                $Grid[$Move{y} + $Move{y_dir}][$Move{x} + $Move{x_dir}] = $Grid[$Move{y}][$Move{x}];
                $Grid[$Move{y}][$Move{x}] = 0;
                undef %Move;
            }
        }
    }
    </code></pre>

<p>30 has been arbitrarily chosen as the speed of the move, as it felt the
best after a little playing and tweaking. Always remember to multiply
things like this by the step value in <code>$_[0]</code> so that the
animation moves in correct time with the updating.</p>

<p>Once the offset is 100 or more, the grid place that the piece is moving
to is set to the value of the piece, and the piece is set to the blank
value. The move is then finished, so <code>%Move</code> is deleted.</p>

<h2>Rendering the Game</h2>

<p>Now that we have all the functionality we need it's finally time to see
the game.</p>

<pre><code> sub on_show {
        $App-&gt;draw_rect( [0,0,$App-&gt;w,$App-&gt;h], 0 );
        for my $y (0..3) {
            for my $x (0..3) {
                ...
            }
        }
        $App-&gt;flip;
    }
    </code></pre>

<p>We start the show handler by drawing a black rect over the entire app.
Entire surface and black are the defaults of <code>draw_rect</code>, so
letting it use the defaults is good. Next we iterate through a
<code>y</code> and <code>x</code> of 0 to 3 so that we can go through each
piece of the grid. At the end of the handler we update the app with a call
to <code>flip</code>.</p>

<pre><code> next unless my $val = $Grid[$y][$x];
    my $xval = $val % 4;
    my $yval = int($val / 4);
    my $move = %Move &amp;&amp; $Move{x} == $x &amp;&amp; $Move{y} == $y;
    ...</code></pre>

<p>Inside the two loops we put this. First we set <code>$val</code> to the
grid value at the current position, and we skip to the next piece if it's
the blank piece. We have the <code>x</code> and <code>y</code> coordinates
of where that piece is on the board, but we need to figure out where it is
on the image. If you refer back to the initialisation of the grid, the two
operations to find the values should make sense. <code>$move</code> is set
with a bool of whether it is this piece that is moving, if there is a piece
moving at all.</p>

<pre><code> $App-&gt;blit_by(
        $CurrentImg,
        [$xval * 100, $yval * 100, 100, 100],
        [$x * 100 + ($move ? $Move{offset} * $Move{x_dir} : 0),
         $y * 100 + ($move ? $Move{offset} * $Move{y_dir} : 0)]
    );</code></pre>

<p>Now that we have all of this, we can blit the portion of the current
image we need to the app. We use <code>blit_by</code> because the image
we're blitting isn't an SDLx::Surface (because we didn't load it as one),
but the app is. Here's how <code>blit_by</code> works as opposed to
<code>blit</code>:</p>

<pre><code> $src-&gt;blit($dest, $src_rect, $dest_rect)
    $dest-&gt;blit_by($src, $src_rect, $dest_rect)</code></pre>

<p>The portion we need is from the <code>$xval</code> and
<code>$yval</code>, and where it needs to go to is from <code>$x</code> and
<code>$y</code>. All are multiplied by 100 because we're dealing with 0 to
300, not 0 to 3. If the piece is moving, the offset multiplied by the
diretion is added to the position.</p>

<p>When the code is run with all 3 handlers, we have a fully working game.
The pieces move around nicely when clicked. The only things it still needs
are a shuffled grid and a way to check if the player has won. To imlement
these two things, we will make two more functions.</p>

<pre><code> use List::Util &#39;shuffle&#39;;

    sub new_grid {
        my @new = shuffle(0..15);
        @Grid = map { [@new[ $_*4..$_*4+3 ]] } 0..3;
        $CurrentImg = $Img[rand @Img];
    }
    </code></pre>

<p>We will replace the grid initialising we did with this sub. First it
shffles the numbers 0 through 15 with <code>List::Util::shuffle</code>.
This array is then arranged into a 2D grid with a <code>map</code> and put
in to @Grid. Setting the current image is also put into this sub.</p>

<pre><code> sub won {
        my $correct = 0;
        for(@Grid) {
            for(@$_) {
                return 0 if $correct != $_;
                $correct++;
            }
        }
        return 1;
    }</code></pre>

<p>This sub returns whether the grid is in the winning configuration, that
is, all piece values are in order from 0 to 15.</p>

<p>Now we put a call to <code>new_grid</code> to replace the grid
initialisation we had before. We put <code>won</code> into the event
handler to make click call <code>new_grid</code> if you have won. Finally,
<code>won</code> is put into the show handler to show the blank piece if
you have won.</p>

<h2>Complete Code</h2>

<p>Here is the finished code:</p>

<pre><code> use strict;
    use warnings;

    use SDL;
    use SDLx::App;
    use SDL::Events;
    use SDL::Image;
    use SDL::GFX::Rotozoom &#39;SMOOTHING_ON&#39;;
    use List::Util &#39;shuffle&#39;;

    my $App = SDLx::App-&gt;new(w =&gt; 400, h =&gt; 400, t =&gt; &#39;Puzz&#39;);

    my @Grid;
    my @Img;
    my $CurrentImg;
    my %Move;

    while(&lt;./*&gt;) {
        if(-f and my $i = SDL::Image::load($_)) {
            $i = SDL::GFX::Rotozoom::surface_xy($i, 0, 400 / $i-&gt;w, 400 / $i-&gt;h, SMOOTHING_ON);
            push @Img, $i;
        }
        else
        {
            warn &quot;Cannot Load $_: &quot; . SDL::get_error() if $_ =~ /jpg|png|bmp/;
        }

    }
    
    die &quot;Please place images in the Current Folder&quot; if $#Img &lt; 0;

    new_grid();

    sub on_event {
        my ($e) = @_;
        if($e-&gt;type == SDL_QUIT or $e-&gt;type == SDL_KEYDOWN and $e-&gt;key_sym == SDLK_ESCAPE) {
            $App-&gt;stop;
        }
        elsif($e-&gt;type == SDL_MOUSEBUTTONDOWN and $e-&gt;button_button == SDL_BUTTON_LEFT) {
            my($x, $y) = map { int($_ / 100) } $e-&gt;button_x, $e-&gt;button_y;
            if(won()) {
                new_grid();
            }
            elsif(!%Move and $Grid[$y][$x]) {
                for([-1, 0], [0, -1], [1, 0], [0, 1]) {
                    my($nx, $ny) = ($x + $_-&gt;[0], $y + $_-&gt;[1]);
                    if($nx &gt;= 0 and $nx &lt; 4 and $ny &gt;= 0 and $ny &lt; 4 and !$Grid[$ny][$nx]) {
                        %Move = (
                            x =&gt; $x,
                            y =&gt; $y,
                            x_dir =&gt; $_-&gt;[0],
                            y_dir =&gt; $_-&gt;[1],
                            offset =&gt; 0,
                        );
                    }
                }
            }
        }
    }

    sub on_move {
        if(%Move) {
            $Move{offset} += 30 * $_[0];
            if($Move{offset} &gt;= 100) {
                $Grid[$Move{y} + $Move{y_dir}][$Move{x} + $Move{x_dir}] = $Grid[$Move{y}][$Move{x}];
                $Grid[$Move{y}][$Move{x}] = 0;
                undef %Move;
            }
        }
    }

    sub on_show {
        $App-&gt;draw_rect( [0,0,$App-&gt;w,$App-&gt;h], 0 );
        for my $y (0..3) {
            for my $x (0..3) {
                next if not my $val = $Grid[$y][$x] and !won();
                my $xval = $val % 4;
                my $yval = int($val / 4);
                my $move = %Move &amp;&amp; $Move{x} == $x &amp;&amp; $Move{y} == $y;
                $App-&gt;blit_by(
                    $CurrentImg,
                    [$xval * 100, $yval * 100, 100, 100],
                    [$x * 100 + ($move ? $Move{offset} * $Move{x_dir} : 0),
                     $y * 100 + ($move ? $Move{offset} * $Move{y_dir} : 0)]
                );
            }
        }
        $App-&gt;flip;
    }

    sub new_grid {
        my @new = shuffle(0..15);
        @Grid = map { [@new[ $_*4..$_*4+3 ]] } 0..3;
        $CurrentImg = $Img[rand @Img];
    }

    sub won {
        my $correct = 0;
        for(@Grid) {
            for(@$_) {
                return 0 if $correct != $_;
                $correct++;
            }
        }
        return 1;
    }

    $App-&gt;add_event_handler(\&amp;on_event);
    $App-&gt;add_move_handler(\&amp;on_move);
    $App-&gt;add_show_handler(\&amp;on_show);
    $App-&gt;run;</code></pre>

<p>You now hopefully know more of the process that goes in to creating a
simple game. The process of creating a complex game is similar, it just
requires more careful planning. You should have also picked up a few other
tricks, like with <code>SDL::GFX::Rotozoom</code>,
<code>SDL::Image::load</code> and <code>blit_by</code>.</p>

<h2>Activities</h2>

<ol>

<li>1. Make the blank piece the bottom right piece instead of the top left
piece.</li>

<li>2. Make the grid dimensions variable by getting the value from
<code>$ARGV[0]</code>. The grid will then be 5x5 if <code>$ARGV[0]</code>
is 5 and so on.</li>

</ol>

<h2>Author</h2>

<p>This chapter's content graciously provided by Blaizer.</p>

<h1>Sound and Music</h1>

<p>Sound and Music in SDL are handled by the <code>Audio</code> and
<code>SDL_Mixer</code> components. Enabling <code>Audio</code> devices is
provided with the Core SDL Library and only supports wav files.
<code>SDL_Mixer</code> supports more audio file formats and has additional
features that we need for sound in Game Development.</p>

<p>Similarly to video in SDL, there are several way for perl developers to
access the Sound components of SDL. For the plain <code>Audio</code>
component the <code>SDL::Audio</code> and related modules are available.
<code>SDL_Mixer</code> is supported with th <code>SDL::Mixer</code> module.
There is currently a <code>SDLx::Sound</code> module in the work, but not
completed at the time of writing this manual. For that reason this chapter
will use <code>SDL::Audio</code> and <code>SDL::Mixer</code>.</p>

<h2>Simple Sound Script</h2>

<p>To begin using sound we must enable and open an audiospec:</p>

<pre><code> use strict;
   use warnings;
   use SDL;
   use Carp;
   use SDL::Audio;
   use SDL::Mixer;
   
   SDL::init(SDL_INIT_AUDIO);
   
   unless( SDL::Mixer::open_audio( 44100, AUDIO_S16SYS, 2, 4096 ) == 0 )
   {
      Carp::croak &quot;Cannot open audio: &quot;.SDL::get_error();
   }
   </code></pre>

<p><code>open_audio</code> will open an audio device with frequency at
44100 Mhz, audio format AUDIO_S16SYS (Note: This is currently the most
portable format, however there are others), 2 channels and a chunk size of
4096. Fiddle with these values if you are comfortable with sound
terminology and techniques.</p>

<h3>Loading Samples</h3>

<p>Next we will load sound samples that generally used for sound effects
and the like. Currently <code>SDL_Mixer</code> reserves samples for
<code>.WAV</code>, <code>.AIFF</code>, <code>.RIFF</code>
<code>.OGG</code>, and <code>.VOC</code> formats.</p>

<p>Samples run on one of the 2 channels that we opened up, while the other
channel will be reserved for multiple plays of the sample. To load samples
we will be doing the following:</p>

<pre><code> +use SDL::Mixer::Samples;

   +#Brillant Lazer Sound from HTTP://FreeSound.Org/samplesViewSingle.php?id=30935
   +my $sample = SDL::Mixer::Samples::load_WAV(&#39;data/sample.wav&#39;);

   +unless($sample)
   +{
   + Carp::croak &quot;Cannot load file data/sample.wav: &quot;.SDL::get_error();
   +}</code></pre>

<h3>Playing the sample and closing audio</h3>

<p>Now we can play that sample on any open channel looping forever:</p>

<pre><code> use SDL::Mixer::Samples;
   +use SDL::Mixer::Channels;
   
   my $sample = SDL::Mixer::Samples::load_WAV(&#39;data/sample.wav&#39;);
   unless( $sample)
   {
      Carp::croak &quot;Cannot load file data/sample.wav: &quot;.SDL::get_error();
   }

   +my $playing_channel = SDL::Mixer::Channels::play_channel( -1, $sample, 0 );</code></pre>

<p><code>play_channel</code> allows us to assign a sample to the channel
<code>-1</code> which indicates any open channel. <code>0</code> indicates
we want to play the sample only once.</p>

<p>Note that since the sound will be playing in an external process we will
need to keep the perl script running. In a game this is no problem but for
a single script like this we can just use a simple <code>sleep</code>
function. Once we are done we can go ahead and close the audio device.</p>

<pre><code> +sleep(1);
   +SDL::Mixer::close_audio();</code></pre>

<h3>Streaming Music</h3>

<p>Next we will use <code>SDL::Mixer::Music</code> to add a background
music to our script here.</p>

<pre><code> use SDL::Mixer::Channels;
    +use SDL::Mixer::Music;

    +#Load our awesome music from HTTP://8BitCollective.Com
    +my $background_music =
        + SDL::Mixer::Music::load_MUS(&#39;data/music/01-PC-Speaker-Sorrow.ogg&#39;);


    +unless( $background_music )
    +{
    + Carp::croak &quot;Cannot load music file data/music/01-PC-Speaker-Sorrow.ogg: &quot;.SDL::get_error() ;
    +}</code></pre>

<p>Music types in <code>SDL::Mixer</code> run in a separate channel from
our samples which allows us to have sound effects (like jump, or lasers
etc) to play at the same time.</p>

<pre><code> +SDL::Mixer::Music::play_music($background_music,0); </code></pre>

<p><code>play_music</code> also takes a parameter for how many loops you
would like to play the song for, where 0 is 1.</p>

<p>To stop the music we can call <code>halt_music</code>.</p>

<pre><code> sleep(2);
   +SDL::Mixer::Music::halt_music();
    SDL::Mixer::close_audio();</code></pre>

<blockquote>

<p>Controlling Volume can be as simple as:</p>

<pre><code> #All channels indicated by the -1
   SDL::Mixer::Channels::volume(-1,10);

   #Specifically for the Music
   SDL::Mixer::Music::volume_music( 10 );</code></pre>

<p>Volumes can be set at anytime and range from <code>1-100</code>.</p>

</blockquote>

<h3>Code so far</h3>

<pre><code> use strict;
    use warnings;
    use SDL;
    use Carp;
    use SDL::Audio;
    use SDL::Mixer;
    use SDL::Mixer::Samples;
    use SDL::Mixer::Channels;
    use SDL::Mixer::Music;
    SDL::init(SDL_INIT_AUDIO);

    unless( SDL::Mixer::open_audio( 44100, AUDIO_S16SYS, 2, 4096 ) == 0 )
    {
        Carp::croak &quot;Cannot open audio: &quot;.SDL::get_error();
    }


    my $sample = SDL::Mixer::Samples::load_WAV(&#39;data/sample.wav&#39;);

    unless( $sample)
    {
        Carp::croak &quot;Cannot load file data/sample.wav: &quot;.SDL::get_error();
    }

    my $playing_channel = SDL::Mixer::Channels::play_channel( -1, $sample, 0 );

    #Load our awesome music from HTTP://8BitCollective.Com
    my $background_music = SDL::Mixer::Music::load_MUS(&#39;data/music/01-PC-Speaker-Sorrow.ogg&#39;);

    unless( $background_music )
    {
        Carp::croak &quot;Cannot load music file data/music/01-PC-Speaker-Sorrow.ogg: &quot;
                .SDL::get_error();
    }

    SDL::Mixer::Music::play_music( $background_music,0 );

    sleep(2);

    SDL::Mixer::Music::halt_music();
    SDL::Mixer::close_audio;</code></pre>

<h2>Sound Applications</h2>

<p>Now that we know how to prepare and play simple sounds we will apply it
to an <code>SDLx::App</code>.</p>

<h3>SDLx::App Audio Initialization</h3>

<p><code>SDLx::App</code> will initialize everything normally for us.
However for a stream line application it is recommend to initialize only
the things we need. In this case that is <code>SDL_INIT_VIDEO</code> and
<code>SDL_INIT_AUDIO</code>.</p>

<pre><code> use strict;
    use warnings;
    use SDL;
    use Carp;
    use SDLx::App;
    use SDL::Audio;
    use SDL::Mixer;
    use SDL::Event;
    use SDL::Events;
    use SDL::Mixer::Music;
    use SDL::Mixer::Samples;
    use SDL::Mixer::Channels;

    my $app = SDLx::App-&gt;new(
        init =&gt; SDL_INIT_AUDIO | SDL_INIT_VIDEO,
        width =&gt; 250,
        height =&gt; 75,
        title =&gt; &quot;Sound Event Demo&quot;,
        eoq =&gt; 1
  
  );</code></pre>

<h3>Loading Resources</h3>

<p>It is highly recommended to perform all resource allocations before a
<code>SDLx::App::run()</code> method is called.</p>

<pre><code> # Initialize the Audio
    unless ( SDL::Mixer::open_audio( 44100, AUDIO_S16SYS, 2, 4096 ) == 0 ) {
        Carp::croak &quot;Cannot open audio: &quot; . SDL::get_error();
    }

    #Something to show while we play music and sounds
    my $channel_volume = 100;
    my $music_volume = 100;
    my $laser_status = &#39;none&#39;;
    my $music_status = &#39;not playing&#39;;

    # Load our sound resources
    my $laser = SDL::Mixer::Samples::load_WAV(&#39;data/sample.wav&#39;);
    unless ($laser) {
        Carp::croak &quot;Cannot load sound: &quot; . SDL::get_error();
    }

    my $background_music =
    SDL::Mixer::Music::load_MUS(&#39;data/music/01-PC-Speaker-Sorrow.ogg&#39;);
    unless ($background_music) {
        Carp::croak &quot;Cannot load music: &quot; . SDL::get_error();
    }</code></pre>

<h3>The Show Handler</h3>

<p>For the purposes of describing the current state of the music lets draw
text to the screen in a <code>show_handler</code>.</p>

<pre><code> $app-&gt;add_show_handler(
    sub {

        $app-&gt;draw_rect([0,0,$app-&gt;w,$app-&gt;h], 0 );

        $app-&gt;draw_gfx_text( [10,10], [255,0,0,255], &quot;Channel Volume : $channel_volume&quot; );
        $app-&gt;draw_gfx_text( [10,25], [255,0,0,255], &quot;Music Volume : $music_volume&quot; );
        $app-&gt;draw_gfx_text( [10,40], [255,0,0,255], &quot;Laser Status : $laser_status&quot; );
        $app-&gt;draw_gfx_text( [10,55], [255,0,0,255], &quot;Music Status : $music_status&quot; );

        $app-&gt;update();

    }
    );</code></pre>

<p>This will draw the channel volume of our samples, and the volume of the
music. It will also print the status of our two sounds in the
application.</p>

<h3>The Event Handler</h3>

<p>Finally our event handler will do the actual leg work and trigger the
music and sound as we need it.</p>

<pre><code> $app-&gt;add_event_handler(
        sub {
            my $event = shift;

            if ( $event-&gt;type == SDL_KEYDOWN ) {
                my $keysym = $event-&gt;key_sym;
                my $keyname = SDL::Events::get_key_name($keysym);

                if ( $keyname eq &#39;space&#39; ) {

                    $laser_status = &#39;PEW!&#39;;
                    #fire lasers!
                    SDL::Mixer::Channels::play_channel( -1, $laser, 0 );

                }
                elsif ( $keyname eq &#39;up&#39; ) {
                    $channel_volume += 5 unless $channel_volume == 100;
                }
                elsif ( $keyname eq &#39;down&#39; ) {
                    $channel_volume -= 5 unless $channel_volume == 0;
                }
                elsif ( $keyname eq &#39;right&#39; ) {
                    $music_volume += 5 unless $music_volume == 100;
                }
                elsif ( $keyname eq &#39;left&#39; ) {
                    $music_volume -= 5 unless $music_volume == 0;
                }
                elsif ( $keyname eq &#39;return&#39; ) {
                    my $playing = SDL::Mixer::Music::playing_music();
                    my $paused = SDL::Mixer::Music::paused_music();

                    if ( $playing == 0 &amp;&amp; $paused == 0 ) {
                        SDL::Mixer::Music::play_music( $background_music, 1 );
                        $music_status = &#39;playing&#39;;
                    }
                    elsif ( $playing &amp;&amp; !$paused ) {
                        SDL::Mixer::Music::pause_music();
                        $music_status = &#39;paused&#39;
                    }
                    elsif ( $playing &amp;&amp; $paused ) {
                        SDL::Mixer::Music::resume_music();
                        $music_status = &#39;resumed playing&#39;;
                    }

                }

                SDL::Mixer::Channels::volume( -1, $channel_volume );
                SDL::Mixer::Music::volume_music($music_volume);

            }

          }

    );</code></pre>

<p>The above event handler fires the laser on pressing the 'Space' key. Go
ahead and press it multiple times as if you are firing a gun in a game! You
will notice that depending on how fast you fire the laser the application
will still manage to overlap the sounds as needed. The sample overlapping
is accomplished by requiring multiple channels in the
<code>open_audio</code> call. If your game has lots of samples that may
play at the same time you may need more channels allocated. Additionally
you can see that the volume control is easily managed both on the channels
and the music with just incrementing or decrementing a value and calling
the appropriate function.</p>

<p>Finally it is worth noticing the various state the background music can
be in.</p>

<p>Lets run this application and the make sure to clean up the audio on the
way out. $app->run(); SDL::Mixer::Music::halt_music();
SDL::Mixer::close_audio;</p>

<h3>Completed Code</h3>

<pre><code> use strict;
    use warnings;

    use Cwd;
    use Carp;
    use File::Spec;

    use threads;
    use threads::shared;

    use SDL;
    use SDL::Event;
    use SDL::Events;

    use SDL::Audio;
    use SDL::Mixer;
    use SDL::Mixer::Music;
    use SDL::Mixer::Effects;

    use SDLx::App;
    my $app = SDLx::App-&gt;new(
        init =&gt; SDL_INIT_AUDIO | SDL_INIT_VIDEO,
        width =&gt; 800,
        height =&gt; 600,
        depth =&gt; 32,
        title =&gt; &quot;Music Visualizer&quot;,
        eoq =&gt; 1,
        dt =&gt; 0.2,
    );

    # Initialize the Audio
    unless ( SDL::Mixer::open_audio( 44100, AUDIO_S16, 2, 1024 ) == 0 ) {
        Carp::croak &quot;Cannot open audio: &quot; . SDL::get_error();
    }

    # Load our music files
    my $data_dir = &#39;.&#39;;
    my @songs = glob &#39;data/music/*.ogg&#39;;

    my @stream_data : shared;

    # Music Effect to pull Stream Data
    sub music_data {
        my ( $channel, $samples, $position, @stream ) = @_;

        {
            lock(@stream_data);
            push @stream_data, @stream;
        }

        return @stream;
    }

    sub done_music_data { }

    my $music_data_effect_id =
      SDL::Mixer::Effects::register( MIX_CHANNEL_POST, &quot;main::music_data&quot;,
        &quot;main::done_music_data&quot;, 0 );

    # Music Playing Callbacks
    my $current_song = 0;
    my $lines = $ARGV[0] || 50;

    my $current_music_callback = sub {
        my ( $delta, $app ) = @_;

        $app-&gt;draw_rect( [ 0, 0, $app-&gt;w(), $app-&gt;h() ], 0x000000FF );
        $app-&gt;draw_gfx_text(
            [ 5, $app-&gt;h() - 10 ],
            [ 255, 0, 0, 255 ],
            &quot;Playing Song: &quot; . $songs[ $current_song - 1 ]
        );

        my @stream;
        {
            lock @stream_data;
            @stream = @stream_data;
            @stream_data = ();
        }

        # To show the right amount of lines we choose a cut of the stream
        # this is purely for asthetic reasons.

        my $cut = @stream / $lines;

        # The width of each line is calculated to use.
        my $l_wdt = ( $app-&gt;w() / $lines ) / 2;

        for ( my $i = 0 ; $i &lt; $#stream ; $i += $cut ) {

            # In stereo mode the stream is split between two alternating streams
            my $left = $stream[$i];
            my $right = $stream[ $i + 1 ];

            # For each bar we calculate a Y point and a X point
            my $point_y = ( ( ($left) ) * $app-&gt;h() / 4 / 32000 ) + ( $app-&gt;h / 2 );
            my $point_y_r =
              ( ( ($right) ) * $app-&gt;h() / 4 / 32000 ) + ( $app-&gt;h / 2 );
            my $point_x = ( $i / @stream ) * $app-&gt;w;

            # Using the parameters
            # Surface, box coordinates and color as RGBA
            SDL::GFX::Primitives::box_RGBA(
                $app,
                $point_x - $l_wdt,
                $app-&gt;h() / 2,
                $point_x + $l_wdt,
                $point_y, 40, 0, 255, 128
            );
            SDL::GFX::Primitives::box_RGBA(
                $app,
                $point_x - $l_wdt,
                $app-&gt;h() / 2,
                $point_x + $l_wdt,
                $point_y_r, 255, 0, 40, 128
            );

        }

        $app-&gt;flip();

    };

    my $cms_move_callback_id;
    my $pns_move_callback_id;
    my $play_next_song_callback;

    sub music_finished_playing {
        SDL::Mixer::Music::halt_music();

        $pns_move_callback_id = $app-&gt;add_move_handler($play_next_song_callback)
          if ( defined $play_next_song_callback );

    }

    $play_next_song_callback = sub {
        return $app-&gt;stop() if $current_song &gt;= @songs;
        my $song = SDL::Mixer::Music::load_MUS( $songs[ $current_song++ ] );
        SDL::Mixer::Music::play_music( $song, 0 );

        $app-&gt;remove_move_handler($pns_move_callback_id)
          if defined $pns_move_callback_id;
    };

    $app-&gt;add_show_handler($current_music_callback);
    $pns_move_callback_id = $app-&gt;add_move_handler($play_next_song_callback);

    $app-&gt;add_move_handler(
        sub {
            my $music_playing = SDL::Mixer::Music::playing_music();

            music_finished_playing() unless $music_playing;

        }
    );

    $app-&gt;add_event_handler(
        sub {
            my ( $event, $app ) = @_;
            if ( $event-&gt;type == SDL_KEYDOWN &amp;&amp; $event-&gt;key_sym == SDLK_DOWN ) {

                # Indicate that we are done playing the music_finished_playing
                music_finished_playing();
            }
        }
    );

    $app-&gt;run();

    SDL::Mixer::Effects::unregister( MIX_CHANNEL_POST, $music_data_effect_id );
    SDL::Mixer::Music::hook_music_finished();
    SDL::Mixer::Music::halt_music();
    SDL::Mixer::close_audio();</code></pre>

<h2>Music Visualizer</h2>

<p>The music visualizer example processes real-time sound data--data as it
plays--and displays the wave form on the screen. It will look something
like:</p>

<p>\includegraphics[width=0.5\textwidth]{../src/images/spectro-1.png}
\caption{Simple Music Visualization} \label{fig:Visualization}</p>



<h3>The Code and Comments</h3>

<p>The program begins with the usual boilerplate of an SDL Perl
application:</p>

<pre><code> use strict;
        use warnings;

        use Cwd;
        use Carp;
        use File::Spec;

        use threads;
        use threads::shared;

        use SDL;
        use SDL::Event;
        use SDL::Events;

        use SDL::Audio;
        use SDL::Mixer;
        use SDL::Mixer::Music;
        use SDL::Mixer::Effects;

        use SDLx::App;</code></pre>

<p>It then creates an application with both audio and video support:</p>

<pre><code> my $app = SDLx::App-&gt;new(
                init =&gt; SDL_INIT_AUDIO | SDL_INIT_VIDEO,
                width =&gt; 800,
                height =&gt; 600,
                depth =&gt; 32,
                title =&gt; &quot;Sound Event Demo&quot;,
                eoq =&gt; 1,
                dt =&gt; 0.2,
        );</code></pre>

<p>The application must initialize the audio system with a format matching
the expected audio input. <code>AUDIO_S16</code> provides a 16-bit signed
integer array for the stream data:</p>

<pre><code> # Initialize the Audio
        unless ( SDL::Mixer::open_audio( 44100, AUDIO_S16, 2, 1024 ) == 0 ) {
                Carp::croak &quot;Cannot open audio: &quot; . SDL::get_error();
        }</code></pre>

<p>The music player needs the music files from the <i>data/music/</i>
directory:</p>

<pre><code> # Load our music files
        my $data_dir = &#39;.&#39;;
        my @songs = glob &#39;data/music/*.ogg&#39;;</code></pre>

<p>A music effect reads stream data, then serializes it to share between
threads:</p>

<pre><code> my @stream_data : shared;

    # Music Effect to pull Stream Data
    sub music_data {
        my ( $channel, $samples, $position, @stream ) = @_;

        {
            lock(@stream_data);
            push @stream_data, @stream;
        }

        return @stream;
    }

    sub done_music_data { }</code></pre>

<p>... and that effect gets registered as a callback with
<code>SDL::Mixer::Effects</code>:</p>

<pre><code> my $music_data_effect_id =
                  SDL::Mixer::Effects::register( MIX_CHANNEL_POST, &quot;main::music_data&quot;,
                        &quot;main::done_music_data&quot;, 0 );</code></pre>

<p>The program's single command-line option governs the number of lines to
display in the visualizer. The default is 50.</p>

<pre><code> my $lines = $ARGV[0] || 50;</code></pre>

<p>The drawing callback for the <code>SDLx::App</code> runs while a song
plays. It reads the stream data and displays it on the screen as a wave
form. The math behind calculating the graphics to display is more detail
than this article intends, but the graphic code is straightforward:</p>

<pre><code> # Music Playing Callbacks
    my $current_song = 0;

    my $current_music_callback = sub {
        my ( $delta, $app ) = @_;

        $app-&gt;draw_rect( [ 0, 0, $app-&gt;w(), $app-&gt;h() ], 0x000000FF );
        $app-&gt;draw_gfx_text(
            [ 5, $app-&gt;h() - 10 ],
            [ 255, 0, 0, 255 ],
            &quot;Playing Song: &quot; . $songs[ $current_song - 1 ]
        );

        my @stream;
        {
            lock @stream_data;
            @stream = @stream_data;
            @stream_data = ();
        }

        # To show the right amount of lines we choose a cut of the stream
        # this is purely for asthetic reasons.

        my $cut = @stream / $lines;

        # The width of each line is calculated to use.
        my $l_wdt = ( $app-&gt;w() / $lines ) / 2;

        for ( my $i = 0 ; $i &lt; $#stream ; $i += $cut ) {

            # In stereo mode the stream is split between two alternating streams
            my $left = $stream[$i];
            my $right = $stream[ $i + 1 ];

            # For each bar we calculate a Y point and a X point
            my $point_y = ( ( ($left) ) * $app-&gt;h() / 4 / 32000 ) + ( $app-&gt;h / 2 );
            my $point_y_r =
              ( ( ($right) ) * $app-&gt;h() / 4 / 32000 ) + ( $app-&gt;h / 2 );
            my $point_x = ( $i / @stream ) * $app-&gt;w;

            # Using the parameters
            # Surface, box coordinates and color as RGBA
            SDL::GFX::Primitives::box_RGBA(
                $app,
                $point_x - $l_wdt,
                $app-&gt;h() / 2,
                $point_x + $l_wdt,
                $point_y, 40, 0, 255, 128
            );
            SDL::GFX::Primitives::box_RGBA(
                $app,
                $point_x - $l_wdt,
                $app-&gt;h() / 2,
                $point_x + $l_wdt,
                $point_y_r, 255, 0, 40, 128
            );

        }

        $app-&gt;flip();

    };</code></pre>

<p>Whenever a song finishes <code>SDL::Mixer::Music::playing_music</code>
returns <code>0</code>. We detect this change in state and call
<code>music_finished_playing()</code> where the program attaches our
<code>$play_next_song_callback</code> callback to switch to the next song
gracefully:</p>

<pre><code> my $cms_move_callback_id;
    my $pns_move_callback_id;
    my $play_next_song_callback;

    sub music_finished_playing {
        SDL::Mixer::Music::halt_music();
        $pns_move_callback_id = $app-&gt;add_move_handler($play_next_song_callback)
          if ( defined $play_next_song_callback );

    }

    $play_next_song_callback = sub {
        return $app-&gt;stop() if $current_song &gt;= @songs;
        my $song = SDL::Mixer::Music::load_MUS( $songs[ $current_song++ ] );
        SDL::Mixer::Music::play_music( $song, 0 );

        $app-&gt;remove_move_handler($pns_move_callback_id)
          if defined $pns_move_callback_id;
    };</code></pre>

<p>A move handler is attached to detect if music is playing or not:</p>

<pre><code> $app-&gt;add_move_handler(
        sub {
            my $music_playing = SDL::Mixer::Music::playing_music();
            music_finished_playing() unless $music_playing;
        }
    ) </code></pre>

<p>The first callback to trigger the <code>$play_next_song_callback</code>
gets the first song:</p>

<pre><code> $app-&gt;add_show_handler($current_music_callback);
    $pns_move_callback_id = $app-&gt;add_move_handler($play_next_song_callback);</code></pre>

<p>... and a keyboard event handler for a keypress allows the user to move
through songs:</p>

<pre><code> $app-&gt;add_event_handler(
        sub {
                my ($event, $app) = @_;

                if( $event-&gt;type == SDL_KEYDOWN &amp;&amp; $event-&gt;key_sym == SDLK_DOWN)
                {
                        #Indicate that we are done playing the music_finished_playing
                        music_finished_playing();
                }

        }
        );</code></pre>

<p>From there, the application is ready to run:</p>

<pre><code> $app-&gt;run();</code></pre>

<p>... and the final code gracefully stops <code>SDL::Mixer</code>:</p>

<pre><code> SDL::Mixer::Effects::unregister( MIX_CHANNEL_POST, $music_data_effect_id );
        SDL::Mixer::Music::hook_music_finished();
        SDL::Mixer::Music::halt_music();
        SDL::Mixer::close_audio();</code></pre>

<p>The result? Several dozen lines of code to glue together the SDL mixer
and display a real-time visualization of the music.</p>

<h1>CPAN</h1>

<p>The Comprehensive Perl Archive Network (CPAN) is the other part of the
Perl language. By now most Perl developers should be aware of how to search
and get modules from CPAN. This chapter will focus on why to use CPAN for
games. Next we will take a look in what domain (Model, View or Controller)
does a module solve a problem for. Moreover we would want to look at what
is criteria to pick one module from another, using the many tools provided
by CPAN.</p>

<h2>Modules</h2>

<p>It is good to reuse code.</p>

<h3>MVC Method</h3>

<p>See where the module fits, Model, View or Controller</p>

<h4>View</h4>

<p>SDL will do most but helper module (Clipboard) are cool to have.</p>

<p>The <i>SDLx::Widget</i> bundle comes separately, but is meant to provide
you with several common game elements such as menu, dialog boxes and
buttons, all seamlessly integrated with SDL.</p>

<h4>Model</h4>

<p>The logic and modelling behind most popular games is already on CPAN, so
you can easily plug them in to create a new game of Chess, Checkers, Go,
Life, Minesweeping, Cards, etc. There are even classes for platform games
(like <i>Games::Nintendo::Mario</i>), creating and solving mazes,
generating random dungeon maps, you name it. Have a look at
<i>Roguelike-Utils</i> and <i>Games::RolePlay::MapGen</i> for just a few of
those.</p>

<p>If your game needs to store data, like objects and status for saved
games or checkpoints, you can use <i>Storable</i> or any of the many data
serializers available.</p>

<p>In fact, speaking of data structures, it is common to keep game data in
standard formats such as JSON, YAML or XML, to make you able to
import/export them directly from third-party tools like visual map makers
or 3D modeling software. Perl provides very nice modules to handle the most
popular formats - and some pretty unusual ones. Parsers vary in speed, size
and thoroughness, so make sure to check the possible candidates and use the
one that fits your needs for speed, size and accuracy.</p>

<h4>Controller</h4>

<p>If you need to roll a dice, you can use <i>Games::Dice</i>, that even
lets you receive an array of rolled dice, and use RPG-like syntax (e.g.
"2d6+1" for 2 rolls of a 6-side die, adding 1 to the result).</p>

<p>You can also use <i>Sub::Frequency</i> if you need to do something or
trigger a particular action or event only sometimes, or at a given
probability.</p>

<p>Your game may need you to mix words, find substrings or manipulate word
permutations in any way (like when playing scrabble), in which case you
might find the <i>Games::Word</i> module useful.</p>

<h2>Picking Modules</h2>

<p>So, you thought of a nice game, identified your needs, typed some
keywords in HTTP://Search.CPAN.Org, and got tons of results. What now? How
to avoid vaporware and find the perfect solution for your needs?</p>

<h3>Documentation</h3>

<p>Once you find a potential module for your application, make sure you
will know how to use it. Take a look at the SYNOPSIS section of the module,
it should contain some code snippets showing you how to use the module's
main features. Are you comfortable with the usage syntax? Does it seem to
do what you expect it to? Will it fit nicely to whatever it is you're
coding?</p>

<p>Next, skim through the rest of the documentation. Is it solid enough for
you? Does it look complete enough for your needs, or is it easily
extendable?</p>

<h3>License</h3>

<p>It's useless to find a module you can't legally use. Most (if not all)
modules in HTTP://Search.CPAN.Org are free and open source software, but
even so each needs a license telling developers what they can and cannot do
with it. A lot of CPAN modules are released <i>"under the same terms as
Perl itself"</i>, and this means you can pick between the Artistic License
or the GPL (version 1).</p>

<p>Below is a short and incomplete list of some popular license choices by
CPAN developers:</p>

<ul>

<li>Artistic License - HTTP://Dev.Perl.Org/licenses/artistic.html</li>

<li>GPL (all versions and variations) - HTTP://GNU.Org/licenses</li>

<li>MIT License - HTTP://OpenSource.Org/licenses/mit-license.php</li>

</ul>

<p>See HTTP://OpenSource.Org/licenses/alphabetical for a comprehensive list
with each license's full documentation.</p>

<p>You should be able to find the module's license by going to a "LICENSE
AND COPYRIGHT" section, usually available at the bottom of the
documentation, or by looking for a license file inside that
distribution.</p>

<p><b>Note:</b> Some modules might even be released into CPAN as <i>public
domain</i>, meaning they are not covered by intellectual property rights at
all, and you are free to use them as you see fit. Even so, it's usually
considered polite to mention authors as a courtesy, you know, giving credit
where credit is due.</p>

<h3>Ratings</h3>

<p>The CPAN Ratings is a service where developers rate modules they used
for their own projects, and is a great way to have some actual feedback on
how it was to use the code on a real application. The ratings are compiled
into a 1 to 5 grade, and displayed below the module name on CPAN. You can
click on the <i>"Reviews"</i> link right next to the rating stars to see
any additional comments by the reviewers, praising, criticizing or giving
some additional comments or the distribution and/or its competition.</p>

<h3>Dependencies</h3>

<p>Modules exist so you don't have to reinvent the wheel, and for that same
reason each usually depends on one or more modules itself. Don't worry if a
module depends on several others - code reusability is a good thing.</p>

<p>You may, however, be interested in <b>which</b> modules it depends on,
or, more practically, in the likelihood of a clean installation by your
users. For that, you can browse to HTTP://Deps.CPANTesters.Org and input
the module's name on the search box.</p>

<p>The CPAN Testers is a collaborative matrix designed to help developers
test their modules in several different platforms, with over a hundred
testers each month making more than 3 million reports of CPAN modules. This
particular CPAN Testers service will show you a list of dependencies and
test results for each of them, calculating the average chance of all tests
passing (for any platform).</p>

<p>While seeing all the dependencies and test results of a couple of
modules that do the same thing might help you make your pick, it's
important to realize that the <i>"chance of all tests passing"</i>
information at the bottom of the results means very little. This is because
test failures can rarely be considered independent events, and are usually
tied to not running on a specific type of operating system, to the perl
version, or even due to the tester running out of memory for reasons that
may not even concern the module being evaluated. If you don't care about
your application running on AIX or on perl 5.6.0, why would you dismiss a
module that only fails on those conditions?</p>

<h3>CPAN Testers Charts</h3>

<p>So, how do you know the actual test results for a module on the CPAN?
How can you tell if that module will run in your target machine according
to architecture, operating system and perl version?</p>

<p>The CPAN Testers website at HTTP://CPANTesters.Org offers a direct
search for distributions by name or author. To see the results for the SDL
module, for instance, you can go to
HTTP://CPANTesters.Org/distro/S/SDL.html. You can also find a test report
summary directly on CPAN, by selecting the distribution and looking at the
<i>"CPAN Testers"</i> line. If you click on the <i>"View Reports"</i> link,
you'll be redirected to the proper CPAN Testers page, like the one shown
above.</p>

<p>The first chart is a PASS summary, containing information about the most
recent version of that module with at least one <i>PASS</i> report
submitted, separated by platform and perl version.</p>

<p>Second is a list of selected reports, detailing all the submitted test
results for the latest version of the given module. If you see a
<i>FAIL</i> or <i>UNKNOWN</i> result that might concern you - usually at a
platform you expect your application to run - you can click on it to see a
verbose output of all the tests, to see why it failed.</p>

<p>Another interesting information displayed is the report summary on the
left sidebar, showing a small colored graph of PASS-UNKNOWN-FAIL results
for the latest versions of the chosen module. If you see a released version
with lots of FAIL results, it might be interesting to dig deeper or simply
require a greater version of that module in your application.</p>

<h4>Bug Reports</h4>

<p>When picking a module to use, it is very important to check out its bug
reports. You can do that by either clicking on the <i>"View/Report
Bugs"</i> link on the module's page on CPAN, or on the <i>"CPAN RT"</i>
(for Request Tracker) box on the right side of the documentation page.</p>

<p>Look for open bugs and their description - i.e. if it's a bug or a
whislist - and see if it concerns your planned usage for that module. Some
bug reports are simple notices about a typo on the documentation or a very
specific issue, so make sure you look around the ticket description to see
if it's something that blocks your usage, or if you can live with it, at
least until the author delivers an update.</p>

<p>It may also interest you to see how long the open bugs have been there.
Distributions with bugs dating for more than two years might indicate that
the author abandoned the module to pursue other projects, so you'll likely
be on your own if you find any bumps. Of course, being free software, that
doesn't mean you can't fix things yourself, and maybe even ask the author
for maintainance privileges so you can update your fixes for other people
to use.</p>

<h3>Release Date</h3>

<p>A old distribution might mean a solid and stable distribution, but it
can also mean that the author doesn't care much about it anymore. If you
find a module whose latest version is over 5 years old, make sure to double
check test results and bug reports, as explained above.</p>

<h2>Conclusion</h2>

<p>CPAN is an amazing repository filled with nice modules ready for you to
use in your games. More than often you'll find that 90% of your application
is already done on CPAN, and all you have to do to get that awesome idea
implemented is glue them together, worrying only about your application's
own logic instead of boring sidework. This means faster development, and
more fun!</p>

<h2>Author</h2>

<p>This chapter's content graciously provided by Breno G. de Oliveira
(<code>garu</code>).</p>

<h1>Pixel Effects</h1>

<p>In this chapter we will look at how to use pixel effects in Perl. Pixel
effects are operations that are done directly on the bank of a
<code>SDL_Surface</code>'s pixel. These effects are used to do visual
effects in games and applications, most notably by <code>Frozen
Bubble</code>.</p>

<p>\includegraphics[h!][width=0.5\textwidth]{../src/images/effects.png}
\caption{Snow Effect covering Frozen Bubble's Logo }
\label{fig:frozen_bubble}</p>



<p>These effects can be done in purely in Perl, for 1 passes and non real
time applications. Effects that need to be done real time will have to be
done in C via XS. This chapter will show two methods of doing this.</p>

<h2>Sol's Ripple Effect</h2>

<p>For our first pixel effect we will be doing is a ripple effect from a
well known SDL resource, HTTP://Sol.Gfxile.Net/gp/ch02.html. This effects
uses <code>SDL::get_ticks</code> to animate a ripple effect across the
surface as seen in the following figure.</p>

<p>\includegraphics[width=0.5\textwidth]{../src/images/xs_effects.png}
\caption{Sol's Chapter 01 Ripple Effect} \label{fig:ripple}</p>



<h3>Pure Perl</h3>

<p>First lets make the effect in pure Perl. To do any operations with a
<code>SDL::Surface</code> we must do
<code>SDL::Video::lock_surface()</code> call as seen below. Locking the
surface prevents other process in SDL from accessing the surface. The
surface pixels can be accessed several ways from Perl. Here we are using
the <code>SDL::Surface::set_pixels</code> which takes an offset for the
<code>SDL_Surface</code> pixels array, and sets a value there for us. The
actual pixel effect is just a time dependent (using
<code>SDL::get_ticks</code> for time) render of a function. See
HTTP://Sol.Gfxile.Net/gp/ch02.html for a deeper explanation.</p>

<pre><code> use strict;
    use warnings;

    use SDL;
    use SDLx::App;

        # Render callback that we use to fiddle the colors on the surface
    sub render {
        my $screen = shift;
        if ( SDL::Video::MUSTLOCK($screen) ) {
            return if ( SDL::Video::lock_surface($screen) &lt; 0 );
        }

        my $ticks = SDL::get_ticks();
        my ( $i, $y, $yofs, $ofs ) = ( 0, 0, 0, 0 );
        for ( $i = 0; $i &lt; 480; $i++ ) {
            for ( my $j = 0, $ofs = $yofs; $j &lt; 640; $j++, $ofs++ ) {
                $screen-&gt;set_pixels( $ofs, ( $i * $i + $j * $j + $ticks ) );
            }
            $yofs += $screen-&gt;pitch / 4;
        }


        SDL::Video::unlock_surface($screen) if ( SDL::Video::MUSTLOCK($screen) );

        SDL::Video::update_rect( $screen, 0, 0, 640, 480 );

        return 0;
    }


    my $app = SDLx::App-&gt;new( width =&gt; 640,
                              height =&gt; 480,
                              eoq =&gt; 1,
                              title =&gt; &quot;Grovvy XS Effects&quot; );

    $app-&gt;add_show_handler( sub{ render( $app ) } );

    $app-&gt;run();</code></pre>

<p>One you run this program you will find it pretty much maxing out the CPU
and not running very smoothly. At this point running a loop through the
entire pixel bank of a <code>640x480</code> sized screen is too much for
Perl. We will need to move the intensive calculations to
<code>C</code>.</p>

<h3>Inline Effects </h3>

<p>In the below example we use <code>Inline</code> to write Inline
<code>C</code> code to handle the pixel effect for us. <code>SDL</code> now
provides support to work with <code>Inline</code>. The <code>render</code>
callback is now moved to <code>C</code> code, using <code>Inline C</code>.
When the program first runs it will compile the code and link it in for
us.</p>

<pre><code> use strict;
    use warnings;
    use Inline with =&gt; &#39;SDL&#39;;
    use SDL;
    use SDLx::App;


    my $app = SDLx::App-&gt;new( width =&gt; 640,
                              height =&gt; 480,
                              eoq =&gt; 1,
                              title =&gt; &quot;Grovvy XS Effects&quot; );

        # Make render a callback which has the expected signature from show_handlers
    $app-&gt;add_show_handler( \&amp;render);

    $app-&gt;run();

    use Inline C =&gt; &lt;&lt;&#39;END&#39;;

        // Show handlers recieve both float and the SDLx::App which is a SDL_Screen
    void render( float delta, SDL_Surface *screen )
    {
        // Lock surface if needed
        if (SDL_MUSTLOCK(screen))
            if (SDL_LockSurface(screen) &lt; 0)
                return;

        // Ask SDL for the time in milliseconds
        int tick = SDL_GetTicks();

        // Declare a couple of variables
        int i, j, yofs, ofs;

        // Draw to screen
        yofs = 0;
        for (i = 0; i &lt; 480; i++)
        {
            for (j = 0, ofs = yofs; j &lt; 640; j++, ofs++)
            {
                ((unsigned int*)screen-&gt;pixels)[ofs] = i * i + j * j + tick;
            }
            yofs += screen-&gt;pitch / 4;
        }

        // Unlock if needed
        if (SDL_MUSTLOCK(screen))
            SDL_UnlockSurface(screen);

        // Tell SDL to update the whole screen
        SDL_UpdateRect(screen, 0, 0, 640, 480);
    }

    END</code></pre>

<h1>Additional Modules</h1>

<h2>PDL</h2>

<p>The Perl Data Language (PDL) is a tool aimed at a more scientific crowd.
Accuracy is paramount and speed is the name of the game. PDL brings to Perl
fast matrix and numerical calculations. For games in most cases a accuracy
is not critical, but speed and efficiency is a great concern. For this
reason we will briefly explore how to share SDL texture data between PDL
and OpenGL.</p>

<p>This example will do the following:</p>

<p>\includegraphics[width=0.5\textwidth]{../src/images/pdl.png}
\caption{Not terribly interesting, but the speed is phenomenal}
\label{fig:pdl}</p>



<h3>Make the application</h3>

<p>Let's start an application to use with PDL. Make sure you do <code>use
PDL</code>.</p>

<pre><code> + use strict;
    + use warnings;
    + use SDL;
    + use SDL::Video;
    + use SDLx::App;
    +
    + use PDL;
    +
    + my $app = SDLx::App-&gt;new(
    + title =&gt; &#39;PDL and SDL application&#39;,
    + width =&gt; 640, height =&gt; 480, depth =&gt; 32,
    + eoq =&gt; 1);</code></pre>

<h3>Attaching the Piddle</h3>

<p>PDL core object is something called a piddle. To be able to perform PDL
calculations and show them on SDL surfaces, we need to share the memory
between them. SDL Surface memory is stored in a <code>void *</code> block
called <code>pixels</code>. <code>void *</code> memory has the property
that allows Surfaces to have varying depth, and pixel formats. This also
means that we can have PDL's memory as our <code>pixels</code> for our
surface.</p>

<pre><code> + sub make_surface_piddle {
    + my ( $bytes_per_pixel, $width, $height) = @_;
    + my $piddle = zeros( byte, $bytes_per_pixel, $width, $height );
    + my $pointer = $piddle-&gt;get_dataref();</code></pre>

<p>At this point we have a pointer to the <code>$piddle</code>'s memory
with the given specifications. Next we have our surface use that
memory.</p>

<pre><code> + my $s = SDL::Surface-&gt;new_form(
    + $pointer, $width, $height, 32,
    + $width * $bytes_per_pixel
    + );
    +
    + #Wrap it into a SDLx::Surface for ease of use
    + my $surface = SDLx::Surface-&gt;new( surface =&gt; $s );
    +
    + return ( $piddle, $surface );
    + } </code></pre>

<p>Lets make some global variables to hold our <code>$piddle</code> and
<code>$surface</code>.</p>

<pre><code> + my ( $piddle, $surface ) = make_surface_piddle( 4, 400, 200 ); </code></pre>

<h3>Drawing and Updating</h3>

<p><code>make_surface_piddle()</code> will return to use an anonymous array
with a <code>$piddle</code> and <code>$surface</code> which we can use with
PDL and SDL. PDL will be used to operate on the <code>$piddle</code>. SDL
will be used to update the <code>$surface</code> and render it to the
<code>SDLx::App</code>.</p>

<pre><code> + $app-&gt;add_move_handler( sub {
    +
    + SDL::Video::lock_surface($surface);
    +
    + $piddle-&gt;mslice( &#39;X&#39;,
    + [ rand(400), rand(400), 1 ],
    + [ rand(200), rand(200), 1 ]
    + ) .= pdl( rand(225), rand(225), rand(225), 255 );
    +
    + SDL::Video::unlock_surface($surface);
    + } );</code></pre>

<p><code>SDL::Video::lock_surface</code> prevents SDL from doing any
operations on the <code>$surface</code> until
<code>SDL::Video::unlock_surface</code> is called. Next we will blit this
surface onto the <code>$app</code>.</p>

<p>In this case we use PDL to draw random rectangles of random color.</p>

<h3>Running the App</h3>

<p>Finally we blit the <code>$surface</code> and update the
<code>$app</code>.</p>

<pre><code> + $app-&gt;add_show_handler( sub {
    +
    + $surface-&gt;blit( $app, [0,0,$surface-&gt;w,$surface-&gt;h], [10,10,0,0] );
    + $app-&gt;update();
    +
    + });

    + $app-&gt;run();</code></pre>

<h3>Complete Program</h3>

<pre><code> use strict;
    use warnings;
    use SDLx::App;

    use PDL;

    my $app = SDLx::App-&gt;new(
            title =&gt; &quot;PDL and SDL aplication&quot;,
            width =&gt; 640, height =&gt; 480, eoq =&gt; 1 );


    sub make_surface_piddle {
        my ( $bytes_per_pixel, $width, $height) = @_;
        my $piddle = zeros( byte, $bytes_per_pixel, $width, $height );
        my $pointer = $piddle-&gt;get_dataref();
        my $s = SDL::Surface-&gt;new_from(
            $pointer, $width, $height, 32,
            $width * $bytes_per_pixel
        );

        my $surface = SDLx::Surface-&gt;new( surface =&gt; $s );

        return ( $piddle, $surface );
    }


    my ( $piddle, $surface ) = make_surface_piddle( 4, 400, 200 );

    $app-&gt;add_move_handler( sub {

            SDL::Video::lock_surface($surface);

            $piddle-&gt;mslice( &#39;X&#39;,
                [ rand(400), rand(400), 1 ],
                [ rand(200), rand(200), 1 ]
                ) .= pdl( rand(225), rand(225), rand(225), 255 );

            SDL::Video::unlock_surface($surface);
            } );


    $app-&gt;add_show_handler( sub {

        $surface-&gt;blit( $app, [0,0,$surface-&gt;w,$surface-&gt;h], [10,10,0,0] );
        $app-&gt;update();

    });

    $app-&gt;run();</code></pre>

<h2>OpenGL and SDL</h2>

<p>OpenGL is a cross platform library for interactive 2D and 3D graphics
applications. However OpenGL specifies only the graphics pipeline and
doesn't handle inputs and events. SDL can hand over the graphics component
of an application over to OpenGL and take control over the event handling,
sound, and textures. In the first example we will see how to set up Perl's
<code>OpenGL</code> module with <code>SDLx::App</code>.</p>

<p>\includegraphics[width=0.5\textwidth]{../src/images/opengl-1.png}
\caption{The lovely blue teapot} \label{fig:opengl-1}</p>



<h3>SDL Setup</h3>

<pre><code> use strict;
        use warnings;
        use SDL;
        use SDLx::App;

        use OpenGL qw/:all/;

        my $app = SDLx::App-&gt;new(
                title =&gt; &quot;OpenGL App&quot;,
                width =&gt; 600,
                height =&gt; 600,
                gl =&gt; 1,
                eoq =&gt; 1
           );


        $app-&gt;run();</code></pre>

<p>Enabling <code>OpenGL</code> mode is as simple as adding the
<code>gl</code> flag to the <code>SDLx::App</code> constructor.</p>

<h3>OpenGL Setup</h3>

<p>Next we will make a <code>OpenGL</code> perspective with the
<code>$app</code>'s dimensions:</p>

<pre><code> glEnable(GL_DEPTH_TEST);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity;
        gluPerspective(60, $app-&gt;w/$app-&gt;h, 1, 1000 );
        glTranslatef( 0,0,-20);</code></pre>

<p>Additionally we will be initializing <code>glut</code>, but just to draw
something quick.</p>

<pre><code> #Using glut to draw something interesting really quick
        glutInit();</code></pre>

<h3>The Render Callback</h3>

<p>Now we are prepared to put something on the screen.</p>

<pre><code> $app-&gt;add_show_handler(
                sub{
                        my $dt = shift;
                
                        #clear the screen
                        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
                        glColor3d(0,1,1);

                        glutSolidTeapot(2);

                        #sync the SDL application with the OpenGL buffer data
                        $app-&gt;sync;


                }
        );</code></pre>

<p>At this point there should be a light blue teapot on the screen. The
only special thing to notice here is that we need to call the
<code>sync()</code> method on <code>$app</code>. This will flush the
buffers and update the SDL application for us.</p>

<h3>Event handling</h3>

<p>Event handling is the same as any other <code>SDLx::App</code>. We will
use the mouse motion changes to rotate the teapot.</p>

<p>First add a global variable to hold your rotate values. And then use
those values to rotate our teapot.</p>

<pre><code> glutInit();

    + my $rotate = [0,0];
     
      $app-&gt;add_show_handler(
        sub{
        my $dt = shift;
    
        #clear the screen
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        glColor3d(0,1,1);

    + glPushMatrix();

        + glRotatef($rotate-&gt;[0], 1,0,0);
    + glRotatef($rotate-&gt;[1], 0,1,0);

        glutSolidTeapot(2);

        #sync the SDL application with the OpenGL buffer data
        $app-&gt;sync;

   + glPopMatrix();
        }
    );</code></pre>

<p>Next we will add an event handler to the app to update the rotate values
for us.</p>

<pre><code> $app-&gt;add_event_handler(

        sub {
            my ($e ) = shift;

            if( $e-&gt;type == SDL_MOUSEMOTION )
                {
                    $rotate = [$e-&gt;motion_x, $e-&gt;motion_y];
                }

        }

    );</code></pre>

<p>Finally we run the application.</p>

<pre><code> $app-&gt;run();</code></pre>

<h3>Complete Code</h3>

<pre><code> use strict;
    use warnings;
    use SDL;
    use SDLx::App;
    use SDL::Event;

    use OpenGL qw/:all/;

    my $app = SDLx::App-&gt;new(
            title =&gt; &quot;OpenGL App&quot;,
            width =&gt; 600,
            height =&gt; 600,
            gl =&gt; 1,
            eoq =&gt; 1
            );

    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity;
    gluPerspective(60, $app-&gt;w/$app-&gt;h, 1, 1000 );
    glTranslatef( 0,0,-20);
    glutInit();

    my $rotate = [0,0];

    $app-&gt;add_show_handler(
            sub{
            my $dt = shift;

    #clear the screen
            glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
            glColor3d(0,1,1);

            glPushMatrix();

            glRotatef($rotate-&gt;[0], 1,0,0);
            glRotatef($rotate-&gt;[1], 0,1,0);

            glutSolidTeapot(2);

    #sync the SDL application with the OpenGL buffer data
            $app-&gt;sync;

            glPopMatrix();
            }
            );

    $app-&gt;add_event_handler(

            sub {
            my ($e ) = shift;

            if( $e-&gt;type == SDL_MOUSEMOTION )
            {
            $rotate = [$e-&gt;motion_x, $e-&gt;motion_y];
            }

            }

            );

    $app-&gt;run();</code></pre>

<h1>Free Resources</h1>

<p>When developing a game, coding is unfortunately not everything. Not by a
very, very long shot. To make up (a little) for that, below is a list of
free resources you can use in your games, either in full or simply as
inspiration for your own productions, in case you have an artistic vein
yourself.</p>

<p>Make sure to check the licence for the resource and use it accordingly,
giving the original author proper credit.</p>

<p><b>Note:</b> websites come and go, so if you find any of the links
broken, or know a nice free resource that's not listed here, please let us
know so we can update the list.</p>

<h2>Art and Sprites</h2>

<ul>

<li>HTTP://CGTextures.Com</li>

<li>HTTP://Mayang.Com/textures</li>

<li>HTTP://GRSites.Com/archive/textures</li>

<li>HTTP://ImageAfter.Com</li>

<li>HTTP://AbsoluteCross.Com/graphics/textures</li>

<li>HTTP://FreeFoto.Com</li>

<li>HTTP://Noctua-Graphics.De</li>

<li>HTTP://M3Corp.Com/a/download/3d_textures/pages</li>

<li>HTTP://ReinersTileSet.4Players.De/englisch.html</li>

<li>HTTP://VirtualWorlds.Wikia.Com</li>

<li>HTTP://Lunar.LostGarden.Com/labels/free%20game%20graphics.html</li>

<li>HTTP://PDGameResources.WordPress.Com</li>

<li>HTTP://GamingGroundZero.Com</li>

<li>HTTP://FlyingYogi.Com/fun/spritelib.html</li>

<li>HTTP://PixelPoke.Com</li>

</ul>

<h2>Music and Sound Effects</h2>

<ul>

<li>HTTP://FreeSound.Org</li>

<li>HTTP://CCMixter.Org</li>

<li>HTTP://Jamendo.Com</li>

<li>HTTP://8BC.Org</li>

<li>HTTP://Sakari-Infinity.Net</li>

<li>HTTP://FindSounds.Com</li>

<li>HTTP://GRSites.Com/archive/sounds</li>

</ul>

<h2>Fonts</h2>

<ul>

<li>HTTP://DAFont.Com</li>

<li>HTTP://FontSquirrel.Com</li>

<li>HTTP://TheLeagueOfMoveableType.Com</li>

<li>HTTP://OpenFontLibrary.Org</li>

<li>HTTP://AcidFonts.Com</li>

<li>HTTP://GRSites.Com/archive/fonts</li>

<li>HTTP://UrbanFonts.Com</li>

</ul>

<h2>DIY</h2>

<p>HTTP://GameSoundDesign.Com has several tips on making game music,
including several sources for inspiration.</p>

<p>If you want to create 3D models, either for cutscenes or to integrate
into your game via OpenGL, there are several nice libraries out there for
you:</p>

<p><b>Blender</b> - A free 3D graphics application for modeling, texturing,
water and smoke simulations, rendering, etc. HTTP://Blender.Org</p>

<p><b>OGRE</b> - An open-source graphics rendering engine, used in a large
number of production projects. It can be easily integrated via Scott
Lanning's <i>Ogre</i> Perl bindings, on CPAN. HTTP://Ogre3D.Org</p>

<h2>Author</h2>

<p>This chapter's content graciously provided by Breno G. de Oliveira
(<code>garu</code>).</p>

Something went wrong with that request. Please try again.