/* LTUNNEL.C * * S2 The Party '94 64kb intro * -- Line tunnel * * Copyright 1995 Petteri Kangaslampi and Jarno Paananen * * This file is part of the MIDAS Sound System, and may only be * used, modified and distributed under the terms of the MIDAS * Sound System license, LICENSE.TXT. By continuing to use, * modify or distribute this file you indicate that you have * read the license and understand and accept it fully. */ #include #include #include #include #include #include #include #include "intro.h" #define LINESPERCIRCLE 16 #define NUMCIRCLES 24 #define NUMDELAYS 8 int linTab[LINESPERCIRCLE * 4 * NUMCIRCLES * NUMDELAYS]; char palette[256*3*NUMDELAYS]; uchar lineTab[LINESPERCIRCLE * 2 * NUMCIRCLES]; extern char WaterPalette[]; extern char LineColor; void doPalette(char *palette, char *delayColors, char delayNum); #pragma aux doPalette = \ "mov ch,1" \ "mov al,ch" \ "shl al,cl" \ "mov cl,al" \ "l1: mov al,cl" \ "push si" \ "l2: test ch,al" \ "jnz found" \ "ror al,1" \ "add si,3" \ "jmp l2" \ "found:" \ "movsw" \ "movsb" \ "pop si" \ "inc ch" \ "jnz l1" \ parm [es di] [ds si] [cl] \ modify exact [cx al di]; void SetPaletteEntry(uchar color, uchar r, uchar g, uchar b); #pragma aux SetPaletteEntry = \ "mov dx,03C8h" \ "out dx,al" \ "inc dx" \ "mov al,bl" \ "out dx,al" \ "mov al,cl" \ "out dx,al" \ "mov al,ch" \ "out dx,al" \ parm [al] [bl] [cl] [ch] \ modify exact [ax dx]; /****************************************************************************\ * * Function: void LineTunnel(void) * * Description: The Line tunnel part * \****************************************************************************/ void LineTunnel(void) { int error; int *sini; ushort sinSeg; int *sini2; int *transTab; int i, c, d, l, o; int x1, y1, x2, y2; long e, b; int zTab[NUMCIRCLES+1]; int cSin[NUMCIRCLES+1]; int starting = 1; int stopping = 0; int stop = 0; int lineCount = 0; int oframeCnt; int delay = 0; int z, dx, dy, z2, dx2, dy2; int direction = 4; long ff; int f; char delays[8*3] = { 53,53,63, 26,26,36, 17,17,22, 12,12,17, 10,10,15, 7,7,13, 5,5,11, 1,0,13 }; scrStart = 0; vgaSetC4(); /* Allocate memory for sine table: */ if ( (error = memAlloc(512*2+16, (void**) &sini)) != OK ) Error(errorMsg[error]); if ( (error = memAlloc(1024 * sizeof(int), (void**) &transTab)) != OK ) Error(errorMsg[error]); /* Clear line table */ memset(&linTab[0], 0, sizeof(int) * LINESPERCIRCLE * 4 * NUMCIRCLES * NUMDELAYS); /* Set sine segment point to sine table: */ sinSeg = FP_SEG(sini) + (FP_OFF(sini) + 15) / 16; sini2 = MK_FP(sinSeg,0); for (e = 0; e < 512; e++) { b = 360*e/256; sini2[e] = iSinMult(b, 339*32); // 200 } /* Do translation table */ for (i = 0; i < 1024; i++) transTab[i] = i * 5 / 6; /* Initialize circles */ c = 0; while ( c < NUMCIRCLES * 2 * LINESPERCIRCLE ) { for (i = 0; i < LINESPERCIRCLE; i++) { lineTab[c] = i * 16; lineTab[c+1] = (i + 1) * 16; c += 2; } } for (c = 0; c < NUMCIRCLES; c++) { zTab[c] = 666; } zTab[NUMCIRCLES] = zTab[0]; for (c = 0; c < NUMCIRCLES; c++) { cSin[c] = c * (360/NUMCIRCLES); } cSin[NUMCIRCLES] = cSin[0]; for (d = 0; d < NUMDELAYS; d++) doPalette(&palette[d*256*3], &delays[0], d); d = 0; oframeCnt = frameCount; /* Main loop */ // while ( info->pos < 0x16 ) ff = frameCount; while ( !stop ) { UpdInfo(); if ( info->pos >= 0x15 ) direction = -4; if ( (info->pos >= 0x15) && (info->row >=0x10) ) stopping = 1; if ( info->pos >= 0x16 ) stop = 1; WaitFrame(); f = frameCount - ff; if ( f > 64 ) f = 64; SetPaletteEntry(0, fadeTable[(f << 8) + 1], 0, fadeTable[(f << 8) + 0x0D]); /* Set the correct RGB palette: */ SetPalette(&palette[d*256*3], 1, 255); // SetBorder(255); for (; oframeCnt < frameCount; oframeCnt++) { if (starting) { if ( delay == 0 ) { zTab[lineCount] = NUMCIRCLES * 32; delay = 8; if (++lineCount == NUMCIRCLES + 1) starting = 0; } else { delay--; } } for ( c = 0; c < NUMCIRCLES + 1; c++) { if (zTab[c] != 666) { zTab[c] -= 4; if (zTab[c] < 32) { if(!stopping) { zTab[c] += NUMCIRCLES * 32; } else { zTab[c] = 666; } } } cSin[c] += direction; } } if ( ++d == NUMDELAYS ) d -= NUMDELAYS; LineColor = (1 << d) ^ 0xff; c = d * NUMCIRCLES * LINESPERCIRCLE * 4; for (i = 0; i < NUMCIRCLES*LINESPERCIRCLE; i++) { DrawLine(linTab[c], linTab[c+1], linTab[c+2], linTab[c+3]); c += 4; } c = d * NUMCIRCLES * LINESPERCIRCLE * 4; l = 0; o = 0; LineColor = 1 << d; while ( c < ( d + 1 ) * NUMCIRCLES * 4 * LINESPERCIRCLE ) { z = zTab[o]; if ( z != 666 ) { z = z << 4; z2 = z + (32 * 16); dx = iSinMult(cSin[o], z); dy = iCosMult(cSin[o], z); dx2 = iSinMult(cSin[o+1], z2); dy2 = iCosMult(cSin[o+1], z2); z = z >> 4; z2 = z2 >> 4; for ( i = 0; i < LINESPERCIRCLE; i++) { x1 = y1 = (int)lineTab[l]; x2 = y2 = (int)lineTab[l+1]; linTab[c] = (sini2[x1 + 64] + dx) / z + 160; linTab[c+1] = transTab[(sini2[y1] + dy) / z + 512] - 320; linTab[c+2] = (sini2[x2 + 64] + dx2) / z2 + 160; linTab[c+3] = transTab[(sini2[y2] + dy2) / z2 + 512] - 320; DrawLine2(linTab[c], linTab[c+1], linTab[c+2], linTab[c+3]); c += 4; l += 2; } } else { for ( i = 0; i < LINESPERCIRCLE; i++) { linTab[c] = -1; linTab[c+1] = -1; linTab[c+2] = -1; linTab[c+3] = -1; c += 4; l += 2; } } o++; } // SetBorder(0); } /* Deallocate sine table: */ if ( (error = memFree(sini)) != OK ) Error(errorMsg[error]); if ( (error = memFree(transTab)) != OK ) Error(errorMsg[error]); }