--- /dev/null
+var SCREEN_WIDTH = 320;\r
+var SCREEN_HEIGHT = 400;\r
+var FRAME_BUFFER_WIDTH = 384;\r
+var FRAME_BUFFER_HEIGHT = 400;\r
+var PLANE_COUNT = 4;\r
+var COLOURS_PER_ENTRY = 3;\r
+var DPII = (3.1415926535*2.0);\r
+var MAXY = 280;\r
+\r
+var g_au8FrameBuffer = new Uint8Array(FRAME_BUFFER_WIDTH * FRAME_BUFFER_HEIGHT);\r
+var s_abSelectedPlanes = [ false, false, false, false ];\r
+var s_nLineCompareY = 0;\r
+var s_nHorizontalScrollOffset = 0;\r
+var s_au8Palette = new Uint8Array(256 * COLOURS_PER_ENTRY);\r
+var frame_count = 0;\r
+var cop_drop = 0;\r
+var do_pal = 0;\r
+var cop_start = 0;\r
+var cop_scrl = 0;\r
+var cop_plz = 1;\r
+var pompi = 0;\r
+var dtau = new Array();\r
+var fadepal = new Uint8Array(768 * 2);\r
+var cop_fadepal_SelectedPaletteIndex = 0;\r
+var anSelfModifyOffsets = new Uint16Array(5 * 84);\r
+\r
+// [NK 8/1/2014] The assembly code assumes the tables are sequential in memory,\r
+// [NK 8/1/2014] so merge them into one array to be safe.\r
+var psini = new Uint8Array(16384 + (8192 * 2) + (8192 * 2));\r
+var psini_DataView = new DataView(psini.buffer);\r
+var ptau = new Uint8Array(256);\r
+var pals = new Uint16Array(6 * 768);\r
+var pals_DataView = new DataView(pals.buffer);\r
+\r
+var curpal=0;\r
+var timetable=[64*6*2-45,64*6*4-45,64*6*5-45,64*6*6-45,64*6*7+90,0];\r
+var ttptr=0;\r
+\r
+var l1=1000, l2=2000, l3=3000, l4=4000;\r
+var k1=3500, k2=2300, k3=3900, k4=3670;\r
+\r
+var il1=1000, il2=2000, il3=3000, il4=4000;\r
+var ik1=3500, ik2=2300, ik3=3900, ik4=3670;\r
+\r
+var inittable = new Array();\r
+var IsComplete = false;\r
+\r
+//--------------------------------------------------------------------------------------\r
+// Variable wrappers\r
+\r
+function Palette_WriteByte(nOffset, u8Byte)\r
+{\r
+ s_au8Palette[nOffset] = u8Byte;\r
+}\r
+\r
+function Palette_ReadByte(nOffset)\r
+{\r
+ return s_au8Palette[nOffset];\r
+}\r
+\r
+function FrameBuffer_WriteByte(nOffset, u8Byte)\r
+{\r
+ g_au8FrameBuffer[nOffset] = u8Byte;\r
+}\r
+\r
+function FrameBuffer_ReadByte(nOffset)\r
+{\r
+ return g_au8FrameBuffer[nOffset];\r
+}\r
+\r
+function lsini16_GetOffset()\r
+{\r
+ return 16384 + (8192 * 2);\r
+}\r
+\r
+function lsini4_GetOffset()\r
+{\r
+ return 16384;\r
+}\r
+\r
+function cop_fadepal_SetSelectedPaletteIndex(nIndex)\r
+{\r
+ cop_fadepal_SelectedPaletteIndex = nIndex;\r
+}\r
+\r
+function cop_fadepal_ReadWord(nByteOffset)\r
+{\r
+ // Advance to the currently selected palette.\r
+ nByteOffset += (cop_fadepal_SelectedPaletteIndex * 768 * 2);\r
+\r
+ return pals_DataView.getUint16(nByteOffset);\r
+}\r
+\r
+function fadepal_ReadByte(nByteOffset)\r
+{\r
+ return fadepal[nByteOffset];\r
+}\r
+\r
+function fadepal_WriteByte(nByteOffset, nValue)\r
+{\r
+ fadepal[nByteOffset] = nValue;\r
+}\r
+\r
+function lsini4_WriteWord(nIndex, nValue)\r
+{\r
+ var nByteOffset = lsini4_GetOffset() + (nIndex * 2);\r
+ psini_WriteWord(nByteOffset, nValue);\r
+}\r
+\r
+function lsini16_WriteWord(nIndex, nValue)\r
+{\r
+ var nByteOffset = lsini16_GetOffset() + (nIndex * 2);\r
+ psini_WriteWord(nByteOffset, nValue);\r
+}\r
+\r
+function psini_WriteByte(nIndex, nValue)\r
+{\r
+ psini[nIndex] = nValue;\r
+}\r
+\r
+function psini_ReadByte(nIndex, nValue)\r
+{\r
+ return psini[nIndex];\r
+}\r
+\r
+function psini_WriteWord(nByteOffset, nValue) {\r
+ psini_DataView.setUint16(nByteOffset, nValue);\r
+}\r
+\r
+function psini_ReadWord(nByteOffset, nValue) {\r
+ return psini_DataView.getUint16(nByteOffset);\r
+}\r
+\r
+function ptau_WriteByte(nIndex, nValue)\r
+{\r
+ ptau[nIndex] = nValue;\r
+}\r
+\r
+function ptau_ReadByte(nIndex)\r
+{\r
+ return ptau[nIndex];\r
+}\r
+\r
+function pal_WriteWord(nByteOffset, nWord)\r
+{\r
+ pals_DataView.setUint16(nByteOffset, nWord);\r
+}\r
+\r
+function pal_ReadWord(nByteOffset)\r
+{\r
+ return pals_DataView.getUint16(nByteOffset);\r
+}\r
+\r
+function fadepal_Clear()\r
+{\r
+ for (var i = 0; i < 768; i++)\r
+ {\r
+ fadepal[i] = 0;\r
+ }\r
+}\r
+\r
+function fadepal_ClearToWhite() {\r
+ for (var i = 0; i < 768; i++) {\r
+ fadepal[i] = 63;\r
+ }\r
+}\r
+\r
+function anSelfModifyOffsets_ReadWord(nOffset)\r
+{\r
+ return anSelfModifyOffsets[nOffset];\r
+}\r
+\r
+function anSelfModifyOffsets_WriteWord(nOffset, nValue)\r
+{\r
+ anSelfModifyOffsets[nOffset] = nValue;\r
+}\r
+\r
+//--------------------------------------------------------------------------------------\r
+// SDL\r
+\r
+function SDL_SetPixel(x, y, color)\r
+{\r
+ var pixels = image.data;\r
+ var nOffset = (((y * 320) + x) * 4);\r
+ pixels[nOffset] = (color >> 0) & 0xFF;\r
+ nOffset++;\r
+ pixels[nOffset] = (color >> 8) & 0xFF;\r
+ nOffset++;\r
+ pixels[nOffset] = (color >> 16) & 0xFF;\r
+ nOffset++;\r
+ pixels[nOffset] = 0xFF;\r
+ nOffset++;\r
+}\r
+\r
+function SDL_SetPixelColours(x, y, nRed, nGreen, nBlue)\r
+{\r
+ var pixels = image.data;\r
+ var nOffset = (((y * 320) + x) * 4);\r
+ pixels[nOffset] = (nRed) & 0xFF;\r
+ nOffset++;\r
+ pixels[nOffset] = (nGreen) & 0xFF;\r
+ nOffset++;\r
+ pixels[nOffset] = (nBlue) & 0xFF;\r
+ nOffset++;\r
+ pixels[nOffset] = 0xFF;\r
+ nOffset++;\r
+}\r
+\r
+//--------------------------------------------------------------------------------------\r
+// VGA\r
+\r
+function VGA_SelectBitPlanes02()\r
+{\r
+ s_abSelectedPlanes[0] = true;\r
+ s_abSelectedPlanes[1] = false;\r
+ s_abSelectedPlanes[2] = true;\r
+ s_abSelectedPlanes[3] = false;\r
+}\r
+\r
+function VGA_SelectBitPlanes13()\r
+{\r
+ s_abSelectedPlanes[0] = false;\r
+ s_abSelectedPlanes[1] = true;\r
+ s_abSelectedPlanes[2] = false;\r
+ s_abSelectedPlanes[3] = true;\r
+}\r
+\r
+function VGA_SelectBitPlanes0123()\r
+{\r
+ s_abSelectedPlanes[0] = true;\r
+ s_abSelectedPlanes[1] = true;\r
+ s_abSelectedPlanes[2] = true;\r
+ s_abSelectedPlanes[3] = true;\r
+}\r
+\r
+function VGA_WriteDword(nOffset, uValue)\r
+{\r
+ // For each selected plane, calculate 4 pixel offsets and write 4 bytes.\r
+ // nOffset = 0, 4, 8, etc\r
+\r
+ for (var nPlaneIndex = 0; nPlaneIndex < PLANE_COUNT; nPlaneIndex++)\r
+ {\r
+ if (s_abSelectedPlanes[nPlaneIndex])\r
+ {\r
+ for (var nPixelIndex = 0; nPixelIndex < 4; nPixelIndex++)\r
+ {\r
+ // Get byte to write.\r
+ var u8Byte = (uValue >> (nPixelIndex * 8)) & 0xFF;\r
+\r
+ // Calculate offset.\r
+ var nFrameBufferOffset = nPlaneIndex + (nOffset * 4) + (nPixelIndex * 4);\r
+\r
+ // Write pixel.\r
+ FrameBuffer_WriteByte(nFrameBufferOffset, u8Byte);\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+function VGA_SetLineCompare(nY)\r
+{\r
+ s_nLineCompareY = nY;\r
+}\r
+\r
+function VGA_SetPaletteEntry(nIndex, u8Red, u8Green, u8Blue)\r
+{\r
+ var nOffset = 0;\r
+\r
+ nOffset = (nIndex * 3) + 0;\r
+ Palette_WriteByte(nOffset, u8Red);\r
+\r
+ nOffset = (nIndex * 3) + 1;\r
+ Palette_WriteByte(nOffset, u8Green);\r
+\r
+ nOffset = (nIndex * 3) + 2;\r
+ Palette_WriteByte(nOffset, u8Blue);\r
+}\r
+\r
+function VGA_ShowFrameBuffer()\r
+{\r
+ copper1();\r
+ copper2();\r
+\r
+ var nFirstLineIndex = (s_nLineCompareY + 1);\r
+\r
+ // Plot the palettised frame buffer.\r
+ var nFrameBufferOffset = 0;\r
+\r
+ for (var nY = nFirstLineIndex; nY < SCREEN_HEIGHT; nY++)\r
+ {\r
+ for (var nX = 0; nX < SCREEN_WIDTH; nX++)\r
+ {\r
+ //ASSERT(nX + s_nHorizontalScrollOffset < FRAME_BUFFER_WIDTH);\r
+ var nPaletteIndex = FrameBuffer_ReadByte(nFrameBufferOffset + nX + s_nHorizontalScrollOffset);\r
+\r
+ var nPaletteOffset = 0;\r
+ nPaletteOffset = (nPaletteIndex * 3) + 0;\r
+ var nRed = Palette_ReadByte(nPaletteOffset);\r
+ nPaletteOffset = (nPaletteIndex * 3) + 1;\r
+ var nGreen = Palette_ReadByte(nPaletteOffset);\r
+ nPaletteOffset = (nPaletteIndex * 3) + 2;\r
+ var nBlue = Palette_ReadByte(nPaletteOffset);\r
+\r
+ // [NK 12/1/2014] VGA colours range from 0 - 63 inclusive, but\r
+ // [NK 12/1/2014] SDL colours range from 0 - 255 inclusive, so\r
+ // [NK 12/1/2014] account for this here.\r
+ nRed &= 63;\r
+ nGreen &= 63;\r
+ nBlue &= 63;\r
+\r
+ nRed *= 255;\r
+ nRed /= 63;\r
+ nGreen *= 255;\r
+ nGreen /= 63;\r
+ nBlue *= 255;\r
+ nBlue /= 63;\r
+\r
+ SDL_SetPixelColours(nX, nY, nRed, nGreen, nBlue);\r
+ }\r
+\r
+ nFrameBufferOffset += FRAME_BUFFER_WIDTH;\r
+ }\r
+}\r
+\r
+function VGA_SetHorizontalScrollOffset(nOffset)\r
+{\r
+ s_nHorizontalScrollOffset = nOffset;\r
+}\r
+\r
+function VGA_UploadPalette(Palette)\r
+{\r
+ var Source = new Uint8Array(Palette.buffer, 0, 768);\r
+ var Destination = s_au8Palette;\r
+ Destination.set(Source);\r
+}\r
+\r
+//--------------------------------------------------------------------------------------\r
+// Tweak\r
+\r
+function tw_setrgbpalette(pal, r, g, b)\r
+{\r
+ VGA_SetPaletteEntry(pal, r, g, b);\r
+}\r
+\r
+//--------------------------------------------------------------------------------------\r
+// Asmyt\r
+\r
+function plzline(y, vseg)\r
+{\r
+ // vseg represented a segment, so multiply by sixteen (shift left by 4)\r
+ // to convert into an offset.\r
+ var nVgaYOffset = vseg * 16;\r
+\r
+ var cccTable =\r
+ [\r
+ 3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12,19,18,17,16,23,22,21,20,27,26,25,24,31,30,29,28,35,34,33,32,39,38,37,36,43,42,41,40,47,46,45,44,51,50,49,48,55,54,53,52,59,58,57,56,63,62,61,60,67,66,65,64,71,70,69,68,75,74,73,72,79,78,77,76,83,82,81,80\r
+ ];\r
+ var nCount = 84;\r
+\r
+ var ah = 0;\r
+ var al = 0;\r
+ var eax = 0;\r
+\r
+ for (var nIndex = 0; nIndex < nCount; nIndex++)\r
+ {\r
+ var ccc = cccTable[nIndex];\r
+\r
+ if ((ccc & 1) == 1)\r
+ {\r
+ var nByteOffset = 0;\r
+ var bx = 0;\r
+\r
+ nByteOffset = (y * 2) + anSelfModifyOffsets_ReadWord((2 * 84) + ccc);\r
+ nByteOffset &= 0xFFFF;\r
+ bx = psini_ReadWord(nByteOffset);\r
+\r
+ nByteOffset = bx + anSelfModifyOffsets_ReadWord((1 * 84) + ccc);\r
+ nByteOffset &= 0xFFFF;\r
+ ah = psini_ReadByte(nByteOffset);\r
+\r
+ nByteOffset = (y * 2) + anSelfModifyOffsets_ReadWord((4 * 84) + ccc);\r
+ nByteOffset &= 0xFFFF;\r
+ bx = psini_ReadWord(nByteOffset);\r
+\r
+ nByteOffset = bx + (y * 2) + anSelfModifyOffsets_ReadWord((3 * 84) + ccc);\r
+ nByteOffset &= 0xFFFF;\r
+ ah += psini_ReadByte(nByteOffset);\r
+ ah &= 0xFF;\r
+ }\r
+ else\r
+ {\r
+ var nByteOffset = 0;\r
+ var bx = 0;\r
+\r
+ nByteOffset = (y * 2) + anSelfModifyOffsets_ReadWord((2 * 84) + ccc);\r
+ nByteOffset &= 0xFFFF;\r
+ bx = psini_ReadWord(nByteOffset);\r
+\r
+ nByteOffset = bx + anSelfModifyOffsets_ReadWord((1 * 84) + ccc);\r
+ nByteOffset &= 0xFFFF;\r
+ al = psini_ReadByte(nByteOffset);\r
+\r
+ nByteOffset = (y * 2) + anSelfModifyOffsets_ReadWord((4 * 84) + ccc);\r
+ nByteOffset &= 0xFFFF;\r
+ bx = psini_ReadWord(nByteOffset);\r
+\r
+ nByteOffset = bx + (y * 2) + anSelfModifyOffsets_ReadWord((3 * 84) + ccc);\r
+ nByteOffset &= 0xFFFF;\r
+ al += psini_ReadByte(nByteOffset);\r
+ al &= 0xFF;\r
+ }\r
+\r
+ if ((ccc & 3) == 2)\r
+ {\r
+ eax = (ah << 8) | (al << 0);\r
+ eax <<= 16;\r
+ }\r
+\r
+ if ((ccc & 3) == 0)\r
+ {\r
+ eax |= (ah << 8) | (al << 0);\r
+\r
+ VGA_WriteDword(nVgaYOffset + ccc, eax);\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+function setplzparas(c1, c2, c3, c4)\r
+{\r
+ var psiniOffset = 0;\r
+ var lsini16Offset = lsini16_GetOffset();\r
+ var lsini4Offset = lsini4_GetOffset();\r
+\r
+ for (var ccc = 0; ccc < 84; ccc++)\r
+ {\r
+ var lc1 = c1 + psiniOffset + (ccc * 8);\r
+ lc1 &= 0xFFFF;\r
+ anSelfModifyOffsets_WriteWord((1 * 84) + ccc, lc1);\r
+\r
+ var lc2 = (c2 * 2) + lsini16Offset - (ccc * 8) + (80 * 8); \r
+ lc2 &= 0xFFFF;\r
+ anSelfModifyOffsets_WriteWord((2 * 84) + ccc, lc2);\r
+\r
+ var lc3 = c3 + psiniOffset - (ccc * 4) + (80 * 4);\r
+ lc3 &= 0xFFFF;\r
+ anSelfModifyOffsets_WriteWord((3 * 84) + ccc, lc3);\r
+\r
+ var lc4 = (c4 * 2) + lsini4Offset + (ccc * 32);\r
+ lc4 &= 0xFFFF;\r
+ anSelfModifyOffsets_WriteWord((4 * 84) + ccc, lc4);\r
+ } \r
+\r
+ return 0;\r
+}\r
+\r
+function set_plzstart(start)\r
+{\r
+ VGA_SetLineCompare(start);\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+//--------------------------------------------------------------------------------------\r
+// Copper\r
+\r
+function init_copper()\r
+{\r
+ for (var ccc = 0; ccc < 65; ccc++)\r
+ {\r
+ dtau[ccc] = Math.floor(ccc * ccc / 4 * 43 / 128 + 60);\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+function close_copper()\r
+{\r
+ return 0;\r
+}\r
+\r
+function pompota() {\r
+\r
+ // [NK 18/1/2014] Disable this for now, as it looks a bit jittery.\r
+ return;\r
+\r
+ // [nk] This function toggles the horizontal split point every frame\r
+ // [nk] between line 60 and 61, along with the horizontal offset.\r
+ // [nk] (since set_plzstart == 60, it's splitting at the top of the plasma)\r
+ VGA_SetLineCompare(60);\r
+ cop_scrl = 4;\r
+\r
+ pompi++;\r
+\r
+ if ((pompi & 1) != 0)\r
+ {\r
+ // [NK 12/1/2014] Moving the starting line up and down each alternate frame\r
+ // [NK 12/1/2014] doesn't look good in windowed mode.\r
+ // [NK 13/1/2014] Seems to work okay in fullscreen mode though.\r
+ //VGA_SetLineCompare(61);\r
+ cop_scrl = 0;\r
+ }\r
+}\r
+\r
+function moveplz()\r
+{\r
+ k1 += -3;\r
+ k1 &= 4095;\r
+ k2 += -2;\r
+ k2 &= 4095;\r
+ k3 += 1;\r
+ k3 &= 4095;\r
+ k4 += 2;\r
+ k4 &= 4095;\r
+ l1 += -1;\r
+ l1 &= 4095;\r
+ l2 += -2;\r
+ l2 &= 4095;\r
+ l3 += 2;\r
+ l3 &= 4095;\r
+ l4 += 3;\r
+ l4 &= 4095;\r
+}\r
+\r
+function initpparas()\r
+{\r
+ l1 = il1;\r
+ l2 = il2;\r
+ l3 = il3;\r
+ l4 = il4;\r
+\r
+ k1 = ik1;\r
+ k2 = ik2;\r
+ k3 = ik3;\r
+ k4 = ik4;\r
+}\r
+\r
+function do_drop()\r
+{\r
+ cop_drop++;\r
+\r
+ if (cop_drop <= 64)\r
+ {\r
+ VGA_SetLineCompare(dtau[cop_drop]);\r
+ }\r
+ else\r
+ {\r
+ var bShouldFade = false;\r
+\r
+ // [NK 18/1/2014] Hack for looping back to the first plasma.\r
+ if ((cop_drop == 65) && (ttptr == 0)) {\r
+ cop_drop = 128;\r
+ }\r
+\r
+ if (cop_drop >= 256)\r
+ {\r
+ }\r
+ else if (cop_drop >= 128)\r
+ {\r
+ bShouldFade = true;\r
+ }\r
+ else if (cop_drop > 96)\r
+ {\r
+ }\r
+ else //if (cop_drop > 64)\r
+ {\r
+ bShouldFade = true;\r
+ }\r
+\r
+ if (bShouldFade)\r
+ {\r
+ // [NK 15/1/2014] cop_pal always points to fadepal, so just upload fadepal.\r
+ //cop_pal = fadepal;\r
+ do_pal = 1;\r
+\r
+ if (cop_drop == 65)\r
+ {\r
+ VGA_SetLineCompare(400);\r
+ initpparas();\r
+ }\r
+ else\r
+ {\r
+ VGA_SetLineCompare(60);\r
+\r
+ // [NK 9/1/2014] I think it's using 8.8 fixed point numbers to fade the palette.\r
+ var cop_fadepalIndex = 0;\r
+ var pfadepalIndex = 0;\r
+\r
+ for (var nIndex = 0; nIndex < (768 / 16); nIndex++)\r
+ {\r
+ for (var ccc = 0; ccc < 16; ccc++)\r
+ {\r
+ // var al = cop_fadepal_ReadByte(cop_fadepalIndex + (ccc * 2));\r
+ // al &= 0xFF;\r
+ // var ah = cop_fadepal_ReadByte(cop_fadepalIndex + (ccc * 2) + 1);\r
+ // ah &= 0xFF;\r
+ // [NK 17/1/2014] Read cop_fadepal as words, rather than bytes,\r
+ // [NK 17/1/2014] to avoid endian issues.\r
+ var ax = cop_fadepal_ReadWord(cop_fadepalIndex + (ccc * 2));\r
+ var al = ax & 0xFF;\r
+ var ah = (ax >> 8) & 0xFF;\r
+\r
+ var nOldValue = fadepal_ReadByte(pfadepalIndex + ccc + 768);\r
+ nOldValue &= 0xFF;\r
+\r
+ var t = fadepal_ReadByte(pfadepalIndex + ccc + 768);\r
+ t &= 0xFF;\r
+ t += al;\r
+ t &= 0xFF;\r
+ fadepal_WriteByte(pfadepalIndex + ccc + 768, t);\r
+\r
+ var nNewValue = fadepal_ReadByte(pfadepalIndex + ccc + 768);\r
+ nNewValue &= 0xFF;\r
+\r
+ var nCarry = 0;\r
+\r
+ if (nNewValue < nOldValue)\r
+ {\r
+ nCarry = 1;\r
+ }\r
+\r
+ t = fadepal_ReadByte(pfadepalIndex + ccc);\r
+ t &= 0xFF;\r
+ t += ah + nCarry;\r
+ t &= 0xFF;\r
+ fadepal_WriteByte(pfadepalIndex + ccc, t);\r
+ }\r
+\r
+ cop_fadepalIndex += 32;\r
+ pfadepalIndex += 16;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ cop_drop = 0;\r
+ }\r
+ }\r
+}\r
+\r
+// [nk] just before retrace\r
+function copper1()\r
+{\r
+ // There is also assembly code to set the first pixel of\r
+ // display memory here, but it may not be necessary.\r
+\r
+ VGA_SetHorizontalScrollOffset(cop_scrl);\r
+}\r
+\r
+// [nk] in retrace\r
+function copper2()\r
+{\r
+ // [nk] Don't think this is used.\r
+ frame_count++;\r
+\r
+ if (do_pal != 0)\r
+ {\r
+ do_pal = 0;\r
+ // [NK 15/1/2014] cop_pal always points to fadepal, so just upload fadepal.\r
+ //VGA_UploadPalette(cop_pal);\r
+ VGA_UploadPalette(fadepal);\r
+ }\r
+\r
+ pompota();\r
+ moveplz();\r
+\r
+ if (cop_drop != 0)\r
+ {\r
+ do_drop();\r
+ }\r
+}\r
+\r
+\r
+//--------------------------------------------------------------------------------------\r
+// Plz\r
+\r
+function dis_exit()\r
+{\r
+ return false;\r
+}\r
+\r
+var s_nFrameCount = 0;\r
+function dis_getmframe()\r
+{\r
+ s_nFrameCount++;\r
+ return s_nFrameCount;\r
+}\r
+\r
+function init_plz()\r
+{\r
+ var a;\r
+\r
+ // [NK 8/1/2014] Instead of writing the tables as assembly files,\r
+ // [NK 8/1/2014] just use them directly in C++.\r
+ {\r
+ for(var a=0;a<1024*16;a++)\r
+ {\r
+ if(a<1024*8)\r
+ {\r
+ lsini4_WriteWord(a, (Math.sin(a * DPII / 4096) * 55 + Math.sin(a * DPII / 4096 * 5) * 8 + Math.sin(a * DPII / 4096 * 15) * 2 + 64) * 8);\r
+ lsini16_WriteWord(a, (Math.sin(a * DPII / 4096) * 55 + Math.sin(a * DPII / 4096 * 4) * 5 + Math.sin(a * DPII / 4096 * 17) * 3 + 64) * 16);\r
+ }\r
+ psini_WriteByte(a, Math.sin(a * DPII / 4096) * 55 + Math.sin(a * DPII / 4096 * 6) * 5 + Math.sin(a * DPII / 4096 * 21) * 4 + 64);\r
+ }\r
+\r
+ for(var a=1;a<=128;a++)\r
+ {\r
+ ptau_WriteByte(a, Math.cos(a * DPII / 128 + 3.1415926535) * 31 + 32);\r
+ }\r
+ }\r
+\r
+ cop_start=96*(682-400);\r
+ set_plzstart(60);\r
+ init_copper();\r
+ for(var a=0;a<256;a++) tw_setrgbpalette(a,63,63,63);\r
+\r
+// RGB\r
+ var nPalOffset = ((0 * 768) + 3) * 2;\r
+ for(a=1;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)); nPalOffset += 2;\r
+ }\r
+ for(a=0;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63 - a)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)); nPalOffset += 2;\r
+ }\r
+ for(a=0;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a)); nPalOffset += 2;\r
+ }\r
+ for(a=0;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63 - a)); nPalOffset += 2;\r
+ }\r
+\r
+// RB-black\r
+ nPalOffset = ((1 * 768) + 3) * 2;\r
+ for(a=1;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)); nPalOffset += 2;\r
+ }\r
+ for(a=0;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63 - a)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a)); nPalOffset += 2;\r
+ }\r
+ for(a=0;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63 - a)); nPalOffset += 2;\r
+ }\r
+ for(a=0;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a)); nPalOffset += 2;\r
+ }\r
+\r
+// RB-white\r
+ nPalOffset = ((3 * 768) + 3) * 2;\r
+ for(a=1;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)); nPalOffset += 2;\r
+ }\r
+ for(a=0;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a)); nPalOffset += 2;\r
+ }\r
+ for(a=0;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63-a)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63-a)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63)); nPalOffset += 2;\r
+ }\r
+ for(a=0;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63)); nPalOffset += 2;\r
+ }\r
+\r
+// white\r
+ nPalOffset = ((2 * 768) + 3) * 2;\r
+ for(a=1;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)/2); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)/2); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)/2); nPalOffset += 2;\r
+ }\r
+ for(a=0;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a)/2); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a)/2); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a)/2); nPalOffset += 2;\r
+ }\r
+ for(a=0;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63-a)/2); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63-a)/2); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63-a)/2); nPalOffset += 2;\r
+ }\r
+ for(a=0;a<64;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)/2); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)/2); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(0)/2); nPalOffset += 2;\r
+ }\r
+\r
+\r
+// white II\r
+ nPalOffset = ((4 * 768) + 3) * 2;\r
+ for(a=1;a<75;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63-a*64/75)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63-a*64/75)); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(63-a*64/75)); nPalOffset += 2;\r
+ }\r
+ for(a=0;a<106;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, 0); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, 0); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, 0); nPalOffset += 2;\r
+ }\r
+ for(a=0;a<75;a++)\r
+ {\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a*64/75)*8/10); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a*64/75)*9/10); nPalOffset += 2;\r
+ pal_WriteWord(nPalOffset, ptau_ReadByte(a*64/75)); nPalOffset += 2;\r
+ }\r
+\r
+ nPalOffset = 0;\r
+ for(var a=0;a<768;a++)\r
+ {\r
+ var n = pal_ReadWord(nPalOffset);\r
+ n -= 63;\r
+ n *= 2;\r
+ n &= 0xFFFF;\r
+ pal_WriteWord(nPalOffset, n);\r
+ nPalOffset += 2;\r
+ }\r
+\r
+ for(var a=768;a<768*5;a++)\r
+ {\r
+ var n = pal_ReadWord(nPalOffset);\r
+ n *= 8;\r
+ n &= 0xFFFF;\r
+ pal_WriteWord(nPalOffset, n);\r
+ nPalOffset += 2;\r
+ }\r
+}\r
+\r
+function plz()\r
+{\r
+ var y;\r
+\r
+ if(dis_getmframe()>timetable[ttptr])\r
+ {\r
+ fadepal_Clear();\r
+ cop_drop=1;\r
+ ttptr++;\r
+\r
+ if (ttptr == 4) {\r
+ // [NK 18/1/2014] Loop back to the first plasma again.\r
+ ttptr = 0;\r
+ curpal = 0;\r
+ s_nFrameCount = 0;\r
+ fadepal_ClearToWhite();\r
+ cop_drop = 1;\r
+ }\r
+\r
+ cop_fadepal_SetSelectedPaletteIndex(curpal++);\r
+\r
+ il1=inittable[ttptr][0];\r
+ il2=inittable[ttptr][1];\r
+ il3=inittable[ttptr][2];\r
+ il4=inittable[ttptr][3];\r
+ ik1=inittable[ttptr][4];\r
+ ik2=inittable[ttptr][5];\r
+ ik3=inittable[ttptr][6];\r
+ ik4=inittable[ttptr][7];\r
+ }\r
+// if (curpal == 5 && cop_drop > 64) {\r
+// return true;\r
+// }\r
+\r
+ VGA_SelectBitPlanes02();\r
+\r
+ setplzparas(k1,k2,k3,k4);\r
+ for(y=0;y<MAXY;y+=2)\r
+ plzline(y,y*6);\r
+ setplzparas(l1,l2,l3,l4);\r
+ for(y=1;y<MAXY;y+=2)\r
+ plzline(y,y*6);\r
+\r
+ VGA_SelectBitPlanes13();\r
+\r
+ setplzparas(k1,k2,k3,k4);\r
+ for(y=1;y<MAXY;y+=2)\r
+ plzline(y,y*6);\r
+ setplzparas(l1,l2,l3,l4);\r
+ for(y=0;y<MAXY;y+=2)\r
+ plzline(y,y*6);\r
+\r
+ VGA_ShowFrameBuffer();\r
+\r
+ return false;\r
+// cop_drop=0;\r
+// set_plzstart(500);\r
+// cop_plz=0;\r
+}\r
+\r
+\r
+//--------------------------------------------------------------------------------------\r
+// Main\r
+\r
+function tmain()\r
+{\r
+ // Create arrays.\r
+ inittable[0] = [1000,2000,3000,4000,3500,2300,3900,3670];\r
+ inittable[1] = [1000,2000,4000,4000,1500,2300,3900,1670];\r
+ inittable[2] = [3500,1000,3000,1000,3500,3300,2900,2670];\r
+ inittable[3] = [1000,2000,3000,4000,3500,2300,3900,3670];\r
+ inittable[4] = [1000,2000,3000,4000,3500,2300,3900,3670];\r
+ inittable[5] = [1000,2000,3000,4000,3500,2300,3900,3670];\r
+\r
+ init_copper();\r
+ init_plz();\r
+ cop_drop = 128;\r
+ cop_fadepal_SetSelectedPaletteIndex(curpal++);\r
+}\r
+\r
+\r
+//--------------------------------------------------------------------------------------\r
+// HTML5 specific code\r
+\r
+window.onload = function () {\r
+ document.getElementsByTagName("body")[0].className = "js";\r
+\r
+ start();\r
+};\r
+\r
+var canvas = null;\r
+var context = null;\r
+var fps = null;\r
+var tscale = 0.02;\r
+var lastTick = 0;\r
+var targetFps = 1;\r
+var image;\r
+var canvasId = "canvas";\r
+var fpsId = "fps";\r
+\r
+function init() {\r
+ canvas = canvasId ? document.getElementById(canvasId) : null;\r
+ fps = fpsId ? document.getElementById(fpsId) : null;\r
+\r
+ if (canvas && canvas.getContext) {\r
+ // canvas.width = width = window.innerWidth;\r
+ // canvas.height = height = window.innerHeight;\r
+ canvas.width = 320;\r
+ canvas.height = 400;\r
+\r
+ context = canvas.getContext("2d");\r
+\r
+ if (context.createImageData) {\r
+ image = context.createImageData(canvas.width, canvas.height);\r
+ } else if (context.getImageData) {\r
+ image = context.getImageData(0, 0, canvas.width, canvas.height);\r
+ } else {\r
+ // it's Opera\r
+ image = { 'width': canvas.width, 'height': canvas.height,\r
+ 'data': new Array(canvas.width * canvas.height * 4)\r
+ }\r
+ }\r
+\r
+ for (i = 0; i < image.data.length; i++) {\r
+ image.data[i] = 255;\r
+ }\r
+ return true;\r
+ } else {\r
+ return false;\r
+ }\r
+}\r
+\r
+function draw() {\r
+\r
+ // Clear to black.\r
+ length = 320 * 400;\r
+ var p = 0;\r
+ for (var i = 0; i < length; i++) {\r
+ image.data[p] = 0;\r
+ p++;\r
+ image.data[p] = 0;\r
+ p++;\r
+ image.data[p] = 0;\r
+ p++;\r
+ image.data[p] = 0xFF;\r
+ p++;\r
+ }\r
+\r
+ IsComplete = plz();\r
+\r
+ if (!image) {\r
+ return;\r
+ }\r
+\r
+ var x = 0;\r
+ var y = 0;\r
+// var x = (window.innerWidth - 320) / 2;\r
+// var y = (window.innerHeight - 400) / 2;\r
+\r
+ context.putImageData(image, x, y);\r
+}\r
+\r
+function tick() {\r
+ var start, elapsed, sleep, target;\r
+ start = new Date().getTime();\r
+\r
+ // check if the canvas has been resized\r
+// if ((canvas.clientWidth / 8) != width ||\r
+// (canvas.clientHeight / 8) != height) {\r
+// init();\r
+// }\r
+\r
+ if (!IsComplete) {\r
+ draw();\r
+ }\r
+\r
+ // calculate stable FPS \r
+ elapsed = new Date().getTime() - start;\r
+\r
+ target = 1000 / 60;\r
+\r
+ // calculate sleep and schedule next tick\r
+ sleep = target - elapsed;\r
+ if (sleep < 1) {\r
+ sleep = 1;\r
+ } else if (sleep > 1000) {\r
+ sleep = 1000;\r
+ }\r
+\r
+ lastTick = start;\r
+ setTimeout(tick, sleep);\r
+}\r
+\r
+function start() {\r
+ lastTick = new Date().getTime();\r
+\r
+ tmain();\r
+\r
+ if (init()) tick();\r
+}\r