src/mess/tapectrl.c
| r8327 | r8328 | |
| 1 | | /********************************************************************* |
| 2 | | |
| 3 | | tapectrl.c |
| 4 | | |
| 5 | | MESS's clunky built-in tape control |
| 6 | | |
| 7 | | *********************************************************************/ |
| 8 | | |
| 9 | | #include "emu.h" |
| 10 | | #include "image.h" |
| 11 | | #include "ui.h" |
| 12 | | #include "uimenu.h" |
| 13 | | #include "devices/cassette.h" |
| 14 | | |
| 15 | | |
| 16 | | |
| 17 | | /*************************************************************************** |
| 18 | | TYPE DEFINITIONS |
| 19 | | ***************************************************************************/ |
| 20 | | #define TAPECMD_NULL ((void *) 0x0000) |
| 21 | | #define TAPECMD_STOP ((void *) 0x0001) |
| 22 | | #define TAPECMD_PLAY ((void *) 0x0002) |
| 23 | | #define TAPECMD_RECORD ((void *) 0x0003) |
| 24 | | #define TAPECMD_REWIND ((void *) 0x0004) |
| 25 | | #define TAPECMD_FAST_FORWARD ((void *) 0x0005) |
| 26 | | #define TAPECMD_SLIDER ((void *) 0x0006) |
| 27 | | #define TAPECMD_SELECT ((void *) 0x0007) |
| 28 | | |
| 29 | | |
| 30 | | |
| 31 | | typedef struct _tape_control_menu_state tape_control_menu_state; |
| 32 | | struct _tape_control_menu_state |
| 33 | | { |
| 34 | | int index; |
| 35 | | device_image_interface *device; |
| 36 | | }; |
| 37 | | |
| 38 | | |
| 39 | | |
| 40 | | /*************************************************************************** |
| 41 | | IMPLEMENTATION |
| 42 | | ***************************************************************************/ |
| 43 | | |
| 44 | | /*------------------------------------------------- |
| 45 | | cassette_count - returns the number of cassette |
| 46 | | devices in the machine |
| 47 | | -------------------------------------------------*/ |
| 48 | | |
| 49 | | INLINE int cassette_count( running_machine *machine ) |
| 50 | | { |
| 51 | | int count = 0; |
| 52 | | running_device *device = machine->devicelist.first(CASSETTE ); |
| 53 | | |
| 54 | | while ( device ) |
| 55 | | { |
| 56 | | count++; |
| 57 | | device = device->typenext(); |
| 58 | | } |
| 59 | | return count; |
| 60 | | } |
| 61 | | |
| 62 | | /*------------------------------------------------- |
| 63 | | tapecontrol_gettime - returns a textual |
| 64 | | representation of the time |
| 65 | | -------------------------------------------------*/ |
| 66 | | |
| 67 | | astring *tapecontrol_gettime(astring *dest, running_device *device, int *curpos, int *endpos) |
| 68 | | { |
| 69 | | double t0, t1; |
| 70 | | |
| 71 | | t0 = cassette_get_position(device); |
| 72 | | t1 = cassette_get_length(device); |
| 73 | | |
| 74 | | if (t1) |
| 75 | | astring_printf(dest, "%04d/%04d", (int) t0, (int) t1); |
| 76 | | else |
| 77 | | astring_printf(dest, "%04d/%04d", 0, (int) t1); |
| 78 | | |
| 79 | | if (curpos != NULL) |
| 80 | | *curpos = t0; |
| 81 | | if (endpos != NULL) |
| 82 | | *endpos = t1; |
| 83 | | |
| 84 | | return dest; |
| 85 | | } |
| 86 | | |
| 87 | | |
| 88 | | |
| 89 | | /*------------------------------------------------- |
| 90 | | menu_tape_control_populate - populates the |
| 91 | | main tape control menu |
| 92 | | -------------------------------------------------*/ |
| 93 | | |
| 94 | | static void menu_tape_control_populate(running_machine *machine, ui_menu *menu, tape_control_menu_state *menustate) |
| 95 | | { |
| 96 | | astring timepos; |
| 97 | | cassette_state state; |
| 98 | | int count = cassette_count(machine); |
| 99 | | UINT32 flags = 0; |
| 100 | | |
| 101 | | if( count > 0 ) |
| 102 | | { |
| 103 | | if( menustate->index == (count-1) ) |
| 104 | | flags |= MENU_FLAG_LEFT_ARROW; |
| 105 | | else |
| 106 | | flags |= MENU_FLAG_RIGHT_ARROW; |
| 107 | | } |
| 108 | | |
| 109 | | if (menustate->device->exists()) |
| 110 | | { |
| 111 | | double t0, t1; |
| 112 | | UINT32 tapeflags = 0; |
| 113 | | |
| 114 | | t0 = cassette_get_position(&menustate->device->device()); |
| 115 | | t1 = cassette_get_length(&menustate->device->device()); |
| 116 | | |
| 117 | | if (t1 > 0) |
| 118 | | { |
| 119 | | if (t0 > 0) |
| 120 | | tapeflags |= MENU_FLAG_LEFT_ARROW; |
| 121 | | if (t0 < t1) |
| 122 | | tapeflags |= MENU_FLAG_RIGHT_ARROW; |
| 123 | | } |
| 124 | | |
| 125 | | /* name of tape */ |
| 126 | | ui_menu_item_append(menu, menustate->device->image_config().name(), menustate->device->filename(), flags, TAPECMD_SELECT); |
| 127 | | |
| 128 | | /* state */ |
| 129 | | tapecontrol_gettime(&timepos, &menustate->device->device(), NULL, NULL); |
| 130 | | state = cassette_get_state(&menustate->device->device()); |
| 131 | | ui_menu_item_append( |
| 132 | | menu, |
| 133 | | (state & CASSETTE_MASK_UISTATE) == CASSETTE_STOPPED |
| 134 | | ? "stopped" |
| 135 | | : ((state & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY |
| 136 | | ? ((state & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_ENABLED ? "playing" : "(playing)") |
| 137 | | : ((state & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_ENABLED ? "recording" : "(recording)") |
| 138 | | ), |
| 139 | | astring_c(&timepos), |
| 140 | | tapeflags, |
| 141 | | TAPECMD_SLIDER); |
| 142 | | |
| 143 | | /* pause or stop */ |
| 144 | | ui_menu_item_append(menu, "Pause/Stop", NULL, 0, TAPECMD_STOP); |
| 145 | | |
| 146 | | /* play */ |
| 147 | | ui_menu_item_append(menu, "Play", NULL, 0, TAPECMD_PLAY); |
| 148 | | |
| 149 | | /* record */ |
| 150 | | ui_menu_item_append(menu, "Record", NULL, 0, TAPECMD_RECORD); |
| 151 | | |
| 152 | | /* rewind */ |
| 153 | | ui_menu_item_append(menu, "Rewind", NULL, 0, TAPECMD_REWIND); |
| 154 | | |
| 155 | | /* fast forward */ |
| 156 | | ui_menu_item_append(menu, "Fast Forward", NULL, 0, TAPECMD_FAST_FORWARD); |
| 157 | | } |
| 158 | | else |
| 159 | | { |
| 160 | | /* no tape loaded */ |
| 161 | | ui_menu_item_append(menu, "No Tape Image loaded", NULL, flags, NULL); |
| 162 | | } |
| 163 | | } |
| 164 | | |
| 165 | | |
| 166 | | /*------------------------------------------------- |
| 167 | | menu_tape_control - main tape control menu |
| 168 | | -------------------------------------------------*/ |
| 169 | | |
| 170 | | void ui_mess_menu_tape_control(running_machine *machine, ui_menu *menu, void *parameter, void *state) |
| 171 | | { |
| 172 | | tape_control_menu_state *menustate; |
| 173 | | const ui_menu_event *event; |
| 174 | | |
| 175 | | /* if no state, allocate some */ |
| 176 | | if (state == NULL) |
| 177 | | state = ui_menu_alloc_state(menu, sizeof(*menustate), NULL); |
| 178 | | menustate = (tape_control_menu_state *) state; |
| 179 | | |
| 180 | | /* do we have to load the device? */ |
| 181 | | if (menustate->device == NULL) |
| 182 | | { |
| 183 | | int index = menustate->index; |
| 184 | | device_image_interface *device = NULL; |
| 185 | | for (bool gotone = machine->devicelist.first(device); gotone; gotone = device->next(device)) |
| 186 | | { |
| 187 | | if(device->device().type() == CASSETTE) { |
| 188 | | if (index==0) break; |
| 189 | | index--; |
| 190 | | } |
| 191 | | } |
| 192 | | menustate->device = device; |
| 193 | | ui_menu_reset(menu, (ui_menu_reset_options)0); |
| 194 | | } |
| 195 | | |
| 196 | | /* rebuild the menu - we have to do this so that the counter updates */ |
| 197 | | ui_menu_reset(menu, UI_MENU_RESET_REMEMBER_POSITION); |
| 198 | | menu_tape_control_populate(machine, menu, (tape_control_menu_state*)state); |
| 199 | | |
| 200 | | /* process the menu */ |
| 201 | | event = ui_menu_process(machine, menu, UI_MENU_PROCESS_LR_REPEAT); |
| 202 | | if (event != NULL) |
| 203 | | { |
| 204 | | switch(event->iptkey) |
| 205 | | { |
| 206 | | case IPT_UI_LEFT: |
| 207 | | if (event->itemref==TAPECMD_SLIDER) |
| 208 | | cassette_seek(&menustate->device->device(), -1, SEEK_CUR); |
| 209 | | else |
| 210 | | if (event->itemref==TAPECMD_SELECT) |
| 211 | | { |
| 212 | | /* left arrow - rotate left through cassette devices */ |
| 213 | | if (menustate->index > 0) |
| 214 | | menustate->index--; |
| 215 | | else |
| 216 | | menustate->index = cassette_count(machine) - 1; |
| 217 | | menustate->device = NULL; |
| 218 | | } |
| 219 | | break; |
| 220 | | |
| 221 | | case IPT_UI_RIGHT: |
| 222 | | if (event->itemref==TAPECMD_SLIDER) |
| 223 | | cassette_seek(&menustate->device->device(), +1, SEEK_CUR); |
| 224 | | else |
| 225 | | if (event->itemref==TAPECMD_SELECT) |
| 226 | | { |
| 227 | | /* right arrow - rotate right through cassette devices */ |
| 228 | | if (menustate->index < cassette_count(machine) - 1) |
| 229 | | menustate->index++; |
| 230 | | else |
| 231 | | menustate->index = 0; |
| 232 | | menustate->device = NULL; |
| 233 | | } |
| 234 | | break; |
| 235 | | |
| 236 | | case IPT_UI_SELECT: |
| 237 | | { |
| 238 | | if (event->itemref==TAPECMD_STOP) |
| 239 | | cassette_change_state(&menustate->device->device(), CASSETTE_STOPPED, CASSETTE_MASK_UISTATE); |
| 240 | | else |
| 241 | | if (event->itemref==TAPECMD_PLAY) |
| 242 | | cassette_change_state(&menustate->device->device(), CASSETTE_PLAY, CASSETTE_MASK_UISTATE); |
| 243 | | else |
| 244 | | if (event->itemref==TAPECMD_RECORD) |
| 245 | | cassette_change_state(&menustate->device->device(), CASSETTE_RECORD, CASSETTE_MASK_UISTATE); |
| 246 | | else |
| 247 | | if (event->itemref==TAPECMD_REWIND) |
| 248 | | cassette_seek(&menustate->device->device(), -30, SEEK_CUR); |
| 249 | | else |
| 250 | | if (event->itemref==TAPECMD_FAST_FORWARD) |
| 251 | | cassette_seek(&menustate->device->device(), 30, SEEK_CUR); |
| 252 | | else |
| 253 | | if (event->itemref==TAPECMD_SLIDER) |
| 254 | | cassette_seek(&menustate->device->device(), 0, SEEK_SET); |
| 255 | | } |
| 256 | | break; |
| 257 | | } |
| 258 | | } |
| 259 | | } |
src/mess/uimess.c
| r8327 | r8328 | |
| 15 | 15 | |
| 16 | 16 | |
| 17 | 17 | /*************************************************************************** |
| 18 | TYPE DEFINITIONS |
| 19 | ***************************************************************************/ |
| 20 | #define TAPECMD_NULL ((void *) 0x0000) |
| 21 | #define TAPECMD_STOP ((void *) 0x0001) |
| 22 | #define TAPECMD_PLAY ((void *) 0x0002) |
| 23 | #define TAPECMD_RECORD ((void *) 0x0003) |
| 24 | #define TAPECMD_REWIND ((void *) 0x0004) |
| 25 | #define TAPECMD_FAST_FORWARD ((void *) 0x0005) |
| 26 | #define TAPECMD_SLIDER ((void *) 0x0006) |
| 27 | #define TAPECMD_SELECT ((void *) 0x0007) |
| 28 | |
| 29 | |
| 30 | |
| 31 | typedef struct _tape_control_menu_state tape_control_menu_state; |
| 32 | struct _tape_control_menu_state |
| 33 | { |
| 34 | int index; |
| 35 | device_image_interface *device; |
| 36 | }; |
| 37 | |
| 38 | |
| 39 | |
| 40 | /*************************************************************************** |
| 18 | 41 | IMPLEMENTATION |
| 19 | 42 | ***************************************************************************/ |
| 20 | 43 | |
| r8327 | r8328 | |
| 28 | 51 | if (machine->devicelist.first(CASSETTE)) |
| 29 | 52 | ui_menu_item_append(menu, "Tape Control", NULL, 0, (void*)ui_mess_menu_tape_control); |
| 30 | 53 | } |
| 54 | |
| 55 | |
| 56 | /*------------------------------------------------- |
| 57 | cassette_count - returns the number of cassette |
| 58 | devices in the machine |
| 59 | -------------------------------------------------*/ |
| 60 | |
| 61 | INLINE int cassette_count( running_machine *machine ) |
| 62 | { |
| 63 | int count = 0; |
| 64 | running_device *device = machine->devicelist.first(CASSETTE ); |
| 65 | |
| 66 | while ( device ) |
| 67 | { |
| 68 | count++; |
| 69 | device = device->typenext(); |
| 70 | } |
| 71 | return count; |
| 72 | } |
| 73 | |
| 74 | /*------------------------------------------------- |
| 75 | tapecontrol_gettime - returns a textual |
| 76 | representation of the time |
| 77 | -------------------------------------------------*/ |
| 78 | |
| 79 | astring *tapecontrol_gettime(astring *dest, running_device *device, int *curpos, int *endpos) |
| 80 | { |
| 81 | double t0, t1; |
| 82 | |
| 83 | t0 = cassette_get_position(device); |
| 84 | t1 = cassette_get_length(device); |
| 85 | |
| 86 | if (t1) |
| 87 | astring_printf(dest, "%04d/%04d", (int) t0, (int) t1); |
| 88 | else |
| 89 | astring_printf(dest, "%04d/%04d", 0, (int) t1); |
| 90 | |
| 91 | if (curpos != NULL) |
| 92 | *curpos = t0; |
| 93 | if (endpos != NULL) |
| 94 | *endpos = t1; |
| 95 | |
| 96 | return dest; |
| 97 | } |
| 98 | |
| 99 | |
| 100 | |
| 101 | /*------------------------------------------------- |
| 102 | menu_tape_control_populate - populates the |
| 103 | main tape control menu |
| 104 | -------------------------------------------------*/ |
| 105 | |
| 106 | static void menu_tape_control_populate(running_machine *machine, ui_menu *menu, tape_control_menu_state *menustate) |
| 107 | { |
| 108 | astring timepos; |
| 109 | cassette_state state; |
| 110 | int count = cassette_count(machine); |
| 111 | UINT32 flags = 0; |
| 112 | |
| 113 | if( count > 0 ) |
| 114 | { |
| 115 | if( menustate->index == (count-1) ) |
| 116 | flags |= MENU_FLAG_LEFT_ARROW; |
| 117 | else |
| 118 | flags |= MENU_FLAG_RIGHT_ARROW; |
| 119 | } |
| 120 | |
| 121 | if (menustate->device->exists()) |
| 122 | { |
| 123 | double t0, t1; |
| 124 | UINT32 tapeflags = 0; |
| 125 | |
| 126 | t0 = cassette_get_position(&menustate->device->device()); |
| 127 | t1 = cassette_get_length(&menustate->device->device()); |
| 128 | |
| 129 | if (t1 > 0) |
| 130 | { |
| 131 | if (t0 > 0) |
| 132 | tapeflags |= MENU_FLAG_LEFT_ARROW; |
| 133 | if (t0 < t1) |
| 134 | tapeflags |= MENU_FLAG_RIGHT_ARROW; |
| 135 | } |
| 136 | |
| 137 | /* name of tape */ |
| 138 | ui_menu_item_append(menu, menustate->device->image_config().name(), menustate->device->filename(), flags, TAPECMD_SELECT); |
| 139 | |
| 140 | /* state */ |
| 141 | tapecontrol_gettime(&timepos, &menustate->device->device(), NULL, NULL); |
| 142 | state = cassette_get_state(&menustate->device->device()); |
| 143 | ui_menu_item_append( |
| 144 | menu, |
| 145 | (state & CASSETTE_MASK_UISTATE) == CASSETTE_STOPPED |
| 146 | ? "stopped" |
| 147 | : ((state & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY |
| 148 | ? ((state & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_ENABLED ? "playing" : "(playing)") |
| 149 | : ((state & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_ENABLED ? "recording" : "(recording)") |
| 150 | ), |
| 151 | astring_c(&timepos), |
| 152 | tapeflags, |
| 153 | TAPECMD_SLIDER); |
| 154 | |
| 155 | /* pause or stop */ |
| 156 | ui_menu_item_append(menu, "Pause/Stop", NULL, 0, TAPECMD_STOP); |
| 157 | |
| 158 | /* play */ |
| 159 | ui_menu_item_append(menu, "Play", NULL, 0, TAPECMD_PLAY); |
| 160 | |
| 161 | /* record */ |
| 162 | ui_menu_item_append(menu, "Record", NULL, 0, TAPECMD_RECORD); |
| 163 | |
| 164 | /* rewind */ |
| 165 | ui_menu_item_append(menu, "Rewind", NULL, 0, TAPECMD_REWIND); |
| 166 | |
| 167 | /* fast forward */ |
| 168 | ui_menu_item_append(menu, "Fast Forward", NULL, 0, TAPECMD_FAST_FORWARD); |
| 169 | } |
| 170 | else |
| 171 | { |
| 172 | /* no tape loaded */ |
| 173 | ui_menu_item_append(menu, "No Tape Image loaded", NULL, flags, NULL); |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | |
| 178 | /*------------------------------------------------- |
| 179 | menu_tape_control - main tape control menu |
| 180 | -------------------------------------------------*/ |
| 181 | |
| 182 | void ui_mess_menu_tape_control(running_machine *machine, ui_menu *menu, void *parameter, void *state) |
| 183 | { |
| 184 | tape_control_menu_state *menustate; |
| 185 | const ui_menu_event *event; |
| 186 | |
| 187 | /* if no state, allocate some */ |
| 188 | if (state == NULL) |
| 189 | state = ui_menu_alloc_state(menu, sizeof(*menustate), NULL); |
| 190 | menustate = (tape_control_menu_state *) state; |
| 191 | |
| 192 | /* do we have to load the device? */ |
| 193 | if (menustate->device == NULL) |
| 194 | { |
| 195 | int index = menustate->index; |
| 196 | device_image_interface *device = NULL; |
| 197 | for (bool gotone = machine->devicelist.first(device); gotone; gotone = device->next(device)) |
| 198 | { |
| 199 | if(device->device().type() == CASSETTE) { |
| 200 | if (index==0) break; |
| 201 | index--; |
| 202 | } |
| 203 | } |
| 204 | menustate->device = device; |
| 205 | ui_menu_reset(menu, (ui_menu_reset_options)0); |
| 206 | } |
| 207 | |
| 208 | /* rebuild the menu - we have to do this so that the counter updates */ |
| 209 | ui_menu_reset(menu, UI_MENU_RESET_REMEMBER_POSITION); |
| 210 | menu_tape_control_populate(machine, menu, (tape_control_menu_state*)state); |
| 211 | |
| 212 | /* process the menu */ |
| 213 | event = ui_menu_process(machine, menu, UI_MENU_PROCESS_LR_REPEAT); |
| 214 | if (event != NULL) |
| 215 | { |
| 216 | switch(event->iptkey) |
| 217 | { |
| 218 | case IPT_UI_LEFT: |
| 219 | if (event->itemref==TAPECMD_SLIDER) |
| 220 | cassette_seek(&menustate->device->device(), -1, SEEK_CUR); |
| 221 | else |
| 222 | if (event->itemref==TAPECMD_SELECT) |
| 223 | { |
| 224 | /* left arrow - rotate left through cassette devices */ |
| 225 | if (menustate->index > 0) |
| 226 | menustate->index--; |
| 227 | else |
| 228 | menustate->index = cassette_count(machine) - 1; |
| 229 | menustate->device = NULL; |
| 230 | } |
| 231 | break; |
| 232 | |
| 233 | case IPT_UI_RIGHT: |
| 234 | if (event->itemref==TAPECMD_SLIDER) |
| 235 | cassette_seek(&menustate->device->device(), +1, SEEK_CUR); |
| 236 | else |
| 237 | if (event->itemref==TAPECMD_SELECT) |
| 238 | { |
| 239 | /* right arrow - rotate right through cassette devices */ |
| 240 | if (menustate->index < cassette_count(machine) - 1) |
| 241 | menustate->index++; |
| 242 | else |
| 243 | menustate->index = 0; |
| 244 | menustate->device = NULL; |
| 245 | } |
| 246 | break; |
| 247 | |
| 248 | case IPT_UI_SELECT: |
| 249 | { |
| 250 | if (event->itemref==TAPECMD_STOP) |
| 251 | cassette_change_state(&menustate->device->device(), CASSETTE_STOPPED, CASSETTE_MASK_UISTATE); |
| 252 | else |
| 253 | if (event->itemref==TAPECMD_PLAY) |
| 254 | cassette_change_state(&menustate->device->device(), CASSETTE_PLAY, CASSETTE_MASK_UISTATE); |
| 255 | else |
| 256 | if (event->itemref==TAPECMD_RECORD) |
| 257 | cassette_change_state(&menustate->device->device(), CASSETTE_RECORD, CASSETTE_MASK_UISTATE); |
| 258 | else |
| 259 | if (event->itemref==TAPECMD_REWIND) |
| 260 | cassette_seek(&menustate->device->device(), -30, SEEK_CUR); |
| 261 | else |
| 262 | if (event->itemref==TAPECMD_FAST_FORWARD) |
| 263 | cassette_seek(&menustate->device->device(), 30, SEEK_CUR); |
| 264 | else |
| 265 | if (event->itemref==TAPECMD_SLIDER) |
| 266 | cassette_seek(&menustate->device->device(), 0, SEEK_SET); |
| 267 | } |
| 268 | break; |
| 269 | } |
| 270 | } |
| 271 | } |