Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local component = require("component")
- local gpu = component.gpu
- local event = require("event")
- local math = require("math")
- local unicode = require("unicode")
- local w, h = gpu.getResolution()
- -- Color palettes
- local planeColors = {0x000000, 0x0000FF, 0x00FF00, 0xFF0000, 0xFFFF00}
- local plasmaColors = {0xFF0000, 0xFF7F00, 0xFFFF00, 0x00FF00, 0x0000FF, 0x8B00FF}
- -- Custom buffer implementation
- local Buffer = {}
- Buffer.__index = Buffer
- function Buffer.new(width, height)
- local self = setmetatable({}, Buffer)
- self.width = width
- self.height = height
- self.data = {}
- for i = 1, width * height do
- self.data[i] = {bg = 0x000000, fg = 0xFFFFFF, char = " "}
- end
- return self
- end
- function Buffer:setPixel(x, y, bg, fg, char)
- if x >= 1 and x <= self.width and y >= 1 and y <= self.height then
- self.data[(y - 1) * self.width + x] = {bg = bg, fg = fg, char = char}
- end
- end
- function Buffer:render(gpuBuffer)
- gpu.setActiveBuffer(gpuBuffer)
- local lastBg, lastFg = -1, -1
- for y = 1, self.height do
- local rowStart = (y - 1) * self.width
- for x = 1, self.width do
- local pixel = self.data[rowStart + x]
- if pixel.bg ~= lastBg then
- gpu.setBackground(pixel.bg)
- lastBg = pixel.bg
- end
- if pixel.fg ~= lastFg then
- gpu.setForeground(pixel.fg)
- lastFg = pixel.fg
- end
- gpu.set(x, y, pixel.char)
- end
- end
- end
- -- Create buffers and GPU buffers
- local screenBuffer1 = Buffer.new(w, h)
- local screenBuffer2 = Buffer.new(w, h)
- local gpuBuffer1 = gpu.allocateBuffer(w, h)
- local gpuBuffer2 = gpu.allocateBuffer(w, h)
- local activeBuffer, inactiveBuffer = screenBuffer1, screenBuffer2
- local activeGPUBuffer, inactiveGPUBuffer = gpuBuffer1, gpuBuffer2
- -- Precompute sine and cosine values
- local sineTable, cosineTable = {}, {}
- for i = 0, 360 do
- sineTable[i] = math.sin(math.rad(i))
- cosineTable[i] = math.cos(math.rad(i))
- end
- -- Mode 7 parameters
- local scale = 1
- local angle = 0
- local offsetX, offsetY = 0, 0
- -- Create a simple texture for Mode 7
- local textureSize = 64
- local texture = {}
- for y = 1, textureSize do
- texture[y] = {}
- for x = 1, textureSize do
- texture[y][x] = planeColors[((x + y) % #planeColors) + 1]
- end
- end
- -- Mode 7 transformation function
- local function mode7(screenX, screenY, scale, angle, offsetX, offsetY)
- local sin, cos = sineTable[angle], cosineTable[angle]
- local x = (screenX - w/2) / scale
- local y = (screenY - h) / scale
- return x * cos - y * sin + offsetX, x * sin + y * cos + offsetY
- end
- -- Optimized plasma generation
- local function generatePlasma(buffer, t)
- for y = 1, buffer.height / 2 do
- for x = 1, buffer.width do
- local v = sineTable[(x * 12 + t * 15) % 360]
- v = v + sineTable[(y * 9 + t * 12) % 360]
- v = v + sineTable[((x + y) * 7 + t * 9) % 360]
- v = v + sineTable[(math.floor(math.sqrt(x * x + y * y)) * 8 + t * 7) % 360]
- v = v / 4
- local colorIndex = math.floor((v + 1) * #plasmaColors / 2) + 1
- buffer:setPixel(x, y, plasmaColors[colorIndex], 0x000000, " ")
- end
- end
- end
- -- Main loop
- local t = 0
- local running = true
- event.listen("key_down", function(_, _, _, code)
- if code == 16 then -- 'Q' key
- running = false
- end
- end)
- while running do
- generatePlasma(activeBuffer, t)
- -- Update Mode 7 parameters
- angle = (angle + 1) % 360
- offsetX = 32 + 16 * sineTable[t % 360]
- offsetY = 32 + 16 * sineTable[(t + 90) % 360]
- scale = 0.5 + 0.25 * sineTable[(t * 2) % 360]
- -- Render Mode 7 effect
- for screenY = h/2, h do
- for screenX = 1, w do
- local tx, ty = mode7(screenX, screenY, scale, angle, offsetX, offsetY)
- local textureX = math.floor(tx) % textureSize + 1
- local textureY = math.floor(ty) % textureSize + 1
- local color = texture[textureY][textureX]
- activeBuffer:setPixel(screenX, screenY, color, color, "▄")
- end
- end
- -- Add a moving object
- local objX = math.floor(w / 2 + sineTable[t % 360] * w / 4)
- local objY = math.floor(h / 2 + sineTable[(t + 90) % 360] * h / 4)
- for i = -2, 2 do
- for j = -2, 2 do
- activeBuffer:setPixel(objX + i, objY + j, 0xFFFFFF, 0x000000, "O")
- end
- end
- activeBuffer:render(activeGPUBuffer)
- -- Copy GPU buffer to screen
- gpu.setActiveBuffer(0)
- gpu.bitblt(0, 1, 1, w, h, activeGPUBuffer)
- -- Swap buffers
- activeBuffer, inactiveBuffer = inactiveBuffer, activeBuffer
- activeGPUBuffer, inactiveGPUBuffer = inactiveGPUBuffer, activeGPUBuffer
- t = t + 1
- end
- -- Clean up
- gpu.setActiveBuffer(0)
- gpu.freeBuffer(gpuBuffer1)
- gpu.freeBuffer(gpuBuffer2)
- gpu.setBackground(0x000000)
- gpu.setForeground(0xFFFFFF)
- gpu.fill(1, 1, w, h, " ")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement