-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbadapple.lua
executable file
·172 lines (149 loc) · 5.49 KB
/
badapple.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
local toolName = "TNS|Bad Apple|TNE"
local function delay(time)
local currentTime = getTime()
while (currentTime + time > getTime()) do
end
end
local cchunk = {
-- current chunk
index = -1,
data = nil
}
local video_x_offset = 0
local video_y_offset = 0
local current_frame = 0
local function loadNextChunk()
cchunk.index = cchunk.index + 1
cchunk.data = nil
local script, err = loadScript(string.format("/SCRIPTS/BADAPPLE/chunk%d.luac", cchunk.index), "bx")
if script == nil then
local temp = string.gsub(err, "loadScript%(\"/SCRIPTS/BADAPPLE/chunk", "")
local temp2 = string.gsub(temp, ".luac\", \"bx\"%) error:", "")
lcd.drawText(0, 0, temp2, SMLSIZE)
lcd.refresh()
else
cchunk.data = script()
script = nil
err = nil
end
collectgarbage()
end
local function renderFrame(frame, x_offset, y_offset)
for _, shape in ipairs(frame) do
if #shape == 2 then -- pixel
lcd.drawPoint(
shape[1] + x_offset, shape[2] + y_offset
)
elseif #shape == 3 then -- square
lcd.drawFilledRectangle(
shape[1] + x_offset, shape[2] + y_offset,
shape[1] + 1 + shape[3], shape[2] + 1 + shape[3]
)
elseif #shape == 4 then -- rect
lcd.drawFilledRectangle(
shape[1] + x_offset, shape[2] + y_offset,
shape[3] - shape[1] + 1, shape[4] - shape[2] + 1
)
end
end
end
local function init()
lcd.clear()
local info = loadScript("/SCRIPTS/BADAPPLE/info.lua")()
video_x_offset = (128 - info.video_size[1]) / 2
video_y_offset = (64 - info.video_size[2]) / 2
lcd.clear()
lcd.drawText(2, 12, info.title, MIDSIZE)
lcd.drawText(40, 24, info.subtitle, SMLSIZE)
lcd.drawText(2, 36, string.format("by %s", info.author))
renderFrame(info.banner_image, 50, 0)
local chunk_count = info.chunk_count
info = nil
collectgarbage()
for i = 0, chunk_count - 1 do
lcd.drawFilledRectangle(0, 55, 45, 9, ERASE)
lcd.drawText(2, 55, string.format("Chunk %d", i), SMLSIZE)
lcd.refresh()
loadScript(string.format("/SCRIPTS/BADAPPLE/chunk%d.lua", i), "c")
collectgarbage()
local file = fstat(string.format("/SCRIPTS/BADAPPLE/chunk%d.luac", i))
if file == nil then
local fn, err = loadScript(string.format("/SCRIPTS/BADAPPLE/chunk%d.lua", i), "c")
if fn == nil then
lcd.clear()
lcd.drawText(0, 0, err, SMLSIZE)
lcd.drawText(0, 10, string.format("%d", i), SMLSIZE)
lcd.refresh()
delay(10)
end
fn = nil
err = nil
end
file = nil
collectgarbage()
end
local error_count = 1 -- just so that the while loop can start
while error_count > 0 do
error_count = 0
-- check if there are any not compiled chunks
for i = 0, chunk_count - 1 do
local file = fstat(string.format("/SCRIPTS/BADAPPLE/chunk%d.luac", i))
lcd.drawFilledRectangle(0, 55, 45, 9, ERASE)
lcd.drawText(2, 55, string.format("Checking %d (%d)", i, error_count), SMLSIZE)
lcd.refresh()
if file == nil then
error_count = error_count + 1
local fn, err = loadScript(string.format("/SCRIPTS/BADAPPLE/chunk%d.lua", i), "c")
if fn == nil then
lcd.clear()
lcd.drawText(0, 0, err, SMLSIZE)
lcd.drawText(0, 10, string.format("%d %d", i, error_count), SMLSIZE)
lcd.refresh()
delay(10)
end
fn = nil
err = nil
end
file = nil
collectgarbage()
end
end
end
local function run(event, touchState)
local dynamic_frame_limiter_offset = 0
local show_debug_info = event == EVT_ENTER_LONG
lcd.clear()
loadNextChunk()
local sound_start = getTime() - 50
playFile("/SOUNDS/badapple.wav")
::RENDER::
for _, frame in ipairs(cchunk.data) do
local time = getTime()
local time_delta = getTime() - (sound_start + current_frame * 10)
dynamic_frame_limiter_offset = math.min((10 - time_delta) / 1, -0.1)
if show_debug_info then
lcd.drawText(0, 0, "FPS:", SMLSIZE)
lcd.drawText(0, 8, string.format("%0.1f", 1 / time_delta * 100), SMLSIZE)
lcd.drawText(0, 20, "MEM:", SMLSIZE)
lcd.drawText(0, 28, string.format("%d", getAvailableMemory()), SMLSIZE)
lcd.drawText(0, 40, "CNT:", SMLSIZE)
lcd.drawText(0, 48, string.format("%d", cchunk.index), SMLSIZE)
lcd.drawText(108, 0, "FRM:", SMLSIZE)
lcd.drawText(108, 8, string.format("%d", current_frame), SMLSIZE)
lcd.drawText(108, 20, "FLO:", SMLSIZE)
lcd.drawText(108, 28, string.format("%d", dynamic_frame_limiter_offset), SMLSIZE)
lcd.drawText(108, 40, "TDE:", SMLSIZE)
lcd.drawText(108, 48, string.format("%d", time_delta), SMLSIZE)
end
renderFrame(frame, video_x_offset, video_y_offset)
lcd.refresh()
lcd.resetBacklightTimeout()
current_frame = current_frame + 1
while (time + (10 + dynamic_frame_limiter_offset) > getTime()) do
end
end
loadNextChunk()
goto RENDER
return 0
end
return { run = run, init = init }