trunk/src/emu/bus/nes_ctrl/fckeybrd.c
| r243189 | r243190 | |
| 18 | 18 | |
| 19 | 19 | static INPUT_PORTS_START( fc_keyboard ) |
| 20 | 20 | PORT_START("FCKEY.0") |
| 21 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) |
| 22 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) |
| 21 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) |
| 22 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) |
| 23 | 23 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('[') |
| 24 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(']') |
| 25 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Kana") |
| 26 | | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RSHIFT) |
| 24 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(']') |
| 25 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Kana") |
| 26 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RSHIFT) |
| 27 | 27 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('\\') |
| 28 | | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Stop") PORT_CODE(KEYCODE_BACKSPACE) |
| 28 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Stop") PORT_CODE(KEYCODE_BACKSPACE) |
| 29 | 29 | |
| 30 | 30 | PORT_START("FCKEY.1") |
| 31 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) |
| 31 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) |
| 32 | 32 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@') |
| 33 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') |
| 34 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(';') |
| 35 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CHAR('_') |
| 36 | | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CHAR('/') |
| 37 | | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') |
| 33 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') |
| 34 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(';') |
| 35 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CHAR('_') |
| 36 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CHAR('/') |
| 37 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') |
| 38 | 38 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^') |
| 39 | 39 | |
| 40 | 40 | PORT_START("FCKEY.2") |
| 41 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) |
| 41 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) |
| 42 | 42 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') |
| 43 | 43 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') |
| 44 | 44 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') |
| r243189 | r243190 | |
| 48 | 48 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') |
| 49 | 49 | |
| 50 | 50 | PORT_START("FCKEY.3") |
| 51 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) |
| 51 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) |
| 52 | 52 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') |
| 53 | 53 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') |
| 54 | 54 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') |
| r243189 | r243190 | |
| 58 | 58 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') |
| 59 | 59 | |
| 60 | 60 | PORT_START("FCKEY.4") |
| 61 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) |
| 61 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) |
| 62 | 62 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') |
| 63 | 63 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') |
| 64 | 64 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') |
| r243189 | r243190 | |
| 68 | 68 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') |
| 69 | 69 | |
| 70 | 70 | PORT_START("FCKEY.5") |
| 71 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) |
| 71 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) |
| 72 | 72 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') |
| 73 | 73 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') |
| 74 | 74 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') |
| r243189 | r243190 | |
| 78 | 78 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') |
| 79 | 79 | |
| 80 | 80 | PORT_START("FCKEY.6") |
| 81 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) |
| 81 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) |
| 82 | 82 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') |
| 83 | 83 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') |
| 84 | 84 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') |
| r243189 | r243190 | |
| 88 | 88 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') |
| 89 | 89 | |
| 90 | 90 | PORT_START("FCKEY.7") |
| 91 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) |
| 92 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR(UCHAR_MAMEKEY(ESC)) |
| 93 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') |
| 94 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) |
| 95 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) |
| 96 | | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Grph") PORT_CODE(KEYCODE_LALT) |
| 97 | | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') |
| 98 | | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') |
| 91 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) |
| 92 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR(UCHAR_MAMEKEY(ESC)) |
| 93 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') |
| 94 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) |
| 95 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) |
| 96 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Grph") PORT_CODE(KEYCODE_LALT) |
| 97 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') |
| 98 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') |
| 99 | 99 | |
| 100 | 100 | PORT_START("FCKEY.8") |
| 101 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Clr") |
| 102 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) |
| 103 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) |
| 104 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) |
| 105 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) |
| 106 | | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') |
| 107 | | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Del") PORT_CODE(KEYCODE_DEL) |
| 108 | | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ins") PORT_CODE(KEYCODE_INSERT) |
| 101 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Clr") |
| 102 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) |
| 103 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) |
| 104 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) |
| 105 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) |
| 106 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') |
| 107 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Del") PORT_CODE(KEYCODE_DEL) |
| 108 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ins") PORT_CODE(KEYCODE_INSERT) |
| 109 | 109 | INPUT_PORTS_END |
| 110 | 110 | |
| 111 | 111 | |
| r243189 | r243190 | |
| 183 | 183 | UINT8 nes_fckeybrd_device::read_exp(offs_t offset) |
| 184 | 184 | { |
| 185 | 185 | UINT8 ret = 0; |
| 186 | | if (offset == 0) //$4016 |
| 186 | if (offset == 0) //$4016 |
| 187 | 187 | { |
| 188 | 188 | // FC Keyboard: tape input |
| 189 | 189 | if ((m_cassette->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) |
| r243189 | r243190 | |
| 195 | 195 | ret |= 0x02; |
| 196 | 196 | } |
| 197 | 197 | } |
| 198 | | else //$4017 |
| 198 | else //$4017 |
| 199 | 199 | { |
| 200 | 200 | // FC Keyboard: rows of the keyboard matrix are read 4-bits at time and returned as bit1->bit4 |
| 201 | 201 | if (m_fck_scan < 9) |
| r243189 | r243190 | |
| 216 | 216 | // tape output (not fully tested) |
| 217 | 217 | if ((m_cassette->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_RECORD) |
| 218 | 218 | m_cassette->output(((data & 0x07) == 0x07) ? +1.0 : -1.0); |
| 219 | | |
| 219 | |
| 220 | 220 | if (BIT(data, 2)) // keyboard active |
| 221 | 221 | { |
| 222 | 222 | UINT8 out = BIT(data, 1); // scan |
| 223 | | |
| 223 | |
| 224 | 224 | if (m_fck_mode && !out && ++m_fck_scan > 9) |
| 225 | 225 | m_fck_scan = 0; |
| 226 | | |
| 226 | |
| 227 | 227 | m_fck_mode = out; // access lower or upper 4 bits |
| 228 | | |
| 228 | |
| 229 | 229 | if (BIT(data, 0)) // reset |
| 230 | 230 | m_fck_scan = 0; |
| 231 | 231 | } |
trunk/src/emu/bus/nes_ctrl/joypad.c
| r243189 | r243190 | |
| 3 | 3 | Nintendo Family Computer & Entertainment System Joypads |
| 4 | 4 | |
| 5 | 5 | The original Famicom had two hardwired controller, with the second |
| 6 | | controller slightly different from the first one: it featured no |
| 6 | controller slightly different from the first one: it featured no |
| 7 | 7 | Start nor Select buttons, but had a built-in microphone (with |
| 8 | 8 | very limited capabilities, since it basically only detected two |
| 9 | 9 | states: something blowing into it / nothing blowing into it) for |
| 10 | 10 | some games to react to users "talking" into it |
| 11 | | |
| 12 | | Crazy Climber Pads are not really a kind of separate controllers, |
| 13 | | but just a couple of small sticks to be put on top of d-pads of |
| 14 | | the regular controllers. Users should then control the game by |
| 15 | | using both controllers, turned 90 degrees, as a couple of dual |
| 11 | |
| 12 | Crazy Climber Pads are not really a kind of separate controllers, |
| 13 | but just a couple of small sticks to be put on top of d-pads of |
| 14 | the regular controllers. Users should then control the game by |
| 15 | using both controllers, turned 90 degrees, as a couple of dual |
| 16 | 16 | sticks like in the arcade control panel. However, we emulate them |
| 17 | 17 | separately so to map the controls to a friendlier default. |
| 18 | 18 | |
| r243189 | r243190 | |
| 20 | 20 | by Hori, but possibly licensed by Nintendo, since it use the official |
| 21 | 21 | logo and brand) which fits into the expansion port and allows to |
| 22 | 22 | daisy chain a second controller to the first one, to play 4players |
| 23 | | game (an image of such connection is shown e.g. in Nekketsu Koukou |
| 23 | game (an image of such connection is shown e.g. in Nekketsu Koukou |
| 24 | 24 | Dodgeball Bu manual) |
| 25 | | |
| 25 | |
| 26 | 26 | Copyright MESS Team. |
| 27 | 27 | Visit http://mamedev.org for licensing and usage restrictions. |
| 28 | 28 | |
| r243189 | r243190 | |
| 45 | 45 | PORT_START("JOYPAD") |
| 46 | 46 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("A") |
| 47 | 47 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("B") |
| 48 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) |
| 49 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) |
| 48 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) |
| 49 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) |
| 50 | 50 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY |
| 51 | 51 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY |
| 52 | 52 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY |
| r243189 | r243190 | |
| 58 | 58 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("A") |
| 59 | 59 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("B") |
| 60 | 60 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("Microphone") |
| 61 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 61 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 62 | 62 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY |
| 63 | 63 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY |
| 64 | 64 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY |
| r243189 | r243190 | |
| 69 | 69 | PORT_START("JOYPAD") |
| 70 | 70 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 71 | 71 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 72 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) |
| 73 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) |
| 72 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) |
| 73 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) |
| 74 | 74 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_RIGHT ) PORT_8WAY |
| 75 | 75 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_LEFT ) PORT_8WAY |
| 76 | 76 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_UP ) PORT_8WAY |
| r243189 | r243190 | |
| 81 | 81 | PORT_START("JOYPAD") |
| 82 | 82 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 83 | 83 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 84 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 85 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 84 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 85 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 86 | 86 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_RIGHT ) PORT_8WAY |
| 87 | 87 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_LEFT ) PORT_8WAY |
| 88 | 88 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_UP ) PORT_8WAY |
| r243189 | r243190 | |
| 103 | 103 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("B") |
| 104 | 104 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) |
| 105 | 105 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) |
| 106 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x01) |
| 107 | | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x01) |
| 108 | | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x01) |
| 109 | | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x01) |
| 110 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_4WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x00) |
| 111 | | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x00) |
| 112 | | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_4WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x00) |
| 113 | | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_4WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x00) |
| 106 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x01) |
| 107 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x01) |
| 108 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x01) |
| 109 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x01) |
| 110 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_4WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x00) |
| 111 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x00) |
| 112 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_4WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x00) |
| 113 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_4WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x00) |
| 114 | 114 | INPUT_PORTS_END |
| 115 | 115 | |
| 116 | 116 | //------------------------------------------------- |
| r243189 | r243190 | |
| 245 | 245 | UINT8 nes_fcpad2_device::read_exp(offs_t offset) |
| 246 | 246 | { |
| 247 | 247 | UINT8 ret = 0; |
| 248 | | if (!offset) // microphone input |
| 248 | if (!offset) // microphone input |
| 249 | 249 | ret |= m_joypad->read() & 0x04; |
| 250 | 250 | |
| 251 | 251 | return ret; |
| r243189 | r243190 | |
| 260 | 260 | UINT8 nes_arcstick_device::read_exp(offs_t offset) |
| 261 | 261 | { |
| 262 | 262 | UINT8 ret = 0; |
| 263 | | if (offset == 0) //$4016 |
| 263 | if (offset == 0) //$4016 |
| 264 | 264 | { |
| 265 | | if ((m_cfg->read() & 2) == 0) // we are P1 input |
| 265 | if ((m_cfg->read() & 2) == 0) // we are P1 input |
| 266 | 266 | { |
| 267 | 267 | ret |= (m_latch & 1) << 1; |
| 268 | 268 | m_latch >>= 1; |
| r243189 | r243190 | |
| 270 | 270 | else |
| 271 | 271 | ret |= m_daisychain->read_exp(0); |
| 272 | 272 | } |
| 273 | | else //$4017 |
| 273 | else //$4017 |
| 274 | 274 | { |
| 275 | | if ((m_cfg->read() & 2) == 2) // we are P2 input |
| 275 | if ((m_cfg->read() & 2) == 2) // we are P2 input |
| 276 | 276 | { |
| 277 | 277 | ret |= (m_latch & 1) << 1; |
| 278 | 278 | m_latch >>= 1; |
| r243189 | r243190 | |
| 280 | 280 | else |
| 281 | 281 | ret |= m_daisychain->read_exp(1); |
| 282 | 282 | } |
| 283 | | |
| 283 | |
| 284 | 284 | return ret; |
| 285 | 285 | } |
| 286 | 286 | |
| r243189 | r243190 | |
| 292 | 292 | { |
| 293 | 293 | if (data & 0x01) |
| 294 | 294 | return; |
| 295 | | |
| 295 | |
| 296 | 296 | m_latch = m_joypad->read(); |
| 297 | 297 | } |
| 298 | 298 | |
| r243189 | r243190 | |
| 311 | 311 | |
| 312 | 312 | if (data & 0x01) |
| 313 | 313 | return; |
| 314 | | |
| 314 | |
| 315 | 315 | m_latch = m_joypad->read(); |
| 316 | 316 | } |
| 317 | | |
trunk/src/emu/bus/nes_ctrl/mjpanel.c
| r243189 | r243190 | |
| 18 | 18 | |
| 19 | 19 | static INPUT_PORTS_START( nes_mjpanel ) |
| 20 | 20 | PORT_START("MJPANEL.0") |
| 21 | | PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 21 | PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 22 | 22 | |
| 23 | 23 | PORT_START("MJPANEL.1") |
| 24 | | PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 25 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_MAHJONG_N ) |
| 26 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_MAHJONG_M ) |
| 27 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_MAHJONG_L ) |
| 28 | | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_MAHJONG_K ) |
| 29 | | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_MAHJONG_J ) |
| 30 | | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_MAHJONG_I ) |
| 24 | PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 25 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_MAHJONG_N ) |
| 26 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_MAHJONG_M ) |
| 27 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_MAHJONG_L ) |
| 28 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_MAHJONG_K ) |
| 29 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_MAHJONG_J ) |
| 30 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_MAHJONG_I ) |
| 31 | 31 | |
| 32 | 32 | PORT_START("MJPANEL.2") |
| 33 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_MAHJONG_H ) |
| 34 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_MAHJONG_G ) |
| 35 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_MAHJONG_F ) |
| 36 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_MAHJONG_E ) |
| 37 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_MAHJONG_D ) |
| 38 | | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_MAHJONG_C ) |
| 39 | | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_MAHJONG_B ) |
| 40 | | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_MAHJONG_A ) |
| 33 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_MAHJONG_H ) |
| 34 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_MAHJONG_G ) |
| 35 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_MAHJONG_F ) |
| 36 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_MAHJONG_E ) |
| 37 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_MAHJONG_D ) |
| 38 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_MAHJONG_C ) |
| 39 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_MAHJONG_B ) |
| 40 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_MAHJONG_A ) |
| 41 | 41 | |
| 42 | 42 | PORT_START("MJPANEL.3") |
| 43 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 44 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_MAHJONG_RON ) |
| 45 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_MAHJONG_REACH ) |
| 46 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_MAHJONG_CHI ) |
| 47 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_MAHJONG_PON ) |
| 48 | | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_MAHJONG_KAN ) |
| 49 | | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("Mahjong Select") |
| 50 | | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("Mahjong Start") |
| 43 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 44 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_MAHJONG_RON ) |
| 45 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_MAHJONG_REACH ) |
| 46 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_MAHJONG_CHI ) |
| 47 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_MAHJONG_PON ) |
| 48 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_MAHJONG_KAN ) |
| 49 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("Mahjong Select") |
| 50 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("Mahjong Start") |
| 51 | 51 | INPUT_PORTS_END |
| 52 | 52 | |
| 53 | 53 | |
| r243189 | r243190 | |
| 124 | 124 | { |
| 125 | 125 | if (data & 0x01) |
| 126 | 126 | return; |
| 127 | | |
| 127 | |
| 128 | 128 | if (data & 0xf8) |
| 129 | 129 | logerror("Error: Mahjong panel read with mux data %02x\n", (data & 0xfe)); |
| 130 | 130 | else |
trunk/src/emu/bus/nes_ctrl/suborkey.c
| r243189 | r243190 | |
| 22 | 22 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') |
| 23 | 23 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') |
| 24 | 24 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') |
| 25 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) |
| 25 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) |
| 26 | 26 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') |
| 27 | 27 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') |
| 28 | 28 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') |
| r243189 | r243190 | |
| 32 | 32 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') |
| 33 | 33 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') |
| 34 | 34 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_END) PORT_CHAR(UCHAR_MAMEKEY(END)) |
| 35 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) |
| 35 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) |
| 36 | 36 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') |
| 37 | 37 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') |
| 38 | 38 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') |
| 39 | 39 | |
| 40 | 40 | PORT_START("SUBOR.2") |
| 41 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) |
| 42 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) |
| 43 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("NEXT") |
| 41 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) |
| 42 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) |
| 43 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("NEXT") |
| 44 | 44 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) |
| 45 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) |
| 46 | | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PRIOR") |
| 45 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) |
| 46 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PRIOR") |
| 47 | 47 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL)) |
| 48 | | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME)) |
| 48 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME)) |
| 49 | 49 | |
| 50 | 50 | PORT_START("SUBOR.3") |
| 51 | 51 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') |
| 52 | 52 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') |
| 53 | 53 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') |
| 54 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') |
| 55 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) |
| 54 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') |
| 55 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) |
| 56 | 56 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') |
| 57 | 57 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') |
| 58 | 58 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') |
| 59 | 59 | |
| 60 | 60 | PORT_START("SUBOR.4") |
| 61 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') |
| 62 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) |
| 63 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) |
| 64 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) |
| 65 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) |
| 66 | | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') |
| 67 | | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') |
| 68 | | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) |
| 61 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') |
| 62 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) |
| 63 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) |
| 64 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) |
| 65 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) |
| 66 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') |
| 67 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') |
| 68 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) |
| 69 | 69 | |
| 70 | 70 | PORT_START("SUBOR.5") |
| 71 | 71 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') |
| 72 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) |
| 72 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) |
| 73 | 73 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') |
| 74 | 74 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR('\t') |
| 75 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) |
| 75 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) |
| 76 | 76 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') |
| 77 | 77 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') |
| 78 | | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) |
| 78 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) |
| 79 | 79 | |
| 80 | 80 | PORT_START("SUBOR.6") |
| 81 | 81 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') |
| 82 | 82 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') |
| 83 | 83 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') |
| 84 | 84 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') |
| 85 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) |
| 85 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) |
| 86 | 86 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') |
| 87 | 87 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') |
| 88 | 88 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') |
| r243189 | r243190 | |
| 92 | 92 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') |
| 93 | 93 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') |
| 94 | 94 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') |
| 95 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) |
| 95 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) |
| 96 | 96 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') |
| 97 | 97 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') |
| 98 | | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) |
| 98 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) |
| 99 | 99 | |
| 100 | 100 | PORT_START("SUBOR.8") |
| 101 | 101 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') |
| 102 | 102 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') |
| 103 | 103 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') |
| 104 | 104 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') |
| 105 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) |
| 105 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) |
| 106 | 106 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') |
| 107 | 107 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') |
| 108 | 108 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') |
| r243189 | r243190 | |
| 111 | 111 | PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 112 | 112 | |
| 113 | 113 | PORT_START("SUBOR.10") |
| 114 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("LMENU") |
| 114 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("LMENU") |
| 115 | 115 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) |
| 116 | 116 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) |
| 117 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11)) |
| 118 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) |
| 117 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11)) |
| 118 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) |
| 119 | 119 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) |
| 120 | 120 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) |
| 121 | 121 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) |
| r243189 | r243190 | |
| 124 | 124 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS_PAD)PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) |
| 125 | 125 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) |
| 126 | 126 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR(UCHAR_MAMEKEY(ASTERISK)) |
| 127 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) |
| 128 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) |
| 129 | | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) |
| 127 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) |
| 128 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) |
| 129 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) |
| 130 | 130 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH_PAD)PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD)) |
| 131 | | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(UCHAR_MAMEKEY(NUMLOCK)) |
| 131 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(UCHAR_MAMEKEY(NUMLOCK)) |
| 132 | 132 | |
| 133 | 133 | PORT_START("SUBOR.12") |
| 134 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') |
| 134 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') |
| 135 | 135 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) |
| 136 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PAUSE") |
| 137 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("SPACE2") |
| 138 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) |
| 136 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PAUSE") |
| 137 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("SPACE2") |
| 138 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) |
| 139 | 139 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) |
| 140 | | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad .") PORT_CODE(KEYCODE_DEL_PAD) |
| 140 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad .") PORT_CODE(KEYCODE_DEL_PAD) |
| 141 | 141 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) |
| 142 | 142 | INPUT_PORTS_END |
| 143 | 143 | |
| r243189 | r243190 | |
| 198 | 198 | UINT8 nes_suborkey_device::read_exp(offs_t offset) |
| 199 | 199 | { |
| 200 | 200 | UINT8 ret = 0; |
| 201 | | if (offset == 1) //$4017 |
| 201 | if (offset == 1) //$4017 |
| 202 | 202 | { |
| 203 | 203 | // Subor Keyboard: rows of the keyboard matrix are read 4-bits at time and returned as bit1->bit4 |
| 204 | 204 | if (m_fck_scan < 13) |
| r243189 | r243190 | |
| 206 | 206 | else |
| 207 | 207 | ret |= 0x1e; |
| 208 | 208 | } |
| 209 | | |
| 209 | |
| 210 | 210 | return ret; |
| 211 | 211 | } |
| 212 | 212 | |
| r243189 | r243190 | |
| 218 | 218 | { |
| 219 | 219 | if (BIT(data, 2)) // keyboard active |
| 220 | 220 | { |
| 221 | | UINT8 out = BIT(data, 1); // scan |
| 221 | UINT8 out = BIT(data, 1); // scan |
| 222 | 222 | if (m_fck_mode && !out && ++m_fck_scan > 12) |
| 223 | 223 | m_fck_scan = 0; |
| 224 | | |
| 224 | |
| 225 | 225 | m_fck_mode = out; // access lower or upper 4 bits |
| 226 | | |
| 226 | |
| 227 | 227 | if (BIT(data, 0)) // reset |
| 228 | 228 | m_fck_scan = 0; |
| 229 | 229 | } |
trunk/src/emu/render.c
| r243189 | r243190 | |
| 207 | 207 | |
| 208 | 208 | render_texinfo &render_texinfo::operator=(const render_texinfo &src) |
| 209 | 209 | { |
| 210 | | free_palette(); |
| 211 | | base = src.base; |
| 212 | | rowpixels = src.rowpixels; |
| 213 | | width = src.width; |
| 214 | | height = src.height; |
| 215 | | seqid = src.seqid; |
| 216 | | osddata = src.osddata; |
| 217 | | m_palette = src.m_palette; |
| 218 | | if (m_palette != NULL) |
| 219 | | { |
| 220 | | m_palette->ref_count++; |
| 221 | | } |
| 222 | | return *this; |
| 210 | free_palette(); |
| 211 | base = src.base; |
| 212 | rowpixels = src.rowpixels; |
| 213 | width = src.width; |
| 214 | height = src.height; |
| 215 | seqid = src.seqid; |
| 216 | osddata = src.osddata; |
| 217 | m_palette = src.m_palette; |
| 218 | if (m_palette != NULL) |
| 219 | { |
| 220 | m_palette->ref_count++; |
| 221 | } |
| 222 | return *this; |
| 223 | 223 | } |
| 224 | 224 | |
| 225 | 225 | render_texinfo::render_texinfo(const render_texinfo &src) |
| 226 | 226 | { |
| 227 | | base = src.base; |
| 228 | | rowpixels = src.rowpixels; |
| 229 | | width = src.width; |
| 230 | | height = src.height; |
| 231 | | seqid = src.seqid; |
| 232 | | osddata = src.osddata; |
| 233 | | m_palette = src.m_palette; |
| 234 | | if (m_palette != NULL) |
| 235 | | { |
| 236 | | m_palette->ref_count++; |
| 237 | | } |
| 227 | base = src.base; |
| 228 | rowpixels = src.rowpixels; |
| 229 | width = src.width; |
| 230 | height = src.height; |
| 231 | seqid = src.seqid; |
| 232 | osddata = src.osddata; |
| 233 | m_palette = src.m_palette; |
| 234 | if (m_palette != NULL) |
| 235 | { |
| 236 | m_palette->ref_count++; |
| 237 | } |
| 238 | 238 | } |
| 239 | 239 | |
| 240 | 240 | void render_texinfo::set_palette(const dynamic_array<rgb_t> *source) |
| 241 | 241 | { |
| 242 | | free_palette(); |
| 243 | | if (source != NULL) |
| 244 | | { |
| 245 | | m_palette = global_alloc(render_palette_copy); |
| 246 | | m_palette->palette.copyfrom(*source); |
| 247 | | m_palette->ref_count = 1; |
| 248 | | } |
| 249 | | else |
| 250 | | { |
| 251 | | m_palette = NULL; |
| 252 | | } |
| 242 | free_palette(); |
| 243 | if (source != NULL) |
| 244 | { |
| 245 | m_palette = global_alloc(render_palette_copy); |
| 246 | m_palette->palette.copyfrom(*source); |
| 247 | m_palette->ref_count = 1; |
| 248 | } |
| 249 | else |
| 250 | { |
| 251 | m_palette = NULL; |
| 252 | } |
| 253 | 253 | } |
| 254 | 254 | |
| 255 | 255 | void render_texinfo::free_palette() |
| 256 | 256 | { |
| 257 | | if (m_palette != NULL) |
| 258 | | { |
| 259 | | m_palette->ref_count--; |
| 260 | | if (m_palette->ref_count == 0) |
| 261 | | { |
| 262 | | global_free(m_palette); |
| 263 | | } |
| 264 | | } |
| 265 | | m_palette = NULL; |
| 257 | if (m_palette != NULL) |
| 258 | { |
| 259 | m_palette->ref_count--; |
| 260 | if (m_palette->ref_count == 0) |
| 261 | { |
| 262 | global_free(m_palette); |
| 263 | } |
| 264 | } |
| 265 | m_palette = NULL; |
| 266 | 266 | } |
| 267 | 267 | |
| 268 | 268 | |
| r243189 | r243190 | |
| 277 | 277 | |
| 278 | 278 | void render_primitive::reset() |
| 279 | 279 | { |
| 280 | | // public state |
| 281 | | type = INVALID; |
| 282 | | bounds.x0 = 0; |
| 283 | | bounds.y0 = 0; |
| 284 | | bounds.x1 = 0; |
| 285 | | bounds.y1 = 0; |
| 286 | | color.a = 0; |
| 287 | | color.r = 0; |
| 288 | | color.g = 0; |
| 289 | | color.b = 0; |
| 290 | | flags = 0; |
| 291 | | width = 0.0f; |
| 292 | | texture.set_palette(NULL); |
| 293 | | texture = render_texinfo(); |
| 294 | | texcoords.bl.u = 0.0f; |
| 295 | | texcoords.bl.v = 0.0f; |
| 296 | | texcoords.br.u = 0.0f; |
| 297 | | texcoords.br.v = 0.0f; |
| 298 | | texcoords.tl.u = 0.0f; |
| 299 | | texcoords.tl.v = 0.0f; |
| 300 | | texcoords.tr.u = 0.0f; |
| 301 | | texcoords.tr.v = 0.0f; |
| 280 | // public state |
| 281 | type = INVALID; |
| 282 | bounds.x0 = 0; |
| 283 | bounds.y0 = 0; |
| 284 | bounds.x1 = 0; |
| 285 | bounds.y1 = 0; |
| 286 | color.a = 0; |
| 287 | color.r = 0; |
| 288 | color.g = 0; |
| 289 | color.b = 0; |
| 290 | flags = 0; |
| 291 | width = 0.0f; |
| 292 | texture.set_palette(NULL); |
| 293 | texture = render_texinfo(); |
| 294 | texcoords.bl.u = 0.0f; |
| 295 | texcoords.bl.v = 0.0f; |
| 296 | texcoords.br.u = 0.0f; |
| 297 | texcoords.br.v = 0.0f; |
| 298 | texcoords.tl.u = 0.0f; |
| 299 | texcoords.tl.v = 0.0f; |
| 300 | texcoords.tr.u = 0.0f; |
| 301 | texcoords.tr.v = 0.0f; |
| 302 | 302 | |
| 303 | | // do not clear m_next! |
| 304 | | // memset(&type, 0, FPTR(&texcoords + 1) - FPTR(&type)); |
| 303 | // do not clear m_next! |
| 304 | // memset(&type, 0, FPTR(&texcoords + 1) - FPTR(&type)); |
| 305 | 305 | } |
| 306 | 306 | |
| 307 | 307 | |
| r243189 | r243190 | |
| 556 | 556 | texinfo.width = swidth; |
| 557 | 557 | texinfo.height = sheight; |
| 558 | 558 | // will be set later |
| 559 | | texinfo.set_palette(NULL); |
| 559 | texinfo.set_palette(NULL); |
| 560 | 560 | texinfo.seqid = ++m_curseq; |
| 561 | 561 | } |
| 562 | 562 | else |
| 563 | 563 | { |
| 564 | | // make sure we can recover the original argb32 bitmap |
| 565 | | bitmap_argb32 dummy; |
| 566 | | bitmap_argb32 &srcbitmap = (m_bitmap != NULL) ? downcast<bitmap_argb32 &>(*m_bitmap) : dummy; |
| 564 | // make sure we can recover the original argb32 bitmap |
| 565 | bitmap_argb32 dummy; |
| 566 | bitmap_argb32 &srcbitmap = (m_bitmap != NULL) ? downcast<bitmap_argb32 &>(*m_bitmap) : dummy; |
| 567 | 567 | |
| 568 | | // is it a size we already have? |
| 569 | | scaled_texture *scaled = NULL; |
| 570 | | int scalenum; |
| 571 | | for (scalenum = 0; scalenum < ARRAY_LENGTH(m_scaled); scalenum++) |
| 572 | | { |
| 573 | | scaled = &m_scaled[scalenum]; |
| 568 | // is it a size we already have? |
| 569 | scaled_texture *scaled = NULL; |
| 570 | int scalenum; |
| 571 | for (scalenum = 0; scalenum < ARRAY_LENGTH(m_scaled); scalenum++) |
| 572 | { |
| 573 | scaled = &m_scaled[scalenum]; |
| 574 | 574 | |
| 575 | | // we need a non-NULL bitmap with matching dest size |
| 576 | | if (scaled->bitmap != NULL && dwidth == scaled->bitmap->width() && dheight == scaled->bitmap->height()) |
| 577 | | break; |
| 578 | | } |
| 575 | // we need a non-NULL bitmap with matching dest size |
| 576 | if (scaled->bitmap != NULL && dwidth == scaled->bitmap->width() && dheight == scaled->bitmap->height()) |
| 577 | break; |
| 578 | } |
| 579 | 579 | |
| 580 | | // did we get one? |
| 581 | | if (scalenum == ARRAY_LENGTH(m_scaled)) |
| 582 | | { |
| 583 | | int lowest = -1; |
| 580 | // did we get one? |
| 581 | if (scalenum == ARRAY_LENGTH(m_scaled)) |
| 582 | { |
| 583 | int lowest = -1; |
| 584 | 584 | |
| 585 | | // didn't find one -- take the entry with the lowest seqnum |
| 586 | | for (scalenum = 0; scalenum < ARRAY_LENGTH(m_scaled); scalenum++) |
| 587 | | if ((lowest == -1 || m_scaled[scalenum].seqid < m_scaled[lowest].seqid) && !primlist.has_reference(m_scaled[scalenum].bitmap)) |
| 588 | | lowest = scalenum; |
| 589 | | assert_always(lowest != -1, "Too many live texture instances!"); |
| 585 | // didn't find one -- take the entry with the lowest seqnum |
| 586 | for (scalenum = 0; scalenum < ARRAY_LENGTH(m_scaled); scalenum++) |
| 587 | if ((lowest == -1 || m_scaled[scalenum].seqid < m_scaled[lowest].seqid) && !primlist.has_reference(m_scaled[scalenum].bitmap)) |
| 588 | lowest = scalenum; |
| 589 | assert_always(lowest != -1, "Too many live texture instances!"); |
| 590 | 590 | |
| 591 | | // throw out any existing entries |
| 592 | | scaled = &m_scaled[lowest]; |
| 593 | | if (scaled->bitmap != NULL) |
| 594 | | { |
| 595 | | m_manager->invalidate_all(scaled->bitmap); |
| 596 | | global_free(scaled->bitmap); |
| 597 | | } |
| 591 | // throw out any existing entries |
| 592 | scaled = &m_scaled[lowest]; |
| 593 | if (scaled->bitmap != NULL) |
| 594 | { |
| 595 | m_manager->invalidate_all(scaled->bitmap); |
| 596 | global_free(scaled->bitmap); |
| 597 | } |
| 598 | 598 | |
| 599 | | // allocate a new bitmap |
| 600 | | scaled->bitmap = global_alloc(bitmap_argb32(dwidth, dheight)); |
| 601 | | scaled->seqid = ++m_curseq; |
| 599 | // allocate a new bitmap |
| 600 | scaled->bitmap = global_alloc(bitmap_argb32(dwidth, dheight)); |
| 601 | scaled->seqid = ++m_curseq; |
| 602 | 602 | |
| 603 | | // let the scaler do the work |
| 604 | | (*m_scaler)(*scaled->bitmap, srcbitmap, m_sbounds, m_param); |
| 605 | | } |
| 603 | // let the scaler do the work |
| 604 | (*m_scaler)(*scaled->bitmap, srcbitmap, m_sbounds, m_param); |
| 605 | } |
| 606 | 606 | |
| 607 | | // finally fill out the new info |
| 608 | | primlist.add_reference(scaled->bitmap); |
| 609 | | texinfo.base = &scaled->bitmap->pix32(0); |
| 610 | | texinfo.rowpixels = scaled->bitmap->rowpixels(); |
| 611 | | texinfo.width = dwidth; |
| 612 | | texinfo.height = dheight; |
| 613 | | // will be set later |
| 614 | | texinfo.set_palette(NULL); |
| 615 | | texinfo.seqid = scaled->seqid; |
| 607 | // finally fill out the new info |
| 608 | primlist.add_reference(scaled->bitmap); |
| 609 | texinfo.base = &scaled->bitmap->pix32(0); |
| 610 | texinfo.rowpixels = scaled->bitmap->rowpixels(); |
| 611 | texinfo.width = dwidth; |
| 612 | texinfo.height = dheight; |
| 613 | // will be set later |
| 614 | texinfo.set_palette(NULL); |
| 615 | texinfo.seqid = scaled->seqid; |
| 616 | 616 | } |
| 617 | 617 | } |
| 618 | 618 | |
| r243189 | r243190 | |
| 1817 | 1817 | height = MIN(height, m_maxtexheight); |
| 1818 | 1818 | |
| 1819 | 1819 | curitem->texture()->get_scaled(width, height, prim->texture, list); |
| 1820 | | // set the palette |
| 1820 | // set the palette |
| 1821 | 1821 | #if 1 |
| 1822 | 1822 | const dynamic_array<rgb_t> *adjusted_pal = curitem->texture()->get_adjusted_palette(container); |
| 1823 | | prim->texture.set_palette(adjusted_pal); |
| 1823 | prim->texture.set_palette(adjusted_pal); |
| 1824 | 1824 | #else |
| 1825 | | prim->texture.palette = curitem->texture()->get_adjusted_palette(container); |
| 1825 | prim->texture.palette = curitem->texture()->get_adjusted_palette(container); |
| 1826 | 1826 | #endif |
| 1827 | 1827 | |
| 1828 | | // determine UV coordinates and apply clipping |
| 1829 | | prim->texcoords = oriented_texcoords[finalorient]; |
| 1830 | | clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); |
| 1828 | // determine UV coordinates and apply clipping |
| 1829 | prim->texcoords = oriented_texcoords[finalorient]; |
| 1830 | clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); |
| 1831 | 1831 | |
| 1832 | | // apply the final orientation from the quad flags and then build up the final flags |
| 1833 | | prim->flags = (curitem->flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) | |
| 1834 | | PRIMFLAG_TEXORIENT(finalorient) | |
| 1835 | | PRIMFLAG_TEXFORMAT(curitem->texture()->format()); |
| 1836 | | if (blendmode != -1) |
| 1837 | | prim->flags |= PRIMFLAG_BLENDMODE(blendmode); |
| 1838 | | else |
| 1839 | | prim->flags |= PRIMFLAG_BLENDMODE(PRIMFLAG_GET_BLENDMODE(curitem->flags())); |
| 1832 | // apply the final orientation from the quad flags and then build up the final flags |
| 1833 | prim->flags = (curitem->flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) | |
| 1834 | PRIMFLAG_TEXORIENT(finalorient) | |
| 1835 | PRIMFLAG_TEXFORMAT(curitem->texture()->format()); |
| 1836 | if (blendmode != -1) |
| 1837 | prim->flags |= PRIMFLAG_BLENDMODE(blendmode); |
| 1838 | else |
| 1839 | prim->flags |= PRIMFLAG_BLENDMODE(PRIMFLAG_GET_BLENDMODE(curitem->flags())); |
| 1840 | 1840 | } |
| 1841 | 1841 | else |
| 1842 | 1842 | { |
| r243189 | r243190 | |
| 1876 | 1876 | (container_xform.orientation & ORIENTATION_SWAP_XY) ? width : height, prim->texture, list); |
| 1877 | 1877 | |
| 1878 | 1878 | // determine UV coordinates |
| 1879 | | prim->texcoords = oriented_texcoords[container_xform.orientation]; |
| 1879 | prim->texcoords = oriented_texcoords[container_xform.orientation]; |
| 1880 | 1880 | |
| 1881 | | // set the flags and add it to the list |
| 1882 | | prim->flags = PRIMFLAG_TEXORIENT(container_xform.orientation) | |
| 1883 | | PRIMFLAG_BLENDMODE(BLENDMODE_RGB_MULTIPLY) | |
| 1884 | | PRIMFLAG_TEXFORMAT(container.overlay()->format()) | |
| 1885 | | PRIMFLAG_TEXSHADE(1); |
| 1881 | // set the flags and add it to the list |
| 1882 | prim->flags = PRIMFLAG_TEXORIENT(container_xform.orientation) | |
| 1883 | PRIMFLAG_BLENDMODE(BLENDMODE_RGB_MULTIPLY) | |
| 1884 | PRIMFLAG_TEXFORMAT(container.overlay()->format()) | |
| 1885 | PRIMFLAG_TEXSHADE(1); |
| 1886 | 1886 | |
| 1887 | | list.append_or_return(*prim, false); |
| 1887 | list.append_or_return(*prim, false); |
| 1888 | 1888 | } |
| 1889 | 1889 | } |
| 1890 | 1890 | |
| r243189 | r243190 | |
| 1925 | 1925 | |
| 1926 | 1926 | texture->get_scaled(width, height, prim->texture, list); |
| 1927 | 1927 | |
| 1928 | | // compute the clip rect |
| 1929 | | render_bounds cliprect; |
| 1930 | | cliprect.x0 = render_round_nearest(xform.xoffs); |
| 1931 | | cliprect.y0 = render_round_nearest(xform.yoffs); |
| 1932 | | cliprect.x1 = render_round_nearest(xform.xoffs + xform.xscale); |
| 1933 | | cliprect.y1 = render_round_nearest(xform.yoffs + xform.yscale); |
| 1934 | | sect_render_bounds(&cliprect, &m_bounds); |
| 1928 | // compute the clip rect |
| 1929 | render_bounds cliprect; |
| 1930 | cliprect.x0 = render_round_nearest(xform.xoffs); |
| 1931 | cliprect.y0 = render_round_nearest(xform.yoffs); |
| 1932 | cliprect.x1 = render_round_nearest(xform.xoffs + xform.xscale); |
| 1933 | cliprect.y1 = render_round_nearest(xform.yoffs + xform.yscale); |
| 1934 | sect_render_bounds(&cliprect, &m_bounds); |
| 1935 | 1935 | |
| 1936 | | // determine UV coordinates and apply clipping |
| 1937 | | prim->texcoords = oriented_texcoords[xform.orientation]; |
| 1938 | | bool clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); |
| 1936 | // determine UV coordinates and apply clipping |
| 1937 | prim->texcoords = oriented_texcoords[xform.orientation]; |
| 1938 | bool clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); |
| 1939 | 1939 | |
| 1940 | 1940 | // add to the list or free if we're clipped out |
| 1941 | 1941 | list.append_or_return(*prim, clipped); |
trunk/src/mame/audio/mario.c
| r243189 | r243190 | |
| 46 | 46 | /* ---------------------------------------------------------------------- */ |
| 47 | 47 | static NETLIST_START(nl_mario_snd0) |
| 48 | 48 | |
| 49 | | RES(R17, RES_K(27)) /* 20 according to parts list */ |
| 50 | | /* 27 verified, 30K in schematics */ |
| 51 | | CAP(C14, CAP_U(4.7)) /* verified */ |
| 49 | RES(R17, RES_K(27)) /* 20 according to parts list */ |
| 50 | /* 27 verified, 30K in schematics */ |
| 51 | CAP(C14, CAP_U(4.7)) /* verified */ |
| 52 | 52 | |
| 53 | | TTL_74123(2H_A) |
| 54 | | NET_C(2H_A.VCC, V5) |
| 55 | | NET_C(2H_A.GND, GND) |
| 56 | | NET_C(SOUND0.Q, 2H_A.B) |
| 57 | | NET_C(GND, 2H_A.A) |
| 58 | | NET_C(2H_A.CLRQ, ttlhigh) /* NOT IN SCHEMATICS */ |
| 59 | | DIODE(D1, "1N4148") /* FIXME: try to identify */ |
| 60 | | TTL_7404_INVERT(1H_A, 2H_A.QQ) |
| 61 | | NET_C(R17.1, V5) |
| 62 | | NET_C(R17.2, D1.A, C14.1) |
| 63 | | NET_C(D1.K, 2H_A.RC) |
| 64 | | NET_C(C14.2, 2H_A.C) |
| 53 | TTL_74123(2H_A) |
| 54 | NET_C(2H_A.VCC, V5) |
| 55 | NET_C(2H_A.GND, GND) |
| 56 | NET_C(SOUND0.Q, 2H_A.B) |
| 57 | NET_C(GND, 2H_A.A) |
| 58 | NET_C(2H_A.CLRQ, ttlhigh) /* NOT IN SCHEMATICS */ |
| 59 | DIODE(D1, "1N4148") /* FIXME: try to identify */ |
| 60 | TTL_7404_INVERT(1H_A, 2H_A.QQ) |
| 61 | NET_C(R17.1, V5) |
| 62 | NET_C(R17.2, D1.A, C14.1) |
| 63 | NET_C(D1.K, 2H_A.RC) |
| 64 | NET_C(C14.2, 2H_A.C) |
| 65 | 65 | |
| 66 | | RES(R6, RES_K(4.7)) /* verified */ |
| 67 | | CAP(C3, CAP_U(10)) /* verified */ |
| 66 | RES(R6, RES_K(4.7)) /* verified */ |
| 67 | CAP(C3, CAP_U(10)) /* verified */ |
| 68 | 68 | |
| 69 | | NET_C(1H_A.Q, R6.1) |
| 70 | | NET_C(R6.2, C3.1, 1J_A.FC) |
| 71 | | NET_C(R6.2, 2J_A.FC) |
| 72 | | NET_C(C3.2, GND) |
| 69 | NET_C(1H_A.Q, R6.1) |
| 70 | NET_C(R6.2, C3.1, 1J_A.FC) |
| 71 | NET_C(R6.2, 2J_A.FC) |
| 72 | NET_C(C3.2, GND) |
| 73 | 73 | |
| 74 | | //#define MR_C6 CAP_N(3.9) /* verified */ |
| 74 | //#define MR_C6 CAP_N(3.9) /* verified */ |
| 75 | 75 | |
| 76 | | SN74LS629(1J_A, CAP_N(3.9)) |
| 77 | | NET_C(1J_A.RNG, V5) |
| 78 | | NET_C(1J_A.ENQ, ttllow) |
| 79 | | NET_C(GND, 1J_A.GND) |
| 76 | SN74LS629(1J_A, CAP_N(3.9)) |
| 77 | NET_C(1J_A.RNG, V5) |
| 78 | NET_C(1J_A.ENQ, ttllow) |
| 79 | NET_C(GND, 1J_A.GND) |
| 80 | 80 | |
| 81 | | //#define MR_C17 CAP_N(22) /* verified */ |
| 81 | //#define MR_C17 CAP_N(22) /* verified */ |
| 82 | 82 | |
| 83 | | SN74LS629(2J_A, CAP_N(22)) |
| 84 | | NET_C(2J_A.RNG, V5) |
| 85 | | NET_C(2J_A.ENQ, ttllow) |
| 86 | | NET_C(GND, 2J_A.GND) |
| 83 | SN74LS629(2J_A, CAP_N(22)) |
| 84 | NET_C(2J_A.RNG, V5) |
| 85 | NET_C(2J_A.ENQ, ttllow) |
| 86 | NET_C(GND, 2J_A.GND) |
| 87 | 87 | |
| 88 | | TTL_7486_XOR(1K_A, 1J_A.Y, 2J_A.Y) |
| 89 | | TTL_7408_AND(2K_A, 2H_A.Q, 1K_A) |
| 88 | TTL_7486_XOR(1K_A, 1J_A.Y, 2J_A.Y) |
| 89 | TTL_7408_AND(2K_A, 2H_A.Q, 1K_A) |
| 90 | 90 | NETLIST_END() |
| 91 | 91 | |
| 92 | 92 | /* ---------------------------------------------------------------------- */ |
| r243189 | r243190 | |
| 96 | 96 | // FIXME: Diodes are 1S953 |
| 97 | 97 | static NETLIST_START(nl_mario_snd7) |
| 98 | 98 | |
| 99 | | RES(R61, RES_K(47)) |
| 100 | | CAP(C41, CAP_U(4.7)) /* verified */ |
| 99 | RES(R61, RES_K(47)) |
| 100 | CAP(C41, CAP_U(4.7)) /* verified */ |
| 101 | 101 | |
| 102 | | TTL_74123(4L_A) |
| 103 | | NET_C(4L_A.VCC, V5) |
| 104 | | NET_C(4L_A.GND, GND) |
| 105 | | NET_C(SOUND7.Q, 4L_A.B) |
| 106 | | NET_C(GND, 4L_A.A) |
| 107 | | NET_C(4L_A.CLRQ, ttlhigh) /* NOT IN SCHEMATICS */ |
| 108 | | DIODE(D10, "1N4148") /* FIXME: try to identify */ |
| 109 | | TTL_7404_INVERT(4J_A, 4L_A.Q) |
| 110 | | NET_C(R61.1, V5) |
| 111 | | NET_C(R61.2, D10.A, C41.1) |
| 112 | | NET_C(D10.K, 4L_A.RC) |
| 113 | | NET_C(C41.2, 4L_A.C) |
| 102 | TTL_74123(4L_A) |
| 103 | NET_C(4L_A.VCC, V5) |
| 104 | NET_C(4L_A.GND, GND) |
| 105 | NET_C(SOUND7.Q, 4L_A.B) |
| 106 | NET_C(GND, 4L_A.A) |
| 107 | NET_C(4L_A.CLRQ, ttlhigh) /* NOT IN SCHEMATICS */ |
| 108 | DIODE(D10, "1N4148") /* FIXME: try to identify */ |
| 109 | TTL_7404_INVERT(4J_A, 4L_A.Q) |
| 110 | NET_C(R61.1, V5) |
| 111 | NET_C(R61.2, D10.A, C41.1) |
| 112 | NET_C(D10.K, 4L_A.RC) |
| 113 | NET_C(C41.2, 4L_A.C) |
| 114 | 114 | |
| 115 | | RES(R65, RES_K(10)) |
| 116 | | CAP(C44, CAP_U(3.3)) /* verified */ |
| 115 | RES(R65, RES_K(10)) |
| 116 | CAP(C44, CAP_U(3.3)) /* verified */ |
| 117 | 117 | |
| 118 | | SN74LS629(4K_A, CAP_U(0.022)) |
| 119 | | NET_C(4K_A.RNG, V5) |
| 120 | | NET_C(4K_A.ENQ, ttllow) |
| 121 | | NET_C(GND, 4K_A.GND) |
| 122 | | NET_C(R65.1, 4J_A.Q) |
| 123 | | NET_C(R65.2, 4K_A.FC, C44.1) |
| 124 | | NET_C(C44.2, GND) |
| 118 | SN74LS629(4K_A, CAP_U(0.022)) |
| 119 | NET_C(4K_A.RNG, V5) |
| 120 | NET_C(4K_A.ENQ, ttllow) |
| 121 | NET_C(GND, 4K_A.GND) |
| 122 | NET_C(R65.1, 4J_A.Q) |
| 123 | NET_C(R65.2, 4K_A.FC, C44.1) |
| 124 | NET_C(C44.2, GND) |
| 125 | 125 | |
| 126 | | CD_4020(3H, 4K_B.Y, ttllow, V5, GND) |
| 127 | | TTL_7404_INVERT(4J_B, 3H.Q12) |
| 126 | CD_4020(3H, 4K_B.Y, ttllow, V5, GND) |
| 127 | TTL_7404_INVERT(4J_B, 3H.Q12) |
| 128 | 128 | |
| 129 | | RES(R64, RES_K(20)) |
| 130 | | CAP(C43, CAP_U(3.3)) /* verified */ |
| 129 | RES(R64, RES_K(20)) |
| 130 | CAP(C43, CAP_U(3.3)) /* verified */ |
| 131 | 131 | |
| 132 | | SN74LS629(4K_B, CAP_U(0.0047)) |
| 133 | | NET_C(4K_B.RNG, V5) |
| 134 | | NET_C(4K_B.ENQ, ttllow) |
| 135 | | NET_C(GND, 4K_B.GND) |
| 136 | | NET_C(R64.1, 4J_B.Q) |
| 137 | | NET_C(R64.2, 4K_B.FC, C43.1) |
| 138 | | NET_C(C43.2, GND) |
| 132 | SN74LS629(4K_B, CAP_U(0.0047)) |
| 133 | NET_C(4K_B.RNG, V5) |
| 134 | NET_C(4K_B.ENQ, ttllow) |
| 135 | NET_C(GND, 4K_B.GND) |
| 136 | NET_C(R64.1, 4J_B.Q) |
| 137 | NET_C(R64.2, 4K_B.FC, C43.1) |
| 138 | NET_C(C43.2, GND) |
| 139 | 139 | |
| 140 | | TTL_7486_XOR(1K_C, 3H.Q4, 4K_A.Y) |
| 141 | | TTL_7408_AND(2K_C, 4L_A.Q, 1K_C) |
| 140 | TTL_7486_XOR(1K_C, 3H.Q4, 4K_A.Y) |
| 141 | TTL_7408_AND(2K_C, 4L_A.Q, 1K_C) |
| 142 | 142 | |
| 143 | 143 | NETLIST_END() |
| 144 | 144 | |
| r243189 | r243190 | |
| 146 | 146 | /* DAC sound */ |
| 147 | 147 | /* ---------------------------------------------------------------------- */ |
| 148 | 148 | static NETLIST_START(nl_mario_dac) |
| 149 | | RES(R34, RES_M(2)) |
| 150 | | RES(R35, RES_M(1)) |
| 151 | | RES(R36, RES_M(1.8)) |
| 152 | | LM3900(3M_1) |
| 153 | | NET_C(3M_1.VM, GND) |
| 154 | | NET_C(3M_1.VP, V5) |
| 149 | RES(R34, RES_M(2)) |
| 150 | RES(R35, RES_M(1)) |
| 151 | RES(R36, RES_M(1.8)) |
| 152 | LM3900(3M_1) |
| 153 | NET_C(3M_1.VM, GND) |
| 154 | NET_C(3M_1.VP, V5) |
| 155 | 155 | |
| 156 | | NET_C(DAC.VOUT, R34.1) |
| 157 | | NET_C(3M_1.MINUS, R34.2, R35.2) |
| 158 | | NET_C(3M_1.OUT, R35.1) |
| 159 | | NET_C(3M_1.PLUS, R36.1) |
| 160 | | NET_C(R36.2, GND) |
| 156 | NET_C(DAC.VOUT, R34.1) |
| 157 | NET_C(3M_1.MINUS, R34.2, R35.2) |
| 158 | NET_C(3M_1.OUT, R35.1) |
| 159 | NET_C(3M_1.PLUS, R36.1) |
| 160 | NET_C(R36.2, GND) |
| 161 | 161 | |
| 162 | | RES(R21, RES_M(1.8)) |
| 163 | | RES(R23, RES_K(10)) |
| 164 | | RES(R25, RES_K(10)) |
| 165 | | RES(R37, RES_K(750)) |
| 166 | | RES(R38, RES_K(360)) |
| 167 | | RES(R39, RES_K(750)) |
| 162 | RES(R21, RES_M(1.8)) |
| 163 | RES(R23, RES_K(10)) |
| 164 | RES(R25, RES_K(10)) |
| 165 | RES(R37, RES_K(750)) |
| 166 | RES(R38, RES_K(360)) |
| 167 | RES(R39, RES_K(750)) |
| 168 | 168 | |
| 169 | | CAP(C18, CAP_P(100)) |
| 170 | | CAP(C19, CAP_U(10)) |
| 171 | | CAP(C20, CAP_U(1)) |
| 172 | | CAP(C30, CAP_P(100)) |
| 169 | CAP(C18, CAP_P(100)) |
| 170 | CAP(C19, CAP_U(10)) |
| 171 | CAP(C20, CAP_U(1)) |
| 172 | CAP(C30, CAP_P(100)) |
| 173 | 173 | |
| 174 | | LM3900(3M_2) |
| 175 | | NET_C(3M_2.VM, GND) |
| 176 | | NET_C(3M_2.VP, V5) |
| 174 | LM3900(3M_2) |
| 175 | NET_C(3M_2.VM, GND) |
| 176 | NET_C(3M_2.VP, V5) |
| 177 | 177 | |
| 178 | | NET_C(R35.1, C20.1) |
| 179 | | NET_C(C20.2, R37.1) |
| 180 | | NET_C(R37.2, R38.2, C18.1, R39.2) |
| 178 | NET_C(R35.1, C20.1) |
| 179 | NET_C(C20.2, R37.1) |
| 180 | NET_C(R37.2, R38.2, C18.1, R39.2) |
| 181 | 181 | |
| 182 | | NET_C(C18.2, GND) |
| 183 | | NET_C(R38.1, C30.2, 3M_2.MINUS) |
| 184 | | NET_C(3M_2.OUT, R39.1, C30.1) |
| 182 | NET_C(C18.2, GND) |
| 183 | NET_C(R38.1, C30.2, 3M_2.MINUS) |
| 184 | NET_C(3M_2.OUT, R39.1, C30.1) |
| 185 | 185 | |
| 186 | | NET_C(R21.1, 3M_2.PLUS) |
| 187 | | NET_C(R21.2, C19.1, R25.2, R23.1) |
| 188 | | NET_C(C19.2, R23.2, GND) |
| 189 | | NET_C(R25.1, V5) |
| 186 | NET_C(R21.1, 3M_2.PLUS) |
| 187 | NET_C(R21.2, C19.1, R25.2, R23.1) |
| 188 | NET_C(C19.2, R23.2, GND) |
| 189 | NET_C(R25.1, V5) |
| 190 | 190 | NETLIST_END() |
| 191 | 191 | |
| 192 | 192 | static NETLIST_START(nl_mario) |
| 193 | 193 | |
| 194 | | /* Standard stuff */ |
| 194 | /* Standard stuff */ |
| 195 | 195 | |
| 196 | | SOLVER(Solver, 48000) |
| 197 | | PARAM(Solver.ACCURACY, 1e-8) |
| 198 | | PARAM(Solver.SOR_FACTOR, 1.0) |
| 199 | | PARAM(Solver.GS_THRESHOLD, 5) |
| 200 | | PARAM(Solver.GS_LOOPS, 4) |
| 201 | | //PARAM(Solver.LTE, 5e-2) // Default is not enough for paddle control |
| 202 | | PARAM(Solver.DYNAMIC_TS, 0) |
| 203 | | ANALOG_INPUT(V5, 5) |
| 196 | SOLVER(Solver, 48000) |
| 197 | PARAM(Solver.ACCURACY, 1e-8) |
| 198 | PARAM(Solver.SOR_FACTOR, 1.0) |
| 199 | PARAM(Solver.GS_THRESHOLD, 5) |
| 200 | PARAM(Solver.GS_LOOPS, 4) |
| 201 | //PARAM(Solver.LTE, 5e-2) // Default is not enough for paddle control |
| 202 | PARAM(Solver.DYNAMIC_TS, 0) |
| 203 | ANALOG_INPUT(V5, 5) |
| 204 | 204 | |
| 205 | | TTL_INPUT(SOUND0, 1) |
| 206 | | INCLUDE(nl_mario_snd0) |
| 205 | TTL_INPUT(SOUND0, 1) |
| 206 | INCLUDE(nl_mario_snd0) |
| 207 | 207 | |
| 208 | | TTL_INPUT(SOUND7, 1) |
| 209 | | INCLUDE(nl_mario_snd7) |
| 208 | TTL_INPUT(SOUND7, 1) |
| 209 | INCLUDE(nl_mario_snd7) |
| 210 | 210 | |
| 211 | | R2R_DAC(DAC, 3.4, 10000.0, 8) |
| 212 | | NET_C(DAC.VGND, GND) |
| 211 | R2R_DAC(DAC, 3.4, 10000.0, 8) |
| 212 | NET_C(DAC.VGND, GND) |
| 213 | 213 | |
| 214 | | INCLUDE(nl_mario_dac) |
| 214 | INCLUDE(nl_mario_dac) |
| 215 | 215 | |
| 216 | | /* ---------------------------------------------------------------------- */ |
| 217 | | /* mixing */ |
| 218 | | /* ---------------------------------------------------------------------- */ |
| 216 | /* ---------------------------------------------------------------------- */ |
| 217 | /* mixing */ |
| 218 | /* ---------------------------------------------------------------------- */ |
| 219 | 219 | |
| 220 | | RES(R20, RES_K(22)) /* verified */ |
| 221 | | RES(R19, RES_K(22)) /* verified */ |
| 222 | | RES(R40, RES_K(22)) /* verified */ |
| 223 | | RES(R41, RES_K(100)) /* verified */ |
| 224 | | CAP(C31, CAP_U(0.022)) /* */ |
| 220 | RES(R20, RES_K(22)) /* verified */ |
| 221 | RES(R19, RES_K(22)) /* verified */ |
| 222 | RES(R40, RES_K(22)) /* verified */ |
| 223 | RES(R41, RES_K(100)) /* verified */ |
| 224 | CAP(C31, CAP_U(0.022)) /* */ |
| 225 | 225 | |
| 226 | | NET_C(2K_A.Q, R20.1) |
| 227 | | NET_C(GND, R19.1) //FIXME |
| 228 | | NET_C(2K_C.Q, R41.1) |
| 226 | NET_C(2K_A.Q, R20.1) |
| 227 | NET_C(GND, R19.1) //FIXME |
| 228 | NET_C(2K_C.Q, R41.1) |
| 229 | 229 | |
| 230 | 230 | #if 1 |
| 231 | | RES(DUM, RES_K(22)) |
| 232 | | NET_C(R39.1, DUM.1) |
| 233 | | NET_C(DUM.2, GND) |
| 234 | | FRONTIER(front1, R39.1, R40.1) |
| 231 | RES(DUM, RES_K(22)) |
| 232 | NET_C(R39.1, DUM.1) |
| 233 | NET_C(DUM.2, GND) |
| 234 | FRONTIER(front1, R39.1, R40.1) |
| 235 | 235 | #else |
| 236 | | NET_C(R39.1, R40.1) |
| 236 | NET_C(R39.1, R40.1) |
| 237 | 237 | #endif |
| 238 | 238 | |
| 239 | | NET_C(R20.2, R19.2, R40.2, R41.2, C31.1) |
| 240 | | NET_C(C31.2, GND) |
| 239 | NET_C(R20.2, R19.2, R40.2, R41.2, C31.1) |
| 240 | NET_C(C31.2, GND) |
| 241 | 241 | |
| 242 | | CAP(C32, CAP_U(1)) /* verified */ |
| 243 | | RES(R42, RES_K(43)) /* verified */ |
| 244 | | RES(R43, RES_K(100)) /* verified */ |
| 242 | CAP(C32, CAP_U(1)) /* verified */ |
| 243 | RES(R42, RES_K(43)) /* verified */ |
| 244 | RES(R43, RES_K(100)) /* verified */ |
| 245 | 245 | |
| 246 | | NET_C(C31.1, C32.1) |
| 247 | | NET_C(C32.2, R42.1, R43.2, Q10.B) |
| 248 | | //NET_C(C32.2, R42.1, R43.2) |
| 249 | | NET_C(R43.1, V5) |
| 250 | | NET_C(R42.2, GND) |
| 246 | NET_C(C31.1, C32.1) |
| 247 | NET_C(C32.2, R42.1, R43.2, Q10.B) |
| 248 | //NET_C(C32.2, R42.1, R43.2) |
| 249 | NET_C(R43.1, V5) |
| 250 | NET_C(R42.2, GND) |
| 251 | 251 | #if 1 |
| 252 | | RES(R63, RES_K(1)) /* */ |
| 253 | | RES(R62, 150) /* */ |
| 252 | RES(R63, RES_K(1)) /* */ |
| 253 | RES(R62, 150) /* */ |
| 254 | 254 | |
| 255 | | QBJT_EB(Q10, "2SC1815") |
| 255 | QBJT_EB(Q10, "2SC1815") |
| 256 | 256 | |
| 257 | | NET_C(R62.2, GND) |
| 258 | | NET_C(R62.1, Q10.E) |
| 257 | NET_C(R62.2, GND) |
| 258 | NET_C(R62.1, Q10.E) |
| 259 | 259 | |
| 260 | | NET_C(R63.1, V5) |
| 261 | | NET_C(R63.2, Q10.C) |
| 260 | NET_C(R63.1, V5) |
| 261 | NET_C(R63.2, Q10.C) |
| 262 | 262 | |
| 263 | | CAP(C42, CAP_U(0.1)) |
| 264 | | CAP(C47, CAP_U(4.7)) |
| 265 | | RES(VR1, RES_K(10)) |
| 263 | CAP(C42, CAP_U(0.1)) |
| 264 | CAP(C47, CAP_U(4.7)) |
| 265 | RES(VR1, RES_K(10)) |
| 266 | 266 | |
| 267 | | NET_C(C42.1, C47.1, R62.1) |
| 268 | | NET_C(C42.2, GND) |
| 269 | | NET_C(C47.2, VR1.1) |
| 270 | | NET_C(VR1.2, GND) |
| 267 | NET_C(C42.1, C47.1, R62.1) |
| 268 | NET_C(C42.2, GND) |
| 269 | NET_C(C47.2, VR1.1) |
| 270 | NET_C(VR1.2, GND) |
| 271 | 271 | #endif |
| 272 | | /* ---------------------------------------------------------------------- */ |
| 273 | | /* Output */ |
| 274 | | /* ---------------------------------------------------------------------- */ |
| 272 | /* ---------------------------------------------------------------------- */ |
| 273 | /* Output */ |
| 274 | /* ---------------------------------------------------------------------- */ |
| 275 | 275 | |
| 276 | | RES(ROUT, 1000000) |
| 276 | RES(ROUT, 1000000) |
| 277 | 277 | |
| 278 | | //NET_C(Q10.C, ROUT.1) |
| 279 | | //NET_C(R43.2, ROUT.1) |
| 280 | | NET_C(VR1.1, ROUT.1) |
| 278 | //NET_C(Q10.C, ROUT.1) |
| 279 | //NET_C(R43.2, ROUT.1) |
| 280 | NET_C(VR1.1, ROUT.1) |
| 281 | 281 | |
| 282 | | NET_C(GND, ROUT.2) |
| 282 | NET_C(GND, ROUT.2) |
| 283 | 283 | |
| 284 | 284 | NETLIST_END() |
| 285 | 285 | |
| r243189 | r243190 | |
| 790 | 790 | #if OLD_SOUND |
| 791 | 791 | m_discrete->write(space, DS_SOUND0_INP, 0); |
| 792 | 792 | #else |
| 793 | | m_audio_snd0->write(data); |
| 793 | m_audio_snd0->write(data); |
| 794 | 794 | #endif |
| 795 | 795 | } |
| 796 | 796 | |
| r243189 | r243190 | |
| 835 | 835 | #if OLD_SOUND |
| 836 | 836 | machine().device<discrete_device>("discrete")->write(space, DS_SOUND7_INP, data & 1); |
| 837 | 837 | #else |
| 838 | | m_audio_snd7->write((data & 1) ^ 1); |
| 838 | m_audio_snd7->write((data & 1) ^ 1); |
| 839 | 839 | #endif |
| 840 | 840 | break; |
| 841 | 841 | } |
| r243189 | r243190 | |
| 891 | 891 | MCFG_DISCRETE_INTF(mario) |
| 892 | 892 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1) |
| 893 | 893 | #else |
| 894 | | MCFG_SOUND_ADD("snd_nl", NETLIST_SOUND, 48000) |
| 895 | | MCFG_NETLIST_SETUP(nl_mario) |
| 896 | | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) |
| 894 | MCFG_SOUND_ADD("snd_nl", NETLIST_SOUND, 48000) |
| 895 | MCFG_NETLIST_SETUP(nl_mario) |
| 896 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) |
| 897 | 897 | |
| 898 | | MCFG_NETLIST_LOGIC_INPUT("snd_nl", "snd0", "SOUND0.IN", 0, 1) |
| 899 | | MCFG_NETLIST_LOGIC_INPUT("snd_nl", "snd7", "SOUND7.IN", 0, 1) |
| 900 | | MCFG_NETLIST_LOGIC_INPUT("snd_nl", "dac", "DAC.VAL", 0, 255) |
| 898 | MCFG_NETLIST_LOGIC_INPUT("snd_nl", "snd0", "SOUND0.IN", 0, 1) |
| 899 | MCFG_NETLIST_LOGIC_INPUT("snd_nl", "snd7", "SOUND7.IN", 0, 1) |
| 900 | MCFG_NETLIST_LOGIC_INPUT("snd_nl", "dac", "DAC.VAL", 0, 255) |
| 901 | 901 | |
| 902 | | MCFG_NETLIST_STREAM_OUTPUT("snd_nl", 0, "ROUT.1") |
| 903 | | MCFG_NETLIST_ANALOG_MULT_OFFSET(150000.0, 0.0) |
| 902 | MCFG_NETLIST_STREAM_OUTPUT("snd_nl", 0, "ROUT.1") |
| 903 | MCFG_NETLIST_ANALOG_MULT_OFFSET(150000.0, 0.0) |
| 904 | 904 | #endif |
| 905 | 905 | |
| 906 | 906 | MACHINE_CONFIG_END |
trunk/src/mame/machine/315-5838_317-0229_comp.c
| r243189 | r243190 | |
| 1 | 1 | /* Sega Compression (and possibly encryption) device |
| 2 | 2 | |
| 3 | | 315-5838 - Decathlete (ST-V) |
| 4 | | 317-0229 - Dead or Alive (Model 2A) |
| 3 | 315-5838 - Decathlete (ST-V) |
| 4 | 317-0229 - Dead or Alive (Model 2A) |
| 5 | 5 | |
| 6 | | Package Type: TQFP100 |
| 6 | Package Type: TQFP100 |
| 7 | 7 | |
| 8 | | This appears to be a dual channel compression chip, used in 1996, predating the 5881. |
| 9 | | Decathlete uses it to compress ALL the game graphics, Dead or Alive uses it for a |
| 10 | | dumb security check, decompressing a single string. |
| 8 | This appears to be a dual channel compression chip, used in 1996, predating the 5881. |
| 9 | Decathlete uses it to compress ALL the game graphics, Dead or Alive uses it for a |
| 10 | dumb security check, decompressing a single string. |
| 11 | 11 | |
| 12 | | Each channel appears to be connected to a different set of ROMs, however there is |
| 13 | | defintiely only a single 315-5838 chip. (could the different channels actually just |
| 14 | | be mirror addresses, with part of the address determining the ROMs to use?) |
| 12 | Each channel appears to be connected to a different set of ROMs, however there is |
| 13 | defintiely only a single 315-5838 chip. (could the different channels actually just |
| 14 | be mirror addresses, with part of the address determining the ROMs to use?) |
| 15 | 15 | |
| 16 | | Dead of Alive only uses a single channel, and has the source data in RAM, not ROM. |
| 17 | | This is similar to how some 5881 games were set up, with the ST-V versions decrypting |
| 18 | | data directly from ROM and the Model 2 ones using a RAM source buffer. |
| 16 | Dead of Alive only uses a single channel, and has the source data in RAM, not ROM. |
| 17 | This is similar to how some 5881 games were set up, with the ST-V versions decrypting |
| 18 | data directly from ROM and the Model 2 ones using a RAM source buffer. |
| 19 | 19 | |
| 20 | | Looking at the values read I don't think there is any address based encryption, for |
| 21 | | example many blocks where you'd expect a zero fill start with repeating patterns |
| 22 | | of 8f708f70 (different lengths) channel would appear to relate to compressed 0x00 data |
| 20 | Looking at the values read I don't think there is any address based encryption, for |
| 21 | example many blocks where you'd expect a zero fill start with repeating patterns |
| 22 | of 8f708f70 (different lengths) channel would appear to relate to compressed 0x00 data |
| 23 | 23 | |
| 24 | | read addr 0071253c, blah_r 8f708f70 - read count count 00000004 |
| 25 | | read addr 00712540, blah_r 8f708f70 - read count count 00000008 |
| 26 | | read addr 00712544, blah_r 8f708f70 - read count count 0000000c |
| 27 | | read addr 00712548, blah_r 8f708f70 - read count count 00000010 |
| 28 | | read addr 0071254c, blah_r 8f708f70 - read count count 00000014 |
| 29 | | read addr 00712550, blah_r 8f708f70 - read count count 00000018 |
| 30 | | read addr 00712554, blah_r 8f708f70 - read count count 0000001c |
| 24 | read addr 0071253c, blah_r 8f708f70 - read count count 00000004 |
| 25 | read addr 00712540, blah_r 8f708f70 - read count count 00000008 |
| 26 | read addr 00712544, blah_r 8f708f70 - read count count 0000000c |
| 27 | read addr 00712548, blah_r 8f708f70 - read count count 00000010 |
| 28 | read addr 0071254c, blah_r 8f708f70 - read count count 00000014 |
| 29 | read addr 00712550, blah_r 8f708f70 - read count count 00000018 |
| 30 | read addr 00712554, blah_r 8f708f70 - read count count 0000001c |
| 31 | 31 | |
| 32 | 32 | */ |
| 33 | 33 | |
| r243189 | r243190 | |
| 95 | 95 | |
| 96 | 96 | UINT32 sega_315_5838_comp_device::genericdecathlt_prot_r(UINT32 mem_mask, int channel) |
| 97 | 97 | { |
| 98 | | // UINT32 *fake0 = (UINT32*)memregion( ":fake0" )->base(); |
| 99 | | // UINT32 retvalue = 0xffff; |
| 98 | // UINT32 *fake0 = (UINT32*)memregion( ":fake0" )->base(); |
| 99 | // UINT32 retvalue = 0xffff; |
| 100 | 100 | |
| 101 | 101 | switch (m_channel[channel].m_srcoffset) |
| 102 | 102 | { |
| r243189 | r243190 | |
| 177 | 177 | |
| 178 | 178 | void sega_315_5838_comp_device::set_prot_addr(UINT32 data, UINT32 mem_mask, int channel) |
| 179 | 179 | { |
| 180 | | // printf("set_prot_addr\n"); |
| 180 | // printf("set_prot_addr\n"); |
| 181 | 181 | COMBINE_DATA(&m_channel[channel].m_srcoffset); |
| 182 | 182 | |
| 183 | 183 | //if (m_decathlt_part==0) logerror("%d, last read count was %06x\n",channel, m_channel[channel].m_decathlt_lastcount*4); |
| r243189 | r243190 | |
| 361 | 361 | cpu->space(AS_PROGRAM).install_readwrite_handler(0x01d80000, 0x01dfffff, read32_delegate(FUNC(sega_315_5838_comp_device::doa_prot_r), this), write32_delegate(FUNC(sega_315_5838_comp_device::doa_prot_w), this)); |
| 362 | 362 | cpu->space(AS_PROGRAM).install_write_handler(0x01d87ff0, 0x01d87ff3, write32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot1_srcaddr_w), this)); // set compressed data source address (always set 0, data is in RAM) |
| 363 | 363 | cpu->space(AS_PROGRAM).install_write_handler(0x01d87ff4, 0x01d87ff7, write32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot1_w_doa), this)); // upload tab |
| 364 | | // cpu->space(AS_PROGRAM).install_read_handler(0x01d87ff8, 0x01d87ffb, read32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot1_r), this)); // read decompressed data |
| 364 | // cpu->space(AS_PROGRAM).install_read_handler(0x01d87ff8, 0x01d87ffb, read32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot1_r), this)); // read decompressed data |
| 365 | 365 | |
| 366 | | } |
| | No newline at end of file |
| 366 | } |
trunk/src/mame/machine/315-5881_crypt.c
| r243189 | r243190 | |
| 82 | 82 | { |
| 83 | 83 | if (done_compression == 1) |
| 84 | 84 | enc_start(); |
| 85 | | |
| 86 | 85 | |
| 87 | 86 | |
| 87 | |
| 88 | 88 | line_fill(); |
| 89 | 89 | } |
| 90 | 90 | base = line_buffer + line_buffer_pos; |
| r243189 | r243190 | |
| 176 | 176 | |
| 177 | 177 | void key2label(uint32_t key) |
| 178 | 178 | { |
| 179 | | int bcd0 = ((BIT(key,17)<<3)|(BIT(key,7)<<2)|(BIT(key,14)<<1)|BIT(key,19))^9; |
| 180 | | int bcd1 = ((BIT(key,20)<<3)|(BIT(key,1)<<2)|(BIT(key,4)<<1)|BIT(key,13))^5; |
| 181 | | int bcd2 = (BIT(key,9)<<1)|BIT(key,22); |
| 182 | | int bcd3 = ((BIT(key,9)<<2)|BIT(key,9))^5; |
| 183 | | |
| 184 | | char chiplabel[13]; |
| 185 | | sprintf(chiplabel, "317-%d%d%d%d-%s", bcd3, bcd2, bcd1, bcd0, (BIT(key,5)?"JPN":"COM")); |
| 186 | | |
| 187 | | printf("%s", chiplabel); |
| 179 | int bcd0 = ((BIT(key,17)<<3)|(BIT(key,7)<<2)|(BIT(key,14)<<1)|BIT(key,19))^9; |
| 180 | int bcd1 = ((BIT(key,20)<<3)|(BIT(key,1)<<2)|(BIT(key,4)<<1)|BIT(key,13))^5; |
| 181 | int bcd2 = (BIT(key,9)<<1)|BIT(key,22); |
| 182 | int bcd3 = ((BIT(key,9)<<2)|BIT(key,9))^5; |
| 183 | |
| 184 | char chiplabel[13]; |
| 185 | sprintf(chiplabel, "317-%d%d%d%d-%s", bcd3, bcd2, bcd1, bcd0, (BIT(key,5)?"JPN":"COM")); |
| 186 | |
| 187 | printf("%s", chiplabel); |
| 188 | 188 | } |
| 189 | 189 | |
| 190 | 190 | Given the use of the BCD-encoded security module labels, it's expected that at least other 6 additional bits be present in the |
| r243189 | r243190 | |
| 196 | 196 | |
| 197 | 197 | In the second Feistel Network, every key bit seem to be used at most once (the various uses of current bit #9 are fictitious, as |
| 198 | 198 | that bit really represent various bits in the real key; see comments on the use of the labels above). Given that, it seems probable |
| 199 | | that the real key is 64 bits long, exactly as in the related CPS-2 scheme, and the designers tried to cover all 96 input bits with |
| 199 | that the real key is 64 bits long, exactly as in the related CPS-2 scheme, and the designers tried to cover all 96 input bits with |
| 200 | 200 | the bits provening from the game key, the sequence key and the result from the first feistel network (64+16+16=96). In the first |
| 201 | 201 | Feistel Network, as only 80 bits are available, some bits would be used twice (as can be partially seen in the current implementation). |
| 202 | 202 | The fact that only 29 bits out of the expected 64 have been observed till now would be due to the generation of the key by composing |
| r243189 | r243190 | |
| 453 | 453 | |
| 454 | 454 | { |
| 455 | 455 | { |
| 456 | | 2,2,0,3,0,3,1,0,1,1,2,3,2,3,1,0,0,0,3,2,2,0,2,3,1,3,2,0,3,3,1,3, |
| 456 | 2,2,0,3,0,3,1,0,1,1,2,3,2,3,1,0,0,0,3,2,2,0,2,3,1,3,2,0,3,3,1,3, |
| 457 | 457 | // unused? |
| 458 | 458 | 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, |
| 459 | 459 | }, |
| r243189 | r243190 | |
| 511 | 511 | |
| 512 | 512 | const int sega_315_5881_crypt_device::fn1_game_key_scheduling[FN1GK][2] = { |
| 513 | 513 | {1,29}, {1,71}, {2,4}, {2,54}, {3,8}, {4,56}, {4,73}, {5,11}, |
| 514 | | {6,51}, {7,92}, {8,89}, {9,9}, {9,39}, {9,58}, {9,86}, {10,90}, |
| 514 | {6,51}, {7,92}, {8,89}, {9,9}, {9,39}, {9,58}, {9,86}, {10,90}, |
| 515 | 515 | {11,6}, {12,64}, {13,49}, {14,44}, {15,40}, {16,69}, {17,15}, {18,23}, |
| 516 | 516 | {18,43}, {19,82}, {20,81}, {21,32}, {22,5}, {23,66}, {24,13}, {24,45}, |
| 517 | 517 | {25,12}, {25,35}, {26,61}, {27,10}, {27,59}, {28,25} |
| r243189 | r243190 | |
| 680 | 680 | |
| 681 | 681 | prot_cur_address ++; |
| 682 | 682 | |
| 683 | | // printf("get_decrypted_16 %04x\n", res); |
| 683 | // printf("get_decrypted_16 %04x\n", res); |
| 684 | 684 | |
| 685 | 685 | return res; |
| 686 | 686 | } |
| r243189 | r243190 | |
| 691 | 691 | block_pos = 0; |
| 692 | 692 | done_compression = 0; |
| 693 | 693 | buffer_pos = BUFFER_SIZE; |
| 694 | | |
| 694 | |
| 695 | 695 | if (buffer_bit2 != 15) // if we have remaining bits in the decompression buffer we shouldn't read the next word yet but should instead use the bits we have?? (twcup98) (might just be because we should be pulling bytes not words?) |
| 696 | 696 | { |
| 697 | | // printf("buffer_bit2 is %d\n", buffer_bit2); |
| 697 | // printf("buffer_bit2 is %d\n", buffer_bit2); |
| 698 | 698 | dec_header = (buffer2a & 0x0003) << 16; |
| 699 | 699 | } |
| 700 | 700 | else |
| r243189 | r243190 | |
| 710 | 710 | // etc. after each block a new header must be read, it looks like compressed and uncompressed blocks |
| 711 | 711 | // can be mixed like this, I don't know if the length is src length of decompressed length. |
| 712 | 712 | // deathcox and others confirm format as 0x20000 bit as compressed bit, 0x1ff00 bits as block size 1, 0x000ff bits as block size 2 |
| 713 | | // for compressed streams the 'line size' is block size 1. |
| 713 | // for compressed streams the 'line size' is block size 1. |
| 714 | 714 | |
| 715 | 715 | block_numlines = ((dec_header & 0x000000ff) >> 0) + 1; |
| 716 | 716 | int blocky = ((dec_header & 0x0001ff00) >> 8) + 1; |
| r243189 | r243190 | |
| 824 | 824 | |
| 825 | 825 | int sega_315_5881_crypt_device::get_compressed_bit() |
| 826 | 826 | { |
| 827 | | // if(buffer_pos == BUFFER_SIZE) |
| 828 | | // enc_fill(); |
| 827 | // if(buffer_pos == BUFFER_SIZE) |
| 828 | // enc_fill(); |
| 829 | 829 | |
| 830 | 830 | if (buffer_bit2 == 15) |
| 831 | 831 | { |
| r243189 | r243190 | |
| 833 | 833 | buffer2a = get_decrypted_16(); |
| 834 | 834 | buffer2[0] = buffer2a; |
| 835 | 835 | buffer2[1] = buffer2a >> 8; |
| 836 | | // block_pos+=2; |
| 836 | // block_pos+=2; |
| 837 | 837 | buffer_pos = 0; |
| 838 | 838 | |
| 839 | 839 | } |
| r243189 | r243190 | |
| 842 | 842 | buffer_bit2++; |
| 843 | 843 | } |
| 844 | 844 | |
| 845 | | // if (buffer_bit ==7) printf("using byte %02x\n", buffer2[(buffer_pos&1) ^ 1]); |
| 845 | // if (buffer_bit ==7) printf("using byte %02x\n", buffer2[(buffer_pos&1) ^ 1]); |
| 846 | 846 | |
| 847 | 847 | int res = (buffer2[(buffer_pos&1)^1] >> buffer_bit) & 1; |
| 848 | 848 | buffer_bit--; |
trunk/src/mess/drivers/gamate.c
| r243189 | r243190 | |
| 20 | 20 | : driver_device(mconfig, type, tag) |
| 21 | 21 | , m_maincpu(*this, "maincpu") |
| 22 | 22 | , m_cart(*this, "cartslot") |
| 23 | | #ifdef USE_GFX |
| 23 | #ifdef USE_GFX |
| 24 | 24 | , m_gfxdecode(*this, "gfxdecode") |
| 25 | 25 | #endif |
| 26 | 26 | , m_io_joy(*this, "JOY") |
| r243189 | r243190 | |
| 53 | 53 | |
| 54 | 54 | struct |
| 55 | 55 | { |
| 56 | | UINT8 reg[8]; |
| 57 | | struct { |
| 58 | | bool write; |
| 59 | | bool page2; // else page1 |
| 56 | UINT8 reg[8]; |
| 57 | struct { |
| 58 | bool write; |
| 59 | bool page2; // else page1 |
| 60 | 60 | UINT8 ypos, xpos/*tennis*/; |
| 61 | | UINT8 data[2][0x100][0x20]; |
| 62 | | } bitmap; |
| 63 | | UINT8 x, y; |
| 61 | UINT8 data[2][0x100][0x20]; |
| 62 | } bitmap; |
| 63 | UINT8 x, y; |
| 64 | 64 | bool y_increment; |
| 65 | 65 | } video; |
| 66 | 66 | |
| 67 | 67 | struct { |
| 68 | | bool set; |
| 68 | bool set; |
| 69 | 69 | int bit_shifter; |
| 70 | 70 | UINT8 cartridge_byte; |
| 71 | 71 | UINT16 address; // in reality something more like short local cartridge address offset |
| 72 | 72 | bool unprotected; |
| 73 | 73 | bool failed; |
| 74 | | |
| 74 | |
| 75 | 75 | } card_protection; |
| 76 | 76 | |
| 77 | 77 | required_device<cpu_device> m_maincpu; |
| r243189 | r243190 | |
| 84 | 84 | required_shared_ptr<UINT8> m_bios; |
| 85 | 85 | emu_timer *timer1; |
| 86 | 86 | emu_timer *timer2; |
| 87 | | UINT8 bank_multi; |
| 87 | UINT8 bank_multi; |
| 88 | 88 | UINT8 *m_cart_ptr; |
| 89 | 89 | }; |
| 90 | 90 | |
| 91 | 91 | WRITE8_MEMBER( gamate_state::gamate_cart_protection_w ) |
| 92 | 92 | { |
| 93 | | logerror("%.6f protection write %x %x address:%x data:%x shift:%d\n",machine().time().as_double(), offset, data, card_protection.address, card_protection.cartridge_byte, card_protection.bit_shifter); |
| 94 | | |
| 93 | logerror("%.6f protection write %x %x address:%x data:%x shift:%d\n",machine().time().as_double(), offset, data, card_protection.address, card_protection.cartridge_byte, card_protection.bit_shifter); |
| 94 | |
| 95 | 95 | switch (offset) { |
| 96 | 96 | case 0: |
| 97 | 97 | card_protection.failed= card_protection.failed || ((card_protection.cartridge_byte&0x80)!=0) != ((data&4)!=0); |
| r243189 | r243190 | |
| 105 | 105 | } |
| 106 | 106 | READ8_MEMBER( gamate_state::gamate_cart_protection_r ) |
| 107 | 107 | { |
| 108 | | |
| 109 | | UINT8 ret=1; |
| 110 | | if (card_protection.bit_shifter==7 && card_protection.unprotected) { |
| 111 | | ret=m_cart_ptr[bank_multi*0x4000]; |
| 112 | | } else { |
| 108 | UINT8 ret=1; |
| 109 | if (card_protection.bit_shifter==7 && card_protection.unprotected) { |
| 110 | ret=m_cart_ptr[bank_multi*0x4000]; |
| 111 | } else { |
| 113 | 112 | card_protection.bit_shifter++; |
| 114 | 113 | if (card_protection.bit_shifter==8) { |
| 115 | 114 | card_protection.bit_shifter=0; |
| r243189 | r243190 | |
| 118 | 117 | } |
| 119 | 118 | ret=(card_protection.cartridge_byte&0x80)?2:0; |
| 120 | 119 | if (card_protection.bit_shifter==7 && !card_protection.failed) { // now protection chip on cartridge activates cartridge chip select on cpu accesses |
| 121 | | // m_maincpu->space(AS_PROGRAM).install_read_handler(0x6000, 0x6000, READ8_DELEGATE(gamate_state, gamate_cart_protection_r)); // next time I will try to get this working |
| 120 | // m_maincpu->space(AS_PROGRAM).install_read_handler(0x6000, 0x6000, READ8_DELEGATE(gamate_state, gamate_cart_protection_r)); // next time I will try to get this working |
| 122 | 121 | } |
| 123 | 122 | card_protection.cartridge_byte<<=1; |
| 124 | | } |
| 125 | | logerror("%.6f protection read %x %x address:%x data:%x shift:%d\n",machine().time().as_double(), offset, ret, card_protection.address, card_protection.cartridge_byte, card_protection.bit_shifter); |
| 126 | | return ret; |
| 123 | } |
| 124 | logerror("%.6f protection read %x %x address:%x data:%x shift:%d\n",machine().time().as_double(), offset, ret, card_protection.address, card_protection.cartridge_byte, card_protection.bit_shifter); |
| 125 | return ret; |
| 127 | 126 | } |
| 128 | 127 | |
| 129 | 128 | READ8_MEMBER( gamate_state::protection_r ) { return card_protection.set? 3: 1; } // bits 0 and 1 checked |
| 130 | 129 | |
| 131 | 130 | WRITE8_MEMBER( gamate_state::protection_reset ) |
| 132 | 131 | { |
| 133 | | // writes 0x20 |
| 134 | | card_protection.address=0x6005-0x6001; |
| 135 | | card_protection.bit_shifter=0; |
| 136 | | card_protection.cartridge_byte=m_cart_ptr[card_protection.address++];//m_cart_rom[card_protection.address++]; |
| 137 | | card_protection.failed=false; |
| 138 | | card_protection.unprotected=false; |
| 132 | // writes 0x20 |
| 133 | card_protection.address=0x6005-0x6001; |
| 134 | card_protection.bit_shifter=0; |
| 135 | card_protection.cartridge_byte=m_cart_ptr[card_protection.address++];//m_cart_rom[card_protection.address++]; |
| 136 | card_protection.failed=false; |
| 137 | card_protection.unprotected=false; |
| 139 | 138 | } |
| 140 | 139 | |
| 141 | 140 | READ8_MEMBER( gamate_state::newer_protection_set ) |
| 142 | 141 | { |
| 143 | | card_protection.set=true; |
| 144 | | return 0; |
| 142 | card_protection.set=true; |
| 143 | return 0; |
| 145 | 144 | } |
| 146 | 145 | |
| 147 | 146 | |
| 148 | 147 | WRITE8_MEMBER( gamate_state::gamate_video_w ) |
| 149 | 148 | { |
| 150 | | video.reg[offset]=data; |
| 151 | | switch (offset) { |
| 152 | | case 1: video.bitmap.write=data&0xc0; // more addressing mode |
| 149 | video.reg[offset]=data; |
| 150 | switch (offset) { |
| 151 | case 1: video.bitmap.write=data&0xc0; // more addressing mode |
| 153 | 152 | video.y_increment=data&0x40; |
| 154 | 153 | break; |
| 155 | 154 | case 2: video.bitmap.xpos=data;break; // at least 7 bits |
| 156 | 155 | case 3: video.bitmap.ypos=data;break; // at least 7 bits |
| 157 | | case 4: video.bitmap.page2=data&0x80;video.x=data&0x7f;break; |
| 158 | | case 5: video.y=data;break; |
| 159 | | case 7: |
| 160 | | if (video.bitmap.write) { |
| 161 | | if (video.x<ARRAY_LENGTH(video.bitmap.data[0][0]) /*&& video.y<ARRAY_LENGTH(video.bitmap.data[0])*/) |
| 162 | | video.bitmap.data[video.bitmap.page2][video.y][video.x]=data; |
| 163 | | else |
| 164 | | logerror("%.6f %04x video bitmap x %x invalid\n",machine().time().as_double(), m_maincpu->pc(), video.x); |
| 165 | | } else { |
| 166 | | video.bitmap.data[0][video.y][video.x&(ARRAY_LENGTH(video.bitmap.data[0][0])-1)]=data; |
| 167 | | } |
| 168 | | if (video.y_increment) video.y++; |
| 156 | case 4: video.bitmap.page2=data&0x80;video.x=data&0x7f;break; |
| 157 | case 5: video.y=data;break; |
| 158 | case 7: |
| 159 | if (video.bitmap.write) { |
| 160 | if (video.x<ARRAY_LENGTH(video.bitmap.data[0][0]) /*&& video.y<ARRAY_LENGTH(video.bitmap.data[0])*/) |
| 161 | video.bitmap.data[video.bitmap.page2][video.y][video.x]=data; |
| 162 | else |
| 163 | logerror("%.6f %04x video bitmap x %x invalid\n",machine().time().as_double(), m_maincpu->pc(), video.x); |
| 164 | } else { |
| 165 | video.bitmap.data[0][video.y][video.x&(ARRAY_LENGTH(video.bitmap.data[0][0])-1)]=data; |
| 166 | } |
| 167 | if (video.y_increment) video.y++; |
| 169 | 168 | else video.x++; |
| 170 | | } |
| 169 | } |
| 171 | 170 | } |
| 172 | 171 | |
| 173 | 172 | WRITE8_MEMBER( gamate_state::cart_bankswitchmulti_w ) |
| 174 | 173 | { |
| 175 | | bank_multi=data; |
| 176 | | membank("bankmulti")->set_base(m_cart_ptr+0x4000*data+1); |
| 174 | bank_multi=data; |
| 175 | membank("bankmulti")->set_base(m_cart_ptr+0x4000*data+1); |
| 177 | 176 | } |
| 178 | 177 | |
| 179 | 178 | WRITE8_MEMBER( gamate_state::cart_bankswitch_w ) |
| r243189 | r243190 | |
| 184 | 183 | READ8_MEMBER( gamate_state::gamate_video_r ) |
| 185 | 184 | { |
| 186 | 185 | if (offset!=6) return 0; |
| 187 | | UINT8 data=0; |
| 188 | | if (video.bitmap.write) { |
| 189 | | if (video.x<ARRAY_LENGTH(video.bitmap.data[0][0]) /*&& video.y<ARRAY_LENGTH(video.bitmap.data[0])*/) |
| 190 | | data=video.bitmap.data[video.bitmap.page2][video.y][video.x]; |
| 191 | | else |
| 192 | | logerror("%.6f video bitmap x %x invalid\n",machine().time().as_double(),video.x); |
| 193 | | } else { |
| 194 | | data=video.bitmap.data[0][video.y][video.x&(ARRAY_LENGTH(video.bitmap.data[0][0])-1)]; |
| 195 | | } |
| 196 | | if (m_maincpu->pc()<0xf000) |
| 197 | | logerror("%.6f video read %04x %02x\n",machine().time().as_double(),offset, data); |
| 198 | | return data; |
| 186 | UINT8 data=0; |
| 187 | if (video.bitmap.write) { |
| 188 | if (video.x<ARRAY_LENGTH(video.bitmap.data[0][0]) /*&& video.y<ARRAY_LENGTH(video.bitmap.data[0])*/) |
| 189 | data=video.bitmap.data[video.bitmap.page2][video.y][video.x]; |
| 190 | else |
| 191 | logerror("%.6f video bitmap x %x invalid\n",machine().time().as_double(),video.x); |
| 192 | } else { |
| 193 | data=video.bitmap.data[0][video.y][video.x&(ARRAY_LENGTH(video.bitmap.data[0][0])-1)]; |
| 194 | } |
| 195 | if (m_maincpu->pc()<0xf000) |
| 196 | logerror("%.6f video read %04x %02x\n",machine().time().as_double(),offset, data); |
| 197 | return data; |
| 199 | 198 | } |
| 200 | 199 | |
| 201 | 200 | WRITE8_MEMBER( gamate_state::gamate_audio_w ) |
| 202 | 201 | { |
| 203 | | logerror("%.6f %04x audio write %04x %02x\n",machine().time().as_double(),m_maincpu->pc(),offset,data); |
| 202 | logerror("%.6f %04x audio write %04x %02x\n",machine().time().as_double(),m_maincpu->pc(),offset,data); |
| 204 | 203 | } |
| 205 | 204 | |
| 206 | 205 | READ8_MEMBER( gamate_state::gamate_audio_r ) |
| 207 | 206 | { |
| 208 | | logerror("%.6f %04x audio read %04x \n",machine().time().as_double(),m_maincpu->pc(),offset); |
| 207 | logerror("%.6f %04x audio read %04x \n",machine().time().as_double(),m_maincpu->pc(),offset); |
| 209 | 208 | return 0; |
| 210 | 209 | } |
| 211 | 210 | |
| 212 | 211 | |
| 213 | 212 | READ8_MEMBER( gamate_state::gamate_pad_r ) |
| 214 | 213 | { |
| 215 | | UINT8 data=m_io_joy->read(); |
| 216 | | return data; |
| 214 | UINT8 data=m_io_joy->read(); |
| 215 | return data; |
| 217 | 216 | } |
| 218 | 217 | |
| 219 | 218 | static ADDRESS_MAP_START( gamate_mem, AS_PROGRAM, 8, gamate_state ) |
| 220 | | AM_RANGE(0x0000, 0x03ff) AM_RAM |
| 221 | | AM_RANGE(0x4000, 0x400d) AM_READWRITE(gamate_audio_r, gamate_audio_w) |
| 222 | | AM_RANGE(0x4400, 0x4400) AM_READ(gamate_pad_r) |
| 223 | | AM_RANGE(0x5000, 0x5007) AM_READWRITE(gamate_video_r, gamate_video_w) |
| 224 | | AM_RANGE(0x5800, 0x5800) AM_READ(newer_protection_set) |
| 225 | | AM_RANGE(0x5900, 0x5900) AM_WRITE(protection_reset) |
| 226 | | AM_RANGE(0x5a00, 0x5a00) AM_READ(protection_r) |
| 219 | AM_RANGE(0x0000, 0x03ff) AM_RAM |
| 220 | AM_RANGE(0x4000, 0x400d) AM_READWRITE(gamate_audio_r, gamate_audio_w) |
| 221 | AM_RANGE(0x4400, 0x4400) AM_READ(gamate_pad_r) |
| 222 | AM_RANGE(0x5000, 0x5007) AM_READWRITE(gamate_video_r, gamate_video_w) |
| 223 | AM_RANGE(0x5800, 0x5800) AM_READ(newer_protection_set) |
| 224 | AM_RANGE(0x5900, 0x5900) AM_WRITE(protection_reset) |
| 225 | AM_RANGE(0x5a00, 0x5a00) AM_READ(protection_r) |
| 227 | 226 | |
| 228 | | AM_RANGE(0x6001, 0x9fff) AM_READ_BANK("bankmulti") |
| 229 | | AM_RANGE(0xa000, 0xdfff) AM_READ_BANK("bank") |
| 227 | AM_RANGE(0x6001, 0x9fff) AM_READ_BANK("bankmulti") |
| 228 | AM_RANGE(0xa000, 0xdfff) AM_READ_BANK("bank") |
| 230 | 229 | |
| 231 | 230 | AM_RANGE(0x6000, 0x6000) AM_READWRITE(gamate_cart_protection_r, gamate_cart_protection_w) |
| 232 | 231 | AM_RANGE(0x8000, 0x8000) AM_WRITE(cart_bankswitchmulti_w) |
| 233 | 232 | AM_RANGE(0xc000, 0xc000) AM_WRITE(cart_bankswitch_w) |
| 234 | 233 | |
| 235 | | AM_RANGE(0xf000, 0xffff) AM_ROM AM_SHARE("bios") |
| 234 | AM_RANGE(0xf000, 0xffff) AM_ROM AM_SHARE("bios") |
| 236 | 235 | ADDRESS_MAP_END |
| 237 | 236 | |
| 238 | 237 | |
| r243189 | r243190 | |
| 251 | 250 | #ifdef USE_GFX |
| 252 | 251 | static const struct gfx_layout gamate_charlayout = |
| 253 | 252 | { |
| 254 | | 4, /* width of object */ |
| 255 | | 1, /* height of object */ |
| 256 | | 256,/* 256 characters */ |
| 257 | | 2, /* bits per pixel */ |
| 258 | | { 0,4 }, /* no bitplanes */ |
| 259 | | /* x offsets */ |
| 260 | | { 0,1,2,3 }, |
| 261 | | /* y offsets */ |
| 262 | | { 0 }, |
| 263 | | 8*1 /* size of 1 object in bits */ |
| 253 | 4, /* width of object */ |
| 254 | 1, /* height of object */ |
| 255 | 256,/* 256 characters */ |
| 256 | 2, /* bits per pixel */ |
| 257 | { 0,4 }, /* no bitplanes */ |
| 258 | /* x offsets */ |
| 259 | { 0,1,2,3 }, |
| 260 | /* y offsets */ |
| 261 | { 0 }, |
| 262 | 8*1 /* size of 1 object in bits */ |
| 264 | 263 | }; |
| 265 | 264 | |
| 266 | 265 | static GFXDECODE_START( gamate ) |
| 267 | | GFXDECODE_ENTRY( "gfx1", 0x0000, gamate_charlayout, 0, 0x100 ) |
| 266 | GFXDECODE_ENTRY( "gfx1", 0x0000, gamate_charlayout, 0, 0x100 ) |
| 268 | 267 | GFXDECODE_END |
| 269 | 268 | #endif |
| 270 | 269 | |
| 271 | 270 | /* palette in red, green, blue tribles */ |
| 272 | 271 | static const unsigned char gamate_colors[4][3] = |
| 273 | 272 | { |
| 274 | | { 255,255,255 }, |
| 275 | | { 0xa0, 0xa0, 0xa0 }, |
| 276 | | { 0x60, 0x60, 0x60 }, |
| 277 | | { 0, 0, 0 } |
| 273 | { 255,255,255 }, |
| 274 | { 0xa0, 0xa0, 0xa0 }, |
| 275 | { 0x60, 0x60, 0x60 }, |
| 276 | { 0, 0, 0 } |
| 278 | 277 | }; |
| 279 | 278 | |
| 280 | 279 | PALETTE_INIT_MEMBER(gamate_state, gamate) |
| r243189 | r243190 | |
| 299 | 298 | |
| 300 | 299 | UINT32 gamate_state::screen_update_gamate(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 301 | 300 | { |
| 302 | | int x, y, j; |
| 303 | | for (y=0;y<152;y++) { |
| 304 | | for (x=-(video.bitmap.xpos&7), j=0;x<160;x+=8, j++) { |
| 305 | | UINT8 d1=video.bitmap.data[0][(y+video.bitmap.ypos)&0xff][(j+video.bitmap.xpos/8)&0x1f]; |
| 306 | | UINT8 d2=video.bitmap.data[1][(y+video.bitmap.ypos)&0xff][(j+video.bitmap.xpos/8)&0x1f]; |
| 301 | int x, y, j; |
| 302 | for (y=0;y<152;y++) { |
| 303 | for (x=-(video.bitmap.xpos&7), j=0;x<160;x+=8, j++) { |
| 304 | UINT8 d1=video.bitmap.data[0][(y+video.bitmap.ypos)&0xff][(j+video.bitmap.xpos/8)&0x1f]; |
| 305 | UINT8 d2=video.bitmap.data[1][(y+video.bitmap.ypos)&0xff][(j+video.bitmap.xpos/8)&0x1f]; |
| 307 | 306 | #ifdef USE_GFX |
| 308 | | m_gfxdecode->gfx(0)->opaque(bitmap,cliprect, (d1&0xf)|((d2&0xf)<<4), 0,0,0,x+4,y); |
| 307 | m_gfxdecode->gfx(0)->opaque(bitmap,cliprect, (d1&0xf)|((d2&0xf)<<4), 0,0,0,x+4,y); |
| 309 | 308 | m_gfxdecode->gfx(0)->opaque(bitmap,cliprect, (d1>>4)|(d2&0xf0),0,0,0,x,y); |
| 310 | 309 | #else |
| 311 | | BlitPlane(&bitmap.pix16(y, x+4), d1, d2); |
| 312 | | BlitPlane(&bitmap.pix16(y, x), d1>>4, d2>>4); |
| 313 | | #endif |
| 314 | | } |
| 315 | | } |
| 316 | | return 0; |
| 310 | BlitPlane(&bitmap.pix16(y, x+4), d1, d2); |
| 311 | BlitPlane(&bitmap.pix16(y, x), d1>>4, d2>>4); |
| 312 | #endif |
| 313 | } |
| 314 | } |
| 315 | return 0; |
| 317 | 316 | } |
| 318 | 317 | |
| 319 | 318 | DRIVER_INIT_MEMBER(gamate_state,gamate) |
| r243189 | r243190 | |
| 322 | 321 | #ifdef USE_GFX |
| 323 | 322 | UINT8 *gfx=memregion("gfx1")->base(); |
| 324 | 323 | for (int i=0; i<256; i++) gfx[i]=i; |
| 325 | | #endif |
| 324 | #endif |
| 326 | 325 | timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gamate_state::gamate_timer),this)); |
| 327 | 326 | timer2 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gamate_state::gamate_timer2),this)); |
| 328 | 327 | } |
| r243189 | r243190 | |
| 332 | 331 | { |
| 333 | 332 | m_cart_ptr = memregion("maincpu")->base() + 0x6000; |
| 334 | 333 | if (m_cart->exists()) { |
| 335 | | // m_maincpu->space(AS_PROGRAM).install_read_handler(0x6000, 0x6000, READ8_DELEGATE(gamate_state, gamate_cart_protection_r)); |
| 334 | // m_maincpu->space(AS_PROGRAM).install_read_handler(0x6000, 0x6000, READ8_DELEGATE(gamate_state, gamate_cart_protection_r)); |
| 336 | 335 | m_cart_ptr = m_cart->get_rom_base(); |
| 337 | 336 | membank("bankmulti")->set_base(m_cart->get_rom_base()+1); |
| 338 | 337 | membank("bank")->set_base(m_cart->get_rom_base()+0x4000); // bankswitched games in reality no offset |
| 339 | 338 | } |
| 340 | | // m_bios[0xdf1]=0xea; m_bios[0xdf2]=0xea; // default bios: $47 protection readback |
| 339 | // m_bios[0xdf1]=0xea; m_bios[0xdf2]=0xea; // default bios: $47 protection readback |
| 341 | 340 | card_protection.set=false; |
| 342 | 341 | bank_multi=0; |
| 343 | 342 | card_protection.unprotected=false; |
| r243189 | r243190 | |
| 390 | 389 | |
| 391 | 390 | #ifdef USE_GFX |
| 392 | 391 | MCFG_GFXDECODE_ADD("gfxdecode", "palette", gamate ) |
| 393 | | #endif |
| 392 | #endif |
| 394 | 393 | MCFG_PALETTE_ADD("palette", ARRAY_LENGTH(gamate_colors)) |
| 395 | 394 | MCFG_PALETTE_INIT_OWNER(gamate_state, gamate) |
| 396 | 395 | MCFG_DEFAULT_LAYOUT(layout_lcd) |
| r243189 | r243190 | |
| 408 | 407 | ROMX_LOAD("gamate_bios_umc.bin", 0xf000, 0x1000, CRC(07090415) SHA1(ea449dc607601f9a68d855ad6ab53800d2e99297), ROM_BIOS(1) ) |
| 409 | 408 | ROM_SYSTEM_BIOS(1, "newer", "NEWER") |
| 410 | 409 | ROMX_LOAD("gamate_bios_9130__unknown__bit_icasc00001_9130-bs_r32261.bin", 0xf000, 0x1000, CRC(03a5f3a7) SHA1(4e9dfbfe916ca485530ef4221593ab68738e2217), ROM_BIOS(2) ) |
| 411 | | #ifdef USE_GFX |
| 410 | #ifdef USE_GFX |
| 412 | 411 | ROM_REGION(0x100,"gfx1", ROMREGION_ERASEFF) |
| 413 | | #endif |
| 412 | #endif |
| 414 | 413 | ROM_END |
| 415 | 414 | |
| 416 | 415 | |
| 417 | 416 | /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME */ |
| 418 | 417 | CONS( 19??, gamate, 0, 0, gamate, gamate, gamate_state, gamate, "Bit Corp", "Gamate", GAME_NO_SOUND) |
| 419 | | |
| 420 | | |
trunk/src/mess/drivers/hp9k_3xx.c
| r243189 | r243190 | |
| 1 | 1 | // license:BSD-3-Clause |
| 2 | 2 | // copyright-holders:R. Belmont |
| 3 | 3 | /*************************************************************************** |
| 4 | | |
| 4 | |
| 5 | 5 | hp9k3xx.c: preliminary driver for HP9000 300 Series (aka HP9000/3xx) |
| 6 | 6 | |
| 7 | 7 | Currently supporting: |
| r243189 | r243190 | |
| 16 | 16 | MC68881 FPU |
| 17 | 17 | |
| 18 | 18 | 330: |
| 19 | | MC68020 CPU @ 16.67 MHz |
| 20 | | MC68851 MMU |
| 21 | | MC68881 FPU |
| 19 | MC68020 CPU @ 16.67 MHz |
| 20 | MC68851 MMU |
| 21 | MC68881 FPU |
| 22 | 22 | |
| 23 | 23 | 340: |
| 24 | 24 | MC68030 CPU @ 16.67 MHz w/built-in MMU |
| 25 | | MC68881 FPU |
| 25 | MC68881 FPU |
| 26 | 26 | |
| 27 | 27 | 380: |
| 28 | 28 | MC68040 CPU @ 25 MHz w/built-in MMU and FPU |
| 29 | 29 | |
| 30 | 30 | 382: |
| 31 | 31 | MC68040 CPU @ 25? MHz w/built-in MMU and FPU |
| 32 | | Built-in VGA compatible video |
| 32 | Built-in VGA compatible video |
| 33 | 33 | |
| 34 | 34 | All models have an MC6840 PIT on IRQ6 clocked at 250 kHz. |
| 35 | 35 | |
| r243189 | r243190 | |
| 132 | 132 | |
| 133 | 133 | // shared mappings for all 9000/3xx systems |
| 134 | 134 | static ADDRESS_MAP_START(hp9k3xx_common, AS_PROGRAM, 32, hp9k3xx_state) |
| 135 | | AM_RANGE(0x00000000, 0x0001ffff) AM_ROM AM_REGION("maincpu",0) AM_WRITENOP // writes to 1fffc are the LED |
| 135 | AM_RANGE(0x00000000, 0x0001ffff) AM_ROM AM_REGION("maincpu",0) AM_WRITENOP // writes to 1fffc are the LED |
| 136 | 136 | |
| 137 | | AM_RANGE(0x00500000, 0x0050000f) AM_RAM // this is sufficient to pass the DMA test for now |
| 137 | AM_RANGE(0x00500000, 0x0050000f) AM_RAM // this is sufficient to pass the DMA test for now |
| 138 | 138 | |
| 139 | | AM_RANGE(0x00510000, 0x00510003) AM_READWRITE(buserror_r, buserror_w) // no "Alpha display" |
| 140 | | AM_RANGE(0x00538000, 0x00538003) AM_READWRITE(buserror_r, buserror_w) // no "Graphics" |
| 141 | | AM_RANGE(0x005c0000, 0x005c0003) AM_READWRITE(buserror_r, buserror_w) // no add-on FP coprocessor |
| 139 | AM_RANGE(0x00510000, 0x00510003) AM_READWRITE(buserror_r, buserror_w) // no "Alpha display" |
| 140 | AM_RANGE(0x00538000, 0x00538003) AM_READWRITE(buserror_r, buserror_w) // no "Graphics" |
| 141 | AM_RANGE(0x005c0000, 0x005c0003) AM_READWRITE(buserror_r, buserror_w) // no add-on FP coprocessor |
| 142 | 142 | AM_RANGE(0x005f8000, 0x005f800f) AM_DEVREADWRITE8(PTM6840_TAG, ptm6840_device, read, write, 0x00ff00ff) |
| 143 | 143 | ADDRESS_MAP_END |
| 144 | 144 | |
| 145 | 145 | // 9000/310 - has onboard video that the graphics card used in other 3xxes conflicts with |
| 146 | 146 | static ADDRESS_MAP_START(hp9k310_map, AS_PROGRAM, 16, hp9k3xx_state) |
| 147 | | AM_RANGE(0x000000, 0x01ffff) AM_ROM AM_REGION("maincpu",0) AM_WRITENOP // writes to 1fffc are the LED |
| 147 | AM_RANGE(0x000000, 0x01ffff) AM_ROM AM_REGION("maincpu",0) AM_WRITENOP // writes to 1fffc are the LED |
| 148 | 148 | |
| 149 | | AM_RANGE(0x510000, 0x510003) AM_READWRITE(buserror16_r, buserror16_w) // no "Alpha display" |
| 150 | | AM_RANGE(0x538000, 0x538003) AM_READWRITE(buserror16_r, buserror16_w) // no "Graphics" |
| 151 | | AM_RANGE(0x5c0000, 0x5c0003) AM_READWRITE(buserror16_r, buserror16_w) // no add-on FP coprocessor |
| 149 | AM_RANGE(0x510000, 0x510003) AM_READWRITE(buserror16_r, buserror16_w) // no "Alpha display" |
| 150 | AM_RANGE(0x538000, 0x538003) AM_READWRITE(buserror16_r, buserror16_w) // no "Graphics" |
| 151 | AM_RANGE(0x5c0000, 0x5c0003) AM_READWRITE(buserror16_r, buserror16_w) // no add-on FP coprocessor |
| 152 | 152 | |
| 153 | 153 | AM_RANGE(0x5f8000, 0x5f800f) AM_DEVREADWRITE8(PTM6840_TAG, ptm6840_device, read, write, 0x00ff) |
| 154 | 154 | |
| 155 | | AM_RANGE(0x200000, 0x2fffff) AM_RAM AM_SHARE("vram16") // 98544 mono framebuffer |
| 156 | | AM_RANGE(0x560000, 0x563fff) AM_ROM AM_REGION("graphics", 0x0000) // 98544 mono ROM |
| 155 | AM_RANGE(0x200000, 0x2fffff) AM_RAM AM_SHARE("vram16") // 98544 mono framebuffer |
| 156 | AM_RANGE(0x560000, 0x563fff) AM_ROM AM_REGION("graphics", 0x0000) // 98544 mono ROM |
| 157 | 157 | |
| 158 | 158 | AM_RANGE(0x700000, 0x7fffff) AM_READWRITE(buserror16_r, buserror16_w) |
| 159 | 159 | AM_RANGE(0x800000, 0xffffff) AM_RAM |
| r243189 | r243190 | |
| 161 | 161 | |
| 162 | 162 | // 9000/320 |
| 163 | 163 | static ADDRESS_MAP_START(hp9k320_map, AS_PROGRAM, 32, hp9k3xx_state) |
| 164 | | AM_RANGE(0x00200000, 0x002fffff) AM_RAM AM_SHARE("vram") // 98544 mono framebuffer |
| 165 | | AM_RANGE(0x00560000, 0x00563fff) AM_ROM AM_REGION("graphics", 0x0000) // 98544 mono ROM |
| 164 | AM_RANGE(0x00200000, 0x002fffff) AM_RAM AM_SHARE("vram") // 98544 mono framebuffer |
| 165 | AM_RANGE(0x00560000, 0x00563fff) AM_ROM AM_REGION("graphics", 0x0000) // 98544 mono ROM |
| 166 | 166 | |
| 167 | 167 | AM_RANGE(0xffe00000, 0xffefffff) AM_READWRITE(buserror_r, buserror_w) |
| 168 | 168 | AM_RANGE(0xfff00000, 0xffffffff) AM_RAM |
| r243189 | r243190 | |
| 172 | 172 | |
| 173 | 173 | // 9000/330 and 9000/340 |
| 174 | 174 | static ADDRESS_MAP_START(hp9k330_map, AS_PROGRAM, 32, hp9k3xx_state) |
| 175 | | AM_RANGE(0x00200000, 0x002fffff) AM_RAM AM_SHARE("vram") // 98544 mono framebuffer |
| 176 | | AM_RANGE(0x00560000, 0x00563fff) AM_ROM AM_REGION("graphics", 0x0000) // 98544 mono ROM |
| 175 | AM_RANGE(0x00200000, 0x002fffff) AM_RAM AM_SHARE("vram") // 98544 mono framebuffer |
| 176 | AM_RANGE(0x00560000, 0x00563fff) AM_ROM AM_REGION("graphics", 0x0000) // 98544 mono ROM |
| 177 | 177 | |
| 178 | 178 | AM_RANGE(0xffb00000, 0xffbfffff) AM_READWRITE(buserror_r, buserror_w) |
| 179 | 179 | AM_RANGE(0xffc00000, 0xffffffff) AM_RAM |
| r243189 | r243190 | |
| 183 | 183 | |
| 184 | 184 | // 9000/370 - 8 MB RAM standard |
| 185 | 185 | static ADDRESS_MAP_START(hp9k370_map, AS_PROGRAM, 32, hp9k3xx_state) |
| 186 | | AM_RANGE(0x00200000, 0x002fffff) AM_RAM AM_SHARE("vram") // 98544 mono framebuffer |
| 187 | | AM_RANGE(0x00560000, 0x00563fff) AM_ROM AM_REGION("graphics", 0x0000) // 98544 mono ROM |
| 186 | AM_RANGE(0x00200000, 0x002fffff) AM_RAM AM_SHARE("vram") // 98544 mono framebuffer |
| 187 | AM_RANGE(0x00560000, 0x00563fff) AM_ROM AM_REGION("graphics", 0x0000) // 98544 mono ROM |
| 188 | 188 | |
| 189 | 189 | AM_RANGE(0xff700000, 0xff7fffff) AM_READWRITE(buserror_r, buserror_w) |
| 190 | 190 | AM_RANGE(0xff800000, 0xffffffff) AM_RAM |
| r243189 | r243190 | |
| 292 | 292 | MCFG_CPU_PROGRAM_MAP(hp9k310_map) |
| 293 | 293 | |
| 294 | 294 | MCFG_DEVICE_ADD(PTM6840_TAG, PTM6840, 0) |
| 295 | | MCFG_PTM6840_INTERNAL_CLOCK(250000.0f) // from oscillator module next to the 6840 |
| 295 | MCFG_PTM6840_INTERNAL_CLOCK(250000.0f) // from oscillator module next to the 6840 |
| 296 | 296 | MCFG_PTM6840_EXTERNAL_CLOCKS(250000.0f, 250000.0f, 250000.0f) |
| 297 | 297 | |
| 298 | 298 | MCFG_SCREEN_ADD( "screen", RASTER) |
| r243189 | r243190 | |
| 308 | 308 | MCFG_CPU_PROGRAM_MAP(hp9k320_map) |
| 309 | 309 | |
| 310 | 310 | MCFG_DEVICE_ADD(PTM6840_TAG, PTM6840, 0) |
| 311 | | MCFG_PTM6840_INTERNAL_CLOCK(250000.0f) // from oscillator module next to the 6840 |
| 311 | MCFG_PTM6840_INTERNAL_CLOCK(250000.0f) // from oscillator module next to the 6840 |
| 312 | 312 | MCFG_PTM6840_EXTERNAL_CLOCKS(250000.0f, 250000.0f, 250000.0f) |
| 313 | 313 | |
| 314 | 314 | MCFG_SCREEN_ADD( "screen", RASTER) |
| r243189 | r243190 | |
| 324 | 324 | MCFG_CPU_PROGRAM_MAP(hp9k330_map) |
| 325 | 325 | |
| 326 | 326 | MCFG_DEVICE_ADD(PTM6840_TAG, PTM6840, 0) |
| 327 | | MCFG_PTM6840_INTERNAL_CLOCK(250000.0f) // from oscillator module next to the 6840 |
| 327 | MCFG_PTM6840_INTERNAL_CLOCK(250000.0f) // from oscillator module next to the 6840 |
| 328 | 328 | MCFG_PTM6840_EXTERNAL_CLOCKS(250000.0f, 250000.0f, 250000.0f) |
| 329 | 329 | |
| 330 | 330 | MCFG_SCREEN_ADD( "screen", RASTER) |
| r243189 | r243190 | |
| 340 | 340 | MCFG_CPU_PROGRAM_MAP(hp9k330_map) |
| 341 | 341 | |
| 342 | 342 | MCFG_DEVICE_ADD(PTM6840_TAG, PTM6840, 0) |
| 343 | | MCFG_PTM6840_INTERNAL_CLOCK(250000.0f) // from oscillator module next to the 6840 |
| 343 | MCFG_PTM6840_INTERNAL_CLOCK(250000.0f) // from oscillator module next to the 6840 |
| 344 | 344 | MCFG_PTM6840_EXTERNAL_CLOCKS(250000.0f, 250000.0f, 250000.0f) |
| 345 | 345 | |
| 346 | 346 | MCFG_SCREEN_ADD( "screen", RASTER) |
| r243189 | r243190 | |
| 356 | 356 | MCFG_CPU_PROGRAM_MAP(hp9k370_map) |
| 357 | 357 | |
| 358 | 358 | MCFG_DEVICE_ADD(PTM6840_TAG, PTM6840, 0) |
| 359 | | MCFG_PTM6840_INTERNAL_CLOCK(250000.0f) // from oscillator module next to the 6840 |
| 359 | MCFG_PTM6840_INTERNAL_CLOCK(250000.0f) // from oscillator module next to the 6840 |
| 360 | 360 | MCFG_PTM6840_EXTERNAL_CLOCKS(250000.0f, 250000.0f, 250000.0f) |
| 361 | 361 | |
| 362 | 362 | MCFG_SCREEN_ADD( "screen", RASTER) |
| r243189 | r243190 | |
| 368 | 368 | |
| 369 | 369 | static MACHINE_CONFIG_START( hp9k380, hp9k3xx_state ) |
| 370 | 370 | /* basic machine hardware */ |
| 371 | | MCFG_CPU_ADD(MAINCPU_TAG, M68040, 25000000) // 25 MHz? 33? |
| 371 | MCFG_CPU_ADD(MAINCPU_TAG, M68040, 25000000) // 25 MHz? 33? |
| 372 | 372 | MCFG_CPU_PROGRAM_MAP(hp9k330_map) |
| 373 | 373 | |
| 374 | 374 | MCFG_DEVICE_ADD(PTM6840_TAG, PTM6840, 0) |
| 375 | | MCFG_PTM6840_INTERNAL_CLOCK(250000.0f) // from oscillator module next to the 6840 |
| 375 | MCFG_PTM6840_INTERNAL_CLOCK(250000.0f) // from oscillator module next to the 6840 |
| 376 | 376 | MCFG_PTM6840_EXTERNAL_CLOCKS(250000.0f, 250000.0f, 250000.0f) |
| 377 | 377 | |
| 378 | 378 | MCFG_SCREEN_ADD( "screen", RASTER) |
| r243189 | r243190 | |
| 384 | 384 | |
| 385 | 385 | static MACHINE_CONFIG_START( hp9k382, hp9k3xx_state ) |
| 386 | 386 | /* basic machine hardware */ |
| 387 | | MCFG_CPU_ADD(MAINCPU_TAG, M68040, 25000000) // 25 MHz? 33? |
| 387 | MCFG_CPU_ADD(MAINCPU_TAG, M68040, 25000000) // 25 MHz? 33? |
| 388 | 388 | MCFG_CPU_PROGRAM_MAP(hp9k382_map) |
| 389 | 389 | |
| 390 | 390 | MCFG_DEVICE_ADD(PTM6840_TAG, PTM6840, 0) |
| 391 | | MCFG_PTM6840_INTERNAL_CLOCK(250000.0f) // from oscillator module next to the 6840 |
| 391 | MCFG_PTM6840_INTERNAL_CLOCK(250000.0f) // from oscillator module next to the 6840 |
| 392 | 392 | MCFG_PTM6840_EXTERNAL_CLOCKS(250000.0f, 250000.0f, 250000.0f) |
| 393 | 393 | |
| 394 | 394 | MCFG_SCREEN_ADD( "screen", RASTER) |
| r243189 | r243190 | |
| 400 | 400 | |
| 401 | 401 | ROM_START( hp9k310 ) |
| 402 | 402 | ROM_REGION( 0x20000, MAINCPU_TAG, 0 ) |
| 403 | | ROM_LOAD16_BYTE( "1818-3771.bin", 0x000001, 0x008000, CRC(b9e4e3ad) SHA1(ed6f1fad94a15d95362701dbe124b52877fc3ec4) ) |
| 404 | | ROM_LOAD16_BYTE( "1818-3772.bin", 0x000000, 0x008000, CRC(a3665919) SHA1(ec1bc7e5b7990a1b09af947a06401e8ed3cb0516) ) |
| 403 | ROM_LOAD16_BYTE( "1818-3771.bin", 0x000001, 0x008000, CRC(b9e4e3ad) SHA1(ed6f1fad94a15d95362701dbe124b52877fc3ec4) ) |
| 404 | ROM_LOAD16_BYTE( "1818-3772.bin", 0x000000, 0x008000, CRC(a3665919) SHA1(ec1bc7e5b7990a1b09af947a06401e8ed3cb0516) ) |
| 405 | 405 | |
| 406 | 406 | ROM_REGION( 0x800, "mcu", 0 ) |
| 407 | | ROM_LOAD( "1820-4784_1.bin", 0x000000, 0x000800, CRC(e929044a) SHA1(90849a10bdb8c6e38e73ce027c9c0ad8b3956b1b) ) |
| 408 | | ROM_LOAD( "1820-4784_2.bin", 0x000000, 0x000800, CRC(8defcf50) SHA1(d3abfea468a43db7c2369500a3e390e77a8e22e6) ) |
| 407 | ROM_LOAD( "1820-4784_1.bin", 0x000000, 0x000800, CRC(e929044a) SHA1(90849a10bdb8c6e38e73ce027c9c0ad8b3956b1b) ) |
| 408 | ROM_LOAD( "1820-4784_2.bin", 0x000000, 0x000800, CRC(8defcf50) SHA1(d3abfea468a43db7c2369500a3e390e77a8e22e6) ) |
| 409 | 409 | |
| 410 | 410 | ROM_REGION( 0x4000, "graphics", ROMREGION_ERASEFF | ROMREGION_BE ) |
| 411 | 411 | ROM_LOAD16_BYTE( "98544_1818-1999.bin", 0x000000, 0x002000, CRC(8c7d6480) SHA1(d2bcfd39452c38bc652df39f84c7041cfdf6bd51) ) |
| r243189 | r243190 | |
| 413 | 413 | |
| 414 | 414 | ROM_START( hp9k320 ) |
| 415 | 415 | ROM_REGION( 0x20000, MAINCPU_TAG, 0 ) |
| 416 | | ROM_LOAD16_BYTE( "5061-6538.bin", 0x000001, 0x004000, CRC(d6aafeb1) SHA1(88c6b0b2f504303cbbac0c496c26b85458ac5d63) ) |
| 417 | | ROM_LOAD16_BYTE( "5061-6539.bin", 0x000000, 0x004000, CRC(a7ff104c) SHA1(c640fe68314654716bd41b04c6a7f4e560036c7e) ) |
| 418 | | ROM_LOAD16_BYTE( "5061-6540.bin", 0x008001, 0x004000, CRC(4f6796d6) SHA1(fd254897ac1afb8628f40ea93213f60a082c8d36) ) |
| 419 | | ROM_LOAD16_BYTE( "5061-6541.bin", 0x008000, 0x004000, CRC(39d32998) SHA1(6de1bda75187b0878c03c074942b807cf2924f0e) ) |
| 416 | ROM_LOAD16_BYTE( "5061-6538.bin", 0x000001, 0x004000, CRC(d6aafeb1) SHA1(88c6b0b2f504303cbbac0c496c26b85458ac5d63) ) |
| 417 | ROM_LOAD16_BYTE( "5061-6539.bin", 0x000000, 0x004000, CRC(a7ff104c) SHA1(c640fe68314654716bd41b04c6a7f4e560036c7e) ) |
| 418 | ROM_LOAD16_BYTE( "5061-6540.bin", 0x008001, 0x004000, CRC(4f6796d6) SHA1(fd254897ac1afb8628f40ea93213f60a082c8d36) ) |
| 419 | ROM_LOAD16_BYTE( "5061-6541.bin", 0x008000, 0x004000, CRC(39d32998) SHA1(6de1bda75187b0878c03c074942b807cf2924f0e) ) |
| 420 | 420 | |
| 421 | 421 | ROM_REGION( 0x4000, "graphics", ROMREGION_ERASEFF | ROMREGION_BE | ROMREGION_32BIT ) |
| 422 | 422 | ROM_LOAD16_BYTE( "98544_1818-1999.bin", 0x000001, 0x002000, CRC(8c7d6480) SHA1(d2bcfd39452c38bc652df39f84c7041cfdf6bd51) ) |
| r243189 | r243190 | |
| 424 | 424 | |
| 425 | 425 | ROM_START( hp9k330 ) |
| 426 | 426 | ROM_REGION( 0x20000, MAINCPU_TAG, 0 ) |
| 427 | | ROM_LOAD16_BYTE( "1818-4416.bin", 0x000000, 0x010000, CRC(cd71e85e) SHA1(3e83a80682f733417fdc3720410e45a2cfdcf869) ) |
| 428 | | ROM_LOAD16_BYTE( "1818-4417.bin", 0x000001, 0x010000, CRC(374d49db) SHA1(a12cbf6c151e2f421da4571000b5dffa3ef403b3) ) |
| 427 | ROM_LOAD16_BYTE( "1818-4416.bin", 0x000000, 0x010000, CRC(cd71e85e) SHA1(3e83a80682f733417fdc3720410e45a2cfdcf869) ) |
| 428 | ROM_LOAD16_BYTE( "1818-4417.bin", 0x000001, 0x010000, CRC(374d49db) SHA1(a12cbf6c151e2f421da4571000b5dffa3ef403b3) ) |
| 429 | 429 | |
| 430 | 430 | ROM_REGION( 0x4000, "graphics", ROMREGION_ERASEFF | ROMREGION_BE | ROMREGION_32BIT ) |
| 431 | 431 | ROM_LOAD16_BYTE( "98544_1818-1999.bin", 0x000001, 0x002000, CRC(8c7d6480) SHA1(d2bcfd39452c38bc652df39f84c7041cfdf6bd51) ) |
| r243189 | r243190 | |
| 433 | 433 | |
| 434 | 434 | ROM_START( hp9k340 ) |
| 435 | 435 | ROM_REGION( 0x20000, MAINCPU_TAG, 0 ) |
| 436 | | ROM_LOAD16_BYTE( "1818-4416.bin", 0x000000, 0x010000, CRC(cd71e85e) SHA1(3e83a80682f733417fdc3720410e45a2cfdcf869) ) |
| 437 | | ROM_LOAD16_BYTE( "1818-4417.bin", 0x000001, 0x010000, CRC(374d49db) SHA1(a12cbf6c151e2f421da4571000b5dffa3ef403b3) ) |
| 436 | ROM_LOAD16_BYTE( "1818-4416.bin", 0x000000, 0x010000, CRC(cd71e85e) SHA1(3e83a80682f733417fdc3720410e45a2cfdcf869) ) |
| 437 | ROM_LOAD16_BYTE( "1818-4417.bin", 0x000001, 0x010000, CRC(374d49db) SHA1(a12cbf6c151e2f421da4571000b5dffa3ef403b3) ) |
| 438 | 438 | |
| 439 | 439 | ROM_REGION( 0x4000, "graphics", ROMREGION_ERASEFF | ROMREGION_BE | ROMREGION_32BIT ) |
| 440 | 440 | ROM_LOAD16_BYTE( "98544_1818-1999.bin", 0x000001, 0x002000, CRC(8c7d6480) SHA1(d2bcfd39452c38bc652df39f84c7041cfdf6bd51) ) |
trunk/src/mess/drivers/ngen.c
| r243189 | r243190 | |
| 406 | 406 | |
| 407 | 407 | // X-bus module select |
| 408 | 408 | // The bootstrap ROM creates a table at 0:FC9h, with a count, followed by the module IDs of each |
| 409 | | // expansion module. The base I/O address for the currently selected module is set by writing to |
| 409 | // expansion module. The base I/O address for the currently selected module is set by writing to |
| 410 | 410 | // this register (bits 0-7 are ignored) |
| 411 | 411 | // TODO: make expansion modules slot devices |
| 412 | 412 | WRITE16_MEMBER(ngen_state::xbus_w) |
| r243189 | r243190 | |
| 435 | 435 | READ16_MEMBER(ngen_state::xbus_r) |
| 436 | 436 | { |
| 437 | 437 | UINT16 ret = 0xffff; |
| 438 | | |
| 438 | |
| 439 | 439 | switch(m_xbus_current) |
| 440 | 440 | { |
| 441 | 441 | case 0x00: |
| r243189 | r243190 | |
| 647 | 647 | |
| 648 | 648 | READ8_MEMBER(ngen_state::dma_3_dack_r) |
| 649 | 649 | { |
| 650 | | UINT16 ret = 0xffff; |
| 651 | | |
| 650 | UINT16 ret = 0xffff; |
| 651 | |
| 652 | 652 | if((m_hdc_control & 0x04) && m_disk_rom) |
| 653 | 653 | { |
| 654 | 654 | ret = m_disk_rom->base()[m_disk_rom_ptr++] << 8; |
| r243189 | r243190 | |
| 659 | 659 | //m_dmac->dreq3_w(0); |
| 660 | 660 | } |
| 661 | 661 | } |
| 662 | | m_dma_high_byte = ret & 0xff00; |
| 662 | m_dma_high_byte = ret & 0xff00; |
| 663 | 663 | return ret; |
| 664 | 664 | } |
| 665 | 665 | |
| r243189 | r243190 | |
| 737 | 737 | |
| 738 | 738 | static ADDRESS_MAP_START( ngen_io, AS_IO, 16, ngen_state ) |
| 739 | 739 | AM_RANGE(0x0000, 0x0001) AM_READWRITE(xbus_r,xbus_w) |
| 740 | | |
| 740 | |
| 741 | 741 | // Floppy/Hard disk module |
| 742 | | // AM_RANGE(0x0100, 0x0107) AM_DEVREADWRITE8("fdc",wd2797_t,read,write,0x00ff) // a guess for now |
| 743 | | // AM_RANGE(0x0108, 0x0109) AM_WRITE8(fdc_control_w,0x00ff) |
| 744 | | // AM_RANGE(0x010a, 0x010b) AM_WRITE8(hdc_control_w,0x00ff) |
| 745 | | // AM_RANGE(0x010e, 0x010f) AM_WRITE8(disk_addr_ext,0x00ff) // X-Bus extended address register |
| 746 | | // AM_RANGE(0x0110, 0x0117) AM_DEVREADWRITE8("fdc_timer",pit8253_device,read,write,0x00ff) |
| 742 | // AM_RANGE(0x0100, 0x0107) AM_DEVREADWRITE8("fdc",wd2797_t,read,write,0x00ff) // a guess for now |
| 743 | // AM_RANGE(0x0108, 0x0109) AM_WRITE8(fdc_control_w,0x00ff) |
| 744 | // AM_RANGE(0x010a, 0x010b) AM_WRITE8(hdc_control_w,0x00ff) |
| 745 | // AM_RANGE(0x010e, 0x010f) AM_WRITE8(disk_addr_ext,0x00ff) // X-Bus extended address register |
| 746 | // AM_RANGE(0x0110, 0x0117) AM_DEVREADWRITE8("fdc_timer",pit8253_device,read,write,0x00ff) |
| 747 | 747 | // 0x0120-0x012f - WD1010 Winchester disk controller (unemulated) |
| 748 | | // AM_RANGE(0x0130, 0x0137) AM_DEVREADWRITE8("hdc_timer",pit8253_device,read,write,0x00ff) |
| 749 | | |
| 748 | // AM_RANGE(0x0130, 0x0137) AM_DEVREADWRITE8("hdc_timer",pit8253_device,read,write,0x00ff) |
| 749 | |
| 750 | 750 | ADDRESS_MAP_END |
| 751 | 751 | |
| 752 | 752 | static ADDRESS_MAP_START( ngen386_mem, AS_PROGRAM, 32, ngen_state ) |
| r243189 | r243190 | |
| 851 | 851 | |
| 852 | 852 | // keyboard UART (patent says i8251 is used for keyboard communications, it is located on the video board) |
| 853 | 853 | MCFG_DEVICE_ADD("videouart", I8251, 0) // main clock unknown, Rx/Tx clocks are 19.53kHz |
| 854 | | // MCFG_I8251_TXEMPTY_HANDLER(DEVWRITELINE("pic",pic8259_device,ir4_w)) |
| 854 | // MCFG_I8251_TXEMPTY_HANDLER(DEVWRITELINE("pic",pic8259_device,ir4_w)) |
| 855 | 855 | MCFG_I8251_TXD_HANDLER(DEVWRITELINE("keyboard", rs232_port_device, write_txd)) |
| 856 | 856 | MCFG_RS232_PORT_ADD("keyboard", keyboard, "ngen") |
| 857 | 857 | MCFG_RS232_RXD_HANDLER(DEVWRITELINE("videouart", i8251_device, write_rxd)) |
| r243189 | r243190 | |
| 865 | 865 | MCFG_WD_FDC_DRQ_CALLBACK(DEVWRITELINE("maincpu",i80186_cpu_device,drq1_w)) |
| 866 | 866 | MCFG_WD_FDC_FORCE_READY |
| 867 | 867 | MCFG_DEVICE_ADD("fdc_timer", PIT8253, 0) |
| 868 | | MCFG_PIT8253_CLK0(XTAL_20MHz / 20) |
| 868 | MCFG_PIT8253_CLK0(XTAL_20MHz / 20) |
| 869 | 869 | MCFG_PIT8253_OUT0_HANDLER(DEVWRITELINE("pic",pic8259_device,ir7_w)) // clocked on FDC data register access |
| 870 | 870 | MCFG_PIT8253_CLK1(XTAL_20MHz / 20) |
| 871 | 871 | MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE("pic",pic8259_device,ir7_w)) // 1MHz |
| 872 | 872 | MCFG_PIT8253_CLK2(XTAL_20MHz / 10) |
| 873 | | MCFG_PIT8253_OUT2_HANDLER(DEVWRITELINE("pic",pic8259_device,ir7_w)) |
| 873 | MCFG_PIT8253_OUT2_HANDLER(DEVWRITELINE("pic",pic8259_device,ir7_w)) |
| 874 | 874 | // TODO: WD1010 HDC (not implemented), use WD2010 for now |
| 875 | 875 | MCFG_DEVICE_ADD("hdc", WD2010, XTAL_20MHz / 4) |
| 876 | 876 | MCFG_WD2010_IN_BCS_CB(READ8(ngen_state,hd_buffer_r)) |
trunk/src/osd/modules/font/font_osx.c
| r243189 | r243190 | |
| 26 | 26 | class osd_font_osx : public osd_font |
| 27 | 27 | { |
| 28 | 28 | public: |
| 29 | | virtual ~osd_font_osx() {}; |
| 29 | virtual ~osd_font_osx() {}; |
| 30 | 30 | |
| 31 | | virtual bool open(const char *font_path, const char *name, int &height); |
| 32 | | virtual void close(); |
| 33 | | virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs); |
| 31 | virtual bool open(const char *font_path, const char *name, int &height); |
| 32 | virtual void close(); |
| 33 | virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs); |
| 34 | 34 | private: |
| 35 | | CTFontRef m_font; |
| 35 | CTFontRef m_font; |
| 36 | 36 | }; |
| 37 | 37 | |
| 38 | 38 | bool osd_font_osx::open(const char *font_path, const char *_name, int &height) |
| 39 | 39 | { |
| 40 | | CFStringRef font_name = NULL; |
| 41 | | CTFontRef ct_font = NULL; |
| 42 | | CTFontDescriptorRef font_descriptor; |
| 43 | | CGAffineTransform affine_transform = CGAffineTransformIdentity; |
| 40 | CFStringRef font_name = NULL; |
| 41 | CTFontRef ct_font = NULL; |
| 42 | CTFontDescriptorRef font_descriptor; |
| 43 | CGAffineTransform affine_transform = CGAffineTransformIdentity; |
| 44 | 44 | |
| 45 | | m_font = NULL; |
| 46 | | astring name(_name); |
| 47 | | printf("FONT NAME %s\n", _name); |
| 45 | m_font = NULL; |
| 46 | astring name(_name); |
| 47 | printf("FONT NAME %s\n", _name); |
| 48 | 48 | #if 0 |
| 49 | | if (name == "default") |
| 50 | | { |
| 51 | | name = "LucidaGrande"; |
| 52 | | } |
| 49 | if (name == "default") |
| 50 | { |
| 51 | name = "LucidaGrande"; |
| 52 | } |
| 53 | 53 | #endif |
| 54 | | /* handle bdf fonts in the core */ |
| 55 | | if (name.len() > 4) |
| 56 | | if (name.makeupper().substr(name.len()-4,4) == ".BDF" ) |
| 57 | | return false; |
| 54 | /* handle bdf fonts in the core */ |
| 55 | if (name.len() > 4) |
| 56 | if (name.makeupper().substr(name.len()-4,4) == ".BDF" ) |
| 57 | return false; |
| 58 | 58 | |
| 59 | | font_name = CFStringCreateWithCString( NULL, name.cstr(), kCFStringEncodingUTF8 ); |
| 60 | | if( font_name != NULL ) |
| 61 | | { |
| 62 | | font_descriptor = CTFontDescriptorCreateWithNameAndSize( font_name, 0.0); //POINT_SIZE ); |
| 59 | font_name = CFStringCreateWithCString( NULL, name.cstr(), kCFStringEncodingUTF8 ); |
| 60 | if( font_name != NULL ) |
| 61 | { |
| 62 | font_descriptor = CTFontDescriptorCreateWithNameAndSize( font_name, 0.0); //POINT_SIZE ); |
| 63 | 63 | |
| 64 | | if( font_descriptor != NULL ) |
| 65 | | { |
| 66 | | ct_font = CTFontCreateWithFontDescriptor( font_descriptor, POINT_SIZE, &affine_transform ); |
| 64 | if( font_descriptor != NULL ) |
| 65 | { |
| 66 | ct_font = CTFontCreateWithFontDescriptor( font_descriptor, POINT_SIZE, &affine_transform ); |
| 67 | 67 | |
| 68 | | CFRelease( font_descriptor ); |
| 69 | | } |
| 70 | | } |
| 68 | CFRelease( font_descriptor ); |
| 69 | } |
| 70 | } |
| 71 | 71 | |
| 72 | | CFRelease( font_name ); |
| 72 | CFRelease( font_name ); |
| 73 | 73 | |
| 74 | | if (!ct_font) |
| 75 | | { |
| 76 | | osd_printf_verbose("Couldn't find/open font %s, using MAME default\n", name.cstr()); |
| 77 | | return false; |
| 78 | | } |
| 74 | if (!ct_font) |
| 75 | { |
| 76 | osd_printf_verbose("Couldn't find/open font %s, using MAME default\n", name.cstr()); |
| 77 | return false; |
| 78 | } |
| 79 | 79 | |
| 80 | | CFStringRef real_name = CTFontCopyPostScriptName( ct_font ); |
| 81 | | char real_name_c_string[255]; |
| 82 | | CFStringGetCString ( real_name, real_name_c_string, 255, kCFStringEncodingUTF8 ); |
| 83 | | osd_printf_verbose("Matching font: %s\n", real_name_c_string); |
| 84 | | CFRelease( real_name ); |
| 80 | CFStringRef real_name = CTFontCopyPostScriptName( ct_font ); |
| 81 | char real_name_c_string[255]; |
| 82 | CFStringGetCString ( real_name, real_name_c_string, 255, kCFStringEncodingUTF8 ); |
| 83 | osd_printf_verbose("Matching font: %s\n", real_name_c_string); |
| 84 | CFRelease( real_name ); |
| 85 | 85 | |
| 86 | | CGFloat line_height = 0.0; |
| 87 | | line_height += CTFontGetAscent(ct_font); |
| 88 | | line_height += CTFontGetDescent(ct_font); |
| 89 | | line_height += CTFontGetLeading(ct_font); |
| 90 | | height = ceilf(line_height * EXTRA_HEIGHT); |
| 86 | CGFloat line_height = 0.0; |
| 87 | line_height += CTFontGetAscent(ct_font); |
| 88 | line_height += CTFontGetDescent(ct_font); |
| 89 | line_height += CTFontGetLeading(ct_font); |
| 90 | height = ceilf(line_height * EXTRA_HEIGHT); |
| 91 | 91 | |
| 92 | | m_font = ct_font; |
| 93 | | return true; |
| 92 | m_font = ct_font; |
| 93 | return true; |
| 94 | 94 | } |
| 95 | 95 | |
| 96 | 96 | //------------------------------------------------- |
| r243189 | r243190 | |
| 100 | 100 | |
| 101 | 101 | void osd_font_osx::close() |
| 102 | 102 | { |
| 103 | | if( m_font != NULL ) |
| 104 | | { |
| 105 | | CFRelease( m_font ); |
| 106 | | } |
| 103 | if( m_font != NULL ) |
| 104 | { |
| 105 | CFRelease( m_font ); |
| 106 | } |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | 109 | //------------------------------------------------- |
| r243189 | r243190 | |
| 116 | 116 | |
| 117 | 117 | bool osd_font_osx::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) |
| 118 | 118 | { |
| 119 | | UniChar uni_char; |
| 120 | | CGGlyph glyph; |
| 121 | | CTFontRef ct_font = m_font; |
| 122 | | const CFIndex count = 1; |
| 123 | | CGRect bounding_rect, success_rect; |
| 124 | | CGContextRef context_ref; |
| 119 | UniChar uni_char; |
| 120 | CGGlyph glyph; |
| 121 | CTFontRef ct_font = m_font; |
| 122 | const CFIndex count = 1; |
| 123 | CGRect bounding_rect, success_rect; |
| 124 | CGContextRef context_ref; |
| 125 | 125 | |
| 126 | | if( chnum == ' ' ) |
| 127 | | { |
| 128 | | uni_char = 'n'; |
| 129 | | CTFontGetGlyphsForCharacters( ct_font, &uni_char, &glyph, count ); |
| 130 | | success_rect = CTFontGetBoundingRectsForGlyphs( ct_font, kCTFontDefaultOrientation, &glyph, &bounding_rect, count ); |
| 131 | | uni_char = chnum; |
| 132 | | CTFontGetGlyphsForCharacters( ct_font, &uni_char, &glyph, count ); |
| 133 | | } |
| 134 | | else |
| 135 | | { |
| 136 | | uni_char = chnum; |
| 137 | | CTFontGetGlyphsForCharacters( ct_font, &uni_char, &glyph, count ); |
| 138 | | success_rect = CTFontGetBoundingRectsForGlyphs( ct_font, kCTFontDefaultOrientation, &glyph, &bounding_rect, count ); |
| 139 | | } |
| 126 | if( chnum == ' ' ) |
| 127 | { |
| 128 | uni_char = 'n'; |
| 129 | CTFontGetGlyphsForCharacters( ct_font, &uni_char, &glyph, count ); |
| 130 | success_rect = CTFontGetBoundingRectsForGlyphs( ct_font, kCTFontDefaultOrientation, &glyph, &bounding_rect, count ); |
| 131 | uni_char = chnum; |
| 132 | CTFontGetGlyphsForCharacters( ct_font, &uni_char, &glyph, count ); |
| 133 | } |
| 134 | else |
| 135 | { |
| 136 | uni_char = chnum; |
| 137 | CTFontGetGlyphsForCharacters( ct_font, &uni_char, &glyph, count ); |
| 138 | success_rect = CTFontGetBoundingRectsForGlyphs( ct_font, kCTFontDefaultOrientation, &glyph, &bounding_rect, count ); |
| 139 | } |
| 140 | 140 | |
| 141 | | if( CGRectEqualToRect( success_rect, CGRectNull ) == false ) |
| 142 | | { |
| 143 | | size_t bitmap_width; |
| 144 | | size_t bitmap_height; |
| 141 | if( CGRectEqualToRect( success_rect, CGRectNull ) == false ) |
| 142 | { |
| 143 | size_t bitmap_width; |
| 144 | size_t bitmap_height; |
| 145 | 145 | |
| 146 | | bitmap_width = ceilf(bounding_rect.size.width * EXTRA_WIDTH); |
| 147 | | bitmap_width = bitmap_width == 0 ? 1 : bitmap_width; |
| 146 | bitmap_width = ceilf(bounding_rect.size.width * EXTRA_WIDTH); |
| 147 | bitmap_width = bitmap_width == 0 ? 1 : bitmap_width; |
| 148 | 148 | |
| 149 | | bitmap_height = ceilf( (CTFontGetAscent(ct_font) + CTFontGetDescent(ct_font) + CTFontGetLeading(ct_font)) * EXTRA_HEIGHT); |
| 149 | bitmap_height = ceilf( (CTFontGetAscent(ct_font) + CTFontGetDescent(ct_font) + CTFontGetLeading(ct_font)) * EXTRA_HEIGHT); |
| 150 | 150 | |
| 151 | | xoffs = yoffs = 0; |
| 152 | | width = bitmap_width; |
| 151 | xoffs = yoffs = 0; |
| 152 | width = bitmap_width; |
| 153 | 153 | |
| 154 | | size_t bits_per_component; |
| 155 | | CGColorSpaceRef color_space; |
| 156 | | CGBitmapInfo bitmap_info = kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst; |
| 154 | size_t bits_per_component; |
| 155 | CGColorSpaceRef color_space; |
| 156 | CGBitmapInfo bitmap_info = kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst; |
| 157 | 157 | |
| 158 | | color_space = CGColorSpaceCreateDeviceRGB(); |
| 159 | | bits_per_component = 8; |
| 158 | color_space = CGColorSpaceCreateDeviceRGB(); |
| 159 | bits_per_component = 8; |
| 160 | 160 | |
| 161 | | bitmap.allocate(bitmap_width, bitmap_height); |
| 161 | bitmap.allocate(bitmap_width, bitmap_height); |
| 162 | 162 | |
| 163 | | context_ref = CGBitmapContextCreate( bitmap.raw_pixptr(0), bitmap_width, bitmap_height, bits_per_component, bitmap.rowpixels()*4, color_space, bitmap_info ); |
| 163 | context_ref = CGBitmapContextCreate( bitmap.raw_pixptr(0), bitmap_width, bitmap_height, bits_per_component, bitmap.rowpixels()*4, color_space, bitmap_info ); |
| 164 | 164 | |
| 165 | | if( context_ref != NULL ) |
| 166 | | { |
| 167 | | CGFontRef font_ref; |
| 168 | | font_ref = CTFontCopyGraphicsFont( ct_font, NULL ); |
| 169 | | CGContextSetTextPosition(context_ref, -bounding_rect.origin.x*EXTRA_WIDTH, CTFontGetDescent(ct_font)+CTFontGetLeading(ct_font) ); |
| 170 | | CGContextSetRGBFillColor(context_ref, 1.0, 1.0, 1.0, 1.0); |
| 171 | | CGContextSetFont( context_ref, font_ref ); |
| 172 | | CGContextSetFontSize( context_ref, POINT_SIZE ); |
| 173 | | CGContextShowGlyphs( context_ref, &glyph, count ); |
| 174 | | CGFontRelease( font_ref ); |
| 175 | | CGContextRelease( context_ref ); |
| 176 | | } |
| 165 | if( context_ref != NULL ) |
| 166 | { |
| 167 | CGFontRef font_ref; |
| 168 | font_ref = CTFontCopyGraphicsFont( ct_font, NULL ); |
| 169 | CGContextSetTextPosition(context_ref, -bounding_rect.origin.x*EXTRA_WIDTH, CTFontGetDescent(ct_font)+CTFontGetLeading(ct_font) ); |
| 170 | CGContextSetRGBFillColor(context_ref, 1.0, 1.0, 1.0, 1.0); |
| 171 | CGContextSetFont( context_ref, font_ref ); |
| 172 | CGContextSetFontSize( context_ref, POINT_SIZE ); |
| 173 | CGContextShowGlyphs( context_ref, &glyph, count ); |
| 174 | CGFontRelease( font_ref ); |
| 175 | CGContextRelease( context_ref ); |
| 176 | } |
| 177 | 177 | |
| 178 | | CGColorSpaceRelease( color_space ); |
| 179 | | } |
| 178 | CGColorSpaceRelease( color_space ); |
| 179 | } |
| 180 | 180 | |
| 181 | | return bitmap.valid(); |
| 181 | return bitmap.valid(); |
| 182 | 182 | } |
| 183 | 183 | |
| 184 | 184 | |
| 185 | 185 | class font_osx : public osd_module, public font_module |
| 186 | 186 | { |
| 187 | 187 | public: |
| 188 | | font_osx() |
| 189 | | : osd_module(OSD_FONT_PROVIDER, "osx"), font_module() |
| 190 | | { |
| 191 | | } |
| 188 | font_osx() |
| 189 | : osd_module(OSD_FONT_PROVIDER, "osx"), font_module() |
| 190 | { |
| 191 | } |
| 192 | 192 | |
| 193 | | osd_font *font_alloc() |
| 194 | | { |
| 195 | | return global_alloc(osd_font_osx); |
| 196 | | } |
| 193 | osd_font *font_alloc() |
| 194 | { |
| 195 | return global_alloc(osd_font_osx); |
| 196 | } |
| 197 | 197 | |
| 198 | 198 | }; |
| 199 | 199 | #else /* SDLMAME_UNIX */ |
| 200 | | MODULE_NOT_SUPPORTED(font_osx, OSD_FONT_PROVIDER, "osx") |
| 200 | MODULE_NOT_SUPPORTED(font_osx, OSD_FONT_PROVIDER, "osx") |
| 201 | 201 | #endif |
| 202 | 202 | |
| 203 | 203 | MODULE_DEFINITION(FONT_OSX, font_osx) |
trunk/src/osd/modules/font/font_sdl.c
| r243189 | r243190 | |
| 32 | 32 | class osd_font_sdl : public osd_font |
| 33 | 33 | { |
| 34 | 34 | public: |
| 35 | | virtual ~osd_font_sdl() {}; |
| 35 | virtual ~osd_font_sdl() {}; |
| 36 | 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); |
| 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 | 40 | private: |
| 41 | 41 | #ifndef SDLMAME_HAIKU |
| 42 | | TTF_Font *search_font_config(astring name, bool bold, bool italic, bool underline, bool &bakedstyles); |
| 42 | TTF_Font *search_font_config(astring name, bool bold, bool italic, bool underline, bool &bakedstyles); |
| 43 | 43 | #endif |
| 44 | | bool BDF_Check_Magic(astring name); |
| 45 | | TTF_Font * TTF_OpenFont_Magic(astring name, int fsize); |
| 46 | | TTF_Font *m_font; |
| 44 | bool BDF_Check_Magic(astring name); |
| 45 | TTF_Font * TTF_OpenFont_Magic(astring name, int fsize); |
| 46 | TTF_Font *m_font; |
| 47 | 47 | }; |
| 48 | 48 | |
| 49 | 49 | bool osd_font_sdl::open(const char *font_path, const char *_name, int &height) |
| 50 | 50 | { |
| 51 | | TTF_Font *font = (TTF_Font *)NULL; |
| 52 | | bool bakedstyles = false; |
| 53 | | int style = 0; |
| 51 | TTF_Font *font = (TTF_Font *)NULL; |
| 52 | bool bakedstyles = false; |
| 53 | int style = 0; |
| 54 | 54 | |
| 55 | | // accept qualifiers from the name |
| 56 | | astring name(_name); |
| 55 | // accept qualifiers from the name |
| 56 | astring name(_name); |
| 57 | 57 | |
| 58 | | if (name == "default") |
| 59 | | { |
| 60 | | name = "Liberation Sans"; |
| 61 | | } |
| 58 | if (name == "default") |
| 59 | { |
| 60 | name = "Liberation Sans"; |
| 61 | } |
| 62 | 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); |
| 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 | 67 | |
| 68 | | // first up, try it as a filename |
| 69 | | font = TTF_OpenFont_Magic(name, POINT_SIZE); |
| 68 | // first up, try it as a filename |
| 69 | font = TTF_OpenFont_Magic(name, POINT_SIZE); |
| 70 | 70 | |
| 71 | | // if no success, try the font path |
| 71 | // if no success, try the font path |
| 72 | 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 | | } |
| 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 | 86 | |
| 87 | | // if that didn't work, crank up the FontConfig database |
| 87 | // if that didn't work, crank up the FontConfig database |
| 88 | 88 | #ifndef SDLMAME_HAIKU |
| 89 | | if (!font) |
| 90 | | { |
| 91 | | font = search_font_config(name, bold, italic, underline, bakedstyles); |
| 92 | | } |
| 89 | if (!font) |
| 90 | { |
| 91 | font = search_font_config(name, bold, italic, underline, bakedstyles); |
| 92 | } |
| 93 | 93 | #endif |
| 94 | 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 | | } |
| 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 | 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 |
| 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 | 112 | #if SDL_VERSIONNUM(TTF_MAJOR_VERSION, TTF_MINOR_VERSION, TTF_PATCHLEVEL) > SDL_VERSIONNUM(2,0,9) |
| 113 | | style |= strike ? TTF_STYLE_STRIKETHROUGH : 0; |
| 113 | style |= strike ? TTF_STYLE_STRIKETHROUGH : 0; |
| 114 | 114 | #else |
| 115 | | if (strike) |
| 116 | | osd_printf_warning("Ignoring strikethrough for SDL_TTF older than 2.0.10\n"); |
| 115 | if (strike) |
| 116 | osd_printf_warning("Ignoring strikethrough for SDL_TTF older than 2.0.10\n"); |
| 117 | 117 | #endif // PATCHLEVEL |
| 118 | | TTF_SetFontStyle(font, style); |
| 118 | TTF_SetFontStyle(font, style); |
| 119 | 119 | |
| 120 | | height = TTF_FontLineSkip(font); |
| 120 | height = TTF_FontLineSkip(font); |
| 121 | 121 | |
| 122 | | m_font = font; |
| 123 | | return true; |
| 122 | m_font = font; |
| 123 | return true; |
| 124 | 124 | } |
| 125 | 125 | |
| 126 | 126 | //------------------------------------------------- |
| r243189 | r243190 | |
| 130 | 130 | |
| 131 | 131 | void osd_font_sdl::close() |
| 132 | 132 | { |
| 133 | | TTF_CloseFont(this->m_font); |
| 133 | TTF_CloseFont(this->m_font); |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | 136 | //------------------------------------------------- |
| r243189 | r243190 | |
| 143 | 143 | |
| 144 | 144 | bool osd_font_sdl::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) |
| 145 | 145 | { |
| 146 | | TTF_Font *ttffont; |
| 147 | | SDL_Surface *drawsurf; |
| 148 | | SDL_Color fcol = { 0xff, 0xff, 0xff }; |
| 149 | | UINT16 ustr[16]; |
| 146 | TTF_Font *ttffont; |
| 147 | SDL_Surface *drawsurf; |
| 148 | SDL_Color fcol = { 0xff, 0xff, 0xff }; |
| 149 | UINT16 ustr[16]; |
| 150 | 150 | |
| 151 | | ttffont = m_font; |
| 151 | ttffont = m_font; |
| 152 | 152 | |
| 153 | | memset(ustr,0,sizeof(ustr)); |
| 154 | | ustr[0] = (UINT16)chnum; |
| 155 | | drawsurf = TTF_RenderUNICODE_Solid(ttffont, ustr, fcol); |
| 153 | memset(ustr,0,sizeof(ustr)); |
| 154 | ustr[0] = (UINT16)chnum; |
| 155 | drawsurf = TTF_RenderUNICODE_Solid(ttffont, ustr, fcol); |
| 156 | 156 | |
| 157 | | // was nothing returned? |
| 158 | | if (drawsurf) |
| 159 | | { |
| 160 | | // allocate a MAME destination bitmap |
| 161 | | bitmap.allocate(drawsurf->w, drawsurf->h); |
| 157 | // was nothing returned? |
| 158 | if (drawsurf) |
| 159 | { |
| 160 | // allocate a MAME destination bitmap |
| 161 | bitmap.allocate(drawsurf->w, drawsurf->h); |
| 162 | 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; |
| 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 | 168 | |
| 169 | | srcrow += (y * drawsurf->pitch); |
| 169 | srcrow += (y * drawsurf->pitch); |
| 170 | 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 | | } |
| 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 | 176 | |
| 177 | | // what are these? |
| 178 | | xoffs = yoffs = 0; |
| 179 | | width = drawsurf->w; |
| 177 | // what are these? |
| 178 | xoffs = yoffs = 0; |
| 179 | width = drawsurf->w; |
| 180 | 180 | |
| 181 | | SDL_FreeSurface(drawsurf); |
| 182 | | } |
| 181 | SDL_FreeSurface(drawsurf); |
| 182 | } |
| 183 | 183 | |
| 184 | | return bitmap.valid(); |
| 184 | return bitmap.valid(); |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | 187 | TTF_Font * osd_font_sdl::TTF_OpenFont_Magic(astring name, int fsize) |
| 188 | 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); |
| 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 | 199 | } |
| 200 | 200 | |
| 201 | 201 | bool osd_font_sdl::BDF_Check_Magic(astring name) |
| 202 | 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 | | } |
| 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 | 213 | |
| 214 | | return false; |
| 214 | return false; |
| 215 | 215 | } |
| 216 | 216 | |
| 217 | 217 | #ifndef SDLMAME_HAIKU |
| 218 | 218 | TTF_Font *osd_font_sdl::search_font_config(astring name, bool bold, bool italic, bool underline, bool &bakedstyles) |
| 219 | 219 | { |
| 220 | | TTF_Font *font = (TTF_Font *)NULL; |
| 221 | | FcConfig *config; |
| 222 | | FcPattern *pat; |
| 223 | | FcObjectSet *os; |
| 224 | | FcFontSet *fontset; |
| 225 | | FcValue val; |
| 220 | TTF_Font *font = (TTF_Font *)NULL; |
| 221 | FcConfig *config; |
| 222 | FcPattern *pat; |
| 223 | FcObjectSet *os; |
| 224 | FcFontSet *fontset; |
| 225 | FcValue val; |
| 226 | 226 | |
| 227 | | config = FcConfigGetCurrent(); |
| 228 | | pat = FcPatternCreate(); |
| 229 | | os = FcObjectSetCreate(); |
| 230 | | FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.cstr()); |
| 227 | config = FcConfigGetCurrent(); |
| 228 | pat = FcPatternCreate(); |
| 229 | os = FcObjectSetCreate(); |
| 230 | FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.cstr()); |
| 231 | 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 | | } |
| 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 | 252 | |
| 253 | | FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType"); |
| 253 | FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType"); |
| 254 | 254 | |
| 255 | | FcObjectSetAdd(os, FC_FILE); |
| 256 | | fontset = FcFontList(config, pat, os); |
| 255 | FcObjectSetAdd(os, FC_FILE); |
| 256 | fontset = FcFontList(config, pat, os); |
| 257 | 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 | | } |
| 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 | 264 | |
| 265 | | if (val.type != FcTypeString) |
| 266 | | { |
| 267 | | continue; |
| 268 | | } |
| 265 | if (val.type != FcTypeString) |
| 266 | { |
| 267 | continue; |
| 268 | } |
| 269 | 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 | | } |
| 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 | 275 | |
| 276 | | if (font) |
| 277 | | { |
| 278 | | bakedstyles = true; |
| 279 | | break; |
| 280 | | } |
| 281 | | } |
| 276 | if (font) |
| 277 | { |
| 278 | bakedstyles = true; |
| 279 | break; |
| 280 | } |
| 281 | } |
| 282 | 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); |
| 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 | 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); |
| 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 | 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 | | } |
| 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 | 301 | |
| 302 | | if (val.type != FcTypeString) |
| 303 | | { |
| 304 | | continue; |
| 305 | | } |
| 302 | if (val.type != FcTypeString) |
| 303 | { |
| 304 | continue; |
| 305 | } |
| 306 | 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 | | } |
| 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 | 312 | |
| 313 | | if (font) |
| 314 | | { |
| 315 | | break; |
| 316 | | } |
| 317 | | } |
| 318 | | } |
| 313 | if (font) |
| 314 | { |
| 315 | break; |
| 316 | } |
| 317 | } |
| 318 | } |
| 319 | 319 | |
| 320 | | FcPatternDestroy(pat); |
| 321 | | FcObjectSetDestroy(os); |
| 322 | | FcFontSetDestroy(fontset); |
| 323 | | return font; |
| 320 | FcPatternDestroy(pat); |
| 321 | FcObjectSetDestroy(os); |
| 322 | FcFontSetDestroy(fontset); |
| 323 | return font; |
| 324 | 324 | } |
| 325 | 325 | #endif |
| 326 | 326 | |
| r243189 | r243190 | |
| 328 | 328 | class font_sdl : public osd_module, public font_module |
| 329 | 329 | { |
| 330 | 330 | public: |
| 331 | | font_sdl() |
| 332 | | : osd_module(OSD_FONT_PROVIDER, "sdl"), font_module() |
| 333 | | { |
| 334 | | } |
| 331 | font_sdl() |
| 332 | : osd_module(OSD_FONT_PROVIDER, "sdl"), font_module() |
| 333 | { |
| 334 | } |
| 335 | 335 | |
| 336 | | osd_font *font_alloc() |
| 337 | | { |
| 338 | | return global_alloc(osd_font_sdl); |
| 339 | | } |
| 336 | osd_font *font_alloc() |
| 337 | { |
| 338 | return global_alloc(osd_font_sdl); |
| 339 | } |
| 340 | 340 | |
| 341 | | int init() |
| 342 | | { |
| 343 | | if (TTF_Init() == -1) |
| 344 | | { |
| 345 | | osd_printf_error("SDL_ttf failed: %s\n", TTF_GetError()); |
| 346 | | return -1; |
| 347 | | } |
| 348 | | return 0; |
| 349 | | } |
| 341 | int init() |
| 342 | { |
| 343 | if (TTF_Init() == -1) |
| 344 | { |
| 345 | osd_printf_error("SDL_ttf failed: %s\n", TTF_GetError()); |
| 346 | return -1; |
| 347 | } |
| 348 | return 0; |
| 349 | } |
| 350 | 350 | |
| 351 | | virtual void exit() |
| 352 | | { |
| 353 | | TTF_Quit(); |
| 354 | | } |
| 351 | virtual void exit() |
| 352 | { |
| 353 | TTF_Quit(); |
| 354 | } |
| 355 | 355 | }; |
| 356 | 356 | #else /* SDLMAME_UNIX */ |
| 357 | | MODULE_NOT_SUPPORTED(font_sdl, OSD_FONT_PROVIDER, "sdl") |
| 357 | MODULE_NOT_SUPPORTED(font_sdl, OSD_FONT_PROVIDER, "sdl") |
| 358 | 358 | #endif |
| 359 | 359 | |
| 360 | 360 | MODULE_DEFINITION(FONT_SDL, font_sdl) |
| 361 | | |
| 362 | | |
trunk/src/osd/modules/font/font_windows.c
| r243189 | r243190 | |
| 34 | 34 | class osd_font_windows : public osd_font |
| 35 | 35 | { |
| 36 | 36 | public: |
| 37 | | virtual ~osd_font_windows() {}; |
| 37 | virtual ~osd_font_windows() {}; |
| 38 | 38 | |
| 39 | | virtual bool open(const char *font_path, const char *name, int &height); |
| 40 | | virtual void close(); |
| 41 | | virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs); |
| 39 | virtual bool open(const char *font_path, const char *name, int &height); |
| 40 | virtual void close(); |
| 41 | virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs); |
| 42 | 42 | private: |
| 43 | | HGDIOBJ m_font; |
| 43 | HGDIOBJ m_font; |
| 44 | 44 | }; |
| 45 | 45 | |
| 46 | 46 | bool osd_font_windows::open(const char *font_path, const char *_name, int &height) |
| 47 | 47 | { |
| 48 | | // accept qualifiers from the name |
| 49 | | astring name(_name); |
| 50 | | if (name == "default") name = "Tahoma"; |
| 51 | | bool bold = (name.replace(0, "[B]", "") + name.replace(0, "[b]", "") > 0); |
| 52 | | bool italic = (name.replace(0, "[I]", "") + name.replace(0, "[i]", "") > 0); |
| 48 | // accept qualifiers from the name |
| 49 | astring name(_name); |
| 50 | if (name == "default") name = "Tahoma"; |
| 51 | bool bold = (name.replace(0, "[B]", "") + name.replace(0, "[b]", "") > 0); |
| 52 | bool italic = (name.replace(0, "[I]", "") + name.replace(0, "[i]", "") > 0); |
| 53 | 53 | |
| 54 | | // build a basic LOGFONT description of what we want |
| 55 | | LOGFONT logfont; |
| 56 | | logfont.lfHeight = DEFAULT_FONT_HEIGHT; |
| 57 | | logfont.lfWidth = 0; |
| 58 | | logfont.lfEscapement = 0; |
| 59 | | logfont.lfOrientation = 0; |
| 60 | | logfont.lfWeight = bold ? FW_BOLD : FW_MEDIUM; |
| 61 | | logfont.lfItalic = italic; |
| 62 | | logfont.lfUnderline = FALSE; |
| 63 | | logfont.lfStrikeOut = FALSE; |
| 64 | | logfont.lfCharSet = ANSI_CHARSET; |
| 65 | | logfont.lfOutPrecision = OUT_DEFAULT_PRECIS; |
| 66 | | logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS; |
| 67 | | logfont.lfQuality = NONANTIALIASED_QUALITY; |
| 68 | | logfont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; |
| 54 | // build a basic LOGFONT description of what we want |
| 55 | LOGFONT logfont; |
| 56 | logfont.lfHeight = DEFAULT_FONT_HEIGHT; |
| 57 | logfont.lfWidth = 0; |
| 58 | logfont.lfEscapement = 0; |
| 59 | logfont.lfOrientation = 0; |
| 60 | logfont.lfWeight = bold ? FW_BOLD : FW_MEDIUM; |
| 61 | logfont.lfItalic = italic; |
| 62 | logfont.lfUnderline = FALSE; |
| 63 | logfont.lfStrikeOut = FALSE; |
| 64 | logfont.lfCharSet = ANSI_CHARSET; |
| 65 | logfont.lfOutPrecision = OUT_DEFAULT_PRECIS; |
| 66 | logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS; |
| 67 | logfont.lfQuality = NONANTIALIASED_QUALITY; |
| 68 | logfont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; |
| 69 | 69 | |
| 70 | | // copy in the face name |
| 71 | | TCHAR *face = tstring_from_utf8(name); |
| 72 | | _tcsncpy(logfont.lfFaceName, face, sizeof(logfont.lfFaceName) / sizeof(TCHAR)); |
| 73 | | logfont.lfFaceName[sizeof(logfont.lfFaceName) / sizeof(TCHAR)-1] = 0; |
| 74 | | osd_free(face); |
| 70 | // copy in the face name |
| 71 | TCHAR *face = tstring_from_utf8(name); |
| 72 | _tcsncpy(logfont.lfFaceName, face, sizeof(logfont.lfFaceName) / sizeof(TCHAR)); |
| 73 | logfont.lfFaceName[sizeof(logfont.lfFaceName) / sizeof(TCHAR)-1] = 0; |
| 74 | osd_free(face); |
| 75 | 75 | |
| 76 | | // create the font |
| 77 | | height = logfont.lfHeight; |
| 78 | | m_font = CreateFontIndirect(&logfont); |
| 79 | | if (m_font == NULL) |
| 80 | | return false; |
| 76 | // create the font |
| 77 | height = logfont.lfHeight; |
| 78 | m_font = CreateFontIndirect(&logfont); |
| 79 | if (m_font == NULL) |
| 80 | return false; |
| 81 | 81 | |
| 82 | | // select it into a temp DC and get the real font name |
| 83 | | HDC dummyDC = CreateCompatibleDC(NULL); |
| 84 | | HGDIOBJ oldfont = SelectObject(dummyDC, m_font); |
| 85 | | TCHAR realname[100]; |
| 86 | | GetTextFace(dummyDC, ARRAY_LENGTH(realname), realname); |
| 87 | | SelectObject(dummyDC, oldfont); |
| 88 | | DeleteDC(dummyDC); |
| 82 | // select it into a temp DC and get the real font name |
| 83 | HDC dummyDC = CreateCompatibleDC(NULL); |
| 84 | HGDIOBJ oldfont = SelectObject(dummyDC, m_font); |
| 85 | TCHAR realname[100]; |
| 86 | GetTextFace(dummyDC, ARRAY_LENGTH(realname), realname); |
| 87 | SelectObject(dummyDC, oldfont); |
| 88 | DeleteDC(dummyDC); |
| 89 | 89 | |
| 90 | | // if it doesn't match our request, fail |
| 91 | | char *utf = utf8_from_tstring(realname); |
| 92 | | int result = core_stricmp(utf, name); |
| 93 | | osd_free(utf); |
| 90 | // if it doesn't match our request, fail |
| 91 | char *utf = utf8_from_tstring(realname); |
| 92 | int result = core_stricmp(utf, name); |
| 93 | osd_free(utf); |
| 94 | 94 | |
| 95 | | // if we didn't match, nuke our font and fall back |
| 96 | | if (result != 0) |
| 97 | | { |
| 98 | | DeleteObject(m_font); |
| 99 | | m_font = NULL; |
| 100 | | return false; |
| 101 | | } |
| 102 | | return true; |
| 95 | // if we didn't match, nuke our font and fall back |
| 96 | if (result != 0) |
| 97 | { |
| 98 | DeleteObject(m_font); |
| 99 | m_font = NULL; |
| 100 | return false; |
| 101 | } |
| 102 | return true; |
| 103 | 103 | } |
| 104 | 104 | |
| 105 | 105 | //------------------------------------------------- |
| r243189 | r243190 | |
| 109 | 109 | |
| 110 | 110 | void osd_font_windows::close() |
| 111 | 111 | { |
| 112 | | // delete the font ojbect |
| 113 | | if (m_font != NULL) |
| 114 | | DeleteObject(m_font); |
| 112 | // delete the font ojbect |
| 113 | if (m_font != NULL) |
| 114 | DeleteObject(m_font); |
| 115 | 115 | |
| 116 | 116 | } |
| 117 | 117 | |
| r243189 | r243190 | |
| 125 | 125 | |
| 126 | 126 | bool osd_font_windows::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) |
| 127 | 127 | { |
| 128 | | // create a dummy DC to work with |
| 129 | | HDC dummyDC = CreateCompatibleDC(NULL); |
| 130 | | HGDIOBJ oldfont = SelectObject(dummyDC, m_font); |
| 128 | // create a dummy DC to work with |
| 129 | HDC dummyDC = CreateCompatibleDC(NULL); |
| 130 | HGDIOBJ oldfont = SelectObject(dummyDC, m_font); |
| 131 | 131 | |
| 132 | | // get the text metrics |
| 133 | | TEXTMETRIC metrics = { 0 }; |
| 134 | | GetTextMetrics(dummyDC, &metrics); |
| 132 | // get the text metrics |
| 133 | TEXTMETRIC metrics = { 0 }; |
| 134 | GetTextMetrics(dummyDC, &metrics); |
| 135 | 135 | |
| 136 | | // get the width of this character |
| 137 | | ABC abc; |
| 138 | | if (!GetCharABCWidths(dummyDC, chnum, chnum, &abc)) |
| 139 | | { |
| 140 | | abc.abcA = 0; |
| 141 | | abc.abcC = 0; |
| 142 | | GetCharWidth32(dummyDC, chnum, chnum, reinterpret_cast<LPINT>(&abc.abcB)); |
| 143 | | } |
| 144 | | width = abc.abcA + abc.abcB + abc.abcC; |
| 136 | // get the width of this character |
| 137 | ABC abc; |
| 138 | if (!GetCharABCWidths(dummyDC, chnum, chnum, &abc)) |
| 139 | { |
| 140 | abc.abcA = 0; |
| 141 | abc.abcC = 0; |
| 142 | GetCharWidth32(dummyDC, chnum, chnum, reinterpret_cast<LPINT>(&abc.abcB)); |
| 143 | } |
| 144 | width = abc.abcA + abc.abcB + abc.abcC; |
| 145 | 145 | |
| 146 | | // determine desired bitmap size |
| 147 | | int bmwidth = (50 + abc.abcA + abc.abcB + abc.abcC + 50 + 31) & ~31; |
| 148 | | int bmheight = 50 + metrics.tmHeight + 50; |
| 146 | // determine desired bitmap size |
| 147 | int bmwidth = (50 + abc.abcA + abc.abcB + abc.abcC + 50 + 31) & ~31; |
| 148 | int bmheight = 50 + metrics.tmHeight + 50; |
| 149 | 149 | |
| 150 | | // describe the bitmap we want |
| 151 | | BYTE bitmapinfodata[sizeof(BITMAPINFOHEADER)+2 * sizeof(RGBQUAD)] = { 0 }; |
| 152 | | BITMAPINFO &info = *reinterpret_cast<BITMAPINFO *>(bitmapinfodata); |
| 153 | | info.bmiHeader.biSize = sizeof(info.bmiHeader); |
| 154 | | info.bmiHeader.biWidth = bmwidth; |
| 155 | | info.bmiHeader.biHeight = -bmheight; |
| 156 | | info.bmiHeader.biPlanes = 1; |
| 157 | | info.bmiHeader.biBitCount = 1; |
| 158 | | info.bmiHeader.biCompression = BI_RGB; |
| 159 | | info.bmiHeader.biSizeImage = 0; |
| 160 | | info.bmiHeader.biXPelsPerMeter = GetDeviceCaps(dummyDC, HORZRES) / GetDeviceCaps(dummyDC, HORZSIZE); |
| 161 | | info.bmiHeader.biYPelsPerMeter = GetDeviceCaps(dummyDC, VERTRES) / GetDeviceCaps(dummyDC, VERTSIZE); |
| 162 | | info.bmiHeader.biClrUsed = 0; |
| 163 | | info.bmiHeader.biClrImportant = 0; |
| 164 | | RGBQUAD col1 = info.bmiColors[0]; |
| 165 | | RGBQUAD col2 = info.bmiColors[1]; |
| 166 | | col1.rgbBlue = col1.rgbGreen = col1.rgbRed = 0x00; |
| 167 | | col2.rgbBlue = col2.rgbGreen = col2.rgbRed = 0xff; |
| 150 | // describe the bitmap we want |
| 151 | BYTE bitmapinfodata[sizeof(BITMAPINFOHEADER)+2 * sizeof(RGBQUAD)] = { 0 }; |
| 152 | BITMAPINFO &info = *reinterpret_cast<BITMAPINFO *>(bitmapinfodata); |
| 153 | info.bmiHeader.biSize = sizeof(info.bmiHeader); |
| 154 | info.bmiHeader.biWidth = bmwidth; |
| 155 | info.bmiHeader.biHeight = -bmheight; |
| 156 | info.bmiHeader.biPlanes = 1; |
| 157 | info.bmiHeader.biBitCount = 1; |
| 158 | info.bmiHeader.biCompression = BI_RGB; |
| 159 | info.bmiHeader.biSizeImage = 0; |
| 160 | info.bmiHeader.biXPelsPerMeter = GetDeviceCaps(dummyDC, HORZRES) / GetDeviceCaps(dummyDC, HORZSIZE); |
| 161 | info.bmiHeader.biYPelsPerMeter = GetDeviceCaps(dummyDC, VERTRES) / GetDeviceCaps(dummyDC, VERTSIZE); |
| 162 | info.bmiHeader.biClrUsed = 0; |
| 163 | info.bmiHeader.biClrImportant = 0; |
| 164 | RGBQUAD col1 = info.bmiColors[0]; |
| 165 | RGBQUAD col2 = info.bmiColors[1]; |
| 166 | col1.rgbBlue = col1.rgbGreen = col1.rgbRed = 0x00; |
| 167 | col2.rgbBlue = col2.rgbGreen = col2.rgbRed = 0xff; |
| 168 | 168 | |
| 169 | | // create a DIB to render to |
| 170 | | BYTE *bits; |
| 171 | | HBITMAP dib = CreateDIBSection(dummyDC, &info, DIB_RGB_COLORS, reinterpret_cast<VOID **>(&bits), NULL, 0); |
| 172 | | HGDIOBJ oldbitmap = SelectObject(dummyDC, dib); |
| 169 | // create a DIB to render to |
| 170 | BYTE *bits; |
| 171 | HBITMAP dib = CreateDIBSection(dummyDC, &info, DIB_RGB_COLORS, reinterpret_cast<VOID **>(&bits), NULL, 0); |
| 172 | HGDIOBJ oldbitmap = SelectObject(dummyDC, dib); |
| 173 | 173 | |
| 174 | | // clear the bitmap |
| 175 | | int rowbytes = bmwidth / 8; |
| 176 | | memset(bits, 0, rowbytes * bmheight); |
| 174 | // clear the bitmap |
| 175 | int rowbytes = bmwidth / 8; |
| 176 | memset(bits, 0, rowbytes * bmheight); |
| 177 | 177 | |
| 178 | | // now draw the character |
| 179 | | WCHAR tempchar = chnum; |
| 180 | | SetTextColor(dummyDC, RGB(0xff, 0xff, 0xff)); |
| 181 | | SetBkColor(dummyDC, RGB(0x00, 0x00, 0x00)); |
| 182 | | ExtTextOutW(dummyDC, 50 + abc.abcA, 50, ETO_OPAQUE, NULL, &tempchar, 1, NULL); |
| 178 | // now draw the character |
| 179 | WCHAR tempchar = chnum; |
| 180 | SetTextColor(dummyDC, RGB(0xff, 0xff, 0xff)); |
| 181 | SetBkColor(dummyDC, RGB(0x00, 0x00, 0x00)); |
| 182 | ExtTextOutW(dummyDC, 50 + abc.abcA, 50, ETO_OPAQUE, NULL, &tempchar, 1, NULL); |
| 183 | 183 | |
| 184 | | // characters are expected to be full-height |
| 185 | | rectangle actbounds; |
| 186 | | actbounds.min_y = 50; |
| 187 | | actbounds.max_y = 50 + metrics.tmHeight - 1; |
| 184 | // characters are expected to be full-height |
| 185 | rectangle actbounds; |
| 186 | actbounds.min_y = 50; |
| 187 | actbounds.max_y = 50 + metrics.tmHeight - 1; |
| 188 | 188 | |
| 189 | | // determine the actual left of the character |
| 190 | | for (actbounds.min_x = 0; actbounds.min_x < rowbytes; actbounds.min_x++) |
| 191 | | { |
| 192 | | BYTE *offs = bits + actbounds.min_x; |
| 193 | | UINT8 summary = 0; |
| 194 | | for (int y = 0; y < bmheight; y++) |
| 195 | | summary |= offs[y * rowbytes]; |
| 196 | | if (summary != 0) |
| 197 | | { |
| 198 | | actbounds.min_x *= 8; |
| 199 | | if (!(summary & 0x80)) actbounds.min_x++; |
| 200 | | if (!(summary & 0xc0)) actbounds.min_x++; |
| 201 | | if (!(summary & 0xe0)) actbounds.min_x++; |
| 202 | | if (!(summary & 0xf0)) actbounds.min_x++; |
| 203 | | if (!(summary & 0xf8)) actbounds.min_x++; |
| 204 | | if (!(summary & 0xfc)) actbounds.min_x++; |
| 205 | | if (!(summary & 0xfe)) actbounds.min_x++; |
| 206 | | break; |
| 207 | | } |
| 208 | | } |
| 189 | // determine the actual left of the character |
| 190 | for (actbounds.min_x = 0; actbounds.min_x < rowbytes; actbounds.min_x++) |
| 191 | { |
| 192 | BYTE *offs = bits + actbounds.min_x; |
| 193 | UINT8 summary = 0; |
| 194 | for (int y = 0; y < bmheight; y++) |
| 195 | summary |= offs[y * rowbytes]; |
| 196 | if (summary != 0) |
| 197 | { |
| 198 | actbounds.min_x *= 8; |
| 199 | if (!(summary & 0x80)) actbounds.min_x++; |
| 200 | if (!(summary & 0xc0)) actbounds.min_x++; |
| 201 | if (!(summary & 0xe0)) actbounds.min_x++; |
| 202 | if (!(summary & 0xf0)) actbounds.min_x++; |
| 203 | if (!(summary & 0xf8)) actbounds.min_x++; |
| 204 | if (!(summary & 0xfc)) actbounds.min_x++; |
| 205 | if (!(summary & 0xfe)) actbounds.min_x++; |
| 206 | break; |
| 207 | } |
| 208 | } |
| 209 | 209 | |
| 210 | | // determine the actual right of the character |
| 211 | | for (actbounds.max_x = rowbytes - 1; actbounds.max_x >= 0; actbounds.max_x--) |
| 212 | | { |
| 213 | | BYTE *offs = bits + actbounds.max_x; |
| 214 | | UINT8 summary = 0; |
| 215 | | for (int y = 0; y < bmheight; y++) |
| 216 | | summary |= offs[y * rowbytes]; |
| 217 | | if (summary != 0) |
| 218 | | { |
| 219 | | actbounds.max_x *= 8; |
| 220 | | if (summary & 0x7f) actbounds.max_x++; |
| 221 | | if (summary & 0x3f) actbounds.max_x++; |
| 222 | | if (summary & 0x1f) actbounds.max_x++; |
| 223 | | if (summary & 0x0f) actbounds.max_x++; |
| 224 | | if (summary & 0x07) actbounds.max_x++; |
| 225 | | if (summary & 0x03) actbounds.max_x++; |
| 226 | | if (summary & 0x01) actbounds.max_x++; |
| 227 | | break; |
| 228 | | } |
| 229 | | } |
| 210 | // determine the actual right of the character |
| 211 | for (actbounds.max_x = rowbytes - 1; actbounds.max_x >= 0; actbounds.max_x--) |
| 212 | { |
| 213 | BYTE *offs = bits + actbounds.max_x; |
| 214 | UINT8 summary = 0; |
| 215 | for (int y = 0; y < bmheight; y++) |
| 216 | summary |= offs[y * rowbytes]; |
| 217 | if (summary != 0) |
| 218 | { |
| 219 | actbounds.max_x *= 8; |
| 220 | if (summary & 0x7f) actbounds.max_x++; |
| 221 | if (summary & 0x3f) actbounds.max_x++; |
| 222 | if (summary & 0x1f) actbounds.max_x++; |
| 223 | if (summary & 0x0f) actbounds.max_x++; |
| 224 | if (summary & 0x07) actbounds.max_x++; |
| 225 | if (summary & 0x03) actbounds.max_x++; |
| 226 | if (summary & 0x01) actbounds.max_x++; |
| 227 | break; |
| 228 | } |
| 229 | } |
| 230 | 230 | |
| 231 | | // allocate a new bitmap |
| 232 | | if (actbounds.max_x >= actbounds.min_x && actbounds.max_y >= actbounds.min_y) |
| 233 | | { |
| 234 | | bitmap.allocate(actbounds.max_x + 1 - actbounds.min_x, actbounds.max_y + 1 - actbounds.min_y); |
| 231 | // allocate a new bitmap |
| 232 | if (actbounds.max_x >= actbounds.min_x && actbounds.max_y >= actbounds.min_y) |
| 233 | { |
| 234 | bitmap.allocate(actbounds.max_x + 1 - actbounds.min_x, actbounds.max_y + 1 - actbounds.min_y); |
| 235 | 235 | |
| 236 | | // copy the bits into it |
| 237 | | for (int y = 0; y < bitmap.height(); y++) |
| 238 | | { |
| 239 | | UINT32 *dstrow = &bitmap.pix32(y); |
| 240 | | UINT8 *srcrow = &bits[(y + actbounds.min_y) * rowbytes]; |
| 241 | | for (int x = 0; x < bitmap.width(); x++) |
| 242 | | { |
| 243 | | int effx = x + actbounds.min_x; |
| 244 | | dstrow[x] = ((srcrow[effx / 8] << (effx % 8)) & 0x80) ? rgb_t(0xff, 0xff, 0xff, 0xff) : rgb_t(0x00, 0xff, 0xff, 0xff); |
| 245 | | } |
| 246 | | } |
| 236 | // copy the bits into it |
| 237 | for (int y = 0; y < bitmap.height(); y++) |
| 238 | { |
| 239 | UINT32 *dstrow = &bitmap.pix32(y); |
| 240 | UINT8 *srcrow = &bits[(y + actbounds.min_y) * rowbytes]; |
| 241 | for (int x = 0; x < bitmap.width(); x++) |
| 242 | { |
| 243 | int effx = x + actbounds.min_x; |
| 244 | dstrow[x] = ((srcrow[effx / 8] << (effx % 8)) & 0x80) ? rgb_t(0xff, 0xff, 0xff, 0xff) : rgb_t(0x00, 0xff, 0xff, 0xff); |
| 245 | } |
| 246 | } |
| 247 | 247 | |
| 248 | | // set the final offset values |
| 249 | | xoffs = actbounds.min_x - (50 + abc.abcA); |
| 250 | | yoffs = actbounds.max_y - (50 + metrics.tmAscent); |
| 251 | | } |
| 248 | // set the final offset values |
| 249 | xoffs = actbounds.min_x - (50 + abc.abcA); |
| 250 | yoffs = actbounds.max_y - (50 + metrics.tmAscent); |
| 251 | } |
| 252 | 252 | |
| 253 | | // de-select the font and release the DC |
| 254 | | SelectObject(dummyDC, oldbitmap); |
| 255 | | DeleteObject(dib); |
| 256 | | SelectObject(dummyDC, oldfont); |
| 257 | | DeleteDC(dummyDC); |
| 258 | | return bitmap.valid(); |
| 253 | // de-select the font and release the DC |
| 254 | SelectObject(dummyDC, oldbitmap); |
| 255 | DeleteObject(dib); |
| 256 | SelectObject(dummyDC, oldfont); |
| 257 | DeleteDC(dummyDC); |
| 258 | return bitmap.valid(); |
| 259 | 259 | } |
| 260 | 260 | |
| 261 | 261 | class font_win : public osd_module, public font_module |
| 262 | 262 | { |
| 263 | 263 | public: |
| 264 | | font_win() |
| 265 | | : osd_module(OSD_FONT_PROVIDER, "win"), font_module() |
| 266 | | { |
| 267 | | } |
| 264 | font_win() |
| 265 | : osd_module(OSD_FONT_PROVIDER, "win"), font_module() |
| 266 | { |
| 267 | } |
| 268 | 268 | |
| 269 | | osd_font *font_alloc() |
| 270 | | { |
| 271 | | return global_alloc(osd_font_windows); |
| 272 | | } |
| 269 | osd_font *font_alloc() |
| 270 | { |
| 271 | return global_alloc(osd_font_windows); |
| 272 | } |
| 273 | 273 | |
| 274 | 274 | }; |
| 275 | 275 | #else /* SDLMAME_UNIX */ |
| 276 | | MODULE_NOT_SUPPORTED(font_win, OSD_FONT_PROVIDER, "win") |
| 276 | MODULE_NOT_SUPPORTED(font_win, OSD_FONT_PROVIDER, "win") |
| 277 | 277 | #endif |
| 278 | 278 | |
| 279 | 279 | MODULE_DEFINITION(FONT_WINDOWS, font_win) |
trunk/src/osd/modules/lib/osdlib_macosx.c
| r243189 | r243190 | |
| 34 | 34 | |
| 35 | 35 | const char *osd_getenv(const char *name) |
| 36 | 36 | { |
| 37 | | return getenv(name); |
| 37 | return getenv(name); |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | 40 | //============================================================ |
| r243189 | r243190 | |
| 43 | 43 | |
| 44 | 44 | int osd_setenv(const char *name, const char *value, int overwrite) |
| 45 | 45 | { |
| 46 | | return setenv(name, value, overwrite); |
| 46 | return setenv(name, value, overwrite); |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | 49 | //============================================================ |
| r243189 | r243190 | |
| 52 | 52 | |
| 53 | 53 | void osd_process_kill(void) |
| 54 | 54 | { |
| 55 | | kill(getpid(), SIGKILL); |
| 55 | kill(getpid(), SIGKILL); |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | 58 | //============================================================ |
| r243189 | r243190 | |
| 61 | 61 | |
| 62 | 62 | int osd_get_num_processors(void) |
| 63 | 63 | { |
| 64 | | int processors = 1; |
| 64 | int processors = 1; |
| 65 | 65 | |
| 66 | | struct host_basic_info host_basic_info; |
| 67 | | unsigned int count; |
| 68 | | kern_return_t r; |
| 69 | | mach_port_t my_mach_host_self; |
| 66 | struct host_basic_info host_basic_info; |
| 67 | unsigned int count; |
| 68 | kern_return_t r; |
| 69 | mach_port_t my_mach_host_self; |
| 70 | 70 | |
| 71 | | count = HOST_BASIC_INFO_COUNT; |
| 72 | | my_mach_host_self = mach_host_self(); |
| 73 | | if ( ( r = host_info(my_mach_host_self, HOST_BASIC_INFO, (host_info_t)(&host_basic_info), &count)) == KERN_SUCCESS ) |
| 74 | | { |
| 75 | | processors = host_basic_info.avail_cpus; |
| 76 | | } |
| 77 | | mach_port_deallocate(mach_task_self(), my_mach_host_self); |
| 71 | count = HOST_BASIC_INFO_COUNT; |
| 72 | my_mach_host_self = mach_host_self(); |
| 73 | if ( ( r = host_info(my_mach_host_self, HOST_BASIC_INFO, (host_info_t)(&host_basic_info), &count)) == KERN_SUCCESS ) |
| 74 | { |
| 75 | processors = host_basic_info.avail_cpus; |
| 76 | } |
| 77 | mach_port_deallocate(mach_task_self(), my_mach_host_self); |
| 78 | 78 | |
| 79 | | return processors; |
| 79 | return processors; |
| 80 | 80 | } |
| 81 | 81 | |
| 82 | 82 | //============================================================ |
| r243189 | r243190 | |
| 86 | 86 | void *osd_malloc(size_t size) |
| 87 | 87 | { |
| 88 | 88 | #ifndef MALLOC_DEBUG |
| 89 | | return malloc(size); |
| 89 | return malloc(size); |
| 90 | 90 | #else |
| 91 | 91 | #error "MALLOC_DEBUG not yet supported" |
| 92 | 92 | #endif |
| r243189 | r243190 | |
| 100 | 100 | void *osd_malloc_array(size_t size) |
| 101 | 101 | { |
| 102 | 102 | #ifndef MALLOC_DEBUG |
| 103 | | return malloc(size); |
| 103 | return malloc(size); |
| 104 | 104 | #else |
| 105 | 105 | #error "MALLOC_DEBUG not yet supported" |
| 106 | 106 | #endif |
| r243189 | r243190 | |
| 114 | 114 | void osd_free(void *ptr) |
| 115 | 115 | { |
| 116 | 116 | #ifndef MALLOC_DEBUG |
| 117 | | free(ptr); |
| 117 | free(ptr); |
| 118 | 118 | #else |
| 119 | 119 | #error "MALLOC_DEBUG not yet supported" |
| 120 | 120 | #endif |
| r243189 | r243190 | |
| 131 | 131 | void *osd_alloc_executable(size_t size) |
| 132 | 132 | { |
| 133 | 133 | #if defined(SDLMAME_BSD) || defined(SDLMAME_MACOSX) |
| 134 | | return (void *)mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); |
| 134 | return (void *)mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); |
| 135 | 135 | #elif defined(SDLMAME_UNIX) |
| 136 | | return (void *)mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, 0, 0); |
| 136 | return (void *)mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, 0, 0); |
| 137 | 137 | #endif |
| 138 | 138 | } |
| 139 | 139 | |
| r243189 | r243190 | |
| 146 | 146 | void osd_free_executable(void *ptr, size_t size) |
| 147 | 147 | { |
| 148 | 148 | #ifdef SDLMAME_SOLARIS |
| 149 | | munmap((char *)ptr, size); |
| 149 | munmap((char *)ptr, size); |
| 150 | 150 | #else |
| 151 | | munmap(ptr, size); |
| 151 | munmap(ptr, size); |
| 152 | 152 | #endif |
| 153 | 153 | } |
| 154 | 154 | |
| r243189 | r243190 | |
| 158 | 158 | |
| 159 | 159 | void osd_break_into_debugger(const char *message) |
| 160 | 160 | { |
| 161 | | #ifdef MAME_DEBUG |
| 162 | | printf("MAME exception: %s\n", message); |
| 163 | | printf("Attempting to fall into debugger\n"); |
| 164 | | kill(getpid(), SIGTRAP); |
| 165 | | #else |
| 166 | | printf("Ignoring MAME exception: %s\n", message); |
| 167 | | #endif |
| 161 | #ifdef MAME_DEBUG |
| 162 | printf("MAME exception: %s\n", message); |
| 163 | printf("Attempting to fall into debugger\n"); |
| 164 | kill(getpid(), SIGTRAP); |
| 165 | #else |
| 166 | printf("Ignoring MAME exception: %s\n", message); |
| 167 | #endif |
| 168 | 168 | } |
| 169 | 169 | |
| 170 | 170 | |
| r243189 | r243190 | |
| 191 | 191 | |
| 192 | 192 | static osd_ticks_t init_cycle_counter(void) |
| 193 | 193 | { |
| 194 | | osd_ticks_t start, end; |
| 195 | | osd_ticks_t a, b; |
| 194 | osd_ticks_t start, end; |
| 195 | osd_ticks_t a, b; |
| 196 | 196 | |
| 197 | | cycle_counter = mach_cycle_counter; |
| 198 | | ticks_counter = mach_cycle_counter; |
| 197 | cycle_counter = mach_cycle_counter; |
| 198 | ticks_counter = mach_cycle_counter; |
| 199 | 199 | |
| 200 | | // wait for an edge on the timeGetTime call |
| 201 | | a = SDL_GetTicks(); |
| 202 | | do |
| 203 | | { |
| 204 | | b = SDL_GetTicks(); |
| 205 | | } while (a == b); |
| 200 | // wait for an edge on the timeGetTime call |
| 201 | a = SDL_GetTicks(); |
| 202 | do |
| 203 | { |
| 204 | b = SDL_GetTicks(); |
| 205 | } while (a == b); |
| 206 | 206 | |
| 207 | | // get the starting cycle count |
| 208 | | start = (*cycle_counter)(); |
| 207 | // get the starting cycle count |
| 208 | start = (*cycle_counter)(); |
| 209 | 209 | |
| 210 | | // now wait for 1/4 second total |
| 211 | | do |
| 212 | | { |
| 213 | | a = SDL_GetTicks(); |
| 214 | | } while (a - b < 250); |
| 210 | // now wait for 1/4 second total |
| 211 | do |
| 212 | { |
| 213 | a = SDL_GetTicks(); |
| 214 | } while (a - b < 250); |
| 215 | 215 | |
| 216 | | // get the ending cycle count |
| 217 | | end = (*cycle_counter)(); |
| 216 | // get the ending cycle count |
| 217 | end = (*cycle_counter)(); |
| 218 | 218 | |
| 219 | | // compute ticks_per_sec |
| 220 | | ticks_per_second = (end - start) * 4; |
| 219 | // compute ticks_per_sec |
| 220 | ticks_per_second = (end - start) * 4; |
| 221 | 221 | |
| 222 | | // return the current cycle count |
| 223 | | return (*cycle_counter)(); |
| 222 | // return the current cycle count |
| 223 | return (*cycle_counter)(); |
| 224 | 224 | } |
| 225 | 225 | |
| 226 | 226 | //============================================================ |
| r243189 | r243190 | |
| 232 | 232 | //============================================================ |
| 233 | 233 | static osd_ticks_t mach_cycle_counter(void) |
| 234 | 234 | { |
| 235 | | return mach_absolute_time(); |
| 235 | return mach_absolute_time(); |
| 236 | 236 | } |
| 237 | 237 | |
| 238 | 238 | //============================================================ |
| r243189 | r243190 | |
| 241 | 241 | |
| 242 | 242 | osd_ticks_t osd_ticks(void) |
| 243 | 243 | { |
| 244 | | return (*cycle_counter)(); |
| 244 | return (*cycle_counter)(); |
| 245 | 245 | } |
| 246 | 246 | |
| 247 | 247 | |
| r243189 | r243190 | |
| 251 | 251 | |
| 252 | 252 | osd_ticks_t osd_ticks_per_second(void) |
| 253 | 253 | { |
| 254 | | if (ticks_per_second == 0) |
| 255 | | { |
| 256 | | // if we haven't computed the value yet, there's no time like the present |
| 257 | | init_cycle_counter(); |
| 258 | | } |
| 259 | | return ticks_per_second; |
| 254 | if (ticks_per_second == 0) |
| 255 | { |
| 256 | // if we haven't computed the value yet, there's no time like the present |
| 257 | init_cycle_counter(); |
| 258 | } |
| 259 | return ticks_per_second; |
| 260 | 260 | } |
| 261 | 261 | |
| 262 | 262 | |
| r243189 | r243190 | |
| 267 | 267 | |
| 268 | 268 | void osd_sleep(osd_ticks_t duration) |
| 269 | 269 | { |
| 270 | | UINT32 msec; |
| 270 | UINT32 msec; |
| 271 | 271 | |
| 272 | | // make sure we've computed ticks_per_second |
| 273 | | if (ticks_per_second == 0) |
| 274 | | (void)osd_ticks(); |
| 272 | // make sure we've computed ticks_per_second |
| 273 | if (ticks_per_second == 0) |
| 274 | (void)osd_ticks(); |
| 275 | 275 | |
| 276 | | // convert to milliseconds, rounding down |
| 277 | | msec = (UINT32)(duration * 1000 / ticks_per_second); |
| 276 | // convert to milliseconds, rounding down |
| 277 | msec = (UINT32)(duration * 1000 / ticks_per_second); |
| 278 | 278 | |
| 279 | | // only sleep if at least 2 full milliseconds |
| 280 | | if (msec >= 2) |
| 281 | | { |
| 282 | | // take a couple of msecs off the top for good measure |
| 283 | | msec -= 2; |
| 284 | | usleep(msec*1000); |
| 285 | | } |
| 279 | // only sleep if at least 2 full milliseconds |
| 280 | if (msec >= 2) |
| 281 | { |
| 282 | // take a couple of msecs off the top for good measure |
| 283 | msec -= 2; |
| 284 | usleep(msec*1000); |
| 285 | } |
| 286 | 286 | } |
trunk/src/osd/modules/lib/osdlib_os2.c
| r243189 | r243190 | |
| 31 | 31 | |
| 32 | 32 | const char *osd_getenv(const char *name) |
| 33 | 33 | { |
| 34 | | return getenv(name); |
| 34 | return getenv(name); |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | 37 | //============================================================ |
| r243189 | r243190 | |
| 40 | 40 | |
| 41 | 41 | int osd_setenv(const char *name, const char *value, int overwrite) |
| 42 | 42 | { |
| 43 | | return setenv(name, value, overwrite); |
| 43 | return setenv(name, value, overwrite); |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | 46 | //============================================================ |
| r243189 | r243190 | |
| 49 | 49 | |
| 50 | 50 | void osd_process_kill(void) |
| 51 | 51 | { |
| 52 | | fprintf(stderr,"osd_process_kill missing in OS/2 build\n"); |
| 52 | fprintf(stderr,"osd_process_kill missing in OS/2 build\n"); |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | 55 | //============================================================ |
| r243189 | r243190 | |
| 58 | 58 | |
| 59 | 59 | int osd_get_num_processors(void) |
| 60 | 60 | { |
| 61 | | ULONG numprocs = 1; |
| 61 | ULONG numprocs = 1; |
| 62 | 62 | |
| 63 | | DosQuerySysInfo(QSV_NUMPROCESSORS, QSV_NUMPROCESSORS, &numprocs, sizeof(numprocs)); |
| 63 | DosQuerySysInfo(QSV_NUMPROCESSORS, QSV_NUMPROCESSORS, &numprocs, sizeof(numprocs)); |
| 64 | 64 | |
| 65 | | return numprocs; |
| 65 | return numprocs; |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | 68 | //============================================================ |
| r243189 | r243190 | |
| 72 | 72 | void *osd_malloc(size_t size) |
| 73 | 73 | { |
| 74 | 74 | #ifndef MALLOC_DEBUG |
| 75 | | return malloc(size); |
| 75 | return malloc(size); |
| 76 | 76 | #else |
| 77 | 77 | #error "MALLOC_DEBUG not yet supported" |
| 78 | 78 | #endif |
| r243189 | r243190 | |
| 86 | 86 | void *osd_malloc_array(size_t size) |
| 87 | 87 | { |
| 88 | 88 | #ifndef MALLOC_DEBUG |
| 89 | | return malloc(size); |
| 89 | return malloc(size); |
| 90 | 90 | #else |
| 91 | 91 | #error "MALLOC_DEBUG not yet supported" |
| 92 | 92 | #endif |
| r243189 | r243190 | |
| 100 | 100 | void osd_free(void *ptr) |
| 101 | 101 | { |
| 102 | 102 | #ifndef MALLOC_DEBUG |
| 103 | | free(ptr); |
| 103 | free(ptr); |
| 104 | 104 | #else |
| 105 | 105 | #error "MALLOC_DEBUG not yet supported" |
| 106 | 106 | #endif |
| r243189 | r243190 | |
| 116 | 116 | |
| 117 | 117 | void *osd_alloc_executable(size_t size) |
| 118 | 118 | { |
| 119 | | void *p; |
| 119 | void *p; |
| 120 | 120 | |
| 121 | | DosAllocMem( &p, size, fALLOC ); |
| 122 | | return p; |
| 121 | DosAllocMem( &p, size, fALLOC ); |
| 122 | return p; |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | 125 | //============================================================ |
| r243189 | r243190 | |
| 130 | 130 | |
| 131 | 131 | void osd_free_executable(void *ptr, size_t size) |
| 132 | 132 | { |
| 133 | | DosFreeMem( ptr ); |
| 133 | DosFreeMem( ptr ); |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | 136 | //============================================================ |
| r243189 | r243190 | |
| 139 | 139 | |
| 140 | 140 | void osd_break_into_debugger(const char *message) |
| 141 | 141 | { |
| 142 | | printf("Ignoring MAME exception: %s\n", message); |
| 142 | printf("Ignoring MAME exception: %s\n", message); |
| 143 | 143 | } |
| 144 | 144 | |
| 145 | 145 | //============================================================ |
| r243189 | r243190 | |
| 167 | 167 | |
| 168 | 168 | static osd_ticks_t init_cycle_counter(void) |
| 169 | 169 | { |
| 170 | | osd_ticks_t start, end; |
| 171 | | osd_ticks_t a, b; |
| 170 | osd_ticks_t start, end; |
| 171 | osd_ticks_t a, b; |
| 172 | 172 | |
| 173 | | ULONG frequency; |
| 174 | | PTIB ptib; |
| 175 | | ULONG ulClass; |
| 176 | | ULONG ulDelta; |
| 173 | ULONG frequency; |
| 174 | PTIB ptib; |
| 175 | ULONG ulClass; |
| 176 | ULONG ulDelta; |
| 177 | 177 | |
| 178 | | DosGetInfoBlocks( &ptib, NULL ); |
| 179 | | ulClass = HIBYTE( ptib->tib_ptib2->tib2_ulpri ); |
| 180 | | ulDelta = LOBYTE( ptib->tib_ptib2->tib2_ulpri ); |
| 178 | DosGetInfoBlocks( &ptib, NULL ); |
| 179 | ulClass = HIBYTE( ptib->tib_ptib2->tib2_ulpri ); |
| 180 | ulDelta = LOBYTE( ptib->tib_ptib2->tib2_ulpri ); |
| 181 | 181 | |
| 182 | | if ( DosTmrQueryFreq( &frequency ) == 0 ) |
| 183 | | { |
| 184 | | // use performance counter if available as it is constant |
| 185 | | cycle_counter = performance_cycle_counter; |
| 186 | | ticks_counter = performance_cycle_counter; |
| 182 | if ( DosTmrQueryFreq( &frequency ) == 0 ) |
| 183 | { |
| 184 | // use performance counter if available as it is constant |
| 185 | cycle_counter = performance_cycle_counter; |
| 186 | ticks_counter = performance_cycle_counter; |
| 187 | 187 | |
| 188 | | ticks_per_second = frequency; |
| 188 | ticks_per_second = frequency; |
| 189 | 189 | |
| 190 | | // return the current cycle count |
| 191 | | return (*cycle_counter)(); |
| 192 | | } |
| 193 | | else |
| 194 | | { |
| 195 | | fprintf(stderr, "No Timer available!\n"); |
| 196 | | exit(-1); |
| 197 | | } |
| 190 | // return the current cycle count |
| 191 | return (*cycle_counter)(); |
| 192 | } |
| 193 | else |
| 194 | { |
| 195 | fprintf(stderr, "No Timer available!\n"); |
| 196 | exit(-1); |
| 197 | } |
| 198 | 198 | |
| 199 | | // temporarily set our priority higher |
| 200 | | DosSetPriority( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0 ); |
| 199 | // temporarily set our priority higher |
| 200 | DosSetPriority( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0 ); |
| 201 | 201 | |
| 202 | | // wait for an edge on the timeGetTime call |
| 203 | | a = SDL_GetTicks(); |
| 204 | | do |
| 205 | | { |
| 206 | | b = SDL_GetTicks(); |
| 207 | | } while (a == b); |
| 202 | // wait for an edge on the timeGetTime call |
| 203 | a = SDL_GetTicks(); |
| 204 | do |
| 205 | { |
| 206 | b = SDL_GetTicks(); |
| 207 | } while (a == b); |
| 208 | 208 | |
| 209 | | // get the starting cycle count |
| 210 | | start = (*cycle_counter)(); |
| 209 | // get the starting cycle count |
| 210 | start = (*cycle_counter)(); |
| 211 | 211 | |
| 212 | | // now wait for 1/4 second total |
| 213 | | do |
| 214 | | { |
| 215 | | a = SDL_GetTicks(); |
| 216 | | } while (a - b < 250); |
| 212 | // now wait for 1/4 second total |
| 213 | do |
| 214 | { |
| 215 | a = SDL_GetTicks(); |
| 216 | } while (a - b < 250); |
| 217 | 217 | |
| 218 | | // get the ending cycle count |
| 219 | | end = (*cycle_counter)(); |
| 218 | // get the ending cycle count |
| 219 | end = (*cycle_counter)(); |
| 220 | 220 | |
| 221 | | // compute ticks_per_sec |
| 222 | | ticks_per_second = (end - start) * 4; |
| 221 | // compute ticks_per_sec |
| 222 | ticks_per_second = (end - start) * 4; |
| 223 | 223 | |
| 224 | | // restore our priority |
| 225 | | DosSetPriority( PRTYS_THREAD, ulClass, ulDelta, 0 ); |
| 224 | // restore our priority |
| 225 | DosSetPriority( PRTYS_THREAD, ulClass, ulDelta, 0 ); |
| 226 | 226 | |
| 227 | | // return the current cycle count |
| 228 | | return (*cycle_counter)(); |
| 227 | // return the current cycle count |
| 228 | return (*cycle_counter)(); |
| 229 | 229 | } |
| 230 | 230 | |
| 231 | 231 | //============================================================ |
| r243189 | r243190 | |
| 234 | 234 | |
| 235 | 235 | static osd_ticks_t performance_cycle_counter(void) |
| 236 | 236 | { |
| 237 | | QWORD qwTime; |
| 237 | QWORD qwTime; |
| 238 | 238 | |
| 239 | | DosTmrQueryTime( &qwTime ); |
| 240 | | return (osd_ticks_t)qwTime.ulLo; |
| 239 | DosTmrQueryTime( &qwTime ); |
| 240 | return (osd_ticks_t)qwTime.ulLo; |
| 241 | 241 | } |
| 242 | 242 | |
| 243 | 243 | //============================================================ |
| r243189 | r243190 | |
| 246 | 246 | |
| 247 | 247 | osd_ticks_t osd_ticks(void) |
| 248 | 248 | { |
| 249 | | return (*cycle_counter)(); |
| 249 | return (*cycle_counter)(); |
| 250 | 250 | } |
| 251 | 251 | |
| 252 | 252 | |
| r243189 | r243190 | |
| 256 | 256 | |
| 257 | 257 | osd_ticks_t osd_ticks_per_second(void) |
| 258 | 258 | { |
| 259 | | if (ticks_per_second == 0) |
| 260 | | { |
| 261 | | // if we haven't computed the value yet, there's no time like the present |
| 262 | | init_cycle_counter(); |
| 263 | | } |
| 264 | | return ticks_per_second; |
| 259 | if (ticks_per_second == 0) |
| 260 | { |
| 261 | // if we haven't computed the value yet, there's no time like the present |
| 262 | init_cycle_counter(); |
| 263 | } |
| 264 | return ticks_per_second; |
| 265 | 265 | } |
| 266 | 266 | |
| 267 | 267 | |
| r243189 | r243190 | |
| 271 | 271 | |
| 272 | 272 | void osd_sleep(osd_ticks_t duration) |
| 273 | 273 | { |
| 274 | | UINT32 msec; |
| 274 | UINT32 msec; |
| 275 | 275 | |
| 276 | | // make sure we've computed ticks_per_second |
| 277 | | if (ticks_per_second == 0) |
| 278 | | (void)osd_ticks(); |
| 276 | // make sure we've computed ticks_per_second |
| 277 | if (ticks_per_second == 0) |
| 278 | (void)osd_ticks(); |
| 279 | 279 | |
| 280 | | // convert to milliseconds, rounding down |
| 281 | | msec = (UINT32)(duration * 1000 / ticks_per_second); |
| 280 | // convert to milliseconds, rounding down |
| 281 | msec = (UINT32)(duration * 1000 / ticks_per_second); |
| 282 | 282 | |
| 283 | | // only sleep if at least 2 full milliseconds |
| 284 | | if (msec >= 2) |
| 285 | | { |
| 286 | | // take a couple of msecs off the top for good measure |
| 287 | | msec -= 2; |
| 288 | | usleep(msec*1000); |
| 289 | | } |
| 283 | // only sleep if at least 2 full milliseconds |
| 284 | if (msec >= 2) |
| 285 | { |
| 286 | // take a couple of msecs off the top for good measure |
| 287 | msec -= 2; |
| 288 | usleep(msec*1000); |
| 289 | } |
| 290 | 290 | } |
| 291 | | |
trunk/src/osd/modules/lib/osdlib_win32.c
| r243189 | r243190 | |
| 53 | 53 | |
| 54 | 54 | const char *osd_getenv(const char *name) |
| 55 | 55 | { |
| 56 | | return getenv(name); |
| 56 | return getenv(name); |
| 57 | 57 | } |
| 58 | 58 | |
| 59 | 59 | |
| r243189 | r243190 | |
| 63 | 63 | |
| 64 | 64 | int osd_setenv(const char *name, const char *value, int overwrite) |
| 65 | 65 | { |
| 66 | | char *buf; |
| 67 | | int result; |
| 66 | char *buf; |
| 67 | int result; |
| 68 | 68 | |
| 69 | | if (!overwrite) |
| 70 | | { |
| 71 | | if (osd_getenv(name) != NULL) |
| 72 | | return 0; |
| 73 | | } |
| 74 | | buf = (char *) osd_malloc_array(strlen(name)+strlen(value)+2); |
| 75 | | sprintf(buf, "%s=%s", name, value); |
| 76 | | result = putenv(buf); |
| 69 | if (!overwrite) |
| 70 | { |
| 71 | if (osd_getenv(name) != NULL) |
| 72 | return 0; |
| 73 | } |
| 74 | buf = (char *) osd_malloc_array(strlen(name)+strlen(value)+2); |
| 75 | sprintf(buf, "%s=%s", name, value); |
| 76 | result = putenv(buf); |
| 77 | 77 | |
| 78 | | /* will be referenced by environment |
| 79 | | * Therefore it is not freed here |
| 80 | | */ |
| 78 | /* will be referenced by environment |
| 79 | * Therefore it is not freed here |
| 80 | */ |
| 81 | 81 | |
| 82 | | return result; |
| 82 | return result; |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | 85 | //============================================================ |
| r243189 | r243190 | |
| 88 | 88 | |
| 89 | 89 | void osd_process_kill(void) |
| 90 | 90 | { |
| 91 | | TerminateProcess(GetCurrentProcess(), -1); |
| 91 | TerminateProcess(GetCurrentProcess(), -1); |
| 92 | 92 | } |
| 93 | 93 | |
| 94 | 94 | //============================================================ |
| r243189 | r243190 | |
| 97 | 97 | |
| 98 | 98 | int osd_get_num_processors(void) |
| 99 | 99 | { |
| 100 | | SYSTEM_INFO info; |
| 100 | SYSTEM_INFO info; |
| 101 | 101 | |
| 102 | | // otherwise, fetch the info from the system |
| 103 | | GetSystemInfo(&info); |
| 102 | // otherwise, fetch the info from the system |
| 103 | GetSystemInfo(&info); |
| 104 | 104 | |
| 105 | | // max out at 4 for now since scaling above that seems to do poorly |
| 106 | | return MIN(info.dwNumberOfProcessors, 4); |
| 105 | // max out at 4 for now since scaling above that seems to do poorly |
| 106 | return MIN(info.dwNumberOfProcessors, 4); |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | 109 | //============================================================ |
| r243189 | r243190 | |
| 113 | 113 | void *osd_malloc(size_t size) |
| 114 | 114 | { |
| 115 | 115 | #ifndef MALLOC_DEBUG |
| 116 | | return HeapAlloc(GetProcessHeap(), 0, size); |
| 116 | return HeapAlloc(GetProcessHeap(), 0, size); |
| 117 | 117 | #else |
| 118 | | // add in space for the size |
| 119 | | size += sizeof(size_t); |
| 118 | // add in space for the size |
| 119 | size += sizeof(size_t); |
| 120 | 120 | |
| 121 | | // basic objects just come from the heap |
| 122 | | void *result = HeapAlloc(GetProcessHeap(), 0, size); |
| 121 | // basic objects just come from the heap |
| 122 | void *result = HeapAlloc(GetProcessHeap(), 0, size); |
| 123 | 123 | |
| 124 | | // store the size and return and pointer to the data afterward |
| 125 | | *reinterpret_cast<size_t *>(result) = size; |
| 126 | | return reinterpret_cast<UINT8 *>(result) + sizeof(size_t); |
| 124 | // store the size and return and pointer to the data afterward |
| 125 | *reinterpret_cast<size_t *>(result) = size; |
| 126 | return reinterpret_cast<UINT8 *>(result) + sizeof(size_t); |
| 127 | 127 | #endif |
| 128 | 128 | } |
| 129 | 129 | |
| r243189 | r243190 | |
| 135 | 135 | void *osd_malloc_array(size_t size) |
| 136 | 136 | { |
| 137 | 137 | #ifndef MALLOC_DEBUG |
| 138 | | return HeapAlloc(GetProcessHeap(), 0, size); |
| 138 | return HeapAlloc(GetProcessHeap(), 0, size); |
| 139 | 139 | #else |
| 140 | | // add in space for the size |
| 141 | | size += sizeof(size_t); |
| 140 | // add in space for the size |
| 141 | size += sizeof(size_t); |
| 142 | 142 | |
| 143 | | // round the size up to a page boundary |
| 144 | | size_t rounded_size = ((size + sizeof(void *) + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; |
| 143 | // round the size up to a page boundary |
| 144 | size_t rounded_size = ((size + sizeof(void *) + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; |
| 145 | 145 | |
| 146 | | // reserve that much memory, plus two guard pages |
| 147 | | void *page_base = VirtualAlloc(NULL, rounded_size + 2 * PAGE_SIZE, MEM_RESERVE, PAGE_NOACCESS); |
| 148 | | if (page_base == NULL) |
| 149 | | return NULL; |
| 146 | // reserve that much memory, plus two guard pages |
| 147 | void *page_base = VirtualAlloc(NULL, rounded_size + 2 * PAGE_SIZE, MEM_RESERVE, PAGE_NOACCESS); |
| 148 | if (page_base == NULL) |
| 149 | return NULL; |
| 150 | 150 | |
| 151 | | // now allow access to everything but the first and last pages |
| 152 | | page_base = VirtualAlloc(reinterpret_cast<UINT8 *>(page_base) + PAGE_SIZE, rounded_size, MEM_COMMIT, PAGE_READWRITE); |
| 153 | | if (page_base == NULL) |
| 154 | | return NULL; |
| 151 | // now allow access to everything but the first and last pages |
| 152 | page_base = VirtualAlloc(reinterpret_cast<UINT8 *>(page_base) + PAGE_SIZE, rounded_size, MEM_COMMIT, PAGE_READWRITE); |
| 153 | if (page_base == NULL) |
| 154 | return NULL; |
| 155 | 155 | |
| 156 | | // work backwards from the page base to get to the block base |
| 157 | | void *result = GUARD_ALIGN_START ? page_base : (reinterpret_cast<UINT8 *>(page_base) + rounded_size - size); |
| 156 | // work backwards from the page base to get to the block base |
| 157 | void *result = GUARD_ALIGN_START ? page_base : (reinterpret_cast<UINT8 *>(page_base) + rounded_size - size); |
| 158 | 158 | |
| 159 | | // store the size at the start with a flag indicating it has a guard page |
| 160 | | *reinterpret_cast<size_t *>(result) = size | 0x80000000; |
| 161 | | return reinterpret_cast<UINT8 *>(result) + sizeof(size_t); |
| 159 | // store the size at the start with a flag indicating it has a guard page |
| 160 | *reinterpret_cast<size_t *>(result) = size | 0x80000000; |
| 161 | return reinterpret_cast<UINT8 *>(result) + sizeof(size_t); |
| 162 | 162 | #endif |
| 163 | 163 | } |
| 164 | 164 | |
| r243189 | r243190 | |
| 170 | 170 | void osd_free(void *ptr) |
| 171 | 171 | { |
| 172 | 172 | #ifndef MALLOC_DEBUG |
| 173 | | HeapFree(GetProcessHeap(), 0, ptr); |
| 173 | HeapFree(GetProcessHeap(), 0, ptr); |
| 174 | 174 | #else |
| 175 | | size_t size = reinterpret_cast<size_t *>(ptr)[-1]; |
| 175 | size_t size = reinterpret_cast<size_t *>(ptr)[-1]; |
| 176 | 176 | |
| 177 | | // if no guard page, just free the pointer |
| 178 | | if ((size & 0x80000000) == 0) |
| 179 | | HeapFree(GetProcessHeap(), 0, reinterpret_cast<UINT8 *>(ptr) - sizeof(size_t)); |
| 177 | // if no guard page, just free the pointer |
| 178 | if ((size & 0x80000000) == 0) |
| 179 | HeapFree(GetProcessHeap(), 0, reinterpret_cast<UINT8 *>(ptr) - sizeof(size_t)); |
| 180 | 180 | |
| 181 | | // large items need more care |
| 182 | | else |
| 183 | | { |
| 184 | | ULONG_PTR page_base = (reinterpret_cast<ULONG_PTR>(ptr) - sizeof(size_t)) & ~(PAGE_SIZE - 1); |
| 185 | | VirtualFree(reinterpret_cast<void *>(page_base - PAGE_SIZE), 0, MEM_RELEASE); |
| 186 | | } |
| 181 | // large items need more care |
| 182 | else |
| 183 | { |
| 184 | ULONG_PTR page_base = (reinterpret_cast<ULONG_PTR>(ptr) - sizeof(size_t)) & ~(PAGE_SIZE - 1); |
| 185 | VirtualFree(reinterpret_cast<void *>(page_base - PAGE_SIZE), 0, MEM_RELEASE); |
| 186 | } |
| 187 | 187 | #endif |
| 188 | 188 | } |
| 189 | 189 | |
| r243189 | r243190 | |
| 197 | 197 | |
| 198 | 198 | void *osd_alloc_executable(size_t size) |
| 199 | 199 | { |
| 200 | | return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); |
| 200 | return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); |
| 201 | 201 | } |
| 202 | 202 | |
| 203 | 203 | |
| r243189 | r243190 | |
| 209 | 209 | |
| 210 | 210 | void osd_free_executable(void *ptr, size_t size) |
| 211 | 211 | { |
| 212 | | VirtualFree(ptr, 0, MEM_RELEASE); |
| 212 | VirtualFree(ptr, 0, MEM_RELEASE); |
| 213 | 213 | } |
| 214 | 214 | |
| 215 | 215 | |
| r243189 | r243190 | |
| 220 | 220 | void osd_break_into_debugger(const char *message) |
| 221 | 221 | { |
| 222 | 222 | #ifdef OSD_WINDOWS |
| 223 | | if (IsDebuggerPresent()) |
| 224 | | { |
| 225 | | win_output_debug_string_utf8(message); |
| 226 | | DebugBreak(); |
| 227 | | } |
| 228 | | else if (s_debugger_stack_crawler != NULL) |
| 229 | | (*s_debugger_stack_crawler)(); |
| 223 | if (IsDebuggerPresent()) |
| 224 | { |
| 225 | win_output_debug_string_utf8(message); |
| 226 | DebugBreak(); |
| 227 | } |
| 228 | else if (s_debugger_stack_crawler != NULL) |
| 229 | (*s_debugger_stack_crawler)(); |
| 230 | 230 | #else |
| 231 | | if (IsDebuggerPresent()) |
| 232 | | { |
| 233 | | OutputDebugStringA(message); |
| 234 | | DebugBreak(); |
| 235 | | } |
| 231 | if (IsDebuggerPresent()) |
| 232 | { |
| 233 | OutputDebugStringA(message); |
| 234 | DebugBreak(); |
| 235 | } |
| 236 | 236 | #endif |
| 237 | 237 | } |
| 238 | 238 | |
| r243189 | r243190 | |
| 252 | 252 | |
| 253 | 253 | osd_ticks_t osd_ticks(void) |
| 254 | 254 | { |
| 255 | | LARGE_INTEGER performance_count; |
| 255 | LARGE_INTEGER performance_count; |
| 256 | 256 | |
| 257 | | // if we're suspended, just return that |
| 258 | | if (suspend_ticks != 0) |
| 259 | | return suspend_ticks; |
| 257 | // if we're suspended, just return that |
| 258 | if (suspend_ticks != 0) |
| 259 | return suspend_ticks; |
| 260 | 260 | |
| 261 | | // if we have a per second count, just go for it |
| 262 | | if (ticks_per_second != 0) |
| 263 | | { |
| 264 | | // QueryPerformanceCounter if we can |
| 265 | | if (using_qpc) |
| 266 | | { |
| 267 | | QueryPerformanceCounter(&performance_count); |
| 268 | | return (osd_ticks_t)performance_count.QuadPart - suspend_ticks; |
| 269 | | } |
| 261 | // if we have a per second count, just go for it |
| 262 | if (ticks_per_second != 0) |
| 263 | { |
| 264 | // QueryPerformanceCounter if we can |
| 265 | if (using_qpc) |
| 266 | { |
| 267 | QueryPerformanceCounter(&performance_count); |
| 268 | return (osd_ticks_t)performance_count.QuadPart - suspend_ticks; |
| 269 | } |
| 270 | 270 | |
| 271 | | // otherwise, fall back to timeGetTime |
| 272 | | else |
| 273 | | return (osd_ticks_t)timeGetTime() - suspend_ticks; |
| 274 | | } |
| 271 | // otherwise, fall back to timeGetTime |
| 272 | else |
| 273 | return (osd_ticks_t)timeGetTime() - suspend_ticks; |
| 274 | } |
| 275 | 275 | |
| 276 | | // if not, we have to determine it |
| 277 | | using_qpc = QueryPerformanceFrequency(&performance_count) && (performance_count.QuadPart != 0); |
| 278 | | if (using_qpc) |
| 279 | | ticks_per_second = (osd_ticks_t)performance_count.QuadPart; |
| 280 | | else |
| 281 | | ticks_per_second = 1000; |
| 276 | // if not, we have to determine it |
| 277 | using_qpc = QueryPerformanceFrequency(&performance_count) && (performance_count.QuadPart != 0); |
| 278 | if (using_qpc) |
| 279 | ticks_per_second = (osd_ticks_t)performance_count.QuadPart; |
| 280 | else |
| 281 | ticks_per_second = 1000; |
| 282 | 282 | |
| 283 | | // call ourselves to get the first value |
| 284 | | return osd_ticks(); |
| 283 | // call ourselves to get the first value |
| 284 | return osd_ticks(); |
| 285 | 285 | } |
| 286 | 286 | |
| 287 | 287 | |
| r243189 | r243190 | |
| 291 | 291 | |
| 292 | 292 | osd_ticks_t osd_ticks_per_second(void) |
| 293 | 293 | { |
| 294 | | if (ticks_per_second == 0) |
| 295 | | osd_ticks(); |
| 296 | | return ticks_per_second; |
| 294 | if (ticks_per_second == 0) |
| 295 | osd_ticks(); |
| 296 | return ticks_per_second; |
| 297 | 297 | } |
| 298 | 298 | |
| 299 | 299 | //============================================================ |
| r243189 | r243190 | |
| 302 | 302 | |
| 303 | 303 | void osd_sleep(osd_ticks_t duration) |
| 304 | 304 | { |
| 305 | | DWORD msec; |
| 305 | DWORD msec; |
| 306 | 306 | |
| 307 | | // make sure we've computed ticks_per_second |
| 308 | | if (ticks_per_second == 0) |
| 309 | | (void)osd_ticks(); |
| 307 | // make sure we've computed ticks_per_second |
| 308 | if (ticks_per_second == 0) |
| 309 | (void)osd_ticks(); |
| 310 | 310 | |
| 311 | | // convert to milliseconds, rounding down |
| 312 | | msec = (DWORD)(duration * 1000 / ticks_per_second); |
| 311 | // convert to milliseconds, rounding down |
| 312 | msec = (DWORD)(duration * 1000 / ticks_per_second); |
| 313 | 313 | |
| 314 | | // only sleep if at least 2 full milliseconds |
| 315 | | if (msec >= 2) |
| 316 | | { |
| 317 | | HANDLE current_thread = GetCurrentThread(); |
| 318 | | int old_priority = GetThreadPriority(current_thread); |
| 314 | // only sleep if at least 2 full milliseconds |
| 315 | if (msec >= 2) |
| 316 | { |
| 317 | HANDLE current_thread = GetCurrentThread(); |
| 318 | int old_priority = GetThreadPriority(current_thread); |
| 319 | 319 | |
| 320 | | // take a couple of msecs off the top for good measure |
| 321 | | msec -= 2; |
| 320 | // take a couple of msecs off the top for good measure |
| 321 | msec -= 2; |
| 322 | 322 | |
| 323 | | // bump our thread priority super high so that we get |
| 324 | | // priority when we need it |
| 325 | | SetThreadPriority(current_thread, THREAD_PRIORITY_TIME_CRITICAL); |
| 326 | | Sleep(msec); |
| 327 | | SetThreadPriority(current_thread, old_priority); |
| 328 | | } |
| 323 | // bump our thread priority super high so that we get |
| 324 | // priority when we need it |
| 325 | SetThreadPriority(current_thread, THREAD_PRIORITY_TIME_CRITICAL); |
| 326 | Sleep(msec); |
| 327 | SetThreadPriority(current_thread, old_priority); |
| 328 | } |
| 329 | 329 | } |
trunk/src/osd/modules/lib/osdobj_common.c
| r243189 | r243190 | |
| 17 | 17 | |
| 18 | 18 | const options_entry osd_options::s_option_entries[] = |
| 19 | 19 | { |
| 20 | | { NULL, NULL, OPTION_HEADER, "OSD FONT OPTIONS" }, |
| 21 | | { OSD_FONT_PROVIDER, "auto", OPTION_STRING, "provider for ui font: " }, |
| 20 | { NULL, NULL, OPTION_HEADER, "OSD FONT OPTIONS" }, |
| 21 | { OSD_FONT_PROVIDER, "auto", OPTION_STRING, "provider for ui font: " }, |
| 22 | 22 | |
| 23 | | { NULL, NULL, OPTION_HEADER, "OSD CLI OPTIONS" }, |
| 24 | | { OSDCOMMAND_LIST_MIDI_DEVICES ";mlist", "0", OPTION_COMMAND, "list available MIDI I/O devices" }, |
| 25 | | { OSDCOMMAND_LIST_NETWORK_ADAPTERS ";nlist", "0", OPTION_COMMAND, "list available network adapters" }, |
| 23 | { NULL, NULL, OPTION_HEADER, "OSD CLI OPTIONS" }, |
| 24 | { OSDCOMMAND_LIST_MIDI_DEVICES ";mlist", "0", OPTION_COMMAND, "list available MIDI I/O devices" }, |
| 25 | { OSDCOMMAND_LIST_NETWORK_ADAPTERS ";nlist", "0", OPTION_COMMAND, "list available network adapters" }, |
| 26 | 26 | |
| 27 | | // debugging options |
| 28 | | { NULL, NULL, OPTION_HEADER, "OSD DEBUGGING OPTIONS" }, |
| 29 | | { OSDOPTION_DEBUGGER, OSDOPTVAL_AUTO, OPTION_STRING, "debugger used : " }, |
| 30 | | { OSDOPTION_WATCHDOG ";wdog", "0", OPTION_INTEGER, "force the program to terminate if no updates within specified number of seconds" }, |
| 27 | // debugging options |
| 28 | { NULL, NULL, OPTION_HEADER, "OSD DEBUGGING OPTIONS" }, |
| 29 | { OSDOPTION_DEBUGGER, OSDOPTVAL_AUTO, OPTION_STRING, "debugger used : " }, |
| 30 | { OSDOPTION_WATCHDOG ";wdog", "0", OPTION_INTEGER, "force the program to terminate if no updates within specified number of seconds" }, |
| 31 | 31 | |
| 32 | | // performance options |
| 33 | | { NULL, NULL, OPTION_HEADER, "OSD PERFORMANCE OPTIONS" }, |
| 34 | | { OSDOPTION_MULTITHREADING ";mt", "0", OPTION_BOOLEAN, "enable multithreading; this enables rendering and blitting on a separate thread" }, |
| 35 | | { OSDOPTION_NUMPROCESSORS ";np", OSDOPTVAL_AUTO, OPTION_STRING, "number of processors; this overrides the number the system reports" }, |
| 36 | | { OSDOPTION_BENCH, "0", OPTION_INTEGER, "benchmark for the given number of emulated seconds; implies -video none -sound none -nothrottle" }, |
| 37 | | // video options |
| 38 | | { NULL, NULL, OPTION_HEADER, "OSD VIDEO OPTIONS" }, |
| 32 | // performance options |
| 33 | { NULL, NULL, OPTION_HEADER, "OSD PERFORMANCE OPTIONS" }, |
| 34 | { OSDOPTION_MULTITHREADING ";mt", "0", OPTION_BOOLEAN, "enable multithreading; this enables rendering and blitting on a separate thread" }, |
| 35 | { OSDOPTION_NUMPROCESSORS ";np", OSDOPTVAL_AUTO, OPTION_STRING, "number of processors; this overrides the number the system reports" }, |
| 36 | { OSDOPTION_BENCH, "0", OPTION_INTEGER, "benchmark for the given number of emulated seconds; implies -video none -sound none -nothrottle" }, |
| 37 | // video options |
| 38 | { NULL, NULL, OPTION_HEADER, "OSD VIDEO OPTIONS" }, |
| 39 | 39 | // OS X can be trusted to have working hardware OpenGL, so default to it on for the best user experience |
| 40 | | { OSDOPTION_VIDEO, OSDOPTVAL_AUTO, OPTION_STRING, "video output method: " }, |
| 41 | | { OSDOPTION_NUMSCREENS "(1-4)", "1", OPTION_INTEGER, "number of screens to create; usually, you want just one" }, |
| 42 | | { OSDOPTION_WINDOW ";w", "0", OPTION_BOOLEAN, "enable window mode; otherwise, full screen mode is assumed" }, |
| 43 | | { OSDOPTION_MAXIMIZE ";max", "1", OPTION_BOOLEAN, "default to maximized windows; otherwise, windows will be minimized" }, |
| 44 | | { OSDOPTION_KEEPASPECT ";ka", "1", OPTION_BOOLEAN, "constrain to the proper aspect ratio" }, |
| 45 | | { OSDOPTION_UNEVENSTRETCH ";ues", "1", OPTION_BOOLEAN, "allow non-integer stretch factors" }, |
| 46 | | { OSDOPTION_WAITVSYNC ";vs", "0", OPTION_BOOLEAN, "enable waiting for the start of VBLANK before flipping screens; reduces tearing effects" }, |
| 47 | | { OSDOPTION_SYNCREFRESH ";srf", "0", OPTION_BOOLEAN, "enable using the start of VBLANK for throttling instead of the game time" }, |
| 40 | { OSDOPTION_VIDEO, OSDOPTVAL_AUTO, OPTION_STRING, "video output method: " }, |
| 41 | { OSDOPTION_NUMSCREENS "(1-4)", "1", OPTION_INTEGER, "number of screens to create; usually, you want just one" }, |
| 42 | { OSDOPTION_WINDOW ";w", "0", OPTION_BOOLEAN, "enable window mode; otherwise, full screen mode is assumed" }, |
| 43 | { OSDOPTION_MAXIMIZE ";max", "1", OPTION_BOOLEAN, "default to maximized windows; otherwise, windows will be minimized" }, |
| 44 | { OSDOPTION_KEEPASPECT ";ka", "1", OPTION_BOOLEAN, "constrain to the proper aspect ratio" }, |
| 45 | { OSDOPTION_UNEVENSTRETCH ";ues", "1", OPTION_BOOLEAN, "allow non-integer stretch factors" }, |
| 46 | { OSDOPTION_WAITVSYNC ";vs", "0", OPTION_BOOLEAN, "enable waiting for the start of VBLANK before flipping screens; reduces tearing effects" }, |
| 47 | { OSDOPTION_SYNCREFRESH ";srf", "0", OPTION_BOOLEAN, "enable using the start of VBLANK for throttling instead of the game time" }, |
| 48 | 48 | |
| 49 | | // per-window options |
| 50 | | { NULL, NULL, OPTION_HEADER, "OSD PER-WINDOW VIDEO OPTIONS" }, |
| 51 | | { OSDOPTION_SCREEN, OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" }, |
| 52 | | { OSDOPTION_ASPECT ";screen_aspect", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio for all screens; 'auto' here will try to make a best guess" }, |
| 53 | | { OSDOPTION_RESOLUTION ";r", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution for all screens; format is <width>x<height>[@<refreshrate>] or 'auto'" }, |
| 54 | | { OSDOPTION_VIEW, OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for all screens" }, |
| 49 | // per-window options |
| 50 | { NULL, NULL, OPTION_HEADER, "OSD PER-WINDOW VIDEO OPTIONS" }, |
| 51 | { OSDOPTION_SCREEN, OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" }, |
| 52 | { OSDOPTION_ASPECT ";screen_aspect", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio for all screens; 'auto' here will try to make a best guess" }, |
| 53 | { OSDOPTION_RESOLUTION ";r", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution for all screens; format is <width>x<height>[@<refreshrate>] or 'auto'" }, |
| 54 | { OSDOPTION_VIEW, OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for all screens" }, |
| 55 | 55 | |
| 56 | | { OSDOPTION_SCREEN "0", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" }, |
| 57 | | { OSDOPTION_ASPECT "0", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the first screen; 'auto' here will try to make a best guess" }, |
| 58 | | { OSDOPTION_RESOLUTION "0;r0", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the first screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, |
| 59 | | { OSDOPTION_VIEW "0", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the first screen" }, |
| 56 | { OSDOPTION_SCREEN "0", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" }, |
| 57 | { OSDOPTION_ASPECT "0", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the first screen; 'auto' here will try to make a best guess" }, |
| 58 | { OSDOPTION_RESOLUTION "0;r0", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the first screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, |
| 59 | { OSDOPTION_VIEW "0", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the first screen" }, |
| 60 | 60 | |
| 61 | | { OSDOPTION_SCREEN "1", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the second screen; 'auto' here will try to make a best guess" }, |
| 62 | | { OSDOPTION_ASPECT "1", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the second screen; 'auto' here will try to make a best guess" }, |
| 63 | | { OSDOPTION_RESOLUTION "1;r1", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the second screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, |
| 64 | | { OSDOPTION_VIEW "1", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the second screen" }, |
| 61 | { OSDOPTION_SCREEN "1", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the second screen; 'auto' here will try to make a best guess" }, |
| 62 | { OSDOPTION_ASPECT "1", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the second screen; 'auto' here will try to make a best guess" }, |
| 63 | { OSDOPTION_RESOLUTION "1;r1", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the second screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, |
| 64 | { OSDOPTION_VIEW "1", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the second screen" }, |
| 65 | 65 | |
| 66 | | { OSDOPTION_SCREEN "2", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the third screen; 'auto' here will try to make a best guess" }, |
| 67 | | { OSDOPTION_ASPECT "2", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the third screen; 'auto' here will try to make a best guess" }, |
| 68 | | { OSDOPTION_RESOLUTION "2;r2", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the third screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, |
| 69 | | { OSDOPTION_VIEW "2", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the third screen" }, |
| 66 | { OSDOPTION_SCREEN "2", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the third screen; 'auto' here will try to make a best guess" }, |
| 67 | { OSDOPTION_ASPECT "2", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the third screen; 'auto' here will try to make a best guess" }, |
| 68 | { OSDOPTION_RESOLUTION "2;r2", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the third screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, |
| 69 | { OSDOPTION_VIEW "2", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the third screen" }, |
| 70 | 70 | |
| 71 | | { OSDOPTION_SCREEN "3", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the fourth screen; 'auto' here will try to make a best guess" }, |
| 72 | | { OSDOPTION_ASPECT "3", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the fourth screen; 'auto' here will try to make a best guess" }, |
| 73 | | { OSDOPTION_RESOLUTION "3;r3", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the fourth screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, |
| 74 | | { OSDOPTION_VIEW "3", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the fourth screen" }, |
| 71 | { OSDOPTION_SCREEN "3", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the fourth screen; 'auto' here will try to make a best guess" }, |
| 72 | { OSDOPTION_ASPECT "3", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the fourth screen; 'auto' here will try to make a best guess" }, |
| 73 | { OSDOPTION_RESOLUTION "3;r3", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the fourth screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, |
| 74 | { OSDOPTION_VIEW "3", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the fourth screen" }, |
| 75 | 75 | |
| 76 | | // full screen options |
| 77 | | { NULL, NULL, OPTION_HEADER, "OSD FULL SCREEN OPTIONS" }, |
| 78 | | { OSDOPTION_SWITCHRES, "0", OPTION_BOOLEAN, "enable resolution switching" }, |
| 76 | // full screen options |
| 77 | { NULL, NULL, OPTION_HEADER, "OSD FULL SCREEN OPTIONS" }, |
| 78 | { OSDOPTION_SWITCHRES, "0", OPTION_BOOLEAN, "enable resolution switching" }, |
| 79 | 79 | |
| 80 | | // sound options |
| 81 | | { NULL, NULL, OPTION_HEADER, "OSD SOUND OPTIONS" }, |
| 82 | | { OSDOPTION_SOUND, OSDOPTVAL_AUTO, OPTION_STRING, "sound output method: " }, |
| 83 | | { OSDOPTION_AUDIO_LATENCY "(1-5)", "2", OPTION_INTEGER, "set audio latency (increase to reduce glitches, decrease for responsiveness)" }, |
| 80 | // sound options |
| 81 | { NULL, NULL, OPTION_HEADER, "OSD SOUND OPTIONS" }, |
| 82 | { OSDOPTION_SOUND, OSDOPTVAL_AUTO, OPTION_STRING, "sound output method: " }, |
| 83 | { OSDOPTION_AUDIO_LATENCY "(1-5)", "2", OPTION_INTEGER, "set audio latency (increase to reduce glitches, decrease for responsiveness)" }, |
| 84 | 84 | |
| 85 | | // End of list |
| 86 | | { NULL } |
| 85 | // End of list |
| 86 | { NULL } |
| 87 | 87 | }; |
| 88 | 88 | |
| 89 | 89 | osd_options::osd_options() |
| 90 | 90 | : cli_options() |
| 91 | 91 | { |
| 92 | | add_entries(osd_options::s_option_entries); |
| 92 | add_entries(osd_options::s_option_entries); |
| 93 | 93 | }; |
| 94 | 94 | |
| 95 | 95 | |
| r243189 | r243190 | |
| 99 | 99 | |
| 100 | 100 | osd_common_t::osd_common_t(osd_options &options) |
| 101 | 101 | : m_machine(NULL), |
| 102 | | m_options(options), |
| 103 | | m_sound(NULL), |
| 104 | | m_debugger(NULL) |
| 102 | m_options(options), |
| 103 | m_sound(NULL), |
| 104 | m_debugger(NULL) |
| 105 | 105 | |
| 106 | 106 | { |
| 107 | 107 | } |
| r243189 | r243190 | |
| 110 | 110 | |
| 111 | 111 | void osd_common_t::register_options() |
| 112 | 112 | { |
| 113 | REGISTER_MODULE(m_mod_man, FONT_OSX); |
| 114 | REGISTER_MODULE(m_mod_man, FONT_WINDOWS); |
| 115 | REGISTER_MODULE(m_mod_man, FONT_SDL); |
| 116 | REGISTER_MODULE(m_mod_man, FONT_NONE); |
| 113 | 117 | |
| 114 | | REGISTER_MODULE(m_mod_man, FONT_OSX); |
| 115 | | REGISTER_MODULE(m_mod_man, FONT_WINDOWS); |
| 116 | | REGISTER_MODULE(m_mod_man, FONT_SDL); |
| 117 | | REGISTER_MODULE(m_mod_man, FONT_NONE); |
| 118 | REGISTER_MODULE(m_mod_man, SOUND_DSOUND); |
| 119 | REGISTER_MODULE(m_mod_man, SOUND_JS); |
| 120 | REGISTER_MODULE(m_mod_man, SOUND_SDL); |
| 121 | REGISTER_MODULE(m_mod_man, SOUND_NONE); |
| 118 | 122 | |
| 119 | | REGISTER_MODULE(m_mod_man, SOUND_DSOUND); |
| 120 | | REGISTER_MODULE(m_mod_man, SOUND_JS); |
| 121 | | REGISTER_MODULE(m_mod_man, SOUND_SDL); |
| 122 | | REGISTER_MODULE(m_mod_man, SOUND_NONE); |
| 123 | | |
| 124 | 123 | #ifdef SDLMAME_MACOSX |
| 125 | | REGISTER_MODULE(m_mod_man, DEBUG_OSX); |
| 124 | REGISTER_MODULE(m_mod_man, DEBUG_OSX); |
| 126 | 125 | #endif |
| 127 | | REGISTER_MODULE(m_mod_man, DEBUG_WINDOWS); |
| 128 | | REGISTER_MODULE(m_mod_man, DEBUG_QT); |
| 129 | | REGISTER_MODULE(m_mod_man, DEBUG_INTERNAL); |
| 130 | | REGISTER_MODULE(m_mod_man, DEBUG_NONE); |
| 126 | REGISTER_MODULE(m_mod_man, DEBUG_WINDOWS); |
| 127 | REGISTER_MODULE(m_mod_man, DEBUG_QT); |
| 128 | REGISTER_MODULE(m_mod_man, DEBUG_INTERNAL); |
| 129 | REGISTER_MODULE(m_mod_man, DEBUG_NONE); |
| 131 | 130 | |
| 132 | | // after initialization we know which modules are supported |
| 131 | // after initialization we know which modules are supported |
| 133 | 132 | |
| 134 | | const char *names[20]; |
| 135 | | int num; |
| 136 | | m_mod_man.get_module_names(OSD_FONT_PROVIDER, 20, &num, names); |
| 137 | | dynamic_array<const char *> dnames; |
| 138 | | for (int i = 0; i < num; i++) |
| 139 | | dnames.append(names[i]); |
| 140 | | update_option(OSD_FONT_PROVIDER, dnames); |
| 133 | const char *names[20]; |
| 134 | int num; |
| 135 | m_mod_man.get_module_names(OSD_FONT_PROVIDER, 20, &num, names); |
| 136 | dynamic_array<const char *> dnames; |
| 137 | for (int i = 0; i < num; i++) |
| 138 | dnames.append(names[i]); |
| 139 | update_option(OSD_FONT_PROVIDER, dnames); |
| 141 | 140 | |
| 142 | | m_mod_man.get_module_names(OSD_SOUND_PROVIDER, 20, &num, names); |
| 143 | | dnames.reset(); |
| 144 | | for (int i = 0; i < num; i++) |
| 145 | | dnames.append(names[i]); |
| 146 | | update_option(OSD_SOUND_PROVIDER, dnames); |
| 141 | m_mod_man.get_module_names(OSD_SOUND_PROVIDER, 20, &num, names); |
| 142 | dnames.reset(); |
| 143 | for (int i = 0; i < num; i++) |
| 144 | dnames.append(names[i]); |
| 145 | update_option(OSD_SOUND_PROVIDER, dnames); |
| 147 | 146 | |
| 148 | | // Register debugger options and update options |
| 149 | | m_mod_man.get_module_names(OSD_DEBUG_PROVIDER, 20, &num, names); |
| 150 | | dnames.reset(); |
| 151 | | for (int i = 0; i < num; i++) |
| 152 | | dnames.append(names[i]); |
| 153 | | update_option(OSD_DEBUG_PROVIDER, dnames); |
| 147 | // Register debugger options and update options |
| 148 | m_mod_man.get_module_names(OSD_DEBUG_PROVIDER, 20, &num, names); |
| 149 | dnames.reset(); |
| 150 | for (int i = 0; i < num; i++) |
| 151 | dnames.append(names[i]); |
| 152 | update_option(OSD_DEBUG_PROVIDER, dnames); |
| 154 | 153 | |
| 155 | | // Register video options and update options |
| 156 | | video_options_add("none", NULL); |
| 157 | | video_register(); |
| 158 | | update_option(OSDOPTION_VIDEO, m_video_names); |
| 154 | // Register video options and update options |
| 155 | video_options_add("none", NULL); |
| 156 | video_register(); |
| 157 | update_option(OSDOPTION_VIDEO, m_video_names); |
| 159 | 158 | } |
| 160 | 159 | |
| 161 | 160 | void osd_common_t::update_option(const char * key, dynamic_array<const char *> &values) |
| r243189 | r243190 | |
| 305 | 304 | // It provides an array of stereo samples in L-R order which should be |
| 306 | 305 | // output at the configured sample_rate. |
| 307 | 306 | // |
| 308 | | m_sound->update_audio_stream(m_machine->video().throttled(), buffer,samples_this_frame); |
| 307 | m_sound->update_audio_stream(m_machine->video().throttled(), buffer,samples_this_frame); |
| 309 | 308 | } |
| 310 | 309 | |
| 311 | 310 | |
| r243189 | r243190 | |
| 322 | 321 | // while (attenuation++ < 0) |
| 323 | 322 | // volume /= 1.122018454; // = (10 ^ (1/20)) = 1dB |
| 324 | 323 | // |
| 325 | | if (m_sound != NULL) |
| 326 | | m_sound->set_mastervolume(attenuation); |
| 324 | if (m_sound != NULL) |
| 325 | m_sound->set_mastervolume(attenuation); |
| 327 | 326 | } |
| 328 | 327 | |
| 329 | 328 | |
| r243189 | r243190 | |
| 398 | 397 | |
| 399 | 398 | bool osd_common_t::execute_command(const char *command) |
| 400 | 399 | { |
| 401 | | if (strcmp(command, OSDCOMMAND_LIST_NETWORK_ADAPTERS) == 0) |
| 402 | | { |
| 403 | | network_init(); |
| 404 | | osd_list_network_adapters(); |
| 405 | | network_exit(); |
| 406 | | return true; |
| 407 | | } |
| 408 | | else if (strcmp(command, OSDCOMMAND_LIST_MIDI_DEVICES) == 0) |
| 409 | | { |
| 410 | | osd_list_midi_devices(); |
| 411 | | return true; |
| 412 | | } |
| 400 | if (strcmp(command, OSDCOMMAND_LIST_NETWORK_ADAPTERS) == 0) |
| 401 | { |
| 402 | network_init(); |
| 403 | osd_list_network_adapters(); |
| 404 | network_exit(); |
| 405 | return true; |
| 406 | } |
| 407 | else if (strcmp(command, OSDCOMMAND_LIST_MIDI_DEVICES) == 0) |
| 408 | { |
| 409 | osd_list_midi_devices(); |
| 410 | return true; |
| 411 | } |
| 413 | 412 | |
| 414 | | return false; |
| 413 | return false; |
| 415 | 414 | |
| 416 | 415 | } |
| 417 | 416 | |
| r243189 | r243190 | |
| 437 | 436 | #endif |
| 438 | 437 | midi_init(); |
| 439 | 438 | |
| 440 | | m_font_module = select_module_options<font_module *>(options(), OSD_FONT_PROVIDER); |
| 439 | m_font_module = select_module_options<font_module *>(options(), OSD_FONT_PROVIDER); |
| 441 | 440 | |
| 442 | | m_sound = select_module_options<sound_module *>(options(), OSD_SOUND_PROVIDER); |
| 443 | | m_sound->m_sample_rate = options().sample_rate(); |
| 444 | | m_sound->m_audio_latency = options().audio_latency(); |
| 441 | m_sound = select_module_options<sound_module *>(options(), OSD_SOUND_PROVIDER); |
| 442 | m_sound->m_sample_rate = options().sample_rate(); |
| 443 | m_sound->m_audio_latency = options().audio_latency(); |
| 445 | 444 | |
| 446 | | m_debugger = select_module_options<debug_module *>(options(), OSD_DEBUG_PROVIDER); |
| 445 | m_debugger = select_module_options<debug_module *>(options(), OSD_DEBUG_PROVIDER); |
| 447 | 446 | |
| 448 | | m_mod_man.init(); |
| 447 | m_mod_man.init(); |
| 449 | 448 | |
| 450 | 449 | } |
| 451 | 450 | |
| r243189 | r243190 | |
| 524 | 523 | |
| 525 | 524 | void osd_common_t::osd_exit() |
| 526 | 525 | { |
| 527 | | m_mod_man.exit(); |
| 526 | m_mod_man.exit(); |
| 528 | 527 | |
| 529 | | exit_subsystems(); |
| 528 | exit_subsystems(); |
| 530 | 529 | } |
| 531 | 530 | |
| 532 | 531 | void osd_common_t::video_options_add(const char *name, void *type) |
| r243189 | r243190 | |
| 537 | 536 | |
| 538 | 537 | bool osd_common_t::midi_init() |
| 539 | 538 | { |
| 540 | | // this should be done on the OS_level |
| 541 | | return osd_midi_init(); |
| 539 | // this should be done on the OS_level |
| 540 | return osd_midi_init(); |
| 542 | 541 | } |
| 543 | 542 | |
| 544 | 543 | void osd_common_t::midi_exit() |
| 545 | 544 | { |
| 546 | | osd_midi_exit(); |
| 545 | osd_midi_exit(); |
| 547 | 546 | } |
| 548 | | |
| 549 | | |
trunk/src/osd/modules/lib/osdobj_common.h
| r243189 | r243190 | |
| 62 | 62 | class osd_options : public cli_options |
| 63 | 63 | { |
| 64 | 64 | public: |
| 65 | | // construction/destruction |
| 66 | | osd_options(); |
| 65 | // construction/destruction |
| 66 | osd_options(); |
| 67 | 67 | |
| 68 | | // debugging options |
| 69 | | const char *debugger() const { return value(OSDOPTION_DEBUGGER); } |
| 70 | | int watchdog() const { return int_value(OSDOPTION_WATCHDOG); } |
| 68 | // debugging options |
| 69 | const char *debugger() const { return value(OSDOPTION_DEBUGGER); } |
| 70 | int watchdog() const { return int_value(OSDOPTION_WATCHDOG); } |
| 71 | 71 | |
| 72 | | // performance options |
| 73 | | bool multithreading() const { return bool_value(OSDOPTION_MULTITHREADING); } |
| 74 | | const char *numprocessors() const { return value(OSDOPTION_NUMPROCESSORS); } |
| 75 | | int bench() const { return int_value(OSDOPTION_BENCH); } |
| 72 | // performance options |
| 73 | bool multithreading() const { return bool_value(OSDOPTION_MULTITHREADING); } |
| 74 | const char *numprocessors() const { return value(OSDOPTION_NUMPROCESSORS); } |
| 75 | int bench() const { return int_value(OSDOPTION_BENCH); } |
| 76 | 76 | |
| 77 | | // video options |
| 78 | | const char *video() const { return value(OSDOPTION_VIDEO); } |
| 79 | | int numscreens() const { return int_value(OSDOPTION_NUMSCREENS); } |
| 80 | | bool window() const { return bool_value(OSDOPTION_WINDOW); } |
| 81 | | bool maximize() const { return bool_value(OSDOPTION_MAXIMIZE); } |
| 82 | | bool keep_aspect() const { return bool_value(OSDOPTION_KEEPASPECT); } |
| 83 | | bool uneven_stretch() const { return bool_value(OSDOPTION_UNEVENSTRETCH); } |
| 84 | | bool wait_vsync() const { return bool_value(OSDOPTION_WAITVSYNC); } |
| 85 | | bool sync_refresh() const { return bool_value(OSDOPTION_SYNCREFRESH); } |
| 77 | // video options |
| 78 | const char *video() const { return value(OSDOPTION_VIDEO); } |
| 79 | int numscreens() const { return int_value(OSDOPTION_NUMSCREENS); } |
| 80 | bool window() const { return bool_value(OSDOPTION_WINDOW); } |
| 81 | bool maximize() const { return bool_value(OSDOPTION_MAXIMIZE); } |
| 82 | bool keep_aspect() const { return bool_value(OSDOPTION_KEEPASPECT); } |
| 83 | bool uneven_stretch() const { return bool_value(OSDOPTION_UNEVENSTRETCH); } |
| 84 | bool wait_vsync() const { return bool_value(OSDOPTION_WAITVSYNC); } |
| 85 | bool sync_refresh() const { return bool_value(OSDOPTION_SYNCREFRESH); } |
| 86 | 86 | |
| 87 | | // per-window options |
| 88 | | const char *screen() const { return value(OSDOPTION_SCREEN); } |
| 89 | | const char *aspect() const { return value(OSDOPTION_ASPECT); } |
| 90 | | const char *resolution() const { return value(OSDOPTION_RESOLUTION); } |
| 91 | | const char *view() const { return value(OSDOPTION_VIEW); } |
| 92 | | const char *screen(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_SCREEN, index)); } |
| 93 | | const char *aspect(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_ASPECT, index)); } |
| 94 | | const char *resolution(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_RESOLUTION, index)); } |
| 95 | | const char *view(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_VIEW, index)); } |
| 87 | // per-window options |
| 88 | const char *screen() const { return value(OSDOPTION_SCREEN); } |
| 89 | const char *aspect() const { return value(OSDOPTION_ASPECT); } |
| 90 | const char *resolution() const { return value(OSDOPTION_RESOLUTION); } |
| 91 | const char *view() const { return value(OSDOPTION_VIEW); } |
| 92 | const char *screen(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_SCREEN, index)); } |
| 93 | const char *aspect(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_ASPECT, index)); } |
| 94 | const char *resolution(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_RESOLUTION, index)); } |
| 95 | const char *view(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_VIEW, index)); } |
| 96 | 96 | |
| 97 | | // full screen options |
| 98 | | bool switch_res() const { return bool_value(OSDOPTION_SWITCHRES); } |
| 97 | // full screen options |
| 98 | bool switch_res() const { return bool_value(OSDOPTION_SWITCHRES); } |
| 99 | 99 | |
| 100 | | // sound options |
| 101 | | const char *sound() const { return value(OSDOPTION_SOUND); } |
| 102 | | int audio_latency() const { return int_value(OSDOPTION_AUDIO_LATENCY); } |
| 100 | // sound options |
| 101 | const char *sound() const { return value(OSDOPTION_SOUND); } |
| 102 | int audio_latency() const { return int_value(OSDOPTION_AUDIO_LATENCY); } |
| 103 | 103 | |
| 104 | 104 | private: |
| 105 | | static const options_entry s_option_entries[]; |
| 105 | static const options_entry s_option_entries[]; |
| 106 | 106 | }; |
| 107 | 107 | |
| 108 | 108 | // ======================> osd_interface |
| r243189 | r243190 | |
| 142 | 142 | // video overridables |
| 143 | 143 | virtual void *get_slider_list(); |
| 144 | 144 | |
| 145 | | // command option overrides |
| 146 | | virtual bool execute_command(const char *command); |
| 145 | // command option overrides |
| 146 | virtual bool execute_command(const char *command); |
| 147 | 147 | |
| 148 | | osd_font *font_alloc() { return m_font_module->font_alloc(); } |
| 148 | osd_font *font_alloc() { return m_font_module->font_alloc(); } |
| 149 | 149 | |
| 150 | 150 | // FIXME: everything below seems to be osd specific and not part of |
| 151 | 151 | // this INTERFACE but part of the osd IMPLEMENTATION |
| 152 | 152 | |
| 153 | | // getters |
| 154 | | running_machine &machine() { assert(m_machine != NULL); return *m_machine; } |
| 153 | // getters |
| 154 | running_machine &machine() { assert(m_machine != NULL); return *m_machine; } |
| 155 | 155 | |
| 156 | 156 | |
| 157 | | virtual void debugger_update(); |
| 157 | virtual void debugger_update(); |
| 158 | 158 | |
| 159 | | virtual void init_subsystems(); |
| 159 | virtual void init_subsystems(); |
| 160 | 160 | |
| 161 | | virtual bool video_init(); |
| 162 | | virtual void video_register(); |
| 163 | | virtual bool window_init(); |
| 161 | virtual bool video_init(); |
| 162 | virtual void video_register(); |
| 163 | virtual bool window_init(); |
| 164 | 164 | |
| 165 | | virtual void input_resume(); |
| 166 | | virtual bool output_init(); |
| 167 | | virtual bool network_init(); |
| 168 | | virtual bool midi_init(); |
| 165 | virtual void input_resume(); |
| 166 | virtual bool output_init(); |
| 167 | virtual bool network_init(); |
| 168 | virtual bool midi_init(); |
| 169 | 169 | |
| 170 | | virtual void exit_subsystems(); |
| 171 | | virtual void video_exit(); |
| 172 | | virtual void window_exit(); |
| 173 | | virtual void input_exit(); |
| 174 | | virtual void output_exit(); |
| 175 | | virtual void network_exit(); |
| 176 | | virtual void midi_exit(); |
| 170 | virtual void exit_subsystems(); |
| 171 | virtual void video_exit(); |
| 172 | virtual void window_exit(); |
| 173 | virtual void input_exit(); |
| 174 | virtual void output_exit(); |
| 175 | virtual void network_exit(); |
| 176 | virtual void midi_exit(); |
| 177 | 177 | |
| 178 | | virtual void osd_exit(); |
| 178 | virtual void osd_exit(); |
| 179 | 179 | |
| 180 | | virtual void video_options_add(const char *name, void *type); |
| 180 | virtual void video_options_add(const char *name, void *type); |
| 181 | 181 | |
| 182 | | osd_options &options() { return m_options; } |
| 182 | osd_options &options() { return m_options; } |
| 183 | 183 | |
| 184 | 184 | protected: |
| 185 | | virtual bool input_init(); |
| 186 | | virtual void input_pause(); |
| 185 | virtual bool input_init(); |
| 186 | virtual void input_pause(); |
| 187 | 187 | |
| 188 | 188 | private: |
| 189 | 189 | // internal state |
| 190 | 190 | running_machine * m_machine; |
| 191 | 191 | osd_options& m_options; |
| 192 | 192 | |
| 193 | | osd_module_manager m_mod_man; |
| 194 | | font_module *m_font_module; |
| 193 | osd_module_manager m_mod_man; |
| 194 | font_module *m_font_module; |
| 195 | 195 | |
| 196 | 196 | void update_option(const char * key, dynamic_array<const char *> &values); |
| 197 | | // FIXME: should be elsewhere |
| 198 | | osd_module *select_module_options(const core_options &opts, const astring &opt_name) |
| 199 | | { |
| 200 | | astring opt_val = opts.value(opt_name); |
| 201 | | if (opt_val == "auto") |
| 202 | | opt_val = ""; |
| 203 | | else if (!m_mod_man.type_has_name(opt_name, opt_val)) |
| 204 | | { |
| 205 | | osd_printf_warning("Value %s not supported for option %s - falling back to auto\n", opt_val.cstr(), opt_name.cstr()); |
| 206 | | opt_val = ""; |
| 207 | | } |
| 208 | | return m_mod_man.select_module(opt_name, opt_val); |
| 209 | | } |
| 197 | // FIXME: should be elsewhere |
| 198 | osd_module *select_module_options(const core_options &opts, const astring &opt_name) |
| 199 | { |
| 200 | astring opt_val = opts.value(opt_name); |
| 201 | if (opt_val == "auto") |
| 202 | opt_val = ""; |
| 203 | else if (!m_mod_man.type_has_name(opt_name, opt_val)) |
| 204 | { |
| 205 | osd_printf_warning("Value %s not supported for option %s - falling back to auto\n", opt_val.cstr(), opt_name.cstr()); |
| 206 | opt_val = ""; |
| 207 | } |
| 208 | return m_mod_man.select_module(opt_name, opt_val); |
| 209 | } |
| 210 | 210 | |
| 211 | | template<class C> |
| 212 | | C select_module_options(const core_options &opts, const astring &opt_name) |
| 213 | | { |
| 214 | | return dynamic_cast<C>(select_module_options(opts, opt_name)); |
| 215 | | } |
| 211 | template<class C> |
| 212 | C select_module_options(const core_options &opts, const astring &opt_name) |
| 213 | { |
| 214 | return dynamic_cast<C>(select_module_options(opts, opt_name)); |
| 215 | } |
| 216 | 216 | |
| 217 | 217 | protected: |
| 218 | 218 | sound_module* m_sound; |
trunk/src/osd/modules/midi/portmidi.c
| r243189 | r243190 | |
| 16 | 16 | |
| 17 | 17 | struct osd_midi_device |
| 18 | 18 | { |
| 19 | | PortMidiStream *pmStream; |
| 20 | | PmEvent rx_evBuf[RX_EVENT_BUF_SIZE]; |
| 21 | | UINT8 xmit_in[4]; // Pm_Messages mean we can at most have 3 residue bytes |
| 22 | | int xmit_cnt; |
| 23 | | UINT8 last_status; |
| 24 | | bool rx_sysex; |
| 19 | PortMidiStream *pmStream; |
| 20 | PmEvent rx_evBuf[RX_EVENT_BUF_SIZE]; |
| 21 | UINT8 xmit_in[4]; // Pm_Messages mean we can at most have 3 residue bytes |
| 22 | int xmit_cnt; |
| 23 | UINT8 last_status; |
| 24 | bool rx_sysex; |
| 25 | 25 | }; |
| 26 | 26 | |
| 27 | 27 | bool osd_midi_init() |
| 28 | 28 | { |
| 29 | | Pm_Initialize(); |
| 30 | | return true; |
| 29 | Pm_Initialize(); |
| 30 | return true; |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | 33 | void osd_midi_exit() |
| 34 | 34 | { |
| 35 | | Pm_Terminate(); |
| 35 | Pm_Terminate(); |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | 38 | void osd_list_midi_devices(void) |
| 39 | 39 | { |
| 40 | | int num_devs = Pm_CountDevices(); |
| 41 | | const PmDeviceInfo *pmInfo; |
| 40 | int num_devs = Pm_CountDevices(); |
| 41 | const PmDeviceInfo *pmInfo; |
| 42 | 42 | |
| 43 | | printf("\n"); |
| 43 | printf("\n"); |
| 44 | 44 | |
| 45 | | if (num_devs == 0) |
| 46 | | { |
| 47 | | printf("No MIDI ports were found\n"); |
| 48 | | return; |
| 49 | | } |
| 45 | if (num_devs == 0) |
| 46 | { |
| 47 | printf("No MIDI ports were found\n"); |
| 48 | return; |
| 49 | } |
| 50 | 50 | |
| 51 | | printf("MIDI input ports:\n"); |
| 52 | | for (int i = 0; i < num_devs; i++) |
| 53 | | { |
| 54 | | pmInfo = Pm_GetDeviceInfo(i); |
| 51 | printf("MIDI input ports:\n"); |
| 52 | for (int i = 0; i < num_devs; i++) |
| 53 | { |
| 54 | pmInfo = Pm_GetDeviceInfo(i); |
| 55 | 55 | |
| 56 | | if (pmInfo->input) |
| 57 | | { |
| 58 | | printf("%s %s\n", pmInfo->name, (i == Pm_GetDefaultInputDeviceID()) ? "(default)" : ""); |
| 59 | | } |
| 60 | | } |
| 56 | if (pmInfo->input) |
| 57 | { |
| 58 | printf("%s %s\n", pmInfo->name, (i == Pm_GetDefaultInputDeviceID()) ? "(default)" : ""); |
| 59 | } |
| 60 | } |
| 61 | 61 | |
| 62 | | printf("\nMIDI output ports:\n"); |
| 63 | | for (int i = 0; i < num_devs; i++) |
| 64 | | { |
| 65 | | pmInfo = Pm_GetDeviceInfo(i); |
| 62 | printf("\nMIDI output ports:\n"); |
| 63 | for (int i = 0; i < num_devs; i++) |
| 64 | { |
| 65 | pmInfo = Pm_GetDeviceInfo(i); |
| 66 | 66 | |
| 67 | | if (pmInfo->output) |
| 68 | | { |
| 69 | | printf("%s %s\n", pmInfo->name, (i == Pm_GetDefaultOutputDeviceID()) ? "(default)" : ""); |
| 70 | | } |
| 71 | | } |
| 67 | if (pmInfo->output) |
| 68 | { |
| 69 | printf("%s %s\n", pmInfo->name, (i == Pm_GetDefaultOutputDeviceID()) ? "(default)" : ""); |
| 70 | } |
| 71 | } |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 | osd_midi_device *osd_open_midi_input(const char *devname) |
| 75 | 75 | { |
| 76 | | int num_devs = Pm_CountDevices(); |
| 77 | | int found_dev = -1; |
| 78 | | const PmDeviceInfo *pmInfo; |
| 79 | | PortMidiStream *stm; |
| 80 | | osd_midi_device *ret; |
| 76 | int num_devs = Pm_CountDevices(); |
| 77 | int found_dev = -1; |
| 78 | const PmDeviceInfo *pmInfo; |
| 79 | PortMidiStream *stm; |
| 80 | osd_midi_device *ret; |
| 81 | 81 | |
| 82 | | if (!strcmp("default", devname)) |
| 83 | | { |
| 84 | | found_dev = Pm_GetDefaultInputDeviceID(); |
| 85 | | } |
| 86 | | else |
| 87 | | { |
| 88 | | for (int i = 0; i < num_devs; i++) |
| 89 | | { |
| 90 | | pmInfo = Pm_GetDeviceInfo(i); |
| 82 | if (!strcmp("default", devname)) |
| 83 | { |
| 84 | found_dev = Pm_GetDefaultInputDeviceID(); |
| 85 | } |
| 86 | else |
| 87 | { |
| 88 | for (int i = 0; i < num_devs; i++) |
| 89 | { |
| 90 | pmInfo = Pm_GetDeviceInfo(i); |
| 91 | 91 | |
| 92 | | if (pmInfo->input) |
| 93 | | { |
| 94 | | if (!strcmp(devname, pmInfo->name)) |
| 95 | | { |
| 96 | | found_dev = i; |
| 97 | | break; |
| 98 | | } |
| 99 | | } |
| 100 | | } |
| 101 | | } |
| 92 | if (pmInfo->input) |
| 93 | { |
| 94 | if (!strcmp(devname, pmInfo->name)) |
| 95 | { |
| 96 | found_dev = i; |
| 97 | break; |
| 98 | } |
| 99 | } |
| 100 | } |
| 101 | } |
| 102 | 102 | |
| 103 | | if (found_dev >= 0) |
| 104 | | { |
| 105 | | if (Pm_OpenInput(&stm, found_dev, NULL, RX_EVENT_BUF_SIZE, NULL, NULL) == pmNoError) |
| 106 | | { |
| 107 | | ret = (osd_midi_device *)osd_malloc(sizeof(osd_midi_device)); |
| 108 | | memset(ret, 0, sizeof(osd_midi_device)); |
| 109 | | ret->pmStream = stm; |
| 110 | | return ret; |
| 111 | | } |
| 112 | | else |
| 113 | | { |
| 114 | | printf("Couldn't open PM device\n"); |
| 115 | | return NULL; |
| 116 | | } |
| 117 | | } |
| 118 | | else |
| 119 | | { |
| 120 | | return NULL; |
| 121 | | } |
| 103 | if (found_dev >= 0) |
| 104 | { |
| 105 | if (Pm_OpenInput(&stm, found_dev, NULL, RX_EVENT_BUF_SIZE, NULL, NULL) == pmNoError) |
| 106 | { |
| 107 | ret = (osd_midi_device *)osd_malloc(sizeof(osd_midi_device)); |
| 108 | memset(ret, 0, sizeof(osd_midi_device)); |
| 109 | ret->pmStream = stm; |
| 110 | return ret; |
| 111 | } |
| 112 | else |
| 113 | { |
| 114 | printf("Couldn't open PM device\n"); |
| 115 | return NULL; |
| 116 | } |
| 117 | } |
| 118 | else |
| 119 | { |
| 120 | return NULL; |
| 121 | } |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | 124 | osd_midi_device *osd_open_midi_output(const char *devname) |
| 125 | 125 | { |
| 126 | | int num_devs = Pm_CountDevices(); |
| 127 | | int found_dev = -1; |
| 128 | | const PmDeviceInfo *pmInfo; |
| 129 | | PortMidiStream *stm; |
| 130 | | osd_midi_device *ret; |
| 126 | int num_devs = Pm_CountDevices(); |
| 127 | int found_dev = -1; |
| 128 | const PmDeviceInfo *pmInfo; |
| 129 | PortMidiStream *stm; |
| 130 | osd_midi_device *ret; |
| 131 | 131 | |
| 132 | | if (!strcmp("default", devname)) |
| 133 | | { |
| 134 | | found_dev = Pm_GetDefaultOutputDeviceID(); |
| 135 | | } |
| 136 | | else |
| 137 | | { |
| 138 | | for (int i = 0; i < num_devs; i++) |
| 139 | | { |
| 140 | | pmInfo = Pm_GetDeviceInfo(i); |
| 132 | if (!strcmp("default", devname)) |
| 133 | { |
| 134 | found_dev = Pm_GetDefaultOutputDeviceID(); |
| 135 | } |
| 136 | else |
| 137 | { |
| 138 | for (int i = 0; i < num_devs; i++) |
| 139 | { |
| 140 | pmInfo = Pm_GetDeviceInfo(i); |
| 141 | 141 | |
| 142 | | if (pmInfo->output) |
| 143 | | { |
| 144 | | if (!strcmp(devname, pmInfo->name)) |
| 145 | | { |
| 146 | | found_dev = i; |
| 147 | | break; |
| 148 | | } |
| 149 | | } |
| 150 | | } |
| 151 | | } |
| 142 | if (pmInfo->output) |
| 143 | { |
| 144 | if (!strcmp(devname, pmInfo->name)) |
| 145 | { |
| 146 | found_dev = i; |
| 147 | break; |
| 148 | } |
| 149 | } |
| 150 | } |
| 151 | } |
| 152 | 152 | |
| 153 | | if (found_dev >= 0) |
| 154 | | { |
| 155 | | if (Pm_OpenOutput(&stm, found_dev, NULL, 100, NULL, NULL, 0) == pmNoError) |
| 156 | | { |
| 157 | | ret = (osd_midi_device *)osd_malloc(sizeof(osd_midi_device)); |
| 158 | | memset(ret, 0, sizeof(osd_midi_device)); |
| 159 | | ret->pmStream = stm; |
| 160 | | return ret; |
| 161 | | } |
| 162 | | else |
| 163 | | { |
| 164 | | printf("Couldn't open PM device\n"); |
| 165 | | return NULL; |
| 166 | | } |
| 167 | | } |
| 168 | | else |
| 169 | | { |
| 170 | | return NULL; |
| 171 | | } |
| 172 | | return NULL; |
| 153 | if (found_dev >= 0) |
| 154 | { |
| 155 | if (Pm_OpenOutput(&stm, found_dev, NULL, 100, NULL, NULL, 0) == pmNoError) |
| 156 | { |
| 157 | ret = (osd_midi_device *)osd_malloc(sizeof(osd_midi_device)); |
| 158 | memset(ret, 0, sizeof(osd_midi_device)); |
| 159 | ret->pmStream = stm; |
| 160 | return ret; |
| 161 | } |
| 162 | else |
| 163 | { |
| 164 | printf("Couldn't open PM device\n"); |
| 165 | return NULL; |
| 166 | } |
| 167 | } |
| 168 | else |
| 169 | { |
| 170 | return NULL; |
| 171 | } |
| 172 | return NULL; |
| 173 | 173 | } |
| 174 | 174 | |
| 175 | 175 | void osd_close_midi_channel(osd_midi_device *dev) |
| 176 | 176 | { |
| 177 | | Pm_Close(dev->pmStream); |
| 178 | | osd_free(dev); |
| 177 | Pm_Close(dev->pmStream); |
| 178 | osd_free(dev); |
| 179 | 179 | } |
| 180 | 180 | |
| 181 | 181 | bool osd_poll_midi_channel(osd_midi_device *dev) |
| 182 | 182 | { |
| 183 | | PmError chk = Pm_Poll(dev->pmStream); |
| 183 | PmError chk = Pm_Poll(dev->pmStream); |
| 184 | 184 | |
| 185 | | return (chk == pmGotData) ? true : false; |
| 185 | return (chk == pmGotData) ? true : false; |
| 186 | 186 | } |
| 187 | 187 | |
| 188 | 188 | int osd_read_midi_channel(osd_midi_device *dev, UINT8 *pOut) |
| 189 | 189 | { |
| 190 | | int msgsRead = Pm_Read(dev->pmStream, dev->rx_evBuf, RX_EVENT_BUF_SIZE); |
| 191 | | int bytesOut = 0; |
| 190 | int msgsRead = Pm_Read(dev->pmStream, dev->rx_evBuf, RX_EVENT_BUF_SIZE); |
| 191 | int bytesOut = 0; |
| 192 | 192 | |
| 193 | | if (msgsRead <= 0) |
| 194 | | { |
| 195 | | return 0; |
| 196 | | } |
| 193 | if (msgsRead <= 0) |
| 194 | { |
| 195 | return 0; |
| 196 | } |
| 197 | 197 | |
| 198 | | for (int msg = 0; msg < msgsRead; msg++) |
| 199 | | { |
| 200 | | UINT8 status = Pm_MessageStatus(dev->rx_evBuf[msg].message); |
| 198 | for (int msg = 0; msg < msgsRead; msg++) |
| 199 | { |
| 200 | UINT8 status = Pm_MessageStatus(dev->rx_evBuf[msg].message); |
| 201 | 201 | |
| 202 | | if (dev->rx_sysex) |
| 203 | | { |
| 204 | | if (status & 0x80) // sys real-time imposing on us? |
| 205 | | { |
| 206 | | if ((status == 0xf2) || (status == 0xf3)) |
| 207 | | { |
| 208 | | *pOut++ = status; |
| 209 | | *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message); |
| 210 | | *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message); |
| 211 | | bytesOut += 3; |
| 212 | | } |
| 213 | | else |
| 214 | | { |
| 215 | | *pOut++ = status; |
| 216 | | bytesOut++; |
| 217 | | if (status == MIDI_EOX) |
| 218 | | { |
| 219 | | dev->rx_sysex = false; |
| 220 | | } |
| 221 | | } |
| 222 | | } |
| 223 | | else // shift out the sysex bytes |
| 224 | | { |
| 225 | | for (int i = 0; i < 4; i++) |
| 226 | | { |
| 227 | | UINT8 byte = dev->rx_evBuf[msg].message & 0xff; |
| 228 | | *pOut++ = byte; |
| 229 | | bytesOut++; |
| 230 | | if (byte == MIDI_EOX) |
| 231 | | { |
| 232 | | dev->rx_sysex = false; |
| 233 | | break; |
| 234 | | } |
| 235 | | dev->rx_evBuf[msg].message >>= 8; |
| 236 | | } |
| 237 | | } |
| 238 | | } |
| 239 | | else |
| 240 | | { |
| 241 | | switch ((status>>4) & 0xf) |
| 242 | | { |
| 243 | | case 0xc: // 2-byte messages |
| 244 | | case 0xd: |
| 245 | | *pOut++ = status; |
| 246 | | *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message); |
| 247 | | bytesOut += 2; |
| 248 | | break; |
| 202 | if (dev->rx_sysex) |
| 203 | { |
| 204 | if (status & 0x80) // sys real-time imposing on us? |
| 205 | { |
| 206 | if ((status == 0xf2) || (status == 0xf3)) |
| 207 | { |
| 208 | *pOut++ = status; |
| 209 | *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message); |
| 210 | *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message); |
| 211 | bytesOut += 3; |
| 212 | } |
| 213 | else |
| 214 | { |
| 215 | *pOut++ = status; |
| 216 | bytesOut++; |
| 217 | if (status == MIDI_EOX) |
| 218 | { |
| 219 | dev->rx_sysex = false; |
| 220 | } |
| 221 | } |
| 222 | } |
| 223 | else // shift out the sysex bytes |
| 224 | { |
| 225 | for (int i = 0; i < 4; i++) |
| 226 | { |
| 227 | UINT8 byte = dev->rx_evBuf[msg].message & 0xff; |
| 228 | *pOut++ = byte; |
| 229 | bytesOut++; |
| 230 | if (byte == MIDI_EOX) |
| 231 | { |
| 232 | dev->rx_sysex = false; |
| 233 | break; |
| 234 | } |
| 235 | dev->rx_evBuf[msg].message >>= 8; |
| 236 | } |
| 237 | } |
| 238 | } |
| 239 | else |
| 240 | { |
| 241 | switch ((status>>4) & 0xf) |
| 242 | { |
| 243 | case 0xc: // 2-byte messages |
| 244 | case 0xd: |
| 245 | *pOut++ = status; |
| 246 | *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message); |
| 247 | bytesOut += 2; |
| 248 | break; |
| 249 | 249 | |
| 250 | | case 0xf: // system common |
| 251 | | switch (status & 0xf) |
| 252 | | { |
| 253 | | case 0: // System Exclusive |
| 254 | | { |
| 255 | | *pOut++ = status; // this should be OK: the shortest legal sysex is F0 tt dd F7, I believe |
| 256 | | *pOut++ = (dev->rx_evBuf[msg].message>>8) & 0xff; |
| 257 | | *pOut++ = (dev->rx_evBuf[msg].message>>16) & 0xff; |
| 258 | | UINT8 last = *pOut++ = (dev->rx_evBuf[msg].message>>24) & 0xff; |
| 259 | | bytesOut += 4; |
| 260 | | dev->rx_sysex = (last != MIDI_EOX); |
| 261 | | break; |
| 262 | | } |
| 250 | case 0xf: // system common |
| 251 | switch (status & 0xf) |
| 252 | { |
| 253 | case 0: // System Exclusive |
| 254 | { |
| 255 | *pOut++ = status; // this should be OK: the shortest legal sysex is F0 tt dd F7, I believe |
| 256 | *pOut++ = (dev->rx_evBuf[msg].message>>8) & 0xff; |
| 257 | *pOut++ = (dev->rx_evBuf[msg].message>>16) & 0xff; |
| 258 | UINT8 last = *pOut++ = (dev->rx_evBuf[msg].message>>24) & 0xff; |
| 259 | bytesOut += 4; |
| 260 | dev->rx_sysex = (last != MIDI_EOX); |
| 261 | break; |
| 262 | } |
| 263 | 263 | |
| 264 | | case 7: // End of System Exclusive |
| 265 | | *pOut++ = status; |
| 266 | | bytesOut += 1; |
| 267 | | dev->rx_sysex = false; |
| 268 | | break; |
| 264 | case 7: // End of System Exclusive |
| 265 | *pOut++ = status; |
| 266 | bytesOut += 1; |
| 267 | dev->rx_sysex = false; |
| 268 | break; |
| 269 | 269 | |
| 270 | | case 2: // song pos |
| 271 | | case 3: // song select |
| 272 | | *pOut++ = status; |
| 273 | | *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message); |
| 274 | | *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message); |
| 275 | | bytesOut += 3; |
| 276 | | break; |
| 270 | case 2: // song pos |
| 271 | case 3: // song select |
| 272 | *pOut++ = status; |
| 273 | *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message); |
| 274 | *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message); |
| 275 | bytesOut += 3; |
| 276 | break; |
| 277 | 277 | |
| 278 | | default: // all other defined Fx messages are 1 byte |
| 279 | | break; |
| 280 | | } |
| 281 | | break; |
| 278 | default: // all other defined Fx messages are 1 byte |
| 279 | break; |
| 280 | } |
| 281 | break; |
| 282 | 282 | |
| 283 | | default: |
| 284 | | *pOut++ = status; |
| 285 | | *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message); |
| 286 | | *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message); |
| 287 | | bytesOut += 3; |
| 288 | | break; |
| 289 | | } |
| 290 | | } |
| 291 | | } |
| 283 | default: |
| 284 | *pOut++ = status; |
| 285 | *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message); |
| 286 | *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message); |
| 287 | bytesOut += 3; |
| 288 | break; |
| 289 | } |
| 290 | } |
| 291 | } |
| 292 | 292 | |
| 293 | | return bytesOut; |
| 293 | return bytesOut; |
| 294 | 294 | } |
| 295 | 295 | |
| 296 | 296 | void osd_write_midi_channel(osd_midi_device *dev, UINT8 data) |
| 297 | 297 | { |
| 298 | | int bytes_needed = 0; |
| 299 | | PmEvent ev; |
| 300 | | ev.timestamp = 0; // use the current time |
| 298 | int bytes_needed = 0; |
| 299 | PmEvent ev; |
| 300 | ev.timestamp = 0; // use the current time |
| 301 | 301 | |
| 302 | 302 | // printf("write: %02x (%d)\n", data, dev->xmit_cnt); |
| 303 | 303 | |
| 304 | | // reject data bytes when no valid status exists |
| 305 | | if ((dev->last_status == 0) && !(data & 0x80)) |
| 306 | | { |
| 307 | | dev->xmit_cnt = 0; |
| 308 | | return; |
| 309 | | } |
| 304 | // reject data bytes when no valid status exists |
| 305 | if ((dev->last_status == 0) && !(data & 0x80)) |
| 306 | { |
| 307 | dev->xmit_cnt = 0; |
| 308 | return; |
| 309 | } |
| 310 | 310 | |
| 311 | | if (dev->xmit_cnt >= 4) |
| 312 | | { |
| 313 | | printf("MIDI out: packet assembly overflow, contact MAMEdev!\n"); |
| 314 | | return; |
| 315 | | } |
| 311 | if (dev->xmit_cnt >= 4) |
| 312 | { |
| 313 | printf("MIDI out: packet assembly overflow, contact MAMEdev!\n"); |
| 314 | return; |
| 315 | } |
| 316 | 316 | |
| 317 | | // handle sysex |
| 318 | | if (dev->last_status == MIDI_SYSEX) |
| 319 | | { |
| 317 | // handle sysex |
| 318 | if (dev->last_status == MIDI_SYSEX) |
| 319 | { |
| 320 | 320 | // printf("sysex: %02x (%d)\n", data, dev->xmit_cnt); |
| 321 | 321 | |
| 322 | | // if we get a status that isn't sysex, assume it's system common |
| 323 | | if ((data & 0x80) && (data != MIDI_EOX)) |
| 324 | | { |
| 322 | // if we get a status that isn't sysex, assume it's system common |
| 323 | if ((data & 0x80) && (data != MIDI_EOX)) |
| 324 | { |
| 325 | 325 | // printf("common during sysex!\n"); |
| 326 | | ev.message = Pm_Message(data, 0, 0); |
| 327 | | Pm_Write(dev->pmStream, &ev, 1); |
| 328 | | return; |
| 329 | | } |
| 326 | ev.message = Pm_Message(data, 0, 0); |
| 327 | Pm_Write(dev->pmStream, &ev, 1); |
| 328 | return; |
| 329 | } |
| 330 | 330 | |
| 331 | | dev->xmit_in[dev->xmit_cnt++] = data; |
| 331 | dev->xmit_in[dev->xmit_cnt++] = data; |
| 332 | 332 | |
| 333 | | // if EOX or 4 bytes filled, transmit 4 bytes |
| 334 | | if ((dev->xmit_cnt == 4) || (data == MIDI_EOX)) |
| 335 | | { |
| 336 | | ev.message = dev->xmit_in[0] | (dev->xmit_in[1]<<8) | (dev->xmit_in[2]<<16) | (dev->xmit_in[3]<<24); |
| 337 | | Pm_Write(dev->pmStream, &ev, 1); |
| 338 | | dev->xmit_in[0] = dev->xmit_in[1] = dev->xmit_in[2] = dev->xmit_in[3] = 0; |
| 339 | | dev->xmit_cnt = 0; |
| 333 | // if EOX or 4 bytes filled, transmit 4 bytes |
| 334 | if ((dev->xmit_cnt == 4) || (data == MIDI_EOX)) |
| 335 | { |
| 336 | ev.message = dev->xmit_in[0] | (dev->xmit_in[1]<<8) | (dev->xmit_in[2]<<16) | (dev->xmit_in[3]<<24); |
| 337 | Pm_Write(dev->pmStream, &ev, 1); |
| 338 | dev->xmit_in[0] = dev->xmit_in[1] = dev->xmit_in[2] = dev->xmit_in[3] = 0; |
| 339 | dev->xmit_cnt = 0; |
| 340 | 340 | |
| 341 | 341 | // printf("SysEx packet: %08x\n", ev.message); |
| 342 | 342 | |
| 343 | | // if this is EOX, kill the running status |
| 344 | | if (data == MIDI_EOX) |
| 345 | | { |
| 346 | | dev->last_status = 0; |
| 347 | | } |
| 348 | | } |
| 343 | // if this is EOX, kill the running status |
| 344 | if (data == MIDI_EOX) |
| 345 | { |
| 346 | dev->last_status = 0; |
| 347 | } |
| 348 | } |
| 349 | 349 | |
| 350 | | return; |
| 351 | | } |
| 350 | return; |
| 351 | } |
| 352 | 352 | |
| 353 | | // handle running status. don't allow system real-time messages to be considered as running status. |
| 354 | | if ((dev->xmit_cnt == 0) && (data & 0x80) && (data < 0xf8)) |
| 355 | | { |
| 356 | | dev->last_status = data; |
| 357 | | } |
| 353 | // handle running status. don't allow system real-time messages to be considered as running status. |
| 354 | if ((dev->xmit_cnt == 0) && (data & 0x80) && (data < 0xf8)) |
| 355 | { |
| 356 | dev->last_status = data; |
| 357 | } |
| 358 | 358 | |
| 359 | | if ((dev->xmit_cnt == 0) && !(data & 0x80)) |
| 360 | | { |
| 361 | | dev->xmit_in[dev->xmit_cnt++] = dev->last_status; |
| 362 | | dev->xmit_in[dev->xmit_cnt++] = data; |
| 359 | if ((dev->xmit_cnt == 0) && !(data & 0x80)) |
| 360 | { |
| 361 | dev->xmit_in[dev->xmit_cnt++] = dev->last_status; |
| 362 | dev->xmit_in[dev->xmit_cnt++] = data; |
| 363 | 363 | // printf("\trunning status: [%d] = %02x, [%d] = %02x, last_status = %02x\n", dev->xmit_cnt-2, dev->last_status, dev->xmit_cnt-1, data, dev->last_status); |
| 364 | | } |
| 365 | | else |
| 366 | | { |
| 367 | | dev->xmit_in[dev->xmit_cnt++] = data; |
| 364 | } |
| 365 | else |
| 366 | { |
| 367 | dev->xmit_in[dev->xmit_cnt++] = data; |
| 368 | 368 | // printf("\tNRS: [%d] = %02x\n", dev->xmit_cnt-1, data); |
| 369 | | } |
| 369 | } |
| 370 | 370 | |
| 371 | | if ((dev->xmit_cnt == 1) && (dev->xmit_in[0] == MIDI_SYSEX)) |
| 372 | | { |
| 371 | if ((dev->xmit_cnt == 1) && (dev->xmit_in[0] == MIDI_SYSEX)) |
| 372 | { |
| 373 | 373 | // printf("Start SysEx!\n"); |
| 374 | | dev->last_status = MIDI_SYSEX; |
| 375 | | return; |
| 376 | | } |
| 374 | dev->last_status = MIDI_SYSEX; |
| 375 | return; |
| 376 | } |
| 377 | 377 | |
| 378 | | // are we there yet? |
| 378 | // are we there yet? |
| 379 | 379 | // printf("status check: %02x\n", dev->xmit_in[0]); |
| 380 | | switch ((dev->xmit_in[0]>>4) & 0xf) |
| 381 | | { |
| 382 | | case 0xc: // 2-byte messages |
| 383 | | case 0xd: |
| 384 | | bytes_needed = 2; |
| 385 | | break; |
| 380 | switch ((dev->xmit_in[0]>>4) & 0xf) |
| 381 | { |
| 382 | case 0xc: // 2-byte messages |
| 383 | case 0xd: |
| 384 | bytes_needed = 2; |
| 385 | break; |
| 386 | 386 | |
| 387 | | case 0xf: // system common |
| 388 | | switch (dev->xmit_in[0] & 0xf) |
| 389 | | { |
| 390 | | case 0: // System Exclusive is handled above |
| 391 | | break; |
| 387 | case 0xf: // system common |
| 388 | switch (dev->xmit_in[0] & 0xf) |
| 389 | { |
| 390 | case 0: // System Exclusive is handled above |
| 391 | break; |
| 392 | 392 | |
| 393 | | case 7: // End of System Exclusive |
| 394 | | bytes_needed = 1; |
| 395 | | break; |
| 393 | case 7: // End of System Exclusive |
| 394 | bytes_needed = 1; |
| 395 | break; |
| 396 | 396 | |
| 397 | | case 2: // song pos |
| 398 | | case 3: // song select |
| 399 | | bytes_needed = 3; |
| 400 | | break; |
| 397 | case 2: // song pos |
| 398 | case 3: // song select |
| 399 | bytes_needed = 3; |
| 400 | break; |
| 401 | 401 | |
| 402 | | default: // all other defined Fx messages are 1 byte |
| 403 | | bytes_needed = 1; |
| 404 | | break; |
| 405 | | } |
| 406 | | break; |
| 402 | default: // all other defined Fx messages are 1 byte |
| 403 | bytes_needed = 1; |
| 404 | break; |
| 405 | } |
| 406 | break; |
| 407 | 407 | |
| 408 | | default: |
| 409 | | bytes_needed = 3; |
| 410 | | break; |
| 411 | | } |
| 408 | default: |
| 409 | bytes_needed = 3; |
| 410 | break; |
| 411 | } |
| 412 | 412 | |
| 413 | | if (dev->xmit_cnt == bytes_needed) |
| 414 | | { |
| 415 | | ev.message = Pm_Message(dev->xmit_in[0], dev->xmit_in[1], dev->xmit_in[2]); |
| 416 | | Pm_Write(dev->pmStream, &ev, 1); |
| 417 | | dev->xmit_cnt = 0; |
| 418 | | } |
| 413 | if (dev->xmit_cnt == bytes_needed) |
| 414 | { |
| 415 | ev.message = Pm_Message(dev->xmit_in[0], dev->xmit_in[1], dev->xmit_in[2]); |
| 416 | Pm_Write(dev->pmStream, &ev, 1); |
| 417 | dev->xmit_cnt = 0; |
| 418 | } |
| 419 | 419 | |
| 420 | 420 | } |
trunk/src/osd/modules/sound/sdl_sound.c
| r243189 | r243190 | |
| 43 | 43 | { |
| 44 | 44 | public: |
| 45 | 45 | |
| 46 | | friend void sdl_callback(void *userdata, Uint8 *stream, int len); |
| 46 | friend void sdl_callback(void *userdata, Uint8 *stream, int len); |
| 47 | 47 | |
| 48 | | // number of samples per SDL callback |
| 49 | | static const int SDL_XFER_SAMPLES = 512; |
| 48 | // number of samples per SDL callback |
| 49 | static const int SDL_XFER_SAMPLES = 512; |
| 50 | 50 | |
| 51 | | sound_sdl() |
| 52 | | : osd_module(OSD_SOUND_PROVIDER, "sdl"), sound_module(), |
| 53 | | stream_in_initialized(0), |
| 54 | | stream_loop(0), |
| 55 | | attenuation(0) |
| 56 | | { |
| 57 | | sdl_xfer_samples = SDL_XFER_SAMPLES; |
| 58 | | } |
| 59 | | virtual ~sound_sdl() { } |
| 51 | sound_sdl() |
| 52 | : osd_module(OSD_SOUND_PROVIDER, "sdl"), sound_module(), |
| 53 | stream_in_initialized(0), |
| 54 | stream_loop(0), |
| 55 | attenuation(0) |
| 56 | { |
| 57 | sdl_xfer_samples = SDL_XFER_SAMPLES; |
| 58 | } |
| 59 | virtual ~sound_sdl() { } |
| 60 | 60 | |
| 61 | | virtual int init(); |
| 62 | | virtual void exit(); |
| 61 | virtual int init(); |
| 62 | virtual void exit(); |
| 63 | 63 | |
| 64 | | // sound_module |
| 64 | // sound_module |
| 65 | 65 | |
| 66 | | virtual void update_audio_stream(bool is_throttled, const INT16 *buffer, int samples_this_frame); |
| 67 | | virtual void set_mastervolume(int attenuation); |
| 66 | virtual void update_audio_stream(bool is_throttled, const INT16 *buffer, int samples_this_frame); |
| 67 | virtual void set_mastervolume(int attenuation); |
| 68 | 68 | |
| 69 | 69 | private: |
| 70 | | int lock_buffer(bool is_throttled, long offset, long size, void **buffer1, long *length1, void **buffer2, long *length2); |
| 71 | | void unlock_buffer(void); |
| 72 | | void att_memcpy(void *dest, const INT16 *data, int bytes_to_copy); |
| 73 | | void copy_sample_data(bool is_throttled, const INT16 *data, int bytes_to_copy); |
| 74 | | int sdl_create_buffers(void); |
| 75 | | void sdl_destroy_buffers(void); |
| 70 | int lock_buffer(bool is_throttled, long offset, long size, void **buffer1, long *length1, void **buffer2, long *length2); |
| 71 | void unlock_buffer(void); |
| 72 | void att_memcpy(void *dest, const INT16 *data, int bytes_to_copy); |
| 73 | void copy_sample_data(bool is_throttled, const INT16 *data, int bytes_to_copy); |
| 74 | int sdl_create_buffers(void); |
| 75 | void sdl_destroy_buffers(void); |
| 76 | 76 | |
| 77 | | int sdl_xfer_samples; |
| 78 | | int stream_in_initialized; |
| 79 | | int stream_loop; |
| 80 | | int attenuation; |
| 77 | int sdl_xfer_samples; |
| 78 | int stream_in_initialized; |
| 79 | int stream_loop; |
| 80 | int attenuation; |
| 81 | 81 | |
| 82 | | int buf_locked; |
| 82 | int buf_locked; |
| 83 | 83 | |
| 84 | | INT8 *stream_buffer; |
| 85 | | volatile INT32 stream_playpos; |
| 84 | INT8 *stream_buffer; |
| 85 | volatile INT32 stream_playpos; |
| 86 | 86 | |
| 87 | | UINT32 stream_buffer_size; |
| 88 | | UINT32 stream_buffer_in; |
| 87 | UINT32 stream_buffer_size; |
| 88 | UINT32 stream_buffer_in; |
| 89 | 89 | |
| 90 | | // buffer over/underflow counts |
| 91 | | int buffer_underflows; |
| 92 | | int buffer_overflows; |
| 90 | // buffer over/underflow counts |
| 91 | int buffer_underflows; |
| 92 | int buffer_overflows; |
| 93 | 93 | |
| 94 | 94 | |
| 95 | 95 | }; |
| r243189 | r243190 | |
| 354 | 354 | //============================================================ |
| 355 | 355 | static void sdl_callback(void *userdata, Uint8 *stream, int len) |
| 356 | 356 | { |
| 357 | | sound_sdl *thiz = (sound_sdl *) userdata; |
| 357 | sound_sdl *thiz = (sound_sdl *) userdata; |
| 358 | 358 | int len1, len2, sb_in; |
| 359 | 359 | |
| 360 | 360 | sb_in = thiz->stream_buffer_in; |
| r243189 | r243190 | |
| 379 | 379 | len2 = 0; |
| 380 | 380 | } |
| 381 | 381 | |
| 382 | | memcpy(stream, thiz->stream_buffer + thiz->stream_playpos, len1); |
| 383 | | memset(thiz->stream_buffer + thiz->stream_playpos, 0, len1); // no longer needed |
| 384 | | if (len2) |
| 385 | | { |
| 386 | | memcpy(stream+len1, thiz->stream_buffer, len2); |
| 387 | | memset(thiz->stream_buffer, 0, len2); // no longer needed |
| 388 | | } |
| 382 | memcpy(stream, thiz->stream_buffer + thiz->stream_playpos, len1); |
| 383 | memset(thiz->stream_buffer + thiz->stream_playpos, 0, len1); // no longer needed |
| 384 | if (len2) |
| 385 | { |
| 386 | memcpy(stream+len1, thiz->stream_buffer, len2); |
| 387 | memset(thiz->stream_buffer, 0, len2); // no longer needed |
| 388 | } |
| 389 | 389 | |
| 390 | 390 | |
| 391 | 391 | // move the play cursor |
| 392 | | thiz->stream_playpos += len1 + len2; |
| 392 | thiz->stream_playpos += len1 + len2; |
| 393 | 393 | if (thiz->stream_playpos >= thiz->stream_buffer_size) |
| 394 | 394 | { |
| 395 | | thiz->stream_playpos -= thiz->stream_buffer_size; |
| 395 | thiz->stream_playpos -= thiz->stream_buffer_size; |
| 396 | 396 | thiz->stream_loop = 0; |
| 397 | 397 | |
| 398 | 398 | if (LOG_SOUND) |
| r243189 | r243190 | |
| 416 | 416 | SDL_AudioSpec aspec, obtained; |
| 417 | 417 | char audio_driver[16] = ""; |
| 418 | 418 | |
| 419 | | if (LOG_SOUND) |
| 420 | | sound_log = fopen(SDLMAME_SOUND_LOG, "w"); |
| 419 | if (LOG_SOUND) |
| 420 | sound_log = fopen(SDLMAME_SOUND_LOG, "w"); |
| 421 | 421 | |
| 422 | | // skip if sound disabled |
| 423 | | if (sample_rate() != 0) |
| 424 | | { |
| 425 | | if (SDL_InitSubSystem(SDL_INIT_AUDIO)) { |
| 426 | | osd_printf_error("Could not initialize SDL %s\n", SDL_GetError()); |
| 427 | | return -1; |
| 428 | | } |
| 422 | // skip if sound disabled |
| 423 | if (sample_rate() != 0) |
| 424 | { |
| 425 | if (SDL_InitSubSystem(SDL_INIT_AUDIO)) { |
| 426 | osd_printf_error("Could not initialize SDL %s\n", SDL_GetError()); |
| 427 | return -1; |
| 428 | } |
| 429 | 429 | |
| 430 | | osd_printf_verbose("Audio: Start initialization\n"); |
| 431 | | #if (SDLMAME_SDL2) |
| 432 | | strncpy(audio_driver, SDL_GetCurrentAudioDriver(), sizeof(audio_driver)); |
| 433 | | #else |
| 434 | | SDL_AudioDriverName(audio_driver, sizeof(audio_driver)); |
| 435 | | #endif |
| 436 | | osd_printf_verbose("Audio: Driver is %s\n", audio_driver); |
| 430 | osd_printf_verbose("Audio: Start initialization\n"); |
| 431 | #if (SDLMAME_SDL2) |
| 432 | strncpy(audio_driver, SDL_GetCurrentAudioDriver(), sizeof(audio_driver)); |
| 433 | #else |
| 434 | SDL_AudioDriverName(audio_driver, sizeof(audio_driver)); |
| 435 | #endif |
| 436 | osd_printf_verbose("Audio: Driver is %s\n", audio_driver); |
| 437 | 437 | |
| 438 | | sdl_xfer_samples = SDL_XFER_SAMPLES; |
| 439 | | stream_in_initialized = 0; |
| 440 | | stream_loop = 0; |
| 438 | sdl_xfer_samples = SDL_XFER_SAMPLES; |
| 439 | stream_in_initialized = 0; |
| 440 | stream_loop = 0; |
| 441 | 441 | |
| 442 | | // set up the audio specs |
| 443 | | aspec.freq = sample_rate(); |
| 444 | | aspec.format = AUDIO_S16SYS; // keep endian independent |
| 445 | | aspec.channels = n_channels; |
| 446 | | aspec.samples = sdl_xfer_samples; |
| 447 | | aspec.callback = sdl_callback; |
| 448 | | aspec.userdata = this; |
| 442 | // set up the audio specs |
| 443 | aspec.freq = sample_rate(); |
| 444 | aspec.format = AUDIO_S16SYS; // keep endian independent |
| 445 | aspec.channels = n_channels; |
| 446 | aspec.samples = sdl_xfer_samples; |
| 447 | aspec.callback = sdl_callback; |
| 448 | aspec.userdata = this; |
| 449 | 449 | |
| 450 | | if (SDL_OpenAudio(&aspec, &obtained) < 0) |
| 451 | | goto cant_start_audio; |
| 450 | if (SDL_OpenAudio(&aspec, &obtained) < 0) |
| 451 | goto cant_start_audio; |
| 452 | 452 | |
| 453 | | osd_printf_verbose("Audio: frequency: %d, channels: %d, samples: %d\n", |
| 454 | | obtained.freq, obtained.channels, obtained.samples); |
| 453 | osd_printf_verbose("Audio: frequency: %d, channels: %d, samples: %d\n", |
| 454 | obtained.freq, obtained.channels, obtained.samples); |
| 455 | 455 | |
| 456 | | sdl_xfer_samples = obtained.samples; |
| 456 | sdl_xfer_samples = obtained.samples; |
| 457 | 457 | |
| 458 | | audio_latency = m_audio_latency; |
| 458 | audio_latency = m_audio_latency; |
| 459 | 459 | |
| 460 | | // pin audio latency |
| 461 | | if (audio_latency > MAX_AUDIO_LATENCY) |
| 462 | | { |
| 463 | | audio_latency = MAX_AUDIO_LATENCY; |
| 464 | | } |
| 465 | | else if (audio_latency < 1) |
| 466 | | { |
| 467 | | audio_latency = 1; |
| 468 | | } |
| 460 | // pin audio latency |
| 461 | if (audio_latency > MAX_AUDIO_LATENCY) |
| 462 | { |
| 463 | audio_latency = MAX_AUDIO_LATENCY; |
| 464 | } |
| 465 | else if (audio_latency < 1) |
| 466 | { |
| 467 | audio_latency = 1; |
| 468 | } |
| 469 | 469 | |
| 470 | | // compute the buffer sizes |
| 471 | | stream_buffer_size = (sample_rate() * 2 * sizeof(INT16) * (2 + audio_latency)) / 30; |
| 472 | | stream_buffer_size = (stream_buffer_size / 1024) * 1024; |
| 473 | | if (stream_buffer_size < 1024) |
| 474 | | stream_buffer_size = 1024; |
| 470 | // compute the buffer sizes |
| 471 | stream_buffer_size = (sample_rate() * 2 * sizeof(INT16) * (2 + audio_latency)) / 30; |
| 472 | stream_buffer_size = (stream_buffer_size / 1024) * 1024; |
| 473 | if (stream_buffer_size < 1024) |
| 474 | stream_buffer_size = 1024; |
| 475 | 475 | |
| 476 | | // create the buffers |
| 477 | | if (sdl_create_buffers()) |
| 478 | | goto cant_create_buffers; |
| 476 | // create the buffers |
| 477 | if (sdl_create_buffers()) |
| 478 | goto cant_create_buffers; |
| 479 | 479 | |
| 480 | | // set the startup volume |
| 481 | | set_mastervolume(attenuation); |
| 482 | | osd_printf_verbose("Audio: End initialization\n"); |
| 483 | | return 0; |
| 480 | // set the startup volume |
| 481 | set_mastervolume(attenuation); |
| 482 | osd_printf_verbose("Audio: End initialization\n"); |
| 483 | return 0; |
| 484 | 484 | |
| 485 | | // error handling |
| 486 | | cant_create_buffers: |
| 487 | | cant_start_audio: |
| 488 | | osd_printf_verbose("Audio: Initialization failed. SDL error: %s\n", SDL_GetError()); |
| 485 | // error handling |
| 486 | cant_create_buffers: |
| 487 | cant_start_audio: |
| 488 | osd_printf_verbose("Audio: Initialization failed. SDL error: %s\n", SDL_GetError()); |
| 489 | 489 | |
| 490 | | return -1; |
| 491 | | } |
| 490 | return -1; |
| 491 | } |
| 492 | 492 | |
| 493 | | return 0; |
| 493 | return 0; |
| 494 | 494 | } |
| 495 | 495 | |
| 496 | 496 | |
| r243189 | r243190 | |
| 501 | 501 | |
| 502 | 502 | void sound_sdl::exit() |
| 503 | 503 | { |
| 504 | | // if nothing to do, don't do it |
| 505 | | if (sample_rate() == 0) |
| 506 | | return; |
| 504 | // if nothing to do, don't do it |
| 505 | if (sample_rate() == 0) |
| 506 | return; |
| 507 | 507 | |
| 508 | | osd_printf_verbose("sdl_kill: closing audio\n"); |
| 508 | osd_printf_verbose("sdl_kill: closing audio\n"); |
| 509 | 509 | SDL_CloseAudio(); |
| 510 | 510 | |
| 511 | 511 | SDL_QuitSubSystem(SDL_INIT_AUDIO); |
| 512 | 512 | |
| 513 | | // kill the buffers |
| 514 | | sdl_destroy_buffers(); |
| 513 | // kill the buffers |
| 514 | sdl_destroy_buffers(); |
| 515 | 515 | |
| 516 | | // print out over/underflow stats |
| 517 | | if (buffer_overflows || buffer_underflows) |
| 518 | | osd_printf_verbose("Sound buffer: overflows=%d underflows=%d\n", buffer_overflows, buffer_underflows); |
| 516 | // print out over/underflow stats |
| 517 | if (buffer_overflows || buffer_underflows) |
| 518 | osd_printf_verbose("Sound buffer: overflows=%d underflows=%d\n", buffer_overflows, buffer_underflows); |
| 519 | 519 | |
| 520 | | if (LOG_SOUND) |
| 521 | | { |
| 522 | | fprintf(sound_log, "Sound buffer: overflows=%d underflows=%d\n", buffer_overflows, buffer_underflows); |
| 523 | | fclose(sound_log); |
| 524 | | } |
| 520 | if (LOG_SOUND) |
| 521 | { |
| 522 | fprintf(sound_log, "Sound buffer: overflows=%d underflows=%d\n", buffer_overflows, buffer_underflows); |
| 523 | fclose(sound_log); |
| 524 | } |
| 525 | 525 | } |
| 526 | 526 | |
| 527 | 527 | |
| r243189 | r243190 | |
| 555 | 555 | |
| 556 | 556 | |
| 557 | 557 | #else /* SDLMAME_UNIX */ |
| 558 | | MODULE_NOT_SUPPORTED(sound_sdl, OSD_SOUND_PROVIDER, "sdl") |
| 558 | MODULE_NOT_SUPPORTED(sound_sdl, OSD_SOUND_PROVIDER, "sdl") |
| 559 | 559 | #endif |
| 560 | 560 | |
| 561 | 561 | MODULE_DEFINITION(SOUND_SDL, sound_sdl) |
trunk/src/osd/sdl/draw13.c
| r243189 | r243190 | |
| 48 | 48 | |
| 49 | 49 | static inline bool is_opaque(const float &a) |
| 50 | 50 | { |
| 51 | | return (a >= 1.0f); |
| 51 | return (a >= 1.0f); |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | 54 | static inline bool is_transparent(const float &a) |
| 55 | 55 | { |
| 56 | | return (a < 0.0001f); |
| 56 | return (a < 0.0001f); |
| 57 | 57 | } |
| 58 | 58 | |
| 59 | 59 | //============================================================ |
| r243189 | r243190 | |
| 63 | 63 | |
| 64 | 64 | struct quad_setup_data |
| 65 | 65 | { |
| 66 | | quad_setup_data() |
| 67 | | : dudx(0), dvdx(0), dudy(0), dvdy(0), startu(0), startv(0), |
| 68 | | rotwidth(0), rotheight(0) |
| 69 | | {} |
| 70 | | void compute(const render_primitive &prim); |
| 66 | quad_setup_data() |
| 67 | : dudx(0), dvdx(0), dudy(0), dvdy(0), startu(0), startv(0), |
| 68 | rotwidth(0), rotheight(0) |
| 69 | {} |
| 70 | void compute(const render_primitive &prim); |
| 71 | 71 | |
| 72 | 72 | INT32 dudx, dvdx, dudy, dvdy; |
| 73 | 73 | INT32 startu, startv; |
| r243189 | r243190 | |
| 105 | 105 | /* texture_info holds information about a texture */ |
| 106 | 106 | class texture_info |
| 107 | 107 | { |
| 108 | | friend class simple_list<texture_info>; |
| 108 | friend class simple_list<texture_info>; |
| 109 | 109 | public: |
| 110 | | texture_info(SDL_Renderer *renderer, const render_texinfo &texsource, const quad_setup_data &setup, const UINT32 flags); |
| 111 | | ~texture_info(); |
| 110 | texture_info(SDL_Renderer *renderer, const render_texinfo &texsource, const quad_setup_data &setup, const UINT32 flags); |
| 111 | ~texture_info(); |
| 112 | 112 | |
| 113 | | void set_data(const render_texinfo &texsource, const UINT32 flags); |
| 114 | | void render_quad(const render_primitive *prim, const int x, const int y); |
| 115 | | bool matches(const render_primitive &prim, const quad_setup_data &setup); |
| 113 | void set_data(const render_texinfo &texsource, const UINT32 flags); |
| 114 | void render_quad(const render_primitive *prim, const int x, const int y); |
| 115 | bool matches(const render_primitive &prim, const quad_setup_data &setup); |
| 116 | 116 | |
| 117 | | copy_info_t *compute_size_type(); |
| 117 | copy_info_t *compute_size_type(); |
| 118 | 118 | |
| 119 | 119 | void *m_pixels; // pixels for the texture |
| 120 | 120 | int m_pitch; |
| r243189 | r243190 | |
| 125 | 125 | osd_ticks_t m_last_access; |
| 126 | 126 | |
| 127 | 127 | int raw_width() const { return m_texinfo.width; } |
| 128 | | int raw_height() const { return m_texinfo.height; } |
| 128 | int raw_height() const { return m_texinfo.height; } |
| 129 | 129 | |
| 130 | | texture_info *next() { return m_next; } |
| 131 | | const render_texinfo &texinfo() const { return m_texinfo; } |
| 132 | | render_texinfo &texinfo() { return m_texinfo; } |
| 130 | texture_info *next() { return m_next; } |
| 131 | const render_texinfo &texinfo() const { return m_texinfo; } |
| 132 | render_texinfo &texinfo() { return m_texinfo; } |
| 133 | 133 | |
| 134 | | const HashT hash() const { return m_hash; } |
| 135 | | const UINT32 flags() const { return m_flags; } |
| 136 | | const bool is_pixels_owned() const { // do we own / allocated it ? |
| 137 | | return false && ((m_sdl_access == SDL_TEXTUREACCESS_STATIC) |
| 138 | | && (m_copyinfo->func != NULL)) ; |
| 139 | | } |
| 134 | const HashT hash() const { return m_hash; } |
| 135 | const UINT32 flags() const { return m_flags; } |
| 136 | const bool is_pixels_owned() const { // do we own / allocated it ? |
| 137 | return false && ((m_sdl_access == SDL_TEXTUREACCESS_STATIC) |
| 138 | && (m_copyinfo->func != NULL)) ; |
| 139 | } |
| 140 | 140 | |
| 141 | 141 | private: |
| 142 | | Uint32 m_sdl_access; |
| 143 | | SDL_Renderer * m_renderer; |
| 144 | | render_texinfo m_texinfo; // copy of the texture info |
| 145 | | HashT m_hash; // hash value for the texture (must be >= pointer size) |
| 146 | | UINT32 m_flags; // rendering flags |
| 142 | Uint32 m_sdl_access; |
| 143 | SDL_Renderer * m_renderer; |
| 144 | render_texinfo m_texinfo; // copy of the texture info |
| 145 | HashT m_hash; // hash value for the texture (must be >= pointer size) |
| 146 | UINT32 m_flags; // rendering flags |
| 147 | 147 | |
| 148 | | SDL_Texture * m_texture_id; |
| 149 | | int m_is_rotated; |
| 148 | SDL_Texture * m_texture_id; |
| 149 | int m_is_rotated; |
| 150 | 150 | |
| 151 | | int m_format; // texture format |
| 152 | | SDL_BlendMode m_sdl_blendmode; |
| 151 | int m_format; // texture format |
| 152 | SDL_BlendMode m_sdl_blendmode; |
| 153 | 153 | |
| 154 | | texture_info * m_next; // next texture in the list |
| 154 | texture_info * m_next; // next texture in the list |
| 155 | 155 | }; |
| 156 | 156 | |
| 157 | 157 | /* sdl_info is the information about SDL for the current screen */ |
| 158 | 158 | struct sdl_info |
| 159 | 159 | { |
| 160 | | sdl_info() |
| 161 | | : m_blittimer(0), m_renderer(NULL), |
| 162 | | m_hofs(0), m_vofs(0), |
| 163 | | m_resize_pending(0), m_resize_width(0), m_resize_height(0), |
| 164 | | m_last_blit_time(0), m_last_blit_pixels(0) |
| 165 | | {} |
| 160 | sdl_info() |
| 161 | : m_blittimer(0), m_renderer(NULL), |
| 162 | m_hofs(0), m_vofs(0), |
| 163 | m_resize_pending(0), m_resize_width(0), m_resize_height(0), |
| 164 | m_last_blit_time(0), m_last_blit_pixels(0) |
| 165 | {} |
| 166 | 166 | |
| 167 | | void render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y); |
| 167 | void render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y); |
| 168 | 168 | |
| 169 | | texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup); |
| 170 | | texture_info *texture_update(const render_primitive &prim); |
| 169 | texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup); |
| 170 | texture_info *texture_update(const render_primitive &prim); |
| 171 | 171 | |
| 172 | 172 | INT32 m_blittimer; |
| 173 | 173 | |
| r243189 | r243190 | |
| 389 | 389 | target_rect.w = round_nearest(prim->bounds.x1 - prim->bounds.x0); |
| 390 | 390 | target_rect.h = round_nearest(prim->bounds.y1 - prim->bounds.y0); |
| 391 | 391 | |
| 392 | | SDL_SetTextureBlendMode(m_texture_id, m_sdl_blendmode); |
| 393 | | set_coloralphamode(m_texture_id, &prim->color); |
| 394 | | SDL_RenderCopy(m_renderer, m_texture_id, NULL, &target_rect); |
| 392 | SDL_SetTextureBlendMode(m_texture_id, m_sdl_blendmode); |
| 393 | set_coloralphamode(m_texture_id, &prim->color); |
| 394 | SDL_RenderCopy(m_renderer, m_texture_id, NULL, &target_rect); |
| 395 | 395 | } |
| 396 | 396 | |
| 397 | 397 | void sdl_info::render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y) |
| 398 | 398 | { |
| 399 | | SDL_Rect target_rect; |
| 399 | SDL_Rect target_rect; |
| 400 | 400 | |
| 401 | | target_rect.x = x; |
| 402 | | target_rect.y = y; |
| 403 | | target_rect.w = round_nearest(prim->bounds.x1 - prim->bounds.x0); |
| 404 | | target_rect.h = round_nearest(prim->bounds.y1 - prim->bounds.y0); |
| 401 | target_rect.x = x; |
| 402 | target_rect.y = y; |
| 403 | target_rect.w = round_nearest(prim->bounds.x1 - prim->bounds.x0); |
| 404 | target_rect.h = round_nearest(prim->bounds.y1 - prim->bounds.y0); |
| 405 | 405 | |
| 406 | | if (texture) |
| 407 | | { |
| 408 | | copy_info_t *copyinfo = texture->m_copyinfo; |
| 409 | | copyinfo->time -= osd_ticks(); |
| 410 | | texture->render_quad(prim, x, y); |
| 411 | | copyinfo->time += osd_ticks(); |
| 406 | if (texture) |
| 407 | { |
| 408 | copy_info_t *copyinfo = texture->m_copyinfo; |
| 409 | copyinfo->time -= osd_ticks(); |
| 410 | texture->render_quad(prim, x, y); |
| 411 | copyinfo->time += osd_ticks(); |
| 412 | 412 | |
| 413 | | copyinfo->pixel_count += MAX(STAT_PIXEL_THRESHOLD , (texture->raw_width() * texture->raw_height())); |
| 414 | | if (m_last_blit_pixels) |
| 415 | | { |
| 416 | | copyinfo->time += (m_last_blit_time * (INT64) (texture->raw_width() * texture->raw_height())) / (INT64) m_last_blit_pixels; |
| 417 | | } |
| 418 | | copyinfo->samples++; |
| 419 | | copyinfo->perf = ( texture->m_copyinfo->pixel_count * (osd_ticks_per_second()/1000)) / texture->m_copyinfo->time; |
| 420 | | } |
| 421 | | else |
| 422 | | { |
| 423 | | UINT32 sr = (UINT32)(255.0f * prim->color.r); |
| 424 | | UINT32 sg = (UINT32)(255.0f * prim->color.g); |
| 425 | | UINT32 sb = (UINT32)(255.0f * prim->color.b); |
| 426 | | UINT32 sa = (UINT32)(255.0f * prim->color.a); |
| 413 | copyinfo->pixel_count += MAX(STAT_PIXEL_THRESHOLD , (texture->raw_width() * texture->raw_height())); |
| 414 | if (m_last_blit_pixels) |
| 415 | { |
| 416 | copyinfo->time += (m_last_blit_time * (INT64) (texture->raw_width() * texture->raw_height())) / (INT64) m_last_blit_pixels; |
| 417 | } |
| 418 | copyinfo->samples++; |
| 419 | copyinfo->perf = ( texture->m_copyinfo->pixel_count * (osd_ticks_per_second()/1000)) / texture->m_copyinfo->time; |
| 420 | } |
| 421 | else |
| 422 | { |
| 423 | UINT32 sr = (UINT32)(255.0f * prim->color.r); |
| 424 | UINT32 sg = (UINT32)(255.0f * prim->color.g); |
| 425 | UINT32 sb = (UINT32)(255.0f * prim->color.b); |
| 426 | UINT32 sa = (UINT32)(255.0f * prim->color.a); |
| 427 | 427 | |
| 428 | | SDL_SetRenderDrawBlendMode(m_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags))); |
| 429 | | SDL_SetRenderDrawColor(m_renderer, sr, sg, sb, sa); |
| 430 | | SDL_RenderFillRect(m_renderer, &target_rect); |
| 431 | | } |
| 428 | SDL_SetRenderDrawBlendMode(m_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags))); |
| 429 | SDL_SetRenderDrawColor(m_renderer, sr, sg, sb, sa); |
| 430 | SDL_RenderFillRect(m_renderer, &target_rect); |
| 431 | } |
| 432 | 432 | } |
| 433 | 433 | |
| 434 | 434 | static int RendererSupportsFormat(SDL_Renderer *renderer, Uint32 format, Uint32 access, const char *sformat) |
| r243189 | r243190 | |
| 518 | 518 | else |
| 519 | 519 | osd_printf_verbose("Loaded opengl shared library: %s\n", stemp ? stemp : "<default>"); |
| 520 | 520 | |
| 521 | | /* Enable bilinear filtering in case it is supported. |
| 522 | | * This applies to all texture operations. However, artwort is pre-scaled |
| 523 | | * and thus shouldn't be affected. |
| 524 | | */ |
| 525 | | if (video_config.filter) |
| 526 | | { |
| 527 | | SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); |
| 528 | | } |
| 529 | | else |
| 530 | | { |
| 531 | | SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); |
| 532 | | } |
| 521 | /* Enable bilinear filtering in case it is supported. |
| 522 | * This applies to all texture operations. However, artwort is pre-scaled |
| 523 | * and thus shouldn't be affected. |
| 524 | */ |
| 525 | if (video_config.filter) |
| 526 | { |
| 527 | SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); |
| 528 | } |
| 529 | else |
| 530 | { |
| 531 | SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); |
| 532 | } |
| 533 | 533 | |
| 534 | 534 | return 0; |
| 535 | 535 | } |
| r243189 | r243190 | |
| 604 | 604 | { |
| 605 | 605 | SDL_DisplayMode mode; |
| 606 | 606 | //SDL_GetCurrentDisplayMode(window->monitor()->handle, &mode); |
| 607 | | SDL_GetWindowDisplayMode(window->sdl_window, &mode); |
| 607 | SDL_GetWindowDisplayMode(window->sdl_window, &mode); |
| 608 | 608 | sdl->m_original_mode = mode; |
| 609 | 609 | mode.w = width; |
| 610 | 610 | mode.h = height; |
| r243189 | r243190 | |
| 630 | 630 | osd_printf_warning("Ignoring depth %d\n", window->depth); |
| 631 | 631 | } |
| 632 | 632 | } |
| 633 | | SDL_SetWindowDisplayMode(window->sdl_window, &mode); // Try to set mode |
| 633 | SDL_SetWindowDisplayMode(window->sdl_window, &mode); // Try to set mode |
| 634 | 634 | #ifndef SDLMAME_WIN32 |
| 635 | | /* FIXME: Warp the mouse to 0,0 in case a virtual desktop resolution |
| 636 | | * is in place after the mode switch - which will most likely be the case |
| 637 | | * This is a hack to work around a deficiency in SDL2 |
| 638 | | */ |
| 639 | | SDL_WarpMouseInWindow(window->sdl_window, 1, 1); |
| 635 | /* FIXME: Warp the mouse to 0,0 in case a virtual desktop resolution |
| 636 | * is in place after the mode switch - which will most likely be the case |
| 637 | * This is a hack to work around a deficiency in SDL2 |
| 638 | */ |
| 639 | SDL_WarpMouseInWindow(window->sdl_window, 1, 1); |
| 640 | 640 | #endif |
| 641 | 641 | } |
| 642 | 642 | else |
| r243189 | r243190 | |
| 736 | 736 | SDL_GetWindowSize(window->sdl_window, &window->width, &window->height); |
| 737 | 737 | sdl->m_resize_pending = 0; |
| 738 | 738 | SDL_RenderSetViewport(sdl->m_renderer, NULL); |
| 739 | | //sdlvideo_monitor_refresh(window->monitor()); |
| 739 | //sdlvideo_monitor_refresh(window->monitor()); |
| 740 | 740 | |
| 741 | 741 | } |
| 742 | 742 | |
| r243189 | r243190 | |
| 855 | 855 | |
| 856 | 856 | drawsdl2_destroy_all_textures(window); |
| 857 | 857 | |
| 858 | | if (window->fullscreen() && video_config.switchres) |
| 859 | | { |
| 860 | | SDL_SetWindowFullscreen(window->sdl_window, 0); // Try to set mode |
| 861 | | SDL_SetWindowDisplayMode(window->sdl_window, &sdl->m_original_mode); // Try to set mode |
| 862 | | SDL_SetWindowFullscreen(window->sdl_window, SDL_WINDOW_FULLSCREEN); // Try to set mode |
| 863 | | } |
| 858 | if (window->fullscreen() && video_config.switchres) |
| 859 | { |
| 860 | SDL_SetWindowFullscreen(window->sdl_window, 0); // Try to set mode |
| 861 | SDL_SetWindowDisplayMode(window->sdl_window, &sdl->m_original_mode); // Try to set mode |
| 862 | SDL_SetWindowFullscreen(window->sdl_window, SDL_WINDOW_FULLSCREEN); // Try to set mode |
| 863 | } |
| 864 | 864 | |
| 865 | | SDL_DestroyWindow(window->sdl_window); |
| 865 | SDL_DestroyWindow(window->sdl_window); |
| 866 | 866 | |
| 867 | 867 | global_free(sdl); |
| 868 | 868 | window->dxdata = NULL; |
| r243189 | r243190 | |
| 889 | 889 | { |
| 890 | 890 | if (RendererSupportsFormat(m_renderer, bi->dst_fmt, m_sdl_access, bi->dstname)) |
| 891 | 891 | { |
| 892 | | int perf = bi->perf; |
| 892 | int perf = bi->perf; |
| 893 | 893 | if (perf == 0) |
| 894 | 894 | return bi; |
| 895 | 895 | else if (perf > (maxperf * 102) / 100) |
| r243189 | r243190 | |
| 920 | 920 | |
| 921 | 921 | bool texture_info::matches(const render_primitive &prim, const quad_setup_data &setup) |
| 922 | 922 | { |
| 923 | | return texinfo().base == prim.texture.base && |
| 924 | | texinfo().width == prim.texture.width && |
| 925 | | texinfo().height == prim.texture.height && |
| 926 | | texinfo().rowpixels == prim.texture.rowpixels && |
| 927 | | m_setup.dudx == setup.dudx && |
| 928 | | m_setup.dvdx == setup.dvdx && |
| 929 | | m_setup.dudy == setup.dudy && |
| 930 | | m_setup.dvdy == setup.dvdy && |
| 931 | | ((flags() ^ prim.flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0; |
| 923 | return texinfo().base == prim.texture.base && |
| 924 | texinfo().width == prim.texture.width && |
| 925 | texinfo().height == prim.texture.height && |
| 926 | texinfo().rowpixels == prim.texture.rowpixels && |
| 927 | m_setup.dudx == setup.dudx && |
| 928 | m_setup.dvdx == setup.dvdx && |
| 929 | m_setup.dudy == setup.dudy && |
| 930 | m_setup.dvdy == setup.dvdy && |
| 931 | ((flags() ^ prim.flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0; |
| 932 | 932 | } |
| 933 | 933 | |
| 934 | 934 | //============================================================ |
| r243189 | r243190 | |
| 937 | 937 | |
| 938 | 938 | texture_info::texture_info(SDL_Renderer *renderer, const render_texinfo &texsource, const quad_setup_data &setup, UINT32 flags) |
| 939 | 939 | { |
| 940 | | |
| 941 | 940 | // fill in the core data |
| 942 | | m_renderer = renderer; |
| 941 | m_renderer = renderer; |
| 943 | 942 | m_hash = texture_compute_hash(texsource, flags); |
| 944 | 943 | m_flags = flags; |
| 945 | 944 | m_texinfo = texsource; |
| r243189 | r243190 | |
| 997 | 996 | |
| 998 | 997 | if (m_sdl_access == SDL_TEXTUREACCESS_STATIC) |
| 999 | 998 | { |
| 1000 | | if (m_copyinfo->func != NULL) |
| 1001 | | m_pixels = malloc(m_setup.rotwidth * m_setup.rotheight * m_copyinfo->dst_bpp); |
| 1002 | | else |
| 1003 | | m_pixels = NULL; |
| 999 | if (m_copyinfo->func != NULL) |
| 1000 | m_pixels = malloc(m_setup.rotwidth * m_setup.rotheight * m_copyinfo->dst_bpp); |
| 1001 | else |
| 1002 | m_pixels = NULL; |
| 1004 | 1003 | } |
| 1005 | 1004 | m_last_access = osd_ticks(); |
| 1006 | 1005 | |
| r243189 | r243190 | |
| 1008 | 1007 | |
| 1009 | 1008 | texture_info::~texture_info() |
| 1010 | 1009 | { |
| 1011 | | if ( is_pixels_owned() && (m_pixels != NULL) ) |
| 1012 | | free(m_pixels); |
| 1013 | | SDL_DestroyTexture(m_texture_id); |
| 1010 | if ( is_pixels_owned() && (m_pixels != NULL) ) |
| 1011 | free(m_pixels); |
| 1012 | SDL_DestroyTexture(m_texture_id); |
| 1014 | 1013 | } |
| 1015 | 1014 | |
| 1016 | 1015 | //============================================================ |
| r243189 | r243190 | |
| 1082 | 1081 | |
| 1083 | 1082 | #if 0 |
| 1084 | 1083 | printf("tl.u %f tl.v %f\n", texcoords->tl.u, texcoords->tl.v); |
| 1085 | | printf("tr.u %f tr.v %f\n", texcoords->tr.u, texcoords->tr.v); |
| 1086 | | printf("bl.u %f bl.v %f\n", texcoords->bl.u, texcoords->bl.v); |
| 1087 | | printf("br.u %f br.v %f\n", texcoords->br.u, texcoords->br.v); |
| 1084 | printf("tr.u %f tr.v %f\n", texcoords->tr.u, texcoords->tr.v); |
| 1085 | printf("bl.u %f bl.v %f\n", texcoords->bl.u, texcoords->bl.v); |
| 1086 | printf("br.u %f br.v %f\n", texcoords->br.u, texcoords->br.v); |
| 1088 | 1087 | /* compute start and delta U,V coordinates now */ |
| 1089 | 1088 | #endif |
| 1090 | 1089 | |
| r243189 | r243190 | |
| 1162 | 1161 | if (texture == NULL && prim.texture.base != NULL) |
| 1163 | 1162 | { |
| 1164 | 1163 | texture = global_alloc(texture_info(m_renderer, prim.texture, setup, prim.flags)); |
| 1165 | | /* add us to the texture list */ |
| 1164 | /* add us to the texture list */ |
| 1166 | 1165 | m_texlist.prepend(*texture); |
| 1167 | 1166 | |
| 1168 | 1167 | } |
| r243189 | r243190 | |
| 1191 | 1190 | if(window->primlist) |
| 1192 | 1191 | { |
| 1193 | 1192 | window->primlist->acquire_lock(); |
| 1194 | | sdl->m_texlist.reset(); |
| 1195 | | window->primlist->release_lock(); |
| 1193 | sdl->m_texlist.reset(); |
| 1194 | window->primlist->release_lock(); |
| 1196 | 1195 | } |
| 1197 | 1196 | else |
| 1198 | | sdl->m_texlist.reset(); |
| 1197 | sdl->m_texlist.reset(); |
| 1199 | 1198 | } |
trunk/src/osd/sdl/window.c
| r243189 | r243190 | |
| 270 | 270 | * The code below will document which hints were set. |
| 271 | 271 | */ |
| 272 | 272 | const char * hints[] = { SDL_HINT_FRAMEBUFFER_ACCELERATION, |
| 273 | | SDL_HINT_RENDER_DRIVER, SDL_HINT_RENDER_OPENGL_SHADERS, |
| 274 | | SDL_HINT_RENDER_SCALE_QUALITY, |
| 275 | | SDL_HINT_RENDER_VSYNC, |
| 276 | | SDL_HINT_VIDEO_X11_XVIDMODE, SDL_HINT_VIDEO_X11_XINERAMA, |
| 277 | | SDL_HINT_VIDEO_X11_XRANDR, SDL_HINT_GRAB_KEYBOARD, |
| 278 | | SDL_HINT_MOUSE_RELATIVE_MODE_WARP, |
| 279 | | SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, SDL_HINT_IDLE_TIMER_DISABLED, |
| 280 | | SDL_HINT_ORIENTATIONS, |
| 281 | | SDL_HINT_XINPUT_ENABLED, SDL_HINT_GAMECONTROLLERCONFIG, |
| 282 | | SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, SDL_HINT_ALLOW_TOPMOST, |
| 283 | | SDL_HINT_TIMER_RESOLUTION, |
| 273 | SDL_HINT_RENDER_DRIVER, SDL_HINT_RENDER_OPENGL_SHADERS, |
| 274 | SDL_HINT_RENDER_SCALE_QUALITY, |
| 275 | SDL_HINT_RENDER_VSYNC, |
| 276 | SDL_HINT_VIDEO_X11_XVIDMODE, SDL_HINT_VIDEO_X11_XINERAMA, |
| 277 | SDL_HINT_VIDEO_X11_XRANDR, SDL_HINT_GRAB_KEYBOARD, |
| 278 | SDL_HINT_MOUSE_RELATIVE_MODE_WARP, |
| 279 | SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, SDL_HINT_IDLE_TIMER_DISABLED, |
| 280 | SDL_HINT_ORIENTATIONS, |
| 281 | SDL_HINT_XINPUT_ENABLED, SDL_HINT_GAMECONTROLLERCONFIG, |
| 282 | SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, SDL_HINT_ALLOW_TOPMOST, |
| 283 | SDL_HINT_TIMER_RESOLUTION, |
| 284 | 284 | #if SDL_VERSION_ATLEAST(2, 0, 2) |
| 285 | | SDL_HINT_RENDER_DIRECT3D_THREADSAFE, SDL_HINT_VIDEO_ALLOW_SCREENSAVER, |
| 286 | | SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, |
| 287 | | SDL_HINT_VIDEO_WIN_D3DCOMPILER, SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT, |
| 288 | | SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, |
| 285 | SDL_HINT_RENDER_DIRECT3D_THREADSAFE, SDL_HINT_VIDEO_ALLOW_SCREENSAVER, |
| 286 | SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, |
| 287 | SDL_HINT_VIDEO_WIN_D3DCOMPILER, SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT, |
| 288 | SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, |
| 289 | 289 | #endif |
| 290 | 290 | #if SDL_VERSION_ATLEAST(2, 0, 3) |
| 291 | | SDL_HINT_RENDER_DIRECT3D11_DEBUG, SDL_HINT_VIDEO_HIGHDPI_DISABLED, |
| 292 | | SDL_HINT_WINRT_PRIVACY_POLICY_URL, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL, |
| 293 | | SDL_HINT_WINRT_HANDLE_BACK_BUTTON, |
| 291 | SDL_HINT_RENDER_DIRECT3D11_DEBUG, SDL_HINT_VIDEO_HIGHDPI_DISABLED, |
| 292 | SDL_HINT_WINRT_PRIVACY_POLICY_URL, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL, |
| 293 | SDL_HINT_WINRT_HANDLE_BACK_BUTTON, |
| 294 | 294 | #endif |
| 295 | | NULL |
| 296 | | }; |
| 295 | NULL |
| 296 | }; |
| 297 | 297 | |
| 298 | 298 | |
| 299 | | osd_printf_verbose("\nHints:\n"); |
| 300 | | for (int i = 0; hints[i] != NULL; i++) |
| 301 | | osd_printf_verbose("\t%-40s %s\n", hints[i], SDL_GetHint(hints[i])); |
| 299 | osd_printf_verbose("\nHints:\n"); |
| 300 | for (int i = 0; hints[i] != NULL; i++) |
| 301 | osd_printf_verbose("\t%-40s %s\n", hints[i], SDL_GetHint(hints[i])); |
| 302 | 302 | #endif |
| 303 | 303 | |
| 304 | 304 | // set up the window list |
| r243189 | r243190 | |
| 1018 | 1018 | |
| 1019 | 1019 | if (osd_event_wait(rendered_event, event_wait_ticks)) |
| 1020 | 1020 | { |
| 1021 | | if ((!fullscreen()) || (video_config.switchres)) |
| 1022 | | { |
| 1023 | | blit_surface_size(width, height); |
| 1024 | | } |
| 1025 | | else |
| 1026 | | { |
| 1027 | | blit_surface_size(monitor()->center_width, monitor()->center_height); |
| 1028 | | } |
| 1021 | if ((!fullscreen()) || (video_config.switchres)) |
| 1022 | { |
| 1023 | blit_surface_size(width, height); |
| 1024 | } |
| 1025 | else |
| 1026 | { |
| 1027 | blit_surface_size(monitor()->center_width, monitor()->center_height); |
| 1028 | } |
| 1029 | 1029 | |
| 1030 | 1030 | // ensure the target bounds are up-to-date, and then get the primitives |
| 1031 | | set_target_bounds(this); |
| 1031 | set_target_bounds(this); |
| 1032 | 1032 | |
| 1033 | 1033 | render_primitive_list &primlist = target->get_primitives(); |
| 1034 | 1034 | |