trunk/src/mess/video/spectrum.c
| r18715 | r18716 | |
| 21 | 21 | ***************************************************************************/ |
| 22 | 22 | VIDEO_START_MEMBER(spectrum_state,spectrum) |
| 23 | 23 | { |
| 24 | | m_LastDisplayedBorderColor = -1; |
| 25 | 24 | m_frame_invert_count = 25; |
| 26 | 25 | m_frame_number = 0; |
| 27 | 26 | m_flash_invert = 0; |
| 28 | 27 | |
| 29 | | spectrum_EventList_Initialise(machine(), 30000); |
| 28 | m_previous_border_x = 0; m_previous_border_y = 0; |
| 29 | machine().primary_screen->register_screen_bitmap(m_border_bitmap); |
| 30 | 30 | |
| 31 | | m_retrace_cycles = SPEC_RETRACE_CYCLES; |
| 32 | | |
| 33 | 31 | m_screen_location = m_video_ram; |
| 34 | 32 | } |
| 35 | 33 | |
| 36 | 34 | VIDEO_START_MEMBER(spectrum_state,spectrum_128) |
| 37 | 35 | { |
| 38 | | m_LastDisplayedBorderColor = -1; |
| 39 | 36 | m_frame_invert_count = 25; |
| 40 | 37 | m_frame_number = 0; |
| 41 | 38 | m_flash_invert = 0; |
| 42 | 39 | |
| 43 | | spectrum_EventList_Initialise(machine(), 30000); |
| 44 | | |
| 45 | | m_retrace_cycles = SPEC128_RETRACE_CYCLES; |
| 40 | m_previous_border_x = 0; m_previous_border_y = 0; |
| 41 | machine().primary_screen->register_screen_bitmap(m_border_bitmap); |
| 46 | 42 | } |
| 47 | 43 | |
| 48 | 44 | |
| r18715 | r18716 | |
| 62 | 58 | // rising edge |
| 63 | 59 | if (state) |
| 64 | 60 | { |
| 65 | | EVENT_LIST_ITEM *pItem; |
| 66 | | int NumItems; |
| 67 | | |
| 68 | | m_frame_number++; |
| 69 | | if (m_frame_number >= m_frame_invert_count) |
| 70 | | { |
| 71 | | m_frame_number = 0; |
| 72 | | m_flash_invert = !m_flash_invert; |
| 73 | | } |
| 74 | | |
| 75 | | /* Empty event buffer for undisplayed frames noting the last border |
| 76 | | colour (in case colours are not changed in the next frame). */ |
| 77 | | NumItems = spectrum_EventList_NumEvents(machine()); |
| 78 | | if (NumItems) |
| 79 | | { |
| 80 | | pItem = spectrum_EventList_GetFirstItem(machine()); |
| 81 | | spectrum_border_set_last_color ( machine(), pItem[NumItems-1].Event_Data ); |
| 82 | | spectrum_EventList_Reset(machine()); |
| 83 | | spectrum_EventList_SetOffsetStartTime ( machine(), machine().firstcpu->attotime_to_cycles(screen.scan_period() * screen.vpos()) ); |
| 84 | | logerror ("Event log reset in callback fn.\n"); |
| 85 | | } |
| 61 | spectrum_UpdateBorderBitmap(machine()); |
| 86 | 62 | } |
| 87 | 63 | } |
| 88 | 64 | |
| r18715 | r18716 | |
| 118 | 94 | |
| 119 | 95 | UINT32 spectrum_state::screen_update_spectrum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 120 | 96 | { |
| 97 | // note, don't update borders in here, this can time travel w/regards to other timers and may end up giving you |
| 98 | // screen positions earlier than the last write handler gave you |
| 99 | |
| 121 | 100 | /* for now do a full-refresh */ |
| 122 | 101 | int x, y, b, scrx, scry; |
| 123 | 102 | unsigned short ink, pap; |
| 124 | 103 | unsigned char *attr, *scr; |
| 125 | | int full_refresh = 1; |
| 104 | // int full_refresh = 1; |
| 126 | 105 | |
| 106 | if (m_border_bitmap.valid()) |
| 107 | copyscrollbitmap(bitmap, m_border_bitmap, 0, 0, 0, 0, cliprect); |
| 108 | |
| 127 | 109 | scr=m_screen_location; |
| 128 | 110 | |
| 129 | 111 | for (y=0; y<192; y++) |
| r18715 | r18716 | |
| 159 | 141 | } |
| 160 | 142 | } |
| 161 | 143 | |
| 162 | | spectrum_border_draw(machine(), bitmap, full_refresh, |
| 163 | | SPEC_TOP_BORDER, SPEC_DISPLAY_YSIZE, SPEC_BOTTOM_BORDER, |
| 164 | | SPEC_LEFT_BORDER, SPEC_DISPLAY_XSIZE, SPEC_RIGHT_BORDER, |
| 165 | | SPEC_LEFT_BORDER_CYCLES, SPEC_DISPLAY_XSIZE_CYCLES, |
| 166 | | SPEC_RIGHT_BORDER_CYCLES, m_retrace_cycles, 200, 0xfe); |
| 167 | 144 | return 0; |
| 168 | 145 | } |
| 169 | 146 | |
| r18715 | r18716 | |
| 192 | 169 | palette_set_colors(machine(), 0, spectrum_palette, ARRAY_LENGTH(spectrum_palette)); |
| 193 | 170 | } |
| 194 | 171 | |
| 195 | | /*************************************************************************** |
| 196 | | Border engine: |
| 197 | 172 | |
| 198 | | Functions for drawing multi-coloured screen borders using the |
| 199 | | Event List processing. |
| 173 | /* The code below is just a per-pixel 'partial update' for the border */ |
| 200 | 174 | |
| 201 | | Changes: |
| 202 | | |
| 203 | | 28/05/2000 DJR - Initial implementation. |
| 204 | | 08/06/2000 DJR - Now only uses events with the correct ID value. |
| 205 | | 28/06/2000 DJR - draw_border now uses full_refresh flag. |
| 206 | | |
| 207 | | ***************************************************************************/ |
| 208 | | |
| 209 | | /* Force the border to be redrawn on the next frame */ |
| 210 | | void spectrum_border_force_redraw (running_machine &machine) |
| 175 | INLINE void spectrum_GetNextPos(running_machine &machine, unsigned int &x, unsigned int &y) |
| 211 | 176 | { |
| 212 | 177 | spectrum_state *state = machine.driver_data<spectrum_state>(); |
| 213 | | state->m_LastDisplayedBorderColor = -1; |
| 214 | | } |
| 178 | int width = state->m_border_bitmap.width(); |
| 179 | int height = state->m_border_bitmap.height(); |
| 215 | 180 | |
| 216 | | /* Set the last border colour to have been displayed. Used when loading snap |
| 217 | | shots and to record the last colour change in a frame that was skipped. */ |
| 218 | | void spectrum_border_set_last_color(running_machine &machine, int NewColor) |
| 219 | | { |
| 220 | | spectrum_state *state = machine.driver_data<spectrum_state>(); |
| 221 | | state->m_CurrBorderColor = NewColor; |
| 222 | | } |
| 181 | x += 1; |
| 223 | 182 | |
| 224 | | void spectrum_border_draw(running_machine &machine, bitmap_ind16 &bitmap, |
| 225 | | int full_refresh, /* Full refresh flag */ |
| 226 | | int TopBorderLines, /* Border lines before actual screen */ |
| 227 | | int ScreenLines, /* Screen height in pixels */ |
| 228 | | int BottomBorderLines, /* Border lines below screen */ |
| 229 | | int LeftBorderPixels, /* Border pixels to the left of each screen line */ |
| 230 | | int ScreenPixels, /* Width of actual screen in pixels */ |
| 231 | | int RightBorderPixels, /* Border pixels to the right of each screen line */ |
| 232 | | int LeftBorderCycles, /* Cycles taken to draw left border of each scan line */ |
| 233 | | int ScreenCycles, /* Cycles taken to draw screen data part of each scan line */ |
| 234 | | int RightBorderCycles, /* Cycles taken to draw right border of each scan line */ |
| 235 | | int HorizontalRetraceCycles, /* Cycles taken to return to LHS of CRT after each scan line */ |
| 236 | | int VRetraceTime, /* Cycles taken before start of first border line */ |
| 237 | | int EventID) /* Event ID of border messages */ |
| 238 | | { |
| 239 | | spectrum_state *state = machine.driver_data<spectrum_state>(); |
| 240 | | EVENT_LIST_ITEM *pItem; |
| 241 | | int TotalScreenHeight = TopBorderLines+ScreenLines+BottomBorderLines; |
| 242 | | int TotalScreenWidth = LeftBorderPixels+ScreenPixels+RightBorderPixels; |
| 243 | | int DisplayCyclesPerLine = LeftBorderCycles+ScreenCycles+RightBorderCycles; |
| 244 | | int CyclesPerLine = DisplayCyclesPerLine+HorizontalRetraceCycles; |
| 245 | | int CyclesSoFar = 0; |
| 246 | | int NumItems, CurrItem = 0, NextItem; |
| 247 | | int Count, ScrX, NextScrX, ScrY; |
| 248 | | rectangle r; |
| 249 | | |
| 250 | | pItem = spectrum_EventList_GetFirstItem(machine); |
| 251 | | NumItems = spectrum_EventList_NumEvents(machine); |
| 252 | | |
| 253 | | for (Count = 0; Count < NumItems; Count++) |
| 183 | if (x>width) |
| 254 | 184 | { |
| 255 | | // logerror ("Event no %05d, ID = %04x, data = %04x, time = %ld\n", Count, pItem[Count].Event_ID, pItem[Count].Event_Data, (long) pItem[Count].Event_Time); |
| 256 | | } |
| 185 | x = 0; |
| 186 | y += 1; |
| 257 | 187 | |
| 258 | | /* Find the first and second events with the correct ID */ |
| 259 | | while ((CurrItem < NumItems) && (pItem[CurrItem].Event_ID != EventID)) |
| 260 | | CurrItem++; |
| 261 | | NextItem = CurrItem + 1; |
| 262 | | while ((NextItem < NumItems) && (pItem[NextItem].Event_ID != EventID)) |
| 263 | | NextItem++; |
| 264 | | |
| 265 | | /* Single border colour */ |
| 266 | | if ((CurrItem < NumItems) && (NextItem >= NumItems)) |
| 267 | | state->m_CurrBorderColor = pItem[CurrItem].Event_Data; |
| 268 | | |
| 269 | | if ((NextItem >= NumItems) && (state->m_CurrBorderColor==state->m_LastDisplayedBorderColor) && !full_refresh) |
| 270 | | { |
| 271 | | /* Do nothing if border colour has not changed */ |
| 188 | if (y>height) |
| 189 | { |
| 190 | y = 0; |
| 191 | } |
| 272 | 192 | } |
| 273 | | else if (NextItem >= NumItems) |
| 274 | | { |
| 275 | | /* Single border colour - this is not strictly correct as the |
| 276 | | colour change may have occurred midway through the frame |
| 277 | | or after the last visible border line however the whole |
| 278 | | border would be redrawn in the correct colour during the |
| 279 | | next frame anyway! */ |
| 280 | | r.set(0, TotalScreenWidth-1, 0, TopBorderLines-1); |
| 281 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 193 | } |
| 282 | 194 | |
| 283 | | r.set(0, LeftBorderPixels-1, TopBorderLines, TopBorderLines+ScreenLines-1); |
| 284 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 285 | 195 | |
| 286 | | r.setx(LeftBorderPixels+ScreenPixels, TotalScreenWidth-1); |
| 287 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 196 | void spectrum_UpdateBorderBitmap(running_machine &machine) |
| 197 | { |
| 198 | spectrum_state *state = machine.driver_data<spectrum_state>(); |
| 199 | unsigned int x = machine.primary_screen->hpos(); |
| 200 | unsigned int y = machine.primary_screen->vpos(); |
| 201 | int width = state->m_border_bitmap.width(); |
| 202 | int height = state->m_border_bitmap.height(); |
| 288 | 203 | |
| 289 | | r.set(0, TotalScreenWidth-1, TopBorderLines+ScreenLines, TotalScreenHeight-1); |
| 290 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 291 | 204 | |
| 292 | | // logerror ("Setting border colour to %d (Last = %d, Full Refresh = %d)\n", state->m_CurrBorderColor, state->m_LastDisplayedBorderColor, full_refresh); |
| 293 | | state->m_LastDisplayedBorderColor = state->m_CurrBorderColor; |
| 294 | | } |
| 295 | | else |
| 205 | if (state->m_border_bitmap.valid()) |
| 296 | 206 | { |
| 297 | | /* Multiple border colours */ |
| 207 | int colour = state->m_port_fe_data & 0x07; |
| 298 | 208 | |
| 299 | | /* Process entries before first displayed line */ |
| 300 | | while ((CurrItem < NumItems) && (pItem[CurrItem].Event_Time <= VRetraceTime)) |
| 301 | | { |
| 302 | | state->m_CurrBorderColor = pItem[CurrItem].Event_Data; |
| 303 | | do { |
| 304 | | CurrItem++; |
| 305 | | } while ((CurrItem < NumItems) && (pItem[CurrItem].Event_ID != EventID)); |
| 306 | | } |
| 209 | //printf("update border from %d,%d to %d,%d\n", state->m_previous_border_x, state->m_previous_border_y, x, y); |
| 307 | 210 | |
| 308 | | /* Draw top border */ |
| 309 | | CyclesSoFar = VRetraceTime; |
| 310 | | for (ScrY = 0; ScrY < TopBorderLines; ScrY++) |
| 211 | do |
| 311 | 212 | { |
| 312 | | r.min_x = 0; |
| 313 | | r.min_y = r.max_y = ScrY; |
| 314 | | if ((CurrItem >= NumItems) || (pItem[CurrItem].Event_Time >= (CyclesSoFar+DisplayCyclesPerLine))) |
| 213 | if (state->m_previous_border_y < height) |
| 315 | 214 | { |
| 316 | | /* Single colour on line */ |
| 317 | | r.max_x = TotalScreenWidth-1; |
| 318 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 319 | | } |
| 320 | | else |
| 321 | | { |
| 322 | | /* Multiple colours on a line */ |
| 323 | | ScrX = (int)(pItem[CurrItem].Event_Time - CyclesSoFar) * (float)TotalScreenWidth / (float)DisplayCyclesPerLine; |
| 324 | | r.max_x = ScrX-1; |
| 325 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 326 | | state->m_CurrBorderColor = pItem[CurrItem].Event_Data; |
| 327 | | do { |
| 328 | | CurrItem++; |
| 329 | | } while ((CurrItem < NumItems) && (pItem[CurrItem].Event_ID != EventID)); |
| 215 | UINT16* bm = &state->m_border_bitmap.pix16(state->m_previous_border_y); |
| 330 | 216 | |
| 331 | | while ((CurrItem < NumItems) && (pItem[CurrItem].Event_Time < (CyclesSoFar+DisplayCyclesPerLine))) |
| 332 | | { |
| 333 | | NextScrX = (int)(pItem[CurrItem].Event_Time - CyclesSoFar) * (float)TotalScreenWidth / (float)DisplayCyclesPerLine; |
| 334 | | r.setx(ScrX, NextScrX-1); |
| 335 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 336 | | ScrX = NextScrX; |
| 337 | | state->m_CurrBorderColor = pItem[CurrItem].Event_Data; |
| 338 | | do { |
| 339 | | CurrItem++; |
| 340 | | } while ((CurrItem < NumItems) && (pItem[CurrItem].Event_ID != EventID)); |
| 341 | | } |
| 342 | | r.setx(ScrX, TotalScreenWidth-1); |
| 343 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 217 | if (state->m_previous_border_x < width) |
| 218 | bm[state->m_previous_border_x] = colour; |
| 344 | 219 | } |
| 345 | 220 | |
| 346 | | /* Process colour changes during horizontal retrace */ |
| 347 | | CyclesSoFar+= CyclesPerLine; |
| 348 | | while ((CurrItem < NumItems) && (pItem[CurrItem].Event_Time <= CyclesSoFar)) |
| 349 | | { |
| 350 | | state->m_CurrBorderColor = pItem[CurrItem].Event_Data; |
| 351 | | do { |
| 352 | | CurrItem++; |
| 353 | | } while ((CurrItem < NumItems) && (pItem[CurrItem].Event_ID != EventID)); |
| 354 | | } |
| 221 | spectrum_GetNextPos(machine, state->m_previous_border_x, state->m_previous_border_y); |
| 355 | 222 | } |
| 223 | while (!((state->m_previous_border_x == x) && (state->m_previous_border_y == y))); |
| 356 | 224 | |
| 357 | | /* Draw left and right borders next to screen lines */ |
| 358 | | for (ScrY = TopBorderLines; ScrY < (TopBorderLines+ScreenLines); ScrY++) |
| 359 | | { |
| 360 | | /* Draw left hand border */ |
| 361 | | r.min_x = 0; |
| 362 | | r.min_y = r.max_y = ScrY; |
| 363 | | |
| 364 | | if ((CurrItem >= NumItems) || (pItem[CurrItem].Event_Time >= (CyclesSoFar+LeftBorderCycles))) |
| 365 | | { |
| 366 | | /* Single colour */ |
| 367 | | r.max_x = LeftBorderPixels-1; |
| 368 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 369 | | } |
| 370 | | else |
| 371 | | { |
| 372 | | /* Multiple colours */ |
| 373 | | ScrX = (int)(pItem[CurrItem].Event_Time - CyclesSoFar) * (float)LeftBorderPixels / (float)LeftBorderCycles; |
| 374 | | r.max_x = ScrX-1; |
| 375 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 376 | | state->m_CurrBorderColor = pItem[CurrItem].Event_Data; |
| 377 | | do { |
| 378 | | CurrItem++; |
| 379 | | } while ((CurrItem < NumItems) && (pItem[CurrItem].Event_ID != EventID)); |
| 380 | | |
| 381 | | while ((CurrItem < NumItems) && (pItem[CurrItem].Event_Time < (CyclesSoFar+LeftBorderCycles))) |
| 382 | | { |
| 383 | | NextScrX = (int)(pItem[CurrItem].Event_Time - CyclesSoFar) * (float)LeftBorderPixels / (float)LeftBorderCycles; |
| 384 | | r.setx(ScrX, NextScrX-1); |
| 385 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 386 | | ScrX = NextScrX; |
| 387 | | state->m_CurrBorderColor = pItem[CurrItem].Event_Data; |
| 388 | | do { |
| 389 | | CurrItem++; |
| 390 | | } while ((CurrItem < NumItems) && (pItem[CurrItem].Event_ID != EventID)); |
| 391 | | } |
| 392 | | r.setx(ScrX, LeftBorderPixels-1); |
| 393 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 394 | | } |
| 395 | | |
| 396 | | /* Process colour changes during screen draw */ |
| 397 | | while ((CurrItem < NumItems) && (pItem[CurrItem].Event_Time <= (CyclesSoFar+LeftBorderCycles+ScreenCycles))) |
| 398 | | { |
| 399 | | state->m_CurrBorderColor = pItem[CurrItem].Event_Data; |
| 400 | | do { |
| 401 | | CurrItem++; |
| 402 | | } while ((CurrItem < NumItems) && (pItem[CurrItem].Event_ID != EventID)); |
| 403 | | } |
| 404 | | |
| 405 | | /* Draw right hand border */ |
| 406 | | r.min_x = LeftBorderPixels+ScreenPixels; |
| 407 | | if ((CurrItem >= NumItems) || (pItem[CurrItem].Event_Time >= (CyclesSoFar+DisplayCyclesPerLine))) |
| 408 | | { |
| 409 | | /* Single colour */ |
| 410 | | r.max_x = TotalScreenWidth-1; |
| 411 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 412 | | } |
| 413 | | else |
| 414 | | { |
| 415 | | /* Multiple colours */ |
| 416 | | ScrX = LeftBorderPixels + ScreenPixels + (int)(pItem[CurrItem].Event_Time - CyclesSoFar) * (float)RightBorderPixels / (float)RightBorderCycles; |
| 417 | | r.max_x = ScrX-1; |
| 418 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 419 | | state->m_CurrBorderColor = pItem[CurrItem].Event_Data; |
| 420 | | do { |
| 421 | | CurrItem++; |
| 422 | | } while ((CurrItem < NumItems) && (pItem[CurrItem].Event_ID != EventID)); |
| 423 | | |
| 424 | | while ((CurrItem < NumItems) && (pItem[CurrItem].Event_Time < (CyclesSoFar+DisplayCyclesPerLine))) |
| 425 | | { |
| 426 | | NextScrX = LeftBorderPixels + ScreenPixels + (int)(pItem[CurrItem].Event_Time - CyclesSoFar) * (float)RightBorderPixels / (float)RightBorderCycles; |
| 427 | | r.setx(ScrX, NextScrX-1); |
| 428 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 429 | | ScrX = NextScrX; |
| 430 | | state->m_CurrBorderColor = pItem[CurrItem].Event_Data; |
| 431 | | do { |
| 432 | | CurrItem++; |
| 433 | | } while ((CurrItem < NumItems) && (pItem[CurrItem].Event_ID != EventID)); |
| 434 | | } |
| 435 | | r.setx(ScrX, TotalScreenWidth-1); |
| 436 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 437 | | } |
| 438 | | |
| 439 | | /* Process colour changes during horizontal retrace */ |
| 440 | | CyclesSoFar+= CyclesPerLine; |
| 441 | | while ((CurrItem < NumItems) && (pItem[CurrItem].Event_Time <= CyclesSoFar)) |
| 442 | | { |
| 443 | | state->m_CurrBorderColor = pItem[CurrItem].Event_Data; |
| 444 | | do { |
| 445 | | CurrItem++; |
| 446 | | } while ((CurrItem < NumItems) && (pItem[CurrItem].Event_ID != EventID)); |
| 447 | | } |
| 448 | | } |
| 449 | | |
| 450 | | /* Draw bottom border */ |
| 451 | | for (ScrY = TopBorderLines+ScreenLines; ScrY < TotalScreenHeight; ScrY++) |
| 452 | | { |
| 453 | | r.min_x = 0; |
| 454 | | r.min_y = r.max_y = ScrY; |
| 455 | | if ((CurrItem >= NumItems) || (pItem[CurrItem].Event_Time >= (CyclesSoFar+DisplayCyclesPerLine))) |
| 456 | | { |
| 457 | | /* Single colour on line */ |
| 458 | | r.max_x = TotalScreenWidth-1; |
| 459 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 460 | | } |
| 461 | | else |
| 462 | | { |
| 463 | | /* Multiple colours on a line */ |
| 464 | | ScrX = (int)(pItem[CurrItem].Event_Time - CyclesSoFar) * (float)TotalScreenWidth / (float)DisplayCyclesPerLine; |
| 465 | | r.max_x = ScrX-1; |
| 466 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 467 | | state->m_CurrBorderColor = pItem[CurrItem].Event_Data; |
| 468 | | do { |
| 469 | | CurrItem++; |
| 470 | | } while ((CurrItem < NumItems) && (pItem[CurrItem].Event_ID != EventID)); |
| 471 | | |
| 472 | | while ((CurrItem < NumItems) && (pItem[CurrItem].Event_Time < (CyclesSoFar+DisplayCyclesPerLine))) |
| 473 | | { |
| 474 | | NextScrX = (int)(pItem[CurrItem].Event_Time - CyclesSoFar) * (float)TotalScreenWidth / (float)DisplayCyclesPerLine; |
| 475 | | r.setx(ScrX, NextScrX-1); |
| 476 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 477 | | ScrX = NextScrX; |
| 478 | | state->m_CurrBorderColor = pItem[CurrItem].Event_Data; |
| 479 | | do { |
| 480 | | CurrItem++; |
| 481 | | } while ((CurrItem < NumItems) && (pItem[CurrItem].Event_ID != EventID)); |
| 482 | | } |
| 483 | | r.setx(ScrX, TotalScreenWidth-1); |
| 484 | | bitmap.fill(machine.pens[state->m_CurrBorderColor], r); |
| 485 | | } |
| 486 | | |
| 487 | | /* Process colour changes during horizontal retrace */ |
| 488 | | CyclesSoFar+= CyclesPerLine; |
| 489 | | while ((CurrItem < NumItems) && (pItem[CurrItem].Event_Time <= CyclesSoFar)) |
| 490 | | { |
| 491 | | state->m_CurrBorderColor = pItem[CurrItem].Event_Data; |
| 492 | | do { |
| 493 | | CurrItem++; |
| 494 | | } while ((CurrItem < NumItems) && (pItem[CurrItem].Event_ID != EventID)); |
| 495 | | } |
| 496 | | } |
| 497 | | |
| 498 | | /* Process colour changes after last displayed line */ |
| 499 | | while (CurrItem < NumItems) |
| 500 | | { |
| 501 | | if (pItem[CurrItem].Event_ID == EventID) |
| 502 | | state->m_CurrBorderColor = pItem[CurrItem].Event_Data; |
| 503 | | CurrItem++; |
| 504 | | } |
| 505 | | |
| 506 | | /* Set value to ensure redraw on next frame */ |
| 507 | | state->m_LastDisplayedBorderColor = -1; |
| 508 | | |
| 509 | | // logerror ("Multi coloured border drawn (last colour = %d)\n", CurrBorderColor); |
| 510 | 225 | } |
| 511 | | |
| 512 | | /* Assume all other routines have processed their data from the list */ |
| 513 | | spectrum_EventList_Reset(machine); |
| 514 | | spectrum_EventList_SetOffsetStartTime ( machine, machine.firstcpu->attotime_to_cycles(machine.primary_screen->scan_period() * machine.primary_screen->vpos())); |
| 515 | | } |
| 516 | | |
| 517 | | |
| 518 | | /* initialise */ |
| 519 | | |
| 520 | | /* if the CPU is the controlling factor, the size of the buffer |
| 521 | | can be setup as: |
| 522 | | |
| 523 | | Number_of_CPU_Cycles_In_A_Frame/Minimum_Number_Of_Cycles_Per_Instruction */ |
| 524 | | void spectrum_EventList_Initialise(running_machine &machine, int NumEntries) |
| 525 | | { |
| 526 | | spectrum_state *state = machine.driver_data<spectrum_state>(); |
| 527 | | state->m_pEventListBuffer = auto_alloc_array(machine, char, NumEntries); |
| 528 | | state->m_TotalEvents = NumEntries; |
| 529 | | state->m_CyclesPerFrame = 0; |
| 530 | | spectrum_EventList_Reset(machine); |
| 531 | | } |
| 532 | | |
| 533 | | /* reset the change list */ |
| 534 | | void spectrum_EventList_Reset(running_machine &machine) |
| 535 | | { |
| 536 | | spectrum_state *state = machine.driver_data<spectrum_state>(); |
| 537 | | state->m_NumEvents = 0; |
| 538 | | state->m_pCurrentItem = (EVENT_LIST_ITEM *)state->m_pEventListBuffer; |
| 539 | | } |
| 540 | | |
| 541 | | |
| 542 | | #ifdef UNUSED_FUNCTION |
| 543 | | /* add an event to the buffer */ |
| 544 | | void EventList_AddItem(running_machine &machine, int ID, int Data, int Time) |
| 545 | | { |
| 546 | | spectrum_state *state = machine.driver_data<spectrum_state>(); |
| 547 | | if (state->m_NumEvents < state->m_TotalEvents) |
| 226 | else |
| 548 | 227 | { |
| 549 | | /* setup item only if there is space in the buffer */ |
| 550 | | state->m_pCurrentItem->Event_ID = ID; |
| 551 | | state->m_pCurrentItem->Event_Data = Data; |
| 552 | | state->m_pCurrentItem->Event_Time = Time; |
| 553 | | |
| 554 | | state->m_pCurrentItem++; |
| 555 | | state->m_NumEvents++; |
| 228 | // no border bitmap allocated? fatalerror? |
| 556 | 229 | } |
| 557 | | } |
| 558 | | #endif |
| 559 | 230 | |
| 560 | | /* set the start time for use with EventList_AddItemOffset usually this will |
| 561 | | be cpu_getcurrentcycles() at the time that the screen is being refreshed */ |
| 562 | | void spectrum_EventList_SetOffsetStartTime(running_machine &machine, int StartTime) |
| 563 | | { |
| 564 | | spectrum_state *state = machine.driver_data<spectrum_state>(); |
| 565 | | state->m_LastFrameStartTime = StartTime; |
| 566 | | } |
| 567 | 231 | |
| 568 | | /* add an event to the buffer with a time index offset from a specified time */ |
| 569 | | void spectrum_EventList_AddItemOffset(running_machine &machine, int ID, int Data, int Time) |
| 570 | | { |
| 571 | | spectrum_state *state = machine.driver_data<spectrum_state>(); |
| 572 | | |
| 573 | | if (!state->m_CyclesPerFrame) |
| 574 | | state->m_CyclesPerFrame = (int)(machine.firstcpu->unscaled_clock() / machine.primary_screen->frame_period().attoseconds); //totalcycles(); //_(int)(cpunum_get_clock(0) / machine.config()->frames_per_second); |
| 575 | | |
| 576 | | if (state->m_NumEvents < state->m_TotalEvents) |
| 577 | | { |
| 578 | | /* setup item only if there is space in the buffer */ |
| 579 | | state->m_pCurrentItem->Event_ID = ID; |
| 580 | | state->m_pCurrentItem->Event_Data = Data; |
| 581 | | |
| 582 | | Time -= state->m_LastFrameStartTime; |
| 583 | | if ((Time < 0) || ((Time == 0) && state->m_NumEvents)) |
| 584 | | Time += state->m_CyclesPerFrame; |
| 585 | | state->m_pCurrentItem->Event_Time = Time; |
| 586 | | |
| 587 | | state->m_pCurrentItem++; |
| 588 | | state->m_NumEvents++; |
| 589 | | } |
| 590 | | } |
| 591 | | |
| 592 | | /* get number of events */ |
| 593 | | int spectrum_EventList_NumEvents(running_machine &machine) |
| 594 | | { |
| 595 | | spectrum_state *state = machine.driver_data<spectrum_state>(); |
| 596 | | return state->m_NumEvents; |
| 597 | | } |
| 598 | | |
| 599 | | /* get first item in buffer */ |
| 600 | | EVENT_LIST_ITEM *spectrum_EventList_GetFirstItem(running_machine &machine) |
| 601 | | { |
| 602 | | spectrum_state *state = machine.driver_data<spectrum_state>(); |
| 603 | | return (EVENT_LIST_ITEM *)state->m_pEventListBuffer; |
| 604 | | } |
| 232 | } |
| | No newline at end of file |