branches/kale/src/mame/drivers/model3.c
| r243932 | r243933 | |
| 1756 | 1756 | |
| 1757 | 1757 | READ64_MEMBER(model3_state::model3_security_r) |
| 1758 | 1758 | { |
| 1759 | | UINT64 retvalue = U64(0xffffffffffffffff); |
| 1760 | | |
| 1761 | 1759 | switch(offset) |
| 1762 | 1760 | { |
| 1763 | | case 0x00 / 8: retvalue = 0; break; /* status */ |
| 1761 | case 0x00/8: return 0; /* status */ |
| 1764 | 1762 | case 0x1c/8: /* security board data read */ |
| 1765 | 1763 | { |
| 1766 | 1764 | if (core_stricmp(machine().system().name, "vs299") == 0 || |
| 1767 | 1765 | core_stricmp(machine().system().name, "vs2v991") == 0) |
| 1768 | 1766 | { |
| 1769 | | retvalue = (UINT64)vs299_prot_data[m_prot_data_ptr++] << 48; |
| 1767 | return (UINT64)vs299_prot_data[m_prot_data_ptr++] << 48; |
| 1770 | 1768 | } |
| 1771 | 1769 | else if (core_stricmp(machine().system().name, "swtrilgy") == 0 || |
| 1772 | 1770 | core_stricmp(machine().system().name, "swtrilgya") == 0) |
| r243932 | r243933 | |
| 1776 | 1774 | { |
| 1777 | 1775 | m_prot_data_ptr = 0; |
| 1778 | 1776 | } |
| 1779 | | retvalue = data; |
| 1777 | return data; |
| 1780 | 1778 | } |
| 1781 | 1779 | else if (core_stricmp(machine().system().name, "fvipers2") == 0) |
| 1782 | 1780 | { |
| r243932 | r243933 | |
| 1785 | 1783 | { |
| 1786 | 1784 | m_prot_data_ptr = 0; |
| 1787 | 1785 | } |
| 1788 | | retvalue = data; |
| 1786 | return data; |
| 1789 | 1787 | } |
| 1790 | 1788 | else if (core_stricmp(machine().system().name, "spikeout") == 0 || |
| 1791 | 1789 | core_stricmp(machine().system().name, "spikeofe") == 0) |
| r243932 | r243933 | |
| 1795 | 1793 | { |
| 1796 | 1794 | m_prot_data_ptr = 0; |
| 1797 | 1795 | } |
| 1798 | | retvalue = data; |
| 1796 | return data; |
| 1799 | 1797 | } |
| 1800 | 1798 | else if (core_stricmp(machine().system().name, "eca") == 0 || |
| 1801 | 1799 | core_stricmp(machine().system().name, "ecax") == 0) |
| r243932 | r243933 | |
| 1805 | 1803 | { |
| 1806 | 1804 | m_prot_data_ptr = 0; |
| 1807 | 1805 | } |
| 1808 | | retvalue = data; |
| 1806 | return data; |
| 1809 | 1807 | } |
| 1810 | 1808 | else if (core_stricmp(machine().system().name, "oceanhun") == 0) |
| 1811 | 1809 | { |
| r243932 | r243933 | |
| 1814 | 1812 | { |
| 1815 | 1813 | m_prot_data_ptr = 0; |
| 1816 | 1814 | } |
| 1817 | | retvalue = data; |
| 1815 | return data; |
| 1818 | 1816 | } |
| 1819 | 1817 | else |
| 1820 | 1818 | { |
| 1821 | | retvalue = 0; |
| 1819 | return 0; |
| 1822 | 1820 | } |
| 1823 | | break; |
| 1824 | 1821 | } |
| 1825 | 1822 | } |
| 1826 | | printf("model3_security_r offset %08x : %08x%08x (%08x%08x)\n", offset * 8, (UINT32)(retvalue >> 32), (UINT32)(retvalue & 0xffffffff), (UINT32)(mem_mask >> 32), (UINT32)(mem_mask & 0xffffffff)); |
| 1827 | | |
| 1828 | | return retvalue; |
| 1823 | return U64(0xffffffffffffffff); |
| 1829 | 1824 | } |
| 1830 | 1825 | |
| 1831 | | READ64_MEMBER(model3_state::model3_5881prot_r) |
| 1832 | | { |
| 1833 | | UINT64 retvalue = U64(0xffffffffffffffff); |
| 1834 | | |
| 1835 | | if (offset == 0x00 / 8) |
| 1836 | | { |
| 1837 | | retvalue = 0; |
| 1838 | | } |
| 1839 | | else if (offset == 0x18 / 8) |
| 1840 | | { |
| 1841 | | if (first_read == 1) |
| 1842 | | { |
| 1843 | | // the RAM based schemes expect a dummy value before the start of the stream |
| 1844 | | // to match the previous simulation I use 0xffff here |
| 1845 | | first_read = 0; |
| 1846 | | retvalue = 0xffff << 16; |
| 1847 | | } |
| 1848 | | else |
| 1849 | | { |
| 1850 | | UINT8* base; |
| 1851 | | retvalue = m_cryptdevice->do_decrypt(base); |
| 1852 | | // retvalue = ((retvalue & 0xff00) >> 8) | ((retvalue & 0x00ff) << 8); // don't endian swap the return value on this hardware |
| 1853 | | retvalue <<= 16; |
| 1854 | | } |
| 1855 | | |
| 1856 | | // printf("model3_5881prot_r offset %08x : %08x%08x (%08x%08x)\n", offset * 8, (UINT32)(retvalue >> 32), (UINT32)(retvalue & 0xffffffff), (UINT32)(mem_mask >> 32), (UINT32)(mem_mask & 0xffffffff)); |
| 1857 | | } |
| 1858 | | else |
| 1859 | | { |
| 1860 | | printf("model3_5881prot_r offset %08x : %08x%08x (%08x%08x)\n", offset * 8, (UINT32)(retvalue >> 32), (UINT32)(retvalue & 0xffffffff), (UINT32)(mem_mask >> 32), (UINT32)(mem_mask & 0xffffffff)); |
| 1861 | | } |
| 1862 | | |
| 1863 | | return retvalue; |
| 1864 | | |
| 1865 | | |
| 1866 | | } |
| 1867 | | |
| 1868 | | WRITE64_MEMBER(model3_state::model3_5881prot_w) |
| 1869 | | { |
| 1870 | | if (offset == 0x10 / 8) |
| 1871 | | { |
| 1872 | | // code is copied to RAM first, so base address is always 0 |
| 1873 | | m_cryptdevice->set_addr_low(0); |
| 1874 | | m_cryptdevice->set_addr_high(0); |
| 1875 | | |
| 1876 | | if (data != 0) |
| 1877 | | printf("model3_5881prot_w address isn't 0?\n"); |
| 1878 | | |
| 1879 | | first_read = 1; |
| 1880 | | } |
| 1881 | | else if (offset == 0x18 / 8) |
| 1882 | | { |
| 1883 | | UINT16 subkey = data >> (32 + 16); |
| 1884 | | subkey = ((subkey & 0xff00) >> 8) | ((subkey & 0x00ff) << 8); // endian swap the sub-key for this hardware |
| 1885 | | printf("model3_5881prot_w setting subkey %04x\n", subkey); |
| 1886 | | m_cryptdevice->set_subkey(subkey); |
| 1887 | | } |
| 1888 | | else |
| 1889 | | { |
| 1890 | | printf("model3_5881prot_w offset %08x : %08x%08x (%08x%08x)\n", offset * 8, (UINT32)(data >> 32), (UINT32)(data & 0xffffffff), (UINT32)(mem_mask >> 32), (UINT32)(mem_mask & 0xffffffff)); |
| 1891 | | } |
| 1892 | | |
| 1893 | | |
| 1894 | | |
| 1895 | | } |
| 1896 | | |
| 1897 | 1826 | WRITE64_MEMBER(model3_state::daytona2_rombank_w) |
| 1898 | 1827 | { |
| 1899 | 1828 | if (ACCESSING_BITS_56_63) |
| r243932 | r243933 | |
| 1918 | 1847 | AM_RANGE(0xf00c0000, 0xf00dffff) AM_MIRROR(0x0e000000) AM_RAM AM_SHARE("backup") /* backup SRAM */ |
| 1919 | 1848 | AM_RANGE(0xf0100000, 0xf010003f) AM_MIRROR(0x0e000000) AM_READWRITE(model3_sys_r, model3_sys_w ) |
| 1920 | 1849 | AM_RANGE(0xf0140000, 0xf014003f) AM_MIRROR(0x0e000000) AM_READWRITE(model3_rtc_r, model3_rtc_w ) |
| 1850 | AM_RANGE(0xf0180000, 0xf019ffff) AM_MIRROR(0x0e000000) AM_RAM /* Security Board RAM */ |
| 1851 | AM_RANGE(0xf01a0000, 0xf01a003f) AM_MIRROR(0x0e000000) AM_READ(model3_security_r ) /* Security board */ |
| 1921 | 1852 | |
| 1922 | 1853 | AM_RANGE(0xf1000000, 0xf10f7fff) AM_READWRITE(model3_char_r, model3_char_w ) /* character RAM */ |
| 1923 | 1854 | AM_RANGE(0xf10f8000, 0xf10fffff) AM_READWRITE(model3_tile_r, model3_tile_w ) /* tilemaps */ |
| r243932 | r243933 | |
| 5660 | 5591 | MCFG_SOUND_ROUTE(0, "rspeaker", 2.0) |
| 5661 | 5592 | MACHINE_CONFIG_END |
| 5662 | 5593 | |
| 5663 | | UINT16 model3_state::crypt_read_callback(UINT32 addr) |
| 5664 | | { |
| 5665 | | UINT16 dat = 0; |
| 5666 | | if (addr < 0x8000) |
| 5667 | | { |
| 5668 | | dat = m_maincpu->space().read_word((0xf0180000 + 4 * addr)); // every other word is unused in this RAM, probably 32-bit ram on 64-bit bus? |
| 5669 | | } |
| 5670 | | |
| 5671 | | // dat = ((dat & 0xff00) >> 8) | ((dat & 0x00ff) << 8); |
| 5672 | | // printf("reading %04x\n", dat); |
| 5673 | | return dat; |
| 5674 | | } |
| 5675 | | |
| 5676 | | static MACHINE_CONFIG_DERIVED( model3_21_5881, model3_21 ) |
| 5677 | | MCFG_DEVICE_ADD("315_5881", SEGA315_5881_CRYPT, 0) |
| 5678 | | MCFG_SET_READ_CALLBACK(model3_state, crypt_read_callback) |
| 5679 | | MACHINE_CONFIG_END |
| 5680 | | |
| 5681 | | |
| 5682 | 5594 | static void interleave_vroms(running_machine &machine) |
| 5683 | 5595 | { |
| 5684 | 5596 | model3_state *state = machine.driver_data<model3_state>(); |
| r243932 | r243933 | |
| 5710 | 5622 | } |
| 5711 | 5623 | } |
| 5712 | 5624 | |
| 5713 | | DRIVER_INIT_MEMBER(model3_state, genprot) |
| 5714 | | { |
| 5715 | | INT64 key = get_315_5881_key(machine()); |
| 5716 | | |
| 5717 | | m_maincpu->space(AS_PROGRAM).install_ram(0xf0180000, 0xf019ffff, 0, 0x0e000000); |
| 5718 | | |
| 5719 | | if (key != -1) |
| 5720 | | { |
| 5721 | | // m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xf01a0000, 0xf01a003f, read64_delegate(FUNC(model3_state::model3_5881prot_r), this), write64_delegate(FUNC(model3_state::model3_5881prot_w), this)); |
| 5722 | | m_cryptdevice->set_key(key); |
| 5723 | | m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xf01a0000, 0xf01a003f, 0, 0x0e000000, read64_delegate(FUNC(model3_state::model3_5881prot_r), this), write64_delegate(FUNC(model3_state::model3_5881prot_w), this) ); |
| 5724 | | } |
| 5725 | | else |
| 5726 | | { |
| 5727 | | m_maincpu->space(AS_PROGRAM).install_read_handler(0xf01a0000, 0xf01a003f, 0, 0x0e000000, read64_delegate(FUNC(model3_state::model3_security_r), this) ); |
| 5728 | | } |
| 5729 | | } |
| 5730 | | |
| 5731 | 5625 | DRIVER_INIT_MEMBER(model3_state,model3_10) |
| 5732 | 5626 | { |
| 5733 | 5627 | interleave_vroms(machine()); |
| r243932 | r243933 | |
| 5948 | 5842 | |
| 5949 | 5843 | DRIVER_INIT_MEMBER(model3_state,swtrilgy) |
| 5950 | 5844 | { |
| 5951 | | |
| 5952 | 5845 | UINT32 *rom = (UINT32*)memregion("user1")->base(); |
| 5953 | 5846 | DRIVER_INIT_CALL(model3_20); |
| 5954 | 5847 | |
| r243932 | r243933 | |
| 5959 | 5852 | |
| 5960 | 5853 | rom[(0x043dc^4)/4] = 0x48000090; // skip force feedback setup |
| 5961 | 5854 | rom[(0xf6e44^4)/4] = 0x60000000; |
| 5962 | | |
| 5963 | | |
| 5964 | | DRIVER_INIT_CALL(genprot); |
| 5965 | | |
| 5966 | 5855 | } |
| 5967 | 5856 | |
| 5968 | 5857 | DRIVER_INIT_MEMBER(model3_state,swtrilga) |
| r243932 | r243933 | |
| 6114 | 6003 | GAME( 1999, vs299, vs2v991, model3_20, model3, model3_state, vs299, ROT0, "Sega", "Virtua Striker 2 '99", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6115 | 6004 | |
| 6116 | 6005 | /* Model 3 Step 2.1 */ |
| 6117 | | GAME( 1998, daytona2, 0, model3_21, daytona2, model3_state, daytona2, ROT0, "Sega", "Daytona USA 2 (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6118 | | GAME( 1998, dayto2pe, 0, model3_21, daytona2, model3_state, dayto2pe, ROT0, "Sega", "Daytona USA 2 Power Edition", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6119 | | GAME( 1998, dirtdvls, 0, model3_21, scud, model3_state, dirtdvls, ROT0, "Sega", "Dirt Devils (set 1) (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6120 | | GAME( 1998, dirtdvlsa, dirtdvls, model3_21, scud, model3_state, dirtdvls, ROT0, "Sega", "Dirt Devils (set 2) (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6121 | | GAME( 1998, swtrilgy, 0, model3_21_5881, swtrilgy, model3_state, swtrilgy, ROT0, "Sega / LucasArts", "Star Wars Trilogy (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6122 | | GAME( 1998, swtrilgya, swtrilgy, model3_21_5881, swtrilgy, model3_state, swtrilga, ROT0, "Sega / LucasArts", "Star Wars Trilogy", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6123 | | GAME( 1998, spikeout, 0, model3_21, model3, model3_state, spikeout, ROT0, "Sega", "Spikeout (Revision C)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6124 | | GAME( 1998, spikeofe, 0, model3_21, model3, model3_state, spikeofe, ROT0, "Sega", "Spikeout Final Edition", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6125 | | GAME( 1998, magtruck, 0, model3_21, eca, model3_state, magtruck, ROT0, "Sega", "Magical Truck Adventure", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6126 | | GAME( 1999, eca, 0, model3_21, eca, model3_state, eca, ROT0, "Sega", "Emergency Call Ambulance", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6127 | | GAME( 1999, ecax, eca, model3_21, eca, model3_state, eca, ROT0, "Sega", "Emergency Call Ambulance (Export)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6128 | | GAME( 1999, ecap, eca, model3_21, eca, model3_state, eca, ROT0, "Sega", "Emergency Call Ambulance (US location test?)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6006 | GAME( 1998, daytona2, 0, model3_21, daytona2, model3_state, daytona2, ROT0, "Sega", "Daytona USA 2 (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6007 | GAME( 1998, dayto2pe, 0, model3_21, daytona2, model3_state, dayto2pe, ROT0, "Sega", "Daytona USA 2 Power Edition", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6008 | GAME( 1998, dirtdvls, 0, model3_21, scud, model3_state, dirtdvls, ROT0, "Sega", "Dirt Devils (set 1) (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6009 | GAME( 1998, dirtdvlsa, dirtdvls, model3_21, scud, model3_state, dirtdvls, ROT0, "Sega", "Dirt Devils (set 2) (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6010 | GAME( 1998, swtrilgy, 0, model3_21, swtrilgy, model3_state, swtrilgy, ROT0, "Sega / LucasArts", "Star Wars Trilogy (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6011 | GAME( 1998, swtrilgya, swtrilgy, model3_21, swtrilgy, model3_state, swtrilga, ROT0, "Sega / LucasArts", "Star Wars Trilogy", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6012 | GAME( 1998, spikeout, 0, model3_21, model3, model3_state, spikeout, ROT0, "Sega", "Spikeout (Revision C)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6013 | GAME( 1998, spikeofe, 0, model3_21, model3, model3_state, spikeofe, ROT0, "Sega", "Spikeout Final Edition", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6014 | GAME( 1998, magtruck, 0, model3_21, eca, model3_state, magtruck, ROT0, "Sega", "Magical Truck Adventure", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6015 | GAME( 1999, eca, 0, model3_21, eca, model3_state, eca, ROT0, "Sega", "Emergency Call Ambulance", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6016 | GAME( 1999, ecax, eca, model3_21, eca, model3_state, eca, ROT0, "Sega", "Emergency Call Ambulance (Export)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 6017 | GAME( 1999, ecap, eca, model3_21, eca, model3_state, eca, ROT0, "Sega", "Emergency Call Ambulance (US location test?)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
branches/kale/src/mame/drivers/stv.c
| r243932 | r243933 | |
| 3007 | 3007 | |
| 3008 | 3008 | //GAME YEAR, NAME, PARENT, MACH, INP, INIT, MONITOR |
| 3009 | 3009 | /* Playable */ |
| 3010 | | GAME( 1998, astrass, stvbios, stv, stv6b, stv_state, astrass, ROT0, "Sunsoft", "Astra SuperStars (J 980514 V1.002)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 3010 | GAME( 1998, astrass, stvbios, stv, stv6b, stv_state, astrass, ROT0, "Sunsoft", "Astra SuperStars (J 980514 V1.002)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 3011 | 3011 | GAME( 1995, bakubaku, stvbios, stv, stv, stv_state, stv, ROT0, "Sega", "Baku Baku Animal (J 950407 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3012 | 3012 | GAME( 1996, batmanfr, stvbios, batmanfr, stv, stv_state, batmanfr, ROT0, "Acclaim", "Batman Forever (JUE 960507 V1.000)", GAME_NO_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3013 | 3013 | GAME( 1996, colmns97, stvbios, stv, stv, stv_state, colmns97, ROT0, "Sega", "Columns '97 (JET 961209 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3014 | 3014 | GAME( 1997, cotton2, stvbios, stv, stv, stv_state, cotton2, ROT0, "Success", "Cotton 2 (JUET 970902 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3015 | 3015 | GAME( 1998, cottonbm, stvbios, stv, stv, stv_state, cottonbm, ROT0, "Success", "Cotton Boomerang (JUET 980709 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3016 | 3016 | GAME( 1995, critcrsh, stvbios, stv, critcrsh, stv_state, critcrsh, ROT0, "Sega", "Critter Crusher (EA 951204 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3017 | | GAME( 1999, danchih, stvbios, stv, stvmp, stv_state, danchih, ROT0, "Altron (Tecmo license)", "Danchi de Hanafuda (J 990607 V1.400)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3017 | GAME( 1999, danchih, stvbios, stv, stvmp, stv_state, danchih, ROT0, "Altron (Tecmo license)", "Danchi de Hanafuda (J 990607 V1.400)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3018 | 3018 | GAME( 2000, danchiq, stvbios, stv, stv, stv_state, danchiq, ROT0, "Altron", "Danchi de Quiz Okusan Yontaku Desuyo! (J 001128 V1.200)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3019 | 3019 | GAME( 1996, diehard, stvbios, stv, stv, stv_state, diehard, ROT0, "Sega", "Die Hard Arcade (UET 960515 V1.000)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 3020 | 3020 | GAME( 1996, dnmtdeka, diehard, stv, stv, stv_state, dnmtdeka, ROT0, "Sega", "Dynamite Deka (J 960515 V1.000)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 3021 | 3021 | GAME( 1995, ejihon, stvbios, stv, stv, stv_state, stv, ROT0, "Sega", "Ejihon Tantei Jimusyo (J 950613 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3022 | | GAME( 1998, elandore, stvbios, stv, stv6b, stv_state, elandore, ROT0, "Sai-Mate", "Touryuu Densetsu Elan-Doree / Elan Doree - Legend of Dragoon (JUET 980922 V1.006)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3023 | | GAME( 1999, ffreveng, stvbios, stv, stv, stv_state, ffreveng, ROT0, "Capcom", "Final Fight Revenge (JUET 990714 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3024 | 3022 | GAME( 1995, fhboxers, stvbios, stv, stv, stv_state, fhboxers, ROT0, "Sega", "Funky Head Boxers (JUETBKAL 951218 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3025 | 3023 | GAME( 1997, findlove, stvbios, stv, stv, stv_state, stv, ROT0, "Daiki / FCF", "Zenkoku Seifuku Bishoujo Grand Prix Find Love (J 971212 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3026 | | GAME( 1994, gaxeduel, stvbios, stv, stv6b, stv_state, gaxeduel, ROT0, "Sega", "Golden Axe - The Duel (JUETL 950117 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS) |
| 3024 | GAME( 1994, gaxeduel, stvbios, stv, stv6b, stv_state, gaxeduel, ROT0, "Sega", "Golden Axe - The Duel (JUETL 950117 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS) |
| 3027 | 3025 | GAME( 1998, grdforce, stvbios, stv, stv, stv_state, grdforce, ROT0, "Success", "Guardian Force (JUET 980318 V0.105)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3028 | | GAME( 1998, groovef, stvbios, stv, stv6b, stv_state, groovef, ROT0, "Atlus", "Groove on Fight - Gouketsuji Ichizoku 3 (J 970416 V1.001)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3026 | GAME( 1998, groovef, stvbios, stv, stv6b, stv_state, groovef, ROT0, "Atlus", "Groove on Fight - Gouketsuji Ichizoku 3 (J 970416 V1.001)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3029 | 3027 | GAME( 1997, hanagumi, stvbios, stv, stv, stv_state, hanagumi, ROT0, "Sega", "Sakura Taisen - Hanagumi Taisen Columns (J 971007 V1.010)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 3030 | 3028 | GAME( 1996, introdon, stvbios, stv, stv, stv_state, stv, ROT0, "Sunsoft / Success", "Karaoke Quiz Intro Don Don! (J 960213 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3031 | | GAME( 1995, kiwames, stvbios, stv, stvmp, stv_state, stvmp, ROT0, "Athena", "Pro Mahjong Kiwame S (J 951020 V1.208)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3029 | GAME( 1995, kiwames, stvbios, stv, stvmp, stv_state, stvmp, ROT0, "Athena", "Pro Mahjong Kiwame S (J 951020 V1.208)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3032 | 3030 | GAME( 1997, maruchan, stvbios, stv, stv, stv_state, maruchan, ROT0, "Sega / Toyosuisan", "Maru-Chan de Goo! (J 971216 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3033 | 3031 | GAME( 1996, mausuke, stvbios, stv, stv, stv_state, mausuke, ROT0, "Data East", "Mausuke no Ojama the World (J 960314 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3034 | 3032 | GAME( 1998, myfairld, stvbios, stv, myfairld, stv_state, stvmp, ROT0, "Micronet", "Virtual Mahjong 2 - My Fair Lady (J 980608 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| r243932 | r243933 | |
| 3046 | 3044 | GAME( 1995, sandor, stvbios, stv, stv, stv_state, sandor, ROT0, "Sega", "Puzzle & Action: Sando-R (J 951114 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3047 | 3045 | GAME( 1997, thunt, sandor, stv, stv, stv_state, thunt, ROT0, "Sega", "Puzzle & Action: Treasure Hunt (JUET 970901 V2.00E)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3048 | 3046 | GAME( 1997, thuntk, sandor, stv, stv, stv_state, sandor, ROT0, "Sega / Deniam", "Puzzle & Action: BoMulEul Chajara (JUET 970125 V2.00K)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3049 | | GAME( 1998, twcup98, stvbios, stv, stv, stv_state, twcup98, ROT0, "Tecmo", "Tecmo World Cup '98 (JUET 980410 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3050 | 3047 | GAME( 1995, smleague, stvbios, stv, stv, stv_state, smleague, ROT0, "Sega", "Super Major League (U 960108 V1.000)", GAME_NOT_WORKING | GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3051 | 3048 | GAME( 1995, finlarch, smleague,stv, stv, stv_state, finlarch, ROT0, "Sega", "Final Arch (J 950714 V1.001)", GAME_NOT_WORKING | GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3052 | 3049 | GAME( 1996, sokyugrt, stvbios, stv, stv, stv_state, sokyugrt, ROT0, "Raizing / Eighting", "Soukyugurentai / Terra Diver (JUET 960821 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| r243932 | r243933 | |
| 3056 | 3053 | GAME( 1997, winterht, stvbios, stv, stv, stv_state, winterht, ROT0, "Sega", "Winter Heat (JUET 971012 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3057 | 3054 | GAME( 1997, znpwfv, stvbios, stv, stv, stv_state, znpwfv, ROT0, "Sega", "Zen Nippon Pro-Wrestling Featuring Virtua (J 971123 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3058 | 3055 | |
| 3056 | /* Almost */ |
| 3057 | GAME( 1998, twcup98, stvbios, stv, stv, stv_state, twcup98, ROT0, "Tecmo", "Tecmo World Cup '98 (JUET 980410 V1.000)", GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3058 | GAME( 1998, elandore, stvbios, stv, stv6b, stv_state, elandore, ROT0, "Sai-Mate", "Touryuu Densetsu Elan-Doree / Elan Doree - Legend of Dragoon (JUET 980922 V1.006)", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3059 | |
| 3059 | 3060 | /* Unemulated printer / camera devices */ |
| 3060 | 3061 | GAME( 1998, stress, stvbios, stv, stv, stv_state, stv, ROT0, "Sega", "Stress Busters (J 981020 V1.000)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) |
| 3061 | 3062 | GAME( 1997, nclubv3, stvbios, stv, stv, stv_state, nameclv3, ROT0, "Sega", "Name Club Ver.3 (J 970723 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING ) |
| r243932 | r243933 | |
| 3082 | 3083 | GAME( 1997, techbowl, stvbios, stv, stv, stv_state, stv, ROT0, "Sega", "Technical Bowling (J 971212 V1.000)", GAME_NOT_WORKING ) |
| 3083 | 3084 | GAME( 1999, micrombc, stvbios, stv, stv, stv_state, stv, ROT0, "Sega", "Microman Battle Charge (J 990326 V1.000)", GAME_NOT_WORKING ) |
| 3084 | 3085 | |
| 3086 | /* Black screen */ |
| 3087 | GAME( 1999, ffreveng, stvbios, stv, stv, stv_state, ffreveng, ROT0, "Capcom", "Final Fight Revenge (JUET 990714 V1.000)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS ) |
| 3088 | |
| 3085 | 3089 | /* CD games */ |
| 3086 | 3090 | GAME( 1995, sfish2, 0, stv, stv, stv_state, stv, ROT0, "Sega", "Sport Fishing 2 (UET 951106 V1.10e)", GAME_NO_SOUND | GAME_NOT_WORKING ) |
| 3087 | 3091 | GAME( 1995, sfish2j, sfish2, stv, stv, stv_state, stv, ROT0, "Sega", "Sport Fishing 2 (J 951201 V1.100)", GAME_NO_SOUND | GAME_NOT_WORKING ) |
branches/kale/src/osd/modules/font/font_sdl.c
| r243932 | r243933 | |
| 1 | | /* |
| 2 | | * font_sdl.c |
| 3 | | * |
| 4 | | */ |
| 5 | | |
| 6 | | #include "font_module.h" |
| 7 | | #include "modules/osdmodule.h" |
| 8 | | |
| 9 | | #if defined(SDLMAME_UNIX) && (!defined(SDLMAME_MACOSX)) && (!defined(SDLMAME_HAIKU)) && (!defined(SDLMAME_EMSCRIPTEN)) |
| 10 | | |
| 11 | | #if (SDLMAME_SDL2) |
| 12 | | #include <SDL2/SDL_ttf.h> |
| 13 | | #else |
| 14 | | #include <SDL/SDL_ttf.h> |
| 15 | | #endif |
| 16 | | #ifndef SDLMAME_HAIKU |
| 17 | | #include <fontconfig/fontconfig.h> |
| 18 | | #endif |
| 19 | | |
| 20 | | |
| 21 | | #include "astring.h" |
| 22 | | #include "corealloc.h" |
| 23 | | #include "fileio.h" |
| 24 | | |
| 25 | | #define POINT_SIZE 144.0 |
| 26 | | |
| 27 | | //------------------------------------------------- |
| 28 | | // font_open - attempt to "open" a handle to the |
| 29 | | // font with the given name |
| 30 | | //------------------------------------------------- |
| 31 | | |
| 32 | | class osd_font_sdl : public osd_font |
| 33 | | { |
| 34 | | public: |
| 35 | | virtual ~osd_font_sdl() {}; |
| 36 | | |
| 37 | | virtual bool open(const char *font_path, const char *name, int &height); |
| 38 | | virtual void close(); |
| 39 | | virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs); |
| 40 | | private: |
| 41 | | #ifndef SDLMAME_HAIKU |
| 42 | | TTF_Font *search_font_config(astring name, bool bold, bool italic, bool underline, bool &bakedstyles); |
| 43 | | #endif |
| 44 | | bool BDF_Check_Magic(astring name); |
| 45 | | TTF_Font * TTF_OpenFont_Magic(astring name, int fsize); |
| 46 | | TTF_Font *m_font; |
| 47 | | }; |
| 48 | | |
| 49 | | bool osd_font_sdl::open(const char *font_path, const char *_name, int &height) |
| 50 | | { |
| 51 | | TTF_Font *font = (TTF_Font *)NULL; |
| 52 | | bool bakedstyles = false; |
| 53 | | int style = 0; |
| 54 | | |
| 55 | | // accept qualifiers from the name |
| 56 | | astring name(_name); |
| 57 | | |
| 58 | | if (name == "default") |
| 59 | | { |
| 60 | | name = "Liberation Sans"; |
| 61 | | } |
| 62 | | |
| 63 | | bool bold = (name.replace(0, "[B]", "") + name.replace(0, "[b]", "") > 0); |
| 64 | | bool italic = (name.replace(0, "[I]", "") + name.replace(0, "[i]", "") > 0); |
| 65 | | bool underline = (name.replace(0, "[U]", "") + name.replace(0, "[u]", "") > 0); |
| 66 | | bool strike = (name.replace(0, "[S]", "") + name.replace(0, "[s]", "") > 0); |
| 67 | | |
| 68 | | // first up, try it as a filename |
| 69 | | font = TTF_OpenFont_Magic(name, POINT_SIZE); |
| 70 | | |
| 71 | | // if no success, try the font path |
| 72 | | |
| 73 | | if (!font) |
| 74 | | { |
| 75 | | osd_printf_verbose("Searching font %s in -%s\n", name.cstr(), OPTION_FONTPATH); |
| 76 | | //emu_file file(options().font_path(), OPEN_FLAG_READ); |
| 77 | | emu_file file(font_path, OPEN_FLAG_READ); |
| 78 | | if (file.open(name) == FILERR_NONE) |
| 79 | | { |
| 80 | | astring full_name = file.fullpath(); |
| 81 | | font = TTF_OpenFont_Magic(full_name, POINT_SIZE); |
| 82 | | if (font) |
| 83 | | osd_printf_verbose("Found font %s\n", full_name.cstr()); |
| 84 | | } |
| 85 | | } |
| 86 | | |
| 87 | | // if that didn't work, crank up the FontConfig database |
| 88 | | #ifndef SDLMAME_HAIKU |
| 89 | | if (!font) |
| 90 | | { |
| 91 | | font = search_font_config(name, bold, italic, underline, bakedstyles); |
| 92 | | } |
| 93 | | #endif |
| 94 | | |
| 95 | | if (!font) |
| 96 | | { |
| 97 | | if (!BDF_Check_Magic(name)) |
| 98 | | { |
| 99 | | osd_printf_verbose("font %s is not TrueType or BDF, using MAME default\n", name.cstr()); |
| 100 | | } |
| 101 | | return NULL; |
| 102 | | } |
| 103 | | |
| 104 | | // apply styles |
| 105 | | if (!bakedstyles) |
| 106 | | { |
| 107 | | style |= bold ? TTF_STYLE_BOLD : 0; |
| 108 | | style |= italic ? TTF_STYLE_ITALIC : 0; |
| 109 | | } |
| 110 | | style |= underline ? TTF_STYLE_UNDERLINE : 0; |
| 111 | | // SDL_ttf 2.0.9 and earlier does not define TTF_STYLE_STRIKETHROUGH |
| 112 | | #if SDL_VERSIONNUM(TTF_MAJOR_VERSION, TTF_MINOR_VERSION, TTF_PATCHLEVEL) > SDL_VERSIONNUM(2,0,9) |
| 113 | | style |= strike ? TTF_STYLE_STRIKETHROUGH : 0; |
| 114 | | #else |
| 115 | | if (strike) |
| 116 | | osd_printf_warning("Ignoring strikethrough for SDL_TTF older than 2.0.10\n"); |
| 117 | | #endif // PATCHLEVEL |
| 118 | | TTF_SetFontStyle(font, style); |
| 119 | | |
| 120 | | height = TTF_FontLineSkip(font); |
| 121 | | |
| 122 | | m_font = font; |
| 123 | | return true; |
| 124 | | } |
| 125 | | |
| 126 | | //------------------------------------------------- |
| 127 | | // font_close - release resources associated with |
| 128 | | // a given OSD font |
| 129 | | //------------------------------------------------- |
| 130 | | |
| 131 | | void osd_font_sdl::close() |
| 132 | | { |
| 133 | | TTF_CloseFont(this->m_font); |
| 134 | | } |
| 135 | | |
| 136 | | //------------------------------------------------- |
| 137 | | // font_get_bitmap - allocate and populate a |
| 138 | | // BITMAP_FORMAT_ARGB32 bitmap containing the |
| 139 | | // pixel values rgb_t(0xff,0xff,0xff,0xff) |
| 140 | | // or rgb_t(0x00,0xff,0xff,0xff) for each |
| 141 | | // pixel of a black & white font |
| 142 | | //------------------------------------------------- |
| 143 | | |
| 144 | | bool osd_font_sdl::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) |
| 145 | | { |
| 146 | | TTF_Font *ttffont; |
| 147 | | SDL_Surface *drawsurf; |
| 148 | | SDL_Color fcol = { 0xff, 0xff, 0xff }; |
| 149 | | UINT16 ustr[16]; |
| 150 | | |
| 151 | | ttffont = m_font; |
| 152 | | |
| 153 | | memset(ustr,0,sizeof(ustr)); |
| 154 | | ustr[0] = (UINT16)chnum; |
| 155 | | drawsurf = TTF_RenderUNICODE_Solid(ttffont, ustr, fcol); |
| 156 | | |
| 157 | | // was nothing returned? |
| 158 | | if (drawsurf) |
| 159 | | { |
| 160 | | // allocate a MAME destination bitmap |
| 161 | | bitmap.allocate(drawsurf->w, drawsurf->h); |
| 162 | | |
| 163 | | // copy the rendered character image into it |
| 164 | | for (int y = 0; y < bitmap.height(); y++) |
| 165 | | { |
| 166 | | UINT32 *dstrow = &bitmap.pix32(y); |
| 167 | | UINT8 *srcrow = (UINT8 *)drawsurf->pixels; |
| 168 | | |
| 169 | | srcrow += (y * drawsurf->pitch); |
| 170 | | |
| 171 | | for (int x = 0; x < drawsurf->w; x++) |
| 172 | | { |
| 173 | | dstrow[x] = srcrow[x] ? rgb_t(0xff,0xff,0xff,0xff) : rgb_t(0x00,0xff,0xff,0xff); |
| 174 | | } |
| 175 | | } |
| 176 | | |
| 177 | | // what are these? |
| 178 | | xoffs = yoffs = 0; |
| 179 | | width = drawsurf->w; |
| 180 | | |
| 181 | | SDL_FreeSurface(drawsurf); |
| 182 | | } |
| 183 | | |
| 184 | | return bitmap.valid(); |
| 185 | | } |
| 186 | | |
| 187 | | TTF_Font * osd_font_sdl::TTF_OpenFont_Magic(astring name, int fsize) |
| 188 | | { |
| 189 | | emu_file file(OPEN_FLAG_READ); |
| 190 | | if (file.open(name) == FILERR_NONE) |
| 191 | | { |
| 192 | | unsigned char buffer[5] = { 0xff, 0xff, 0xff, 0xff, 0xff }; |
| 193 | | unsigned char magic[5] = { 0x00, 0x01, 0x00, 0x00, 0x00 }; |
| 194 | | file.read(buffer,5); |
| 195 | | if (memcmp(buffer, magic, 5)) |
| 196 | | return NULL; |
| 197 | | } |
| 198 | | return TTF_OpenFont(name.cstr(), POINT_SIZE); |
| 199 | | } |
| 200 | | |
| 201 | | bool osd_font_sdl::BDF_Check_Magic(astring name) |
| 202 | | { |
| 203 | | emu_file file(OPEN_FLAG_READ); |
| 204 | | if (file.open(name) == FILERR_NONE) |
| 205 | | { |
| 206 | | unsigned char buffer[9]; |
| 207 | | unsigned char magic[9] = { 'S', 'T', 'A', 'R', 'T', 'F', 'O', 'N', 'T' }; |
| 208 | | file.read(buffer, 9); |
| 209 | | file.close(); |
| 210 | | if (!memcmp(buffer, magic, 9)) |
| 211 | | return true; |
| 212 | | } |
| 213 | | |
| 214 | | return false; |
| 215 | | } |
| 216 | | |
| 217 | | #ifndef SDLMAME_HAIKU |
| 218 | | TTF_Font *osd_font_sdl::search_font_config(astring name, bool bold, bool italic, bool underline, bool &bakedstyles) |
| 219 | | { |
| 220 | | TTF_Font *font = (TTF_Font *)NULL; |
| 221 | | FcConfig *config; |
| 222 | | FcPattern *pat; |
| 223 | | FcObjectSet *os; |
| 224 | | FcFontSet *fontset; |
| 225 | | FcValue val; |
| 226 | | |
| 227 | | config = FcConfigGetCurrent(); |
| 228 | | pat = FcPatternCreate(); |
| 229 | | os = FcObjectSetCreate(); |
| 230 | | FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.cstr()); |
| 231 | | |
| 232 | | // try and get a font with the requested styles baked-in |
| 233 | | if (bold) |
| 234 | | { |
| 235 | | if (italic) |
| 236 | | { |
| 237 | | FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Bold Italic"); |
| 238 | | } |
| 239 | | else |
| 240 | | { |
| 241 | | FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Bold"); |
| 242 | | } |
| 243 | | } |
| 244 | | else if (italic) |
| 245 | | { |
| 246 | | FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Italic"); |
| 247 | | } |
| 248 | | else |
| 249 | | { |
| 250 | | FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Regular"); |
| 251 | | } |
| 252 | | |
| 253 | | FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType"); |
| 254 | | |
| 255 | | FcObjectSetAdd(os, FC_FILE); |
| 256 | | fontset = FcFontList(config, pat, os); |
| 257 | | |
| 258 | | for (int i = 0; i < fontset->nfont; i++) |
| 259 | | { |
| 260 | | if (FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch) |
| 261 | | { |
| 262 | | continue; |
| 263 | | } |
| 264 | | |
| 265 | | if (val.type != FcTypeString) |
| 266 | | { |
| 267 | | continue; |
| 268 | | } |
| 269 | | |
| 270 | | osd_printf_verbose("Matching font: %s\n", val.u.s); |
| 271 | | { |
| 272 | | astring match_name((const char*)val.u.s); |
| 273 | | font = TTF_OpenFont_Magic(match_name, POINT_SIZE); |
| 274 | | } |
| 275 | | |
| 276 | | if (font) |
| 277 | | { |
| 278 | | bakedstyles = true; |
| 279 | | break; |
| 280 | | } |
| 281 | | } |
| 282 | | |
| 283 | | // didn't get a font above? try again with no baked-in styles |
| 284 | | if (!font) |
| 285 | | { |
| 286 | | FcPatternDestroy(pat); |
| 287 | | FcFontSetDestroy(fontset); |
| 288 | | |
| 289 | | pat = FcPatternCreate(); |
| 290 | | FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.cstr()); |
| 291 | | FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Regular"); |
| 292 | | FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType"); |
| 293 | | fontset = FcFontList(config, pat, os); |
| 294 | | |
| 295 | | for (int i = 0; i < fontset->nfont; i++) |
| 296 | | { |
| 297 | | if (FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch) |
| 298 | | { |
| 299 | | continue; |
| 300 | | } |
| 301 | | |
| 302 | | if (val.type != FcTypeString) |
| 303 | | { |
| 304 | | continue; |
| 305 | | } |
| 306 | | |
| 307 | | osd_printf_verbose("Matching unstyled font: %s\n", val.u.s); |
| 308 | | { |
| 309 | | astring match_name((const char*)val.u.s); |
| 310 | | font = TTF_OpenFont_Magic(match_name, POINT_SIZE); |
| 311 | | } |
| 312 | | |
| 313 | | if (font) |
| 314 | | { |
| 315 | | break; |
| 316 | | } |
| 317 | | } |
| 318 | | } |
| 319 | | |
| 320 | | FcPatternDestroy(pat); |
| 321 | | FcObjectSetDestroy(os); |
| 322 | | FcFontSetDestroy(fontset); |
| 323 | | return font; |
| 324 | | } |
| 325 | | #endif |
| 326 | | |
| 327 | | |
| 328 | | class font_sdl : public osd_module, public font_module |
| 329 | | { |
| 330 | | public: |
| 331 | | font_sdl() |
| 332 | | : osd_module(OSD_FONT_PROVIDER, "sdl"), font_module() |
| 333 | | { |
| 334 | | } |
| 335 | | |
| 336 | | osd_font *font_alloc() |
| 337 | | { |
| 338 | | return global_alloc(osd_font_sdl); |
| 339 | | } |
| 340 | | |
| 341 | | virtual void init() |
| 342 | | { |
| 343 | | if (TTF_Init() == -1) |
| 344 | | { |
| 345 | | osd_printf_error("SDL_ttf failed: %s\n", TTF_GetError()); |
| 346 | | } |
| 347 | | } |
| 348 | | |
| 349 | | virtual void exit() |
| 350 | | { |
| 351 | | TTF_Quit(); |
| 352 | | } |
| 353 | | }; |
| 354 | | #else /* SDLMAME_UNIX */ |
| 355 | | MODULE_NOT_SUPPORTED(font_sdl, OSD_FONT_PROVIDER, "sdl") |
| 356 | | #endif |
| 357 | | |
| 358 | | MODULE_DEFINITION(FONT_SDL, font_sdl) |
| 359 | | |
| 360 | | |
branches/kale/src/osd/modules/font/font_unix.c
| r0 | r243933 | |
| 1 | /* |
| 2 | * font_sdl.c |
| 3 | * |
| 4 | */ |
| 5 | |
| 6 | #if (SDLMAME_SDL2) |
| 7 | #include <SDL2/SDL_ttf.h> |
| 8 | #else |
| 9 | #include <SDL/SDL_ttf.h> |
| 10 | #endif |
| 11 | #ifndef SDLMAME_HAIKU |
| 12 | #include <fontconfig/fontconfig.h> |
| 13 | #endif |
| 14 | |
| 15 | #include "osdepend.h" |
| 16 | |
| 17 | #include "astring.h" |
| 18 | #include "corealloc.h" |
| 19 | #include "fileio.h" |
| 20 | |
| 21 | #define POINT_SIZE 144.0 |
| 22 | |
| 23 | //------------------------------------------------- |
| 24 | // font_open - attempt to "open" a handle to the |
| 25 | // font with the given name |
| 26 | //------------------------------------------------- |
| 27 | |
| 28 | class osd_font_unix : public osd_font |
| 29 | { |
| 30 | public: |
| 31 | virtual ~osd_font_unix() {}; |
| 32 | |
| 33 | virtual bool open(const char *font_path, const char *name, int &height); |
| 34 | virtual void close(); |
| 35 | virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs); |
| 36 | private: |
| 37 | #ifndef SDLMAME_HAIKU |
| 38 | TTF_Font *search_font_config(astring name, bool bold, bool italic, bool underline, bool &bakedstyles); |
| 39 | #endif |
| 40 | bool BDF_Check_Magic(astring name); |
| 41 | TTF_Font * TTF_OpenFont_Magic(astring name, int fsize); |
| 42 | TTF_Font *m_font; |
| 43 | }; |
| 44 | |
| 45 | osd_font *osd_font_alloc() |
| 46 | { |
| 47 | return global_alloc(osd_font_unix); |
| 48 | } |
| 49 | |
| 50 | bool osd_font_unix::open(const char *font_path, const char *_name, int &height) |
| 51 | { |
| 52 | TTF_Font *font = (TTF_Font *)NULL; |
| 53 | bool bakedstyles = false; |
| 54 | int style = 0; |
| 55 | |
| 56 | // accept qualifiers from the name |
| 57 | astring name(_name); |
| 58 | |
| 59 | if (name == "default") |
| 60 | { |
| 61 | name = "Liberation Sans"; |
| 62 | } |
| 63 | |
| 64 | bool bold = (name.replace(0, "[B]", "") + name.replace(0, "[b]", "") > 0); |
| 65 | bool italic = (name.replace(0, "[I]", "") + name.replace(0, "[i]", "") > 0); |
| 66 | bool underline = (name.replace(0, "[U]", "") + name.replace(0, "[u]", "") > 0); |
| 67 | bool strike = (name.replace(0, "[S]", "") + name.replace(0, "[s]", "") > 0); |
| 68 | |
| 69 | // first up, try it as a filename |
| 70 | font = TTF_OpenFont_Magic(name, POINT_SIZE); |
| 71 | |
| 72 | // if no success, try the font path |
| 73 | |
| 74 | if (!font) |
| 75 | { |
| 76 | osd_printf_verbose("Searching font %s in -%s\n", name.cstr(), OPTION_FONTPATH); |
| 77 | //emu_file file(options().font_path(), OPEN_FLAG_READ); |
| 78 | emu_file file(font_path, OPEN_FLAG_READ); |
| 79 | if (file.open(name) == FILERR_NONE) |
| 80 | { |
| 81 | astring full_name = file.fullpath(); |
| 82 | font = TTF_OpenFont_Magic(full_name, POINT_SIZE); |
| 83 | if (font) |
| 84 | osd_printf_verbose("Found font %s\n", full_name.cstr()); |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | // if that didn't work, crank up the FontConfig database |
| 89 | #ifndef SDLMAME_HAIKU |
| 90 | if (!font) |
| 91 | { |
| 92 | font = search_font_config(name, bold, italic, underline, bakedstyles); |
| 93 | } |
| 94 | #endif |
| 95 | |
| 96 | if (!font) |
| 97 | { |
| 98 | if (!BDF_Check_Magic(name)) |
| 99 | { |
| 100 | osd_printf_verbose("font %s is not TrueType or BDF, using MAME default\n", name.cstr()); |
| 101 | } |
| 102 | return NULL; |
| 103 | } |
| 104 | |
| 105 | // apply styles |
| 106 | if (!bakedstyles) |
| 107 | { |
| 108 | style |= bold ? TTF_STYLE_BOLD : 0; |
| 109 | style |= italic ? TTF_STYLE_ITALIC : 0; |
| 110 | } |
| 111 | style |= underline ? TTF_STYLE_UNDERLINE : 0; |
| 112 | // SDL_ttf 2.0.9 and earlier does not define TTF_STYLE_STRIKETHROUGH |
| 113 | #if SDL_VERSIONNUM(TTF_MAJOR_VERSION, TTF_MINOR_VERSION, TTF_PATCHLEVEL) > SDL_VERSIONNUM(2,0,9) |
| 114 | style |= strike ? TTF_STYLE_STRIKETHROUGH : 0; |
| 115 | #else |
| 116 | if (strike) |
| 117 | osd_printf_warning("Ignoring strikethrough for SDL_TTF older than 2.0.10\n"); |
| 118 | #endif // PATCHLEVEL |
| 119 | TTF_SetFontStyle(font, style); |
| 120 | |
| 121 | height = TTF_FontLineSkip(font); |
| 122 | |
| 123 | m_font = font; |
| 124 | return true; |
| 125 | } |
| 126 | |
| 127 | //------------------------------------------------- |
| 128 | // font_close - release resources associated with |
| 129 | // a given OSD font |
| 130 | //------------------------------------------------- |
| 131 | |
| 132 | void osd_font_unix::close() |
| 133 | { |
| 134 | TTF_CloseFont(this->m_font); |
| 135 | } |
| 136 | |
| 137 | //------------------------------------------------- |
| 138 | // font_get_bitmap - allocate and populate a |
| 139 | // BITMAP_FORMAT_ARGB32 bitmap containing the |
| 140 | // pixel values rgb_t(0xff,0xff,0xff,0xff) |
| 141 | // or rgb_t(0x00,0xff,0xff,0xff) for each |
| 142 | // pixel of a black & white font |
| 143 | //------------------------------------------------- |
| 144 | |
| 145 | bool osd_font_unix::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) |
| 146 | { |
| 147 | TTF_Font *ttffont; |
| 148 | SDL_Surface *drawsurf; |
| 149 | SDL_Color fcol = { 0xff, 0xff, 0xff }; |
| 150 | UINT16 ustr[16]; |
| 151 | |
| 152 | ttffont = m_font; |
| 153 | |
| 154 | memset(ustr,0,sizeof(ustr)); |
| 155 | ustr[0] = (UINT16)chnum; |
| 156 | drawsurf = TTF_RenderUNICODE_Solid(ttffont, ustr, fcol); |
| 157 | |
| 158 | // was nothing returned? |
| 159 | if (drawsurf) |
| 160 | { |
| 161 | // allocate a MAME destination bitmap |
| 162 | bitmap.allocate(drawsurf->w, drawsurf->h); |
| 163 | |
| 164 | // copy the rendered character image into it |
| 165 | for (int y = 0; y < bitmap.height(); y++) |
| 166 | { |
| 167 | UINT32 *dstrow = &bitmap.pix32(y); |
| 168 | UINT8 *srcrow = (UINT8 *)drawsurf->pixels; |
| 169 | |
| 170 | srcrow += (y * drawsurf->pitch); |
| 171 | |
| 172 | for (int x = 0; x < drawsurf->w; x++) |
| 173 | { |
| 174 | dstrow[x] = srcrow[x] ? rgb_t(0xff,0xff,0xff,0xff) : rgb_t(0x00,0xff,0xff,0xff); |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | // what are these? |
| 179 | xoffs = yoffs = 0; |
| 180 | width = drawsurf->w; |
| 181 | |
| 182 | SDL_FreeSurface(drawsurf); |
| 183 | } |
| 184 | |
| 185 | return bitmap.valid(); |
| 186 | } |
| 187 | |
| 188 | TTF_Font * osd_font_unix::TTF_OpenFont_Magic(astring name, int fsize) |
| 189 | { |
| 190 | emu_file file(OPEN_FLAG_READ); |
| 191 | if (file.open(name) == FILERR_NONE) |
| 192 | { |
| 193 | unsigned char buffer[5] = { 0xff, 0xff, 0xff, 0xff, 0xff }; |
| 194 | unsigned char magic[5] = { 0x00, 0x01, 0x00, 0x00, 0x00 }; |
| 195 | file.read(buffer,5); |
| 196 | if (memcmp(buffer, magic, 5)) |
| 197 | return NULL; |
| 198 | } |
| 199 | return TTF_OpenFont(name.cstr(), POINT_SIZE); |
| 200 | } |
| 201 | |
| 202 | bool osd_font_unix::BDF_Check_Magic(astring name) |
| 203 | { |
| 204 | emu_file file(OPEN_FLAG_READ); |
| 205 | if (file.open(name) == FILERR_NONE) |
| 206 | { |
| 207 | unsigned char buffer[9]; |
| 208 | unsigned char magic[9] = { 'S', 'T', 'A', 'R', 'T', 'F', 'O', 'N', 'T' }; |
| 209 | file.read(buffer, 9); |
| 210 | file.close(); |
| 211 | if (!memcmp(buffer, magic, 9)) |
| 212 | return true; |
| 213 | } |
| 214 | |
| 215 | return false; |
| 216 | } |
| 217 | |
| 218 | #ifndef SDLMAME_HAIKU |
| 219 | TTF_Font *osd_font_unix::search_font_config(astring name, bool bold, bool italic, bool underline, bool &bakedstyles) |
| 220 | { |
| 221 | TTF_Font *font = (TTF_Font *)NULL; |
| 222 | FcConfig *config; |
| 223 | FcPattern *pat; |
| 224 | FcObjectSet *os; |
| 225 | FcFontSet *fontset; |
| 226 | FcValue val; |
| 227 | |
| 228 | config = FcConfigGetCurrent(); |
| 229 | pat = FcPatternCreate(); |
| 230 | os = FcObjectSetCreate(); |
| 231 | FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.cstr()); |
| 232 | |
| 233 | // try and get a font with the requested styles baked-in |
| 234 | if (bold) |
| 235 | { |
| 236 | if (italic) |
| 237 | { |
| 238 | FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Bold Italic"); |
| 239 | } |
| 240 | else |
| 241 | { |
| 242 | FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Bold"); |
| 243 | } |
| 244 | } |
| 245 | else if (italic) |
| 246 | { |
| 247 | FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Italic"); |
| 248 | } |
| 249 | else |
| 250 | { |
| 251 | FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Regular"); |
| 252 | } |
| 253 | |
| 254 | FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType"); |
| 255 | |
| 256 | FcObjectSetAdd(os, FC_FILE); |
| 257 | fontset = FcFontList(config, pat, os); |
| 258 | |
| 259 | for (int i = 0; i < fontset->nfont; i++) |
| 260 | { |
| 261 | if (FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch) |
| 262 | { |
| 263 | continue; |
| 264 | } |
| 265 | |
| 266 | if (val.type != FcTypeString) |
| 267 | { |
| 268 | continue; |
| 269 | } |
| 270 | |
| 271 | osd_printf_verbose("Matching font: %s\n", val.u.s); |
| 272 | { |
| 273 | astring match_name((const char*)val.u.s); |
| 274 | font = TTF_OpenFont_Magic(match_name, POINT_SIZE); |
| 275 | } |
| 276 | |
| 277 | if (font) |
| 278 | { |
| 279 | bakedstyles = true; |
| 280 | break; |
| 281 | } |
| 282 | } |
| 283 | |
| 284 | // didn't get a font above? try again with no baked-in styles |
| 285 | if (!font) |
| 286 | { |
| 287 | FcPatternDestroy(pat); |
| 288 | FcFontSetDestroy(fontset); |
| 289 | |
| 290 | pat = FcPatternCreate(); |
| 291 | FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.cstr()); |
| 292 | FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Regular"); |
| 293 | FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType"); |
| 294 | fontset = FcFontList(config, pat, os); |
| 295 | |
| 296 | for (int i = 0; i < fontset->nfont; i++) |
| 297 | { |
| 298 | if (FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch) |
| 299 | { |
| 300 | continue; |
| 301 | } |
| 302 | |
| 303 | if (val.type != FcTypeString) |
| 304 | { |
| 305 | continue; |
| 306 | } |
| 307 | |
| 308 | osd_printf_verbose("Matching unstyled font: %s\n", val.u.s); |
| 309 | { |
| 310 | astring match_name((const char*)val.u.s); |
| 311 | font = TTF_OpenFont_Magic(match_name, POINT_SIZE); |
| 312 | } |
| 313 | |
| 314 | if (font) |
| 315 | { |
| 316 | break; |
| 317 | } |
| 318 | } |
| 319 | } |
| 320 | |
| 321 | FcPatternDestroy(pat); |
| 322 | FcObjectSetDestroy(os); |
| 323 | FcFontSetDestroy(fontset); |
| 324 | return font; |
| 325 | } |
| 326 | #endif |