static void llander_process(_ShortPtr buffer, int start, int n) { int loop,sample; int oversampnum,loop2; for(loop=0;loop<n;loop++) { oversampnum=(int)(sampnum*multiplier)>>16; // if (errorlog) fprintf (errorlog, "LANDER: sampnum=%x oversampnum=%lx\n",sampnum, oversampnum); /* Pick up new noise target value whenever 12khz changes */ if(lastoversampnum>>6!=oversampnum>>6) { lfsr_index=lfsr_buffer.read16(lfsr_index); noisetarg=(lfsr_buffer.read16(lfsr_index)&0x4000)!=0?llander_volume[volume]:0x00; noisetarg<<=16; } /* Do tracking of noisetarg to noise current done in fixed point 16:16 */ /* each step takes us 1/256 of the difference between desired and current */ for(loop2=lastoversampnum;loop2<oversampnum;loop2++) { noisecurrent+=(noisetarg-noisecurrent)>>7; /* Equiv of multiply by 1/256 */ } sample=(int)(noisecurrent>>16); sample<<=1; /* Gain = 2 */ if(tone_3khz!=0) { sample+=sinetable[(oversampnum>>2)&0x3f]; } if(tone_6khz!=0) { sample+=sinetable[(oversampnum>>1)&0x3f]; } if(llander_explosion!=0) { sample+=(int)(noisecurrent>>(16-2)); /* Gain of 4 */ } /* Scale ouput down to buffer */ buffer.write16(start + loop,(ushort)( (sample << 5) - 0x8000)); sampnum++; lastoversampnum=oversampnum; } }
public override int start(Mame.MachineSound msound) { int i, j, sweep, charge, countdown, generator, bit1, bit2; int[] lfovol = { LFO_VOLUME, LFO_VOLUME, LFO_VOLUME }; #if SAMPLES Mame.Machine.samples = Mame.readsamples(galaxian_sample_names, Mame.Machine.gamedrv.name); #endif channelnoise = Mame.mixer_allocate_channel(NOISE_VOLUME); Mame.mixer_set_name(channelnoise, "Noise"); channelshoot = Mame.mixer_allocate_channel(SHOOT_VOLUME); Mame.mixer_set_name(channelshoot, "Shoot"); channellfo = Mame.mixer_allocate_channels(3, lfovol); Mame.mixer_set_name(channellfo + 0, "Background #0"); Mame.mixer_set_name(channellfo + 1, "Background #1"); Mame.mixer_set_name(channellfo + 2, "Background #2"); #if SAMPLES if (Mame.Machine.samples != null && Mame.Machine.samples.sample[0] != null) /* We should check also that Samplename[0] = 0 */ shootsampleloaded = 1; else shootsampleloaded = 0; if (Mame.Machine.samples != null && Mame.Machine.samples.sample[1] != null) /* We should check also that Samplename[0] = 0 */ deathsampleloaded = 1; else deathsampleloaded = 0; #endif if ((noisewave = new _ShortPtr((int)(NOISE_LENGTH * sizeof(short)))) == null) { return 1; } #if NEW_SHOOT byte SHOOT_SEC = 2; shoot_rate = Mame.Machine.sample_rate; shoot_length = SHOOT_SEC * shoot_rate; if ((shootwave = new _ShortPtr(shoot_length * sizeof(short))) == null) #else if( (shootwave = new _ShortPtr(SHOOT_LENGTH * sizeof(short))) == null ) #endif { noisewave = null; return 1; } /* * The RNG shifter is clocked with RNG_RATE, bit 17 is * latched every 2V cycles (every 2nd scanline). * This signal is used as a noise source. */ generator = 0; countdown = (int)(NOISE_RATE / 2); for (i = 0; i < NOISE_LENGTH; i++) { countdown -= (int)RNG_RATE; while (countdown < 0) { generator <<= 1; bit1 = (~generator >> 17) & 1; bit2 = (generator >> 5) & 1; if ((bit1 ^ bit2) != 0) generator |= 1; countdown += (int)NOISE_RATE; } noisewave.write16(i, (ushort)(((generator >> 17) & 1) != 0 ? (ushort)NOISE_AMPLITUDE : -(ushort)NOISE_AMPLITUDE)); } #if NEW_SHOOT /* dummy */ sweep = 100; charge = +2; j = 0; { int R41__ = 100000; int R44__ = 10000; int R45__ = 22000; int R46__ = 10000; int R47__ = 2200; int R48__ = 2200; double C25__ = 0.000001; double C27__ = 0.00000001; double C28__ = 0.000047; double C29__ = 0.00000001; double IC8L3_L = 0.2; /* 7400 L level */ double IC8L3_H = 4.5; /* 7400 H level */ double NOISE_L = 0.2; /* 7474 L level */ double NOISE_H = 4.5; /* 7474 H level */ /* key on/off time is programmable Therefore, it is necessary to make separate sample with key on/off. And, calculate the playback point according to the voltage of c28. */ double SHOOT_KEYON_TIME = 0.1; /* second */ /* NE555-FM input calculation is wrong. The frequency is not proportional to the voltage of FM input. And, duty will be changed,too. */ double NE555_FM_ADJUST_RATE = 0.80; /* discharge : 100K * 1uF */ double v = 5.0; double vK = (shoot_rate) != 0 ? Math.Exp(-1 / (R41__ * C25__) / shoot_rate) : 0; /* -- SHOOT KEY port -- */ double IC8L3 = IC8L3_L; /* key on */ int IC8Lcnt = (int)(SHOOT_KEYON_TIME * shoot_rate); /* count for key off */ /* C28 : KEY port capacity */ /* connection : 8L-3 - R47(2.2K) - C28(47u) - R48(2.2K) - C29 */ double c28v = IC8L3_H - (IC8L3_H - (NOISE_H + NOISE_L) / 2) / (R46__ + R47__ + R48__) * R47__; double c28K = (shoot_rate) != 0 ? Math.Exp(-1 / (22000 * 0.000047) / shoot_rate) : 0; /* C29 : NOISE capacity */ /* connection : NOISE - R46(10K) - C29(0.1u) - R48(2.2K) - C28 */ double c29v = IC8L3_H - (IC8L3_H - (NOISE_H + NOISE_L) / 2) / (R46__ + R47__ + R48__) * (R47__ + R48__); double c29K1 = (shoot_rate) != 0 ? Math.Exp(-1 / (22000 * 0.00000001) / shoot_rate) : 0; /* form C28 */ double c29K2 = (shoot_rate) != 0 ? Math.Exp(-1 / (100000 * 0.00000001) / shoot_rate) : 0; /* from noise */ /* NE555 timer */ /* RA = 10K , RB = 22K , C=.01u ,FM = C29 */ double ne555cnt = 0; double ne555step = (shoot_rate) != 0 ? ((1.44 / ((R44__ + R45__ * 2) * C27__)) / shoot_rate) : 0; double ne555duty = (double)(R44__ + R45__) / (R44__ + R45__ * 2); /* t1 duty */ double ne555sr; /* threshold (FM) rate */ /* NOISE source */ double ncnt = 0.0; double nstep = (shoot_rate) != 0 ? ((double)NOISE_RATE / shoot_rate) : 0; double noise_sh2; /* voltage level */ for (i = 0; i < shoot_length; i++) { /* noise port */ noise_sh2 = noisewave.read16((int)(ncnt % NOISE_LENGTH)) == NOISE_AMPLITUDE ? NOISE_H : NOISE_L; ncnt += nstep; /* calculate NE555 threshold level by FM input */ ne555sr = c29v * NE555_FM_ADJUST_RATE / (5.0 * 2 / 3); /* calc output */ ne555cnt += ne555step; if (ne555cnt >= ne555sr) ne555cnt -= ne555sr; if (ne555cnt < ne555sr * ne555duty) { /* t1 time */ shootwave.write16(i, (ushort)(v / 5 * 0x7fff)); /* discharge output level */ if (IC8L3 == IC8L3_H) v *= vK; } else shootwave.write16(i, 0); /* C28 charge/discharge */ c28v += (IC8L3 - c28v) - (IC8L3 - c28v) * c28K; /* from R47 */ c28v += (c29v - c28v) - (c29v - c28v) * c28K; /* from R48 */ /* C29 charge/discharge */ c29v += (c28v - c29v) - (c28v - c29v) * c29K1; /* from R48 */ c29v += (noise_sh2 - c29v) - (noise_sh2 - c29v) * c29K2; /* from R46 */ /* key off */ if (IC8L3 == IC8L3_L && --IC8Lcnt == 0) IC8L3 = IC8L3_H; } } #else /* * Ra is 10k, Rb is 22k, C is 0.01uF * charge time t1 = 0.693 * (Ra + Rb) * C . 221.76us * discharge time t2 = 0.693 * (Rb) * C . 152.46us * average period 374.22us . 2672Hz * I use an array of 10 values to define some points * of the charge/discharge curve. The wave is modulated * using the charge/discharge timing of C28, a 47uF capacitor, * over a 2k2 resistor. This will change the frequency from * approx. Favg-Favg/3 up to Favg+Favg/3 down to Favg-Favg/3 again. */ sweep = 100; charge = +2; countdown = sweep / 2; for( i = 0, j = 0; i < SHOOT_LENGTH; i++ ) { shootwave[i] = charge_discharge[j]; LOG((errorlog, "shoot[%5d] $%04x (sweep: %3d, j:%d)\n", i, shootwave[i] & 0xffff, sweep, j)); /* * The current sweep and a 2200/10000 fraction (R45 and R48) * of the noise are frequency modulating the NE555 chip. */ countdown -= sweep + noisewave[i % NOISE_LENGTH] / (2200*NOISE_AMPLITUDE/10000); while( countdown < 0 ) { countdown += 100; j = ++j % 10; } /* sweep from 100 to 133 and down to 66 over the time of SHOOT_LENGTH */ if( i % (SHOOT_LENGTH / 33 / 3 ) == 0 ) { sweep += charge; if( sweep >= 133 ) charge = -1; } } #endif //memset(tonewave, 0, sizeof(tonewave)); for (i = 0; i < TOOTHSAW_LENGTH; i++) { //#define V(r0,r1) 2*TOOTHSAW_AMPLITUDE*(r0)/(r0+r1)-TOOTHSAW_AMPLITUDE double r0a = 1.0 / 1e12, r1a = 1.0 / 1e12; double r0b = 1.0 / 1e12, r1b = 1.0 / 1e12; /* #0: VOL1=0 and VOL2=0 * only the 33k and the 22k resistors R51 and R50 */ if ((i & 1) != 0) { r1a += 1.0 / 33000; r1b += 1.0 / 33000; } else { r0a += 1.0 / 33000; r0b += 1.0 / 33000; } if ((i & 4) != 0) { r1a += 1.0 / 22000; r1b += 1.0 / 22000; } else { r0a += 1.0 / 22000; r0b += 1.0 / 22000; } for (int k = 0; k < 4; k++) tonewave[k] = new _BytePtr(TOOTHSAW_LENGTH); tonewave[0][i] = (byte)V(1.0 / r0a, 1.0 / r1a); //#define V(r0,r1) 2*TOOTHSAW_AMPLITUDE*(r0)/(r0+r1)-TOOTHSAW_AMPLITUDE /* #1: VOL1=1 and VOL2=0 * add the 10k resistor R49 for bit QC */ if ((i & 4) != 0) r1a += 1.0 / 10000; else r0a += 1.0 / 10000; tonewave[1][i] = (byte)V(1.0 / r0a, 1.0 / r1a); /* #2: VOL1=0 and VOL2=1 * add the 15k resistor R52 for bit QD */ if ((i & 8) != 0) r1b += 1.0 / 15000; else r0b += 1.0 / 15000; tonewave[2][i] = (byte)V(1.0 / r0b, 1.0 / r1b); /* #3: VOL1=1 and VOL2=1 * add the 10k resistor R49 for QC */ if ((i & 4) != 0) r0b += 1.0 / 10000; else r1b += 1.0 / 10000; tonewave[3][i] = (byte)V(1.0 / r0b, 1.0 / r1b); //LOG((errorlog, "tone[%2d]: $%02x $%02x $%02x $%02x\n", i, tonewave[0][i], tonewave[1][i], tonewave[2][i], tonewave[3][i])); } pitch = 0; vol = 0; tone_stream = Mame.stream_init("Tone", TOOTHSAW_VOLUME, (int)(SOUND_CLOCK / STEPS), 0, tone_update); #if SAMPLES if (deathsampleloaded == 0) #endif { Mame.mixer_set_volume(channelnoise, 0); Mame.mixer_play_sample_16(channelnoise, noisewave, (int)NOISE_LENGTH, (int)NOISE_RATE, true); } #if SAMPLES if (shootsampleloaded == 0) #endif { Mame.mixer_set_volume(channelshoot, 0); Mame.mixer_play_sample_16(channelshoot, shootwave, SHOOT_LENGTH, SHOOT_RATE, false); } Mame.mixer_set_volume(channellfo + 0, 0); Mame.mixer_play_sample_16(channellfo + 0, backgroundwave, backgroundwave.buffer.Length / 2, 1000, true); Mame.mixer_set_volume(channellfo + 1, 0); Mame.mixer_play_sample_16(channellfo + 1, backgroundwave, backgroundwave.buffer.Length / 2, 1000, true); Mame.mixer_set_volume(channellfo + 2, 0); Mame.mixer_play_sample_16(channellfo + 2, backgroundwave, backgroundwave.buffer.Length / 2, 1000, true); return 0; }
static void shuffle(_ShortPtr buf, int len) { if (len == 2) return; if ((len % 4) != 0) throw new Exception(); /* must not happen */ len /= 2; for (int i = 0; i < len / 2; i++) { ushort t = buf.read16(len / 2 + i); buf.write16(len / 2 + i, buf.read16(len + i)); buf.write16(len + i, t); } shuffle(buf, len); shuffle(new _ShortPtr(buf, len*2 ), len); }
static void tone_update(int ch, _ShortPtr buffer, int length) { int i, j; _BytePtr w = new _BytePtr(tonewave[vol]); /* only update if we have non-zero volume and frequency */ if (pitch != 0xff) { for (i = 0; i < length; i++) { int mix = 0; for (j = 0; j < STEPS; j++) { if (countdown >= 256) { counter = (counter + 1) % TOOTHSAW_LENGTH; countdown = pitch; } countdown++; mix += (sbyte)w[counter]; } buffer.write16(0, (ushort)((mix << 8) / STEPS)); buffer.offset += 2; } } else { for (i = 0; i < length; i++) { buffer.write16(0, 0); buffer.offset += 2; } } }
static void K051316_zoom_draw(int chip, Mame.osd_bitmap bitmap) { uint startx,starty,cx,cy; int incxx,incxy,incyx,incyy; int x,sx,sy,ex,ey; Mame.osd_bitmap srcbitmap = K051316_tilemap[chip].pixmap; startx = (uint)(256 * ((short)(256 * K051316_ctrlram[chip][0x00] + K051316_ctrlram[chip][0x01]))); incxx = (short)(256 * K051316_ctrlram[chip][0x02] + K051316_ctrlram[chip][0x03]); incyx = (short)(256 * K051316_ctrlram[chip][0x04] + K051316_ctrlram[chip][0x05]); starty =(uint)( 256 * ((short)(256 * K051316_ctrlram[chip][0x06] + K051316_ctrlram[chip][0x07]))); incxy = (short)(256 * K051316_ctrlram[chip][0x08] + K051316_ctrlram[chip][0x09]); incyy = (short)(256 * K051316_ctrlram[chip][0x0a] + K051316_ctrlram[chip][0x0b]); startx += (uint)((Mame.Machine.drv.visible_area.min_y - (16 + K051316_offset[chip][1])) * incyx); starty += (uint)((Mame.Machine.drv.visible_area.min_y - (16 + K051316_offset[chip][1])) * incyy); startx += (uint)((Mame.Machine.drv.visible_area.min_x - (89 + K051316_offset[chip][0])) * incxx); starty += (uint)((Mame.Machine.drv.visible_area.min_x - (89 + K051316_offset[chip][0])) * incxy); sx = Mame.Machine.drv.visible_area.min_x; sy = Mame.Machine.drv.visible_area.min_y; ex = Mame.Machine.drv.visible_area.max_x; ey = Mame.Machine.drv.visible_area.max_y; if ((Mame.Machine.orientation & Mame.ORIENTATION_SWAP_XY)!=0) { int t; t = (int)startx; startx = starty; starty = (uint)t; t = sx; sx = sy; sy = t; t = ex; ex = ey; ey = t; t = incxx; incxx = incyy; incyy = t; t = incxy; incxy = incyx; incyx = t; } if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_X)!=0) { int w = ex - sx; incxy = -incxy; incyx = -incyx; startx = 0xfffff - startx; startx -= (uint)(incxx * w); starty -= (uint)(incxy * w); } if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_Y)!=0) { int h = ey - sy; incxy = -incxy; incyx = -incyx; starty = 0xfffff - starty; startx -=(uint)(incyx * h); starty -=(uint)(incyy * h); } if (bitmap.depth == 8) { _BytePtr dest; if (incxy == 0 && incyx == 0 && K051316_wraparound[chip]==0) { /* optimized loop for the not rotated case */ if (incxx == 0x800) { /* optimized loop for the not zoomed case */ /* startx is unsigned */ startx = (uint)(((int)startx) >> 11); if (startx >= 512) { sx += (int)-startx; startx = 0; } if (sx <= ex) { while (sy <= ey) { if ((starty & 0xfff00000) == 0) { x = sx; cx = startx; cy = starty >> 11; dest = new _BytePtr(bitmap.line[sy], sx); while (x <= ex && cx < 512) { int c = srcbitmap.line[cy][cx]; if (c != Mame.palette_transparent_pen) dest[0] = (byte)c; cx++; x++; dest.offset++; } } starty += (uint)incyy; sy++; } } } else { while ((startx & 0xfff00000) != 0 && sx <= ex) { startx += (uint)incxx; sx++; } if ((startx & 0xfff00000) == 0) { while (sy <= ey) { if ((starty & 0xfff00000) == 0) { x = sx; cx = startx; cy = starty >> 11; dest = new _BytePtr(bitmap.line[sy], sx); while (x <= ex && (cx & 0xfff00000) == 0) { int c = srcbitmap.line[cy][cx >> 11]; if (c != Mame.palette_transparent_pen) dest[0] = (byte)c; cx +=(uint) incxx; x++; dest.offset++; } } starty += (uint)incyy; sy++; } } } } else { if (K051316_wraparound[chip]!=0) { /* plot with wraparound */ while (sy <= ey) { x = sx; cx = startx; cy = starty; dest = new _BytePtr(bitmap.line[sy],sx); while (x <= ex) { int c = srcbitmap.line[(cy >> 11) & 0x1ff][(cx >> 11) & 0x1ff]; if (c != Mame.palette_transparent_pen) dest[0] = (byte)c; cx += (uint)incxx; cy += (uint)incxy; x++; dest.offset++; } startx += (uint)incyx; starty += (uint)incyy; sy++; } } else { while (sy <= ey) { x = sx; cx = startx; cy = starty; dest = new _BytePtr(bitmap.line[sy],sx); while (x <= ex) { if ((cx & 0xfff00000) == 0 && (cy & 0xfff00000) == 0) { int c = srcbitmap.line[cy >> 11][cx >> 11]; if (c != Mame.palette_transparent_pen) dest[0] = (byte)c; } cx += (uint)incxx; cy += (uint)incxy; x++; dest.offset++; } startx += (uint)incyx; starty += (uint)incyy; sy++; } } } } else { /* 16-bit case */ _ShortPtr dest; if (incxy == 0 && incyx == 0 && K051316_wraparound[chip]==0) { /* optimized loop for the not rotated case */ if (incxx == 0x800) { /* optimized loop for the not zoomed case */ /* startx is unsigned */ startx = (uint)((int)startx) >> 11; if (startx >= 512) { sx += (int)-startx; startx = 0; } if (sx <= ex) { while (sy <= ey) { if ((starty & 0xfff00000) == 0) { x = sx; cx = startx; cy = starty >> 11; dest = new _ShortPtr(bitmap.line[sy], sx); while (x <= ex && cx < 512) { int c = srcbitmap.line[cy].read16((int)cx); if (c != Mame.palette_transparent_pen) dest.write16(0, (ushort)c); cx++; x++; dest.offset += 2; } } starty += (uint)incyy; sy++; } } } else { while ((startx & 0xfff00000) != 0 && sx <= ex) { startx += (uint)incxx; sx++; } if ((startx & 0xfff00000) == 0) { while (sy <= ey) { if ((starty & 0xfff00000) == 0) { x = sx; cx = startx; cy = starty >> 11; dest = new _ShortPtr(bitmap.line[sy], sx); while (x <= ex && (cx & 0xfff00000) == 0) { int c = srcbitmap.line[cy].read16((int)cx >> 11); if (c !=Mame. palette_transparent_pen) dest.write16(0,(ushort) c); cx += (uint)incxx; x++; dest.offset+=2; } } starty += (uint)incyy; sy++; } } } } else { if (K051316_wraparound[chip]!=0) { /* plot with wraparound */ while (sy <= ey) { x = sx; cx = startx; cy = starty; dest = new _ShortPtr(bitmap.line[sy], sx); while (x <= ex) { int c = srcbitmap.line[(cy >> 11) & 0x1ff].read16((int)(cx >> 11) & 0x1ff); if (c != Mame.palette_transparent_pen) dest.write16(0,(ushort)c); cx += (uint)incxx; cy += (uint)incxy; x++; dest.offset += 2; } startx +=(uint) incyx; starty += (uint)incyy; sy++; } } else { while (sy <= ey) { x = sx; cx = startx; cy = starty; dest = new _ShortPtr(bitmap.line[sy], sx); while (x <= ex) { if ((cx & 0xfff00000) == 0 && (cy & 0xfff00000) == 0) { int c = (srcbitmap.line[cy >> 11].read16((int)cx >> 11)); if (c != Mame.palette_transparent_pen) dest.write16(0,(ushort) c); } cx += (uint)incxx; cy += (uint)incxy; x++; dest.offset += 2; } startx += (uint)incyx; starty += (uint)incyy; sy++; } } } } #if false usrintf_showmessage("%02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x", K051316_ctrlram[chip][0x00], K051316_ctrlram[chip][0x01], K051316_ctrlram[chip][0x02], K051316_ctrlram[chip][0x03], K051316_ctrlram[chip][0x04], K051316_ctrlram[chip][0x05], K051316_ctrlram[chip][0x06], K051316_ctrlram[chip][0x07], K051316_ctrlram[chip][0x08], K051316_ctrlram[chip][0x09], K051316_ctrlram[chip][0x0a], K051316_ctrlram[chip][0x0b], K051316_ctrlram[chip][0x0c], /* bank for ROM testing */ K051316_ctrlram[chip][0x0d], K051316_ctrlram[chip][0x0e], /* 0 = test ROMs */ K051316_ctrlram[chip][0x0f]); #endif }