diff options
Diffstat (limited to 'src/mame/video/tutankhm.cpp')
-rw-r--r-- | src/mame/video/tutankhm.cpp | 443 |
1 files changed, 0 insertions, 443 deletions
diff --git a/src/mame/video/tutankhm.cpp b/src/mame/video/tutankhm.cpp deleted file mode 100644 index f3503f5c802..00000000000 --- a/src/mame/video/tutankhm.cpp +++ /dev/null @@ -1,443 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Mirko Buffoni -/*************************************************************************** - - video.c - - Functions to emulate the video hardware of the machine. - -***************************************************************************/ - -#include "emu.h" -#include "includes/tutankhm.h" -#include "video/resnet.h" - -#define STAR_RNG_PERIOD ((1 << 17) - 1) -#define RGB_MAXIMUM 224 - -/************************************* - * - * Write handlers - * - *************************************/ - -WRITE_LINE_MEMBER(tutankhm_state::flip_screen_x_w) -{ - m_flipscreen_x = state; -} - - -WRITE_LINE_MEMBER(tutankhm_state::flip_screen_y_w) -{ - m_flipscreen_y = state; -} - - -/************************************* - * - * Video update - * - *************************************/ - -uint32_t tutankhm_state::screen_update_tutankhm_bootleg(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - bitmap.fill(rgb_t::black(), cliprect); - - int xorx = m_flipscreen_x ? 255 : 0; - int xory = m_flipscreen_y ? 255 : 0; - - for (int y = cliprect.min_y; y <= cliprect.max_y; y++) - { - uint32_t *const dst = &bitmap.pix(y); - - for (int x = cliprect.min_x / GALAXIAN_XSCALE; x <= cliprect.max_x / GALAXIAN_XSCALE; x++) - { - uint8_t effx = x ^ xorx; - uint8_t yscroll = (effx < 192 && m_scroll.found()) ? *m_scroll : 0; - uint8_t effy = (y ^ xory) + yscroll; - uint8_t vrambyte = m_videoram[effy * 128 + effx / 2]; - uint8_t shifted = vrambyte >> (4 * (effx % 2)); - - uint8_t blink_state = m_stars_blink_state & 3; - uint8_t enab = 0; - switch (blink_state) - { - case 0: enab = 1; break; - case 1: enab = (y & 1) == 1; break; - case 2: enab = (y & 2) == 2; break; - case 3: enab = (x & 8) == 0; break; - } - //enab &= (((y>>1) ^ (x >> 3)) & 1); - - int offset = y * 384 + x + 84; - - uint8_t star = m_stars[offset % STAR_RNG_PERIOD ]; - if (m_stars_enabled && enab && (shifted & 0x02) == 0 && (star & 0x80) != 0 - && x > 63) - { - bitmap.pix(y, GALAXIAN_XSCALE*x + 0) = m_star_color[star & 0x3f]; - bitmap.pix(y, GALAXIAN_XSCALE*x + 1) = m_star_color[star & 0x3f]; - bitmap.pix(y, GALAXIAN_XSCALE*x + 2) = m_star_color[star & 0x3f]; - } - - else if (shifted) - { - dst[x * GALAXIAN_XSCALE + 0] = m_palette->pen_color(shifted & 0x0f); - dst[x * GALAXIAN_XSCALE + 1] = m_palette->pen_color(shifted & 0x0f); - dst[x * GALAXIAN_XSCALE + 2] = m_palette->pen_color(shifted & 0x0f); - } - } - } - - return 0; -} - -uint32_t tutankhm_state::screen_update_tutankhm_scramble(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - scramble_draw_background(bitmap, cliprect); - - int xorx = m_flipscreen_x ? 255 : 0; - int xory = m_flipscreen_y ? 255 : 0; - - for (int y = cliprect.min_y; y <= cliprect.max_y; y++) - { - uint32_t *const dst = &bitmap.pix(y); - - for (int x = cliprect.min_x / GALAXIAN_XSCALE; x <= cliprect.max_x / GALAXIAN_XSCALE; x++) - { - uint8_t effx = x ^ xorx; - uint8_t yscroll = (effx < 192 && m_scroll.found()) ? *m_scroll : 0; - uint8_t effy = (y ^ xory) + yscroll; - uint8_t vrambyte = m_videoram[effy * 128 + effx / 2]; - uint8_t shifted = vrambyte >> (4 * (effx % 2)); - if (shifted) - { - dst[x * GALAXIAN_XSCALE + 0] = m_palette->pen_color(shifted & 0x0f); - dst[x * GALAXIAN_XSCALE + 1] = m_palette->pen_color(shifted & 0x0f); - dst[x * GALAXIAN_XSCALE + 2] = m_palette->pen_color(shifted & 0x0f); - } - } - } - - return 0; -} - -uint32_t tutankhm_state::screen_update_tutankhm(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - u8 mode = m_stars_config.read_safe(m_star_mode); - if (mode != m_star_mode) - { - m_star_mode = mode; - stars_init(); - } - - if (m_star_mode) - return screen_update_tutankhm_scramble(screen, bitmap, cliprect); - else - return screen_update_tutankhm_bootleg(screen, bitmap, cliprect); -} - -/************************************* - * - * Copied from galaxian.cpp video code - * - *************************************/ - -rgb_t tutankhm_state::raw_to_rgb_func(u32 raw) -{ - static const int rgb_resistances[3] = { 1000, 470, 220 }; - /* - Sprite/tilemap colors are mapped through a color PROM as follows: - - bit 7 -- 220 ohm resistor -- BLUE - -- 470 ohm resistor -- BLUE - -- 220 ohm resistor -- GREEN - -- 470 ohm resistor -- GREEN - -- 1 kohm resistor -- GREEN - -- 220 ohm resistor -- RED - -- 470 ohm resistor -- RED - bit 0 -- 1 kohm resistor -- RED - - Note that not all boards have this configuration. Namco PCBs may - have 330 ohm resistors instead of 220, but the default setup has - also been used by Namco. - - In parallel with these resistors are a pair of 150 ohm and 100 ohm - resistors on each R,G,B component that are connected to the star - generator. - - And in parallel with the whole mess are a set of 100 ohm resistors - on each R,G,B component that are enabled when a shell/missile is - enabled. - - When computing weights, we use RGB_MAXIMUM as the maximum to give - headroom for stars and shells/missiles. This is not fully accurate, - but if we included all possible sources in parallel, the brightness - of the main game would be very low to allow for all the oversaturation - of the stars and shells/missiles. - */ - double rweights[3], gweights[3], bweights[2]; - compute_resistor_weights(0, RGB_MAXIMUM, -1.0, - 3, &rgb_resistances[0], rweights, 470, 0, - 3, &rgb_resistances[0], gweights, 470, 0, - 2, &rgb_resistances[1], bweights, 470, 0); - - // decode the palette first - - uint8_t bit0, bit1, bit2; - - // red component - bit0 = BIT(raw, 0); - bit1 = BIT(raw, 1); - bit2 = BIT(raw, 2); - int const r = combine_weights(rweights, bit0, bit1, bit2); - - // green component - bit0 = BIT(raw, 3); - bit1 = BIT(raw, 4); - bit2 = BIT(raw, 5); - int const g = combine_weights(gweights, bit0, bit1, bit2); - - // blue component - bit0 = BIT(raw, 6); - bit1 = BIT(raw, 7); - int const b = combine_weights(bweights, bit0, bit1); - - return rgb_t(r, g, b); -} - -void tutankhm_state::galaxian_palette(palette_device &palette) -{ - /* - The maximum sprite/tilemap resistance is ~130 Ohms with all RGB - outputs enabled (1/(1/1000 + 1/470 + 1/220)). Since we normalized - to RGB_MAXIMUM, this maps RGB_MAXIMUM -> 130 Ohms. - - The stars are at 150 Ohms for the LSB, and 100 Ohms for the MSB. - This means the 3 potential values are: - - 150 Ohms -> RGB_MAXIMUM * 130 / 150 - 100 Ohms -> RGB_MAXIMUM * 130 / 100 - 60 Ohms -> RGB_MAXIMUM * 130 / 60 - - Since we can't saturate that high, we instead approximate this - by compressing the values proportionally into the 194->255 range. - */ - int const minval = RGB_MAXIMUM * 130 / 150; - int const midval = RGB_MAXIMUM * 130 / 100; - int const maxval = RGB_MAXIMUM * 130 / 60; - - // compute the values for each of 4 possible star values - uint8_t const starmap[4]{ - 0, - minval, - minval + (255 - minval) * (midval - minval) / (maxval - minval), - 255 }; - - // generate the colors for the stars - for (int i = 0; i < 64; i++) - { - uint8_t bit0, bit1; - - // bit 5 = red @ 150 Ohm, bit 4 = red @ 100 Ohm - bit0 = BIT(i, 5); - bit1 = BIT(i, 4); - int const r = starmap[(bit1 << 1) | bit0]; - - // bit 3 = green @ 150 Ohm, bit 2 = green @ 100 Ohm - bit0 = BIT(i, 3); - bit1 = BIT(i, 2); - int const g = starmap[(bit1 << 1) | bit0]; - - // bit 1 = blue @ 150 Ohm, bit 0 = blue @ 100 Ohm - bit0 = BIT(i, 1); - bit1 = BIT(i, 0); - int const b = starmap[(bit1 << 1) | bit0]; - - // set the RGB color - m_star_color[i] = rgb_t(r, g, b); - } -} - - -void tutankhm_state::video_start() -{ - /* initialize globals */ - m_flipscreen_x = 0; - m_flipscreen_y = 0; - - /* initialize stars */ - m_stars_enabled = 0; - m_stars_blink_state = 0; - stars_init(); - - galaxian_palette(*m_palette); -} - -void tutankhm_state::stars_init() -{ - (m_star_mode) ? stars_init_scramble() : stars_init_bootleg(); -} - -void tutankhm_state::stars_init_bootleg() -{ - /* reset the blink and enabled states */ - m_stars_enabled = false; - m_stars_blink_state = 0; - - /* precalculate the RNG */ - m_stars = std::make_unique<uint8_t[]>(STAR_RNG_PERIOD); - uint32_t shiftreg = 0; - for (int i = 0; i < STAR_RNG_PERIOD; i++) - { - int newbit = ((shiftreg >> 12) ^ ~shiftreg) & 1; - - /* stars are enabled if the upper 8 bits are 1 and the new bit is 0 */ - int enabled = ((shiftreg & 0x1fe00) == 0x1fe00) && (newbit == 0); - //int enabled = ((shiftreg & 0x1fe01) == 0x1fe00); // <- scramble - - /* color comes from the 6 bits below the top 8 bits */ - int color = (~shiftreg & 0x1f8) >> 3; - - /* store the color value in the low 6 bits and the enable in the upper bit */ - m_stars[i] = color | (enabled << 7); - - /* the LFSR is fed based on the XOR of bit 12 and the inverse of bit 0 */ - shiftreg = (shiftreg >> 1) | (newbit << 16); - } -} - -void tutankhm_state::stars_init_scramble() -{ - /* precalculate the RNG */ - m_stars = std::make_unique<uint8_t[]>(STAR_RNG_PERIOD); - uint32_t shiftreg = 0; - for (int i = 0; i < STAR_RNG_PERIOD; i++) - { - const uint8_t shift = 12; - /* stars are enabled if the upper 8 bits are 1 and the low bit is 0 */ - int enabled = ((shiftreg & 0x1fe01) == 0x1fe00); - - /* color comes from the 6 bits below the top 8 bits */ - int color = (~shiftreg & 0x1f8) >> 3; - - /* store the color value in the low 6 bits and the enable in the upper bit */ - m_stars[i] = color | (enabled << 7); - - /* the LFSR is fed based on the XOR of bit 12 and the inverse of bit 0 */ - //shiftreg = (shiftreg >> 1) | ((((shiftreg >> 12) ^ ~shiftreg) & 1) << 16); - shiftreg = (shiftreg >> 1) | ((((shiftreg >> shift) ^ ~shiftreg) & 1) << 16); - } -} - - - -/************************************* - * - * Star blinking - * - *************************************/ - -TIMER_DEVICE_CALLBACK_MEMBER(tutankhm_state::scramble_stars_blink_timer) -{ - m_stars_blink_state++; -} - -void tutankhm_state::stars_draw_row(bitmap_rgb32 &bitmap, int maxx, int y, uint32_t star_offs) -{ - uint8_t flipxor = (m_flipscreen_x ? 0xC0 : 0x00); - - /* ensure our star offset is valid */ - star_offs %= STAR_RNG_PERIOD; - - /* iterate over the specified number of 6MHz pixels */ - for (int x = 0; x < maxx; x++) - { - uint8_t h8q = ((x>>3) & 1) ^ 1; // H8 signal is inverted. - /* stars are suppressed unless V1 ^ H8 == 1 */ - int enable_star = (y ^ h8q) & 1; - uint8_t star; - - uint8_t blink_state = m_stars_blink_state & 3; - uint8_t enab = 0; - switch (blink_state) - { - case 0: enab = 1; break; - case 1: enab = (y & 1) == 1; break; - case 2: enab = (y & 2) == 2; break; - case 3: enab = h8q; break; // H8 signal is inverted. - } - - enable_star &= (enab && ((x & 0xC0) ^ flipxor) != 0xC0); - - /* - The RNG clock is the master clock (18MHz) ANDed with the pixel clock (6MHz). - The divide-by-3 circuit that produces the pixel clock generates a square wave - with a 2/3 duty cycle, so the result of the AND generates a clock like this: - _ _ _ _ _ _ _ _ - MASTER: _| |_| |_| |_| |_| |_| |_| |_| | - _______ _______ ______ - PIXEL: _| |___| |___| - _ _ _ _ _ _ - RNG: _| |_| |_____| |_| |_____| |_| | - - Thus for each pixel, there are 3 master clocks and 2 RNG clocks, and the RNG - is clocked asymmetrically. To simulate this, we expand the horizontal screen - size by 3 and handle the first RNG clock with one pixel and the second RNG - clock with two pixels. - */ - - /* first RNG clock: one pixel */ - star = m_stars[star_offs++]; - if (star_offs >= STAR_RNG_PERIOD) - star_offs = 0; - if (enable_star && (star & 0x80) != 0) - bitmap.pix(y, GALAXIAN_XSCALE*x + 0) = m_star_color[star & 0x3f]; - - /* second RNG clock: two pixels */ - star = m_stars[star_offs++]; - if (star_offs >= STAR_RNG_PERIOD) - star_offs = 0; - if (enable_star && (star & 0x80) != 0) - { - bitmap.pix(y, GALAXIAN_XSCALE*x + 1) = m_star_color[star & 0x3f]; - bitmap.pix(y, GALAXIAN_XSCALE*x + 2) = m_star_color[star & 0x3f]; - } - } -} - -void tutankhm_state::scramble_draw_stars(bitmap_rgb32 &bitmap, const rectangle &cliprect, int maxx) -{ - /* update the star origin to the current frame */ - //stars_update_origin(); - - /* render stars if enabled */ - if (m_stars_enabled) - { - /* iterate over scanlines */ - for (int y = cliprect.min_y; y <= cliprect.max_y; y++) - { - stars_draw_row(bitmap, maxx, y, y * 512); - } - } -} - - -void tutankhm_state::scramble_draw_background(bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - /* blue background - 390 ohm resistor */ - bitmap.fill(rgb_t::black(), cliprect); - - scramble_draw_stars(bitmap, cliprect, 256); -} - -void tutankhm_state::galaxian_stars_enable_w(uint8_t data) -{ - if ((m_stars_enabled ^ data) & 0x01) - { -// m_screen->update_now(); - m_screen->update_partial(m_screen->vpos()); - } - - m_stars_enabled = data & 0x01; -} |