void cinemat_vector_callback(device_t *device, INT16 sx, INT16 sy, INT16 ex, INT16 ey, UINT8 shift) { cinemat_state *state = device->machine().driver_data<cinemat_state>(); const rectangle &visarea = device->machine().primary_screen->visible_area(); int intensity = 0xff; /* adjust for slop */ sx = sx - visarea.min_x; ex = ex - visarea.min_x; sy = sy - visarea.min_y; ey = ey - visarea.min_y; /* point intensity is determined by the shift value */ if (sx == ex && sy == ey) intensity = 0x1ff * shift / 8; /* move to the starting position if we're not there already */ if (sx != state->m_lastx || sy != state->m_lasty) vector_add_point(device->machine(), sx << 16, sy << 16, 0, 0); /* draw the vector */ vector_add_point(device->machine(), ex << 16, ey << 16, state->m_vector_color, intensity); /* remember the last point */ state->m_lastx = ex; state->m_lasty = ey; }
void cinemat_vector_callback(INT16 sx, INT16 sy, INT16 ex, INT16 ey, UINT8 shift) { int intensity = 0xff; /* adjust for slop */ sx = sx - Machine->screen[0].visarea.min_x; ex = ex - Machine->screen[0].visarea.min_x; sy = sy - Machine->screen[0].visarea.min_y; ey = ey - Machine->screen[0].visarea.min_y; /* point intensity is determined by the shift value */ if (sx == ex && sy == ey) intensity = 0x1ff * shift / 8; /* move to the starting position if we're not there already */ if (sx != lastx || sy != lasty) vector_add_point(sx << 16, sy << 16, 0, 0); /* draw the vector */ vector_add_point(ex << 16, ey << 16, vector_color, intensity); /* remember the last point */ lastx = ex; lasty = ey; }
void CinemaVectorData(int fromx, int fromy, int tox, int toy, int color) { static int lastx, lasty; fromy = cinemat_screenh - fromy; toy = cinemat_screenh - toy; if (fromx != lastx || fromx != lasty) vector_add_point (fromx << 16, fromy << 16, 0, 0); if (color_display) vector_add_point (tox << 16, toy << 16, VECTOR_COLOR111(color & 0x07), color & 0x08 ? 0x80: 0x40); else vector_add_point (tox << 16, toy << 16, VECTOR_COLOR111(WHITE), color * 12); lastx = tox; lasty = toy; }
void CinemaVectorData (int fromx, int fromy, int tox, int toy, int color) { static int lastx, lasty; fromy = cinemat_screenh - fromy; toy = cinemat_screenh - toy; if (fromx != lastx || fromx != lasty) vector_add_point (fromx << VEC_SHIFT, fromy << VEC_SHIFT, 0, 0); if (color_display) vector_add_point (tox << VEC_SHIFT, toy << VEC_SHIFT, color & 0x07, color & 0x08 ? 0x80: 0x40); else vector_add_point (tox << VEC_SHIFT, toy << VEC_SHIFT, WHITE, color * 12); lastx = tox; lasty = toy; }
static void aztarac_process_vector_list() { INT32 x, y, c, intensity, xoffset, yoffset, color; INT32 defaddr, objaddr, ndefs; vector_reset(); for (objaddr = 0; objaddr < 0x800; objaddr++) { read_vectorram (objaddr * 2, &xoffset, &yoffset, &c); if (c & 0x4000) break; if ((c & 0x2000) == 0) { defaddr = (c >> 1) & 0x7ff; vector_add_point((xcenter + (xoffset << 16)), (ycenter - (yoffset << 16)), 0, 0); read_vectorram (defaddr * 2, &x, &ndefs, &c); ndefs++; if (c & 0xff00) { intensity = (c >> 8); color = c & 0x3f; while (ndefs--) { defaddr++; read_vectorram (defaddr * 2, &x, &y, &c); if ((c & 0xff00) == 0) vector_add_point((xcenter + ((x + xoffset) << 16)), (ycenter - ((y + yoffset) << 16)), 0, 0); else vector_add_point((xcenter + ((x + xoffset) << 16)), (ycenter - ((y + yoffset) << 16)), color, intensity); } } else { while (ndefs--)
void sega_generate_vector_list (void) { int deltax, deltay; int currentX, currentY; int vectorIndex; int symbolIndex; int rotate, scale; int attrib; int angle, length; int color; int draw; vector_clear_list(); symbolIndex = 0; /* Reset vector PC to 0 */ /* * walk the symbol list until 'last symbol' set */ do { draw = vectorram[symbolIndex++]; if (draw & 1) /* if symbol active */ { currentX = vectorram[symbolIndex + 0] | (vectorram[symbolIndex + 1] << 8); currentY = vectorram[symbolIndex + 2] | (vectorram[symbolIndex + 3] << 8); vectorIndex = vectorram[symbolIndex + 4] | (vectorram[symbolIndex + 5] << 8); rotate = vectorram[symbolIndex + 6] | (vectorram[symbolIndex + 7] << 8); scale = vectorram[symbolIndex + 8]; currentX = ((currentX & 0x7ff) - min_x) << VEC_SHIFT; currentY = (max_y - (currentY & 0x7ff)) << VEC_SHIFT; vector_add_point ( currentX, currentY, 0, 0); vectorIndex &= 0xfff; /* walk the vector list until 'last vector' bit */ /* is set in attributes */ do { attrib = vectorram[vectorIndex + 0]; length = vectorram[vectorIndex + 1]; angle = vectorram[vectorIndex + 2] | (vectorram[vectorIndex + 3] << 8); vectorIndex += 4; /* calculate deltas based on len, angle(s), and scale factor */ angle = (angle + rotate) & 0x3ff; deltax = sinTable[angle] * scale * length; deltay = cosTable[angle] * scale * length; currentX += deltax >> 7; currentY -= deltay >> 7; color = attrib & 0x7e; if ((attrib & 1) && color) { if (translucency) intensity = 0xa0; /* leave room for translucency */ else intensity = 0xff; } else intensity = 0; vector_add_point ( currentX, currentY, color, intensity ); } while (!(attrib & 0x80)); } symbolIndex += 9; if (symbolIndex >= vectorram_size) break; } while (!(draw & 0x80));
static void cchasm_refresh (void) { int pc = 0; int done = 0; int opcode, data; int currentx = 0, currenty = 0; int scalex = 0, scaley = 0; int color = 0; int total_length = 1; /* length of all lines drawn in a frame */ int move = 0; vector_clear_list(); while (!done) { data = cchasm_ram[pc]; opcode = data >> 12; data &= 0xfff; if ((opcode > COLOR) && (data & 0x800)) data |= 0xfffff000; pc++; switch (opcode) { case HALT: done=1; break; case JUMP: pc = data - 0xb00; logerror("JUMP to %x\n", data); break; case COLOR: color = VECTOR_COLOR444(data ^ 0xfff); break; case SCALEY: scaley = data << 5; break; case POSY: move = 1; currenty = ycenter + (data << 16); break; case SCALEX: scalex = data << 5; break; case POSX: move = 1; currentx = xcenter - (data << 16); break; case LENGTH: if (move) { vector_add_point (currentx, currenty, 0, 0); move = 0; } currentx -= data * scalex; currenty += data * scaley; total_length += abs(data); if (color) vector_add_point (currentx, currenty, color, 0xff); else move = 1; break; default: logerror("Unknown refresh proc opcode %x with data %x at pc = %x\n", opcode, data, pc-2); done = 1; break; } } /* Refresh processor runs with 6 MHz */ timer_set (attotime_mul(ATTOTIME_IN_HZ(6000000), total_length), NULL, 0, cchasm_refresh_end); }
static void sega_generate_vector_list(running_machine &machine) { segag80v_state *state = machine.driver_data<segag80v_state>(); UINT8 *sintable = state->memregion("proms")->base(); double total_time = 1.0 / (double)IRQ_CLOCK; UINT16 symaddr = 0; UINT8 *vectorram = state->m_vectorram; vector_clear_list(); /* Loop until we run out of time. */ while (total_time > 0) { UINT16 curx, cury, xaccum, yaccum; UINT16 vecaddr, symangle; UINT8 scale, draw; /* The "draw" flag is clocked at the end of phase 0. */ draw = vectorram[symaddr++ & 0xfff]; /* The low byte of the X coordinate is latched into the */ /* up/down counters at U15/U16 during phase 1. */ curx = vectorram[symaddr++ & 0xfff]; /* The low 3 bits of the high byte of the X coordinate are */ /* latched into the up/down counter at U17 during phase 2. */ /* Bit 2 of the input is latched as both bit 2 and 3. */ curx |= (vectorram[symaddr++ & 0xfff] & 7) << 8; curx |= (curx << 1) & 0x800; /* The low byte of the Y coordinate is latched into the */ /* up/down counters at U18/U19 during phase 3. */ cury = vectorram[symaddr++ & 0xfff]; /* The low 3 bits of the high byte of the X coordinate are */ /* latched into the up/down counter at U17 during phase 4. */ /* Bit 2 of the input is latched as both bit 2 and 3. */ cury |= (vectorram[symaddr++ & 0xfff] & 7) << 8; cury |= (cury << 1) & 0x800; /* The low byte of the vector address is latched into the */ /* counters at U10/U11 during phase 5. */ vecaddr = vectorram[symaddr++ & 0xfff]; /* The low 4 bits of the high byte of the vector address is */ /* latched into the counter at U12 during phase 6. */ vecaddr |= (vectorram[symaddr++ & 0xfff] & 0xf) << 8; /* The low byte of the symbol angle is latched into the tri- */ /* state flip flop at U55 at the end of phase 7. */ symangle = vectorram[symaddr++ & 0xfff]; /* The low 2 bits of the high byte of the symbol angle are */ /* latched into flip flops at U26 at the end of phase 8. */ symangle |= (vectorram[symaddr++ & 0xfff] & 3) << 8; /* The scale is latched in phase 9 as the X input to the */ /* 25LS14 multiplier at U8. */ scale = vectorram[symaddr++ & 0xfff]; /* Account for the 10 phases so far. */ total_time -= 10.0 / (double)U51_CLOCK; /* Skip the rest if we're not drawing this symbol. */ if (draw & 1) { int adjx, adjy, clipped; /* Add a starting point to the vector list. */ clipped = adjust_xy(state, curx, cury, &adjx, &adjy); if (!clipped) vector_add_point(machine, adjx, adjy, 0, 0); /* Loop until we run out of time. */ while (total_time > 0) { UINT16 vecangle, length, deltax, deltay; UINT8 attrib, intensity; UINT32 color; /* The 'attribute' byte is latched at the end of phase 10 into */ /* the tri-state flip flop at U2. The low bit controls whether */ /* or not the beam is enabled. Bits 1-6 control the RGB color */ /* (2 bits per component). In addition, bit 7 of this value is */ /* latched into U52, which controls the pre-load value for the */ /* phase generator. If bit 7 is high, then the phase generator */ /* will reset back to 0 and draw a new symbol; if bit 7 is low */ /* the phase generator will reset back to 10 and draw another */ /* vector. */ attrib = vectorram[vecaddr++ & 0xfff]; /* The length of the vector is loaded into the shift registers */ /* at U6/U7 during phase 11. During phase 12, the 25LS14 */ /* multiplier at U8 is used to multiply the length by the */ /* scale that was loaded during phase 9. The length is clocked */ /* bit by bit out of U6/U7 and the result is clocked into the */ /* other side. After the multiply, the 9 MSBs are loaded into */ /* the counter chain at U15/16/17 and are used to count how */ /* long to draw the vector. */ length = (vectorram[vecaddr++ & 0xfff] * scale) >> 7; /* The vector angle low byte is latched at the end of phase 12 */ /* into the tri-state flip flop at U56. */ vecangle = vectorram[vecaddr++ & 0xfff]; /* The vector angle high byte is preset on the CD bus during */ /* phases 13 and 14, and is used as inputs to the adder at */ /* U46. */ vecangle |= (vectorram[vecaddr++ & 0xfff] & 3) << 8; /* The X increment value is looked up first (phase 13). The */ /* sum of the latched symbol angle and the vector angle is */ /* used as input to the PROM at U39. A0 is tied to ground. */ /* A1-A9 map to bits 0-8 of the summed angles. The output from */ /* the PROM is latched into U48. */ deltax = sintable[((vecangle + symangle) & 0x1ff) << 1]; /* The Y increment value is looked up second (phase 14). The */ /* angle sum is used once again as the input to the PROM, but */ /* this time an additional 0x100 is effectively added to it */ /* before it is used; this separates sin from cos. The output */ /* from the PROM is latched into U49. */ deltay = sintable[((vecangle + symangle + 0x100) & 0x1ff) << 1]; /* Account for the 4 phases for data fetching. */ total_time -= 4.0 / (double)U51_CLOCK; /* Compute color/intensity values from the attributes */ color = VECTOR_COLOR222((attrib >> 1) & 0x3f); if ((attrib & 1) && color) intensity = 0xff; else intensity = 0; /* Loop over the length of the vector. */ clipped = adjust_xy(state, curx, cury, &adjx, &adjy); xaccum = yaccum = 0; while (length-- != 0 && total_time > 0) { int newclip; /* The adders at U44/U45 are used as X accumulators. The value */ /* from U48 is repeatedly added to itself here. The carry out */ /* of bit 8 clocks the up/down counters at U15/U16/U17. Bit 7 */ /* of the input value from U48 is used as a carry in to round */ /* small values downward and larger values upward. */ xaccum += deltax + (deltax >> 7); /* Bit 9 of the summed angles controls the direction the up/ */ /* down counters at U15/U16/U17. */ if (((vecangle + symangle) & 0x200) == 0) curx += xaccum >> 8; else curx -= xaccum >> 8; xaccum &= 0xff; /* The adders at U46/U47 are used as Y accumulators. The value */ /* from U49 is repeatedly added to itself here. The carry out */ /* of bit 8 clocks the up/down counters at U18/U19/U20. Bit 7 */ /* of the input value from U49 is used as a carry in to round */ /* small values downward and larger values upward. */ yaccum += deltay + (deltay >> 7); /* Bit 9 of the summed angles controls the direction the up/ */ /* down counters at U18/U19/U20. */ if (((vecangle + symangle + 0x100) & 0x200) == 0) cury += yaccum >> 8; else cury -= yaccum >> 8; yaccum &= 0xff; /* Apply the clipping from the DAC circuit. If the values clip */ /* the beam is turned off, but the computations continue right */ /* on going. */ newclip = adjust_xy(state, curx, cury, &adjx, &adjy); if (newclip != clipped) { /* if we're just becoming unclipped, add an empty point */ if (!newclip) vector_add_point(machine, adjx, adjy, 0, 0); /* otherwise, add a colored point */ else vector_add_point(machine, adjx, adjy, color, intensity); } clipped = newclip; /* account for vector drawing time */ total_time -= 1.0 / (double)VCL_CLOCK; } /* We're done; if we are not clipped, add a final point. */ if (!clipped) vector_add_point(machine, adjx, adjy, color, intensity); /* if the high bit of the attribute is set, we break out of */ /* this loop and fetch another symbol */ if (attrib & 0x80) break; }
INLINE void aztarac_vector (int x, int y, int color, int intensity) { if (translucency) intensity *= 0.8; vector_add_point (xcenter + (x << VEC_SHIFT), ycenter - (y << VEC_SHIFT), color, intensity); }
static void cchasm_refresh (running_machine &machine) { cchasm_state *state = machine.driver_data<cchasm_state>(); int pc = 0; int done = 0; int opcode, data; int currentx = 0, currenty = 0; int scalex = 0, scaley = 0; int color = 0; int total_length = 1; /* length of all lines drawn in a frame */ int move = 0; vector_clear_list(); while (!done) { data = state->m_ram[pc]; opcode = data >> 12; data &= 0xfff; if ((opcode > COLOR) && (data & 0x800)) data |= 0xfffff000; pc++; switch (opcode) { case HALT: done=1; break; case JUMP: pc = data - 0xb00; logerror("JUMP to %x\n", data); break; case COLOR: color = VECTOR_COLOR444(data ^ 0xfff); break; case SCALEY: scaley = data << 5; break; case POSY: move = 1; currenty = state->m_ycenter + (data << 16); break; case SCALEX: scalex = data << 5; break; case POSX: move = 1; currentx = state->m_xcenter - (data << 16); break; case LENGTH: if (move) { vector_add_point (machine, currentx, currenty, 0, 0); move = 0; } currentx -= data * scalex; currenty += data * scaley; total_length += abs(data); if (color) vector_add_point (machine, currentx, currenty, color, 0xff); else move = 1; break; default: logerror("Unknown refresh proc opcode %x with data %x at pc = %x\n", opcode, data, pc-2); done = 1; break; } } /* Refresh processor runs with 6 MHz */ machine.scheduler().timer_set (attotime::from_hz(6000000) * total_length, FUNC(cchasm_refresh_end)); }