void DoReturn(IGifValue returnValue) { if (stack.Count == 0) { halted = true; return; } else { GifStackFrame returnFrame = stack.Pop(); runningRegister = returnFrame.runningRegister; switch (returnFrame.RHSInstruction) { case 0xCCC: // Assign bool failure; returnValue.Write(returnFrame.LHSValue.Read(), out failure); if (failure) { DoReturn(returnValue); } break; case 0xC8C: // Call stack.Push(new GifStackFrame(returnFrame.runningRegister)); current = returnFrame.LHSValue; runningRegister = returnValue.Read(); break; case 0xCC4: // Retarget ColorRGB lhsColor = returnFrame.LHSValue.Read(); ColorRGB rhsColor = returnValue.Read(); registerTargets[rhsColor.R16, rhsColor.G16, rhsColor.B16] = registerTargets[lhsColor.R16, lhsColor.G16, lhsColor.B16]; current = new GifCursor(rhsColor, GetRegisterPosition(rhsColor), GetRegisterTarget(rhsColor)); break; default: break; } } }
public void Tick() { if (halted) { return; } ColorRGB programPosition = registerPositions[runningRegister]; GifCube program = GetRegisterTarget(runningRegister); ColorRGB instruction = program[programPosition]; ColorRGB currentColor = current.Read(); // point to the next instruction bool overflow; registerPositions[runningRegister] = registerPositions[runningRegister].Increment(out overflow); if (overflow) { halted = true; return; } switch (instruction.hexSignature) { case 0x000: // Return DoReturn(current); break; case 0xCCC: // Assign stack.Push(new GifStackFrame(current, 0xCCC, runningRegister)); break; case 0xC8C: // Call stack.Push(new GifStackFrame(current, 0xC8C, runningRegister)); break; case 0xC04: // Load GIF break; case 0xC84: // Save GIF //registerTargets[currentColor.R16, currentColor.G16, currentColor.B16].Save(GetRegisterName(currentColor) + ".gif"); break; case 0xCC4: // Retarget stack.Push(new GifStackFrame(current, 0xCC4, runningRegister)); break; case 0x00C: // RegisterPos current = new GifCursor(currentColor, currentColor, registerPositions); break; case 0x08C: // RegisterVal current = new GifCursor(currentColor, registerPositions[currentColor], registerTargets[currentColor.R16, currentColor.G16, currentColor.B16]); break; case 0x0CC: // Data current = new GifCursor(ColorRGB.White, currentColor, registerTargets[15, 15, 15]); break; case 0xC0C: // Modify bool failed; registerPositions[runningRegister] = registerPositions[runningRegister] + new ColorRGB(48, 0, 0); current = Modify(currentColor, new ColorRGB[] { program[programPosition + new ColorRGB(16, 0, 0)], program[programPosition + new ColorRGB(32, 0, 0)], program[programPosition + new ColorRGB(48, 0, 0)] }, out failed ); if (failed) { DoReturn(current); } break; default: current = new GifCursor(runningRegister, programPosition, program); break; } }