View difference between Paste ID: GK5Wnjxv and 6CQaBLJH
SHOW: | | - or go back to the newest paste.
1
-- Donald starring in Maui Mallard (E)[!]
2
-- Script for TAS
3-
-- 2013, r57shell
3+
-- 2014, r57shell
4
5
notes = {};
6
msgtable = {};
7
msgidx = 0;
8
require 'donald_tas_notes';
9
_d0 = -100;
10
_d1 = -100;
11
sync = false;
12
show_boxes = true;
13
h_collisions = true;
14
v_collisions = true;
15
show_dmg = true;
16
show_buttons = true;
17
show_ammo = true;
18
show_pos = true;
19
show_notes = true;
20
show_cursor = true;
21
show_life = true;
22
show_hex = false;
23
24
buttons = {
25
[0]={text="hide",x1=288,y1=36,x2=308,y2=46,down=false,proc=function()
26
	show_buttons = not show_buttons
27
end},
28
29
[1]={text="sync",x1=286,y1=48,x2=308,y2=58,down=false,var="sync"},
30
31
[2]={text="pos",x1=286,y1=60,x2=308,y2=70,down=false,var="show_pos"},
32
33
[3]={text="boxes",x1=286,y1=72,x2=308,y2=82,down=false,var="show_boxes"},
34
35
[4]={text="lifes",x1=286,y1=84,x2=308,y2=94,down=false,var="show_life"},
36
37
[5]={text="horiz",x1=286,y1=96,x2=308,y2=106,down=false,var="h_collisions"},
38
39
[6]={text="vert",x1=286,y1=108,x2=308,y2=118,down=false,var="v_collisions"},
40
41
[7]={text="notes",x1=286,y1=120,x2=308,y2=130,down=false,var="show_notes"},
42
43
[8]={text="cursor",x1=282,y1=132,x2=308,y2=142,down=false,var="show_cursor"},
44
45
[9]={text="ammo",x1=286,y1=144,x2=308,y2=154,down=false,var="show_ammo"},
46
47
[10]={text="dmg",x1=286,y1=156,x2=308,y2=166,down=false,var="show_dmg"},
48
49
[11]={text="hex",x1=286,y1=168,x2=308,y2=178,down=false,var="show_hex"},
50
51
};
52
53
input.registerhotkey(1, function()
54
	local hook = 0;
55
	local dir = 0;
56
	local i = 200;
57
	joypad.set({C=false,B=false});
58
	while i>0 do
59
		i = i - 1
60
		hook = memory.readbyte(0xFFE219);
61
		if (hook == 1) then
62
			break;
63
		end
64
		gens.emulateframe();
65
	end
66
	if (i==0) then
67
		print("error hook state 1 not found\n");
68
		return
69
	end
70
	joypad.set({C=true});
71
	dir = AND(XOR(memory.readword(0xFFE1FA), memory.readword(0xFFE1CA)), 0x800);
72
	local p = {left=false,right=false};
73
	local a = {right=true,left=false};
74
	if (dir == 0) then
75
		p = {right=false,left=false};
76
		a = {left=true,right=false};
77
	end
78
	joypad.set(p); gens.emulateframe();
79
	joypad.set(p); gens.emulateframe();
80
	--joypad.set(p); gens.emulateframe(); -- uncomment this it it does not work
81
	joypad.set(a); gens.emulateframe();
82
	joypad.set(a); gens.emulateframe();
83
	joypad.set(a); gens.emulateframe();
84
	joypad.set(a); gens.emulateframe();
85
	joypad.set({B=true});
86
	gens.emulateframe();
87
end)
88
89
function drawcursor()
90
	local inpt = input.get();
91
	local xmouse = inpt.xmouse;
92
	local ymouse = inpt.ymouse;
93
94
	gui.texta(xmouse,ymouse,string.format("%d\n%d",scrollx+xmouse,scrolly+ymouse));
95
end
96
97
function drawnotes()
98
	if (notes[level]) then
99
		for k,v in pairs(notes[level]) do
100
			x,y,text,color = v[1],v[2],v[3],v[4];
101
			if (color == nil) then
102
				color = "white"
103
			end
104
105
			x = x - scrollx;
106
			y = y - scrolly;
107
			if (x > -30 and x < 350 and y > -30 and y < 254) then
108
				gui.texta(x,y,text,color);
109
			end
110
		end
111
	end
112
end
113
114
function getpos(offs)
115
	local x = memory.readwordsigned(offs + 0x12) - scrollx;
116
	local y = memory.readwordsigned(offs + 0x14) - scrolly;
117
	return x,y;
118
end
119
120
function drawbbox(offs,color)
121
	local bbox = memory.readlong(offs + 0xC);
122
	if (bbox == 0) then
123
		return nil,nil;
124
	end
125
	local x,y = getpos(offs);
126
	local stp = memory.readword(bbox)+1;
127
	local count = memory.readword(bbox + 2);
128
	local bb = bbox+stp*10+8;
129
	for i = 1, count do
130
		local x1 = memory.readbytesigned(bb + 0);
131
		local x2 = memory.readbytesigned(bb + 1);
132
		local y1 = memory.readbytesigned(bb + 2);
133
		local y2 = memory.readbytesigned(bb + 3);
134
		bb = bb + 6;
135
		if (AND(XOR(memory.readword(offs),memory.readword(offs+0x30)),0x800) ~= 0) then
136
			x1,x2 = -x2,-x1;
137
		end
138
		if (AND(memory.readword(offs),0x1000) ~= 0) then
139
			y1,y2 = -y2,-y1;
140
		end
141
		if (show_boxes) then
142
			gui.boxa(x+x1,y+y1,x+x2,y+y2,"#FFFFFF00");
143
		end
144
	end
145
	local x1 = memory.readbytesigned(bbox + 4);
146
	local x2 = memory.readbytesigned(bbox + 5);
147
	local y1 = memory.readbytesigned(bbox + 6);
148
	local y2 = memory.readbytesigned(bbox + 7);
149
	if (AND(XOR(memory.readword(offs),memory.readword(offs+0x30)),0x800) ~= 0) then
150
		x1,x2 = -x2,-x1;
151
	end
152
	if (AND(memory.readword(offs),0x1000) ~= 0) then
153
		y1,y2 = -y2,-y1;
154
	end
155
	if (show_boxes) then
156
		gui.boxa(x+x1,y+y1,x+x2,y+y2,color);
157
	end
158
	return x+x1, y+y1;
159
end
160
161
function postext(x,len)
162
	if (show_hex) then
163
		if (x < 0) then
164
			x = string.format("-%X:%02X",AND(-x,0xFFFF00)/0x100,AND(-x,0xFF));
165
		else
166
			x = string.format("%X:%02X",AND(x,0xFFFF00)/0x100,AND(x,0xFF));
167
		end
168
	else
169
		x = string.format("%.3f",x/0x100);
170
	end
171
	while(#x<len) do
172
		x = " "..x;
173
	end
174
	return x;
175
end
176
177
function getboss4dir(px,py,x,y,w,ws)
178
	local r = 1;--0xFFFF;
179
	local angle = math.pi*w/0x200;
180
	local x1 = math.cos(angle)*10;
181
	local y1 = math.sin(angle)*10;
182
	local x2,y2 = x-px,y-py;
183
	if (x1*y2-x2*y1 >= 0) then
184
		r = 0xFFFF;
185
	end
186
	if (AND(XOR(r,ws),0x8000) == 0) then
187
		if (AND(ws,0x8000) == 0) then
188
			ws = ws + 4;
189
			if (ws > 0x1C) then
190
				ws = 0x1C;
191
			end
192
		else
193
			ws = ws - 4;
194
			if (ws < 0xFFE4) then
195
				ws = 0xFFE4;
196
			end
197
		end
198
		return ws;
199
	else
200
		if (r == 1) then
201
			return 4;
202
		else
203
			return 0xFFFC;
204
		end
205
	end
206
end
207
208
function drawboss4(base)
209
-- the Sacrifice of Maui Boss
210
	local x,y = getpos(base);
211
	local w = memory.readword(base+0x4C);
212
	local ws = memory.readword(base+0x2E);
213
	local len = 5;
214
	local x1,y1 = x,y;
215
	for ai = 1, 10 do
216
		local angle = math.pi*w/0x200;
217
		local x2 = x1+math.cos(angle)*len;
218
		local y2 = y1+math.sin(angle)*len;
219
		gui.linea(x1,y1,x2,y2,"#00FF00");
220
		ws = getboss4dir(px,py,x1,y1,w,ws);
221
		x1,y1 = x2,y2;
222
		w = AND(ws+w,0x3FF);
223
	end
224
	local w = memory.readword(base+0x4C);
225
	local ws = memory.readword(base+0x2E);
226
	if (AND(ws,0x8000) == 0) then
227
		w = w + 0xFEC0;
228
	else
229
		w = w + 0x120;
230
	end
231
	w = AND(w,0x3FF);
232
	x1,y1 = x,y;
233
	ws = getboss4dir(px,py,x1,y1,w,ws);
234
	for ai = 1, 10 do
235
		local angle = math.pi*w/0x200;
236
		local x2 = x1+math.cos(angle)*len;
237
		local y2 = y1+math.sin(angle)*len;
238
		gui.linea(x1,y1,x2,y2,"#FFFFFF");
239
		ws = getboss4dir(px,py,x1,y1,w,ws);
240
		x1,y1 = x2,y2;
241
		w = AND(ws+w,0x3FF);
242
	end
243
end
244
245
function drawboss5(base)
246
	if (memory.readbyte(base+0x29) == 0xE8
247
	and AND(memory.readbyte(base+0x5),2) == 2) then
248
	-- bombs pos
249
		local x,y = getpos(base);
250
		gui.setpixela(x,y,"red");
251
	end
252
	if (memory.readword(base+0x20) == 0x6E40) then
253
	-- Frog Boss
254
		local states = {"idle","eating","stealing","burp","death"};
255
		local state = memory.readbyte(base+4);
256
		states[0] = "none";
257
		gui.texta(x-5,y+16,states[state]);
258
		x,y = getpos(base);
259
		local ax = 0x14;
260
		if (AND(memory.readword(base),0x800) ~= 0) then
261
			ax = -ax;
262
		end
263
		if (state ~= 2
264
		and state ~= 5
265
		and state ~= 0) then
266
			gui.boxa(x+ax-8,y-16,x+ax+8,y,"#FF000000");
267
		end
268
	end
269
end
270
271
function drawall()
272
	gui.draw_info = {idx = 1};
273
274
	local no = true;
275
	for i = 0xFFE176, 0xFFE192, 4 do
276
		if (memory.readlong(i) == 0x298C44) then
277
			no = false
278
		end
279
	end
280
	if (no == true) then
281
		return;
282
	end
283
284
	level = memory.readword(0xFF1B14);
285
286
	pbase = 0xFFE1CA;
287
	life    = memory.readword(0xFF1346);
288
	maxlife = memory.readword(0xFF1348);
289
	invtime = memory.readwordsigned(pbase + 0xA);
290
	ninjat = memory.readbyte(0xFF1A03);
291
	hookstate = memory.readbyte(0xFFE219);
292
	platform = AND(memory.readword(0xFFE196),0x30)/0x10;
293
294
	scrollx = memory.readwordsigned(0xFFE1BC);
295
	scrolly = memory.readwordsigned(0xFFE1BE);
296
	posx = memory.readwordsigned(pbase + 0x12)*256 + memory.readbyte(pbase + 0x1A);
297
	posy = memory.readwordsigned(pbase + 0x14)*256 + memory.readbyte(pbase + 0x1B);
298
	px,py = getpos(pbase);
299
	speedy = memory.readwordsigned(pbase + 0x18);
300
	speedx = memory.readwordsigned(pbase + 0x16);
301
	if (AND(memory.readword(pbase),0x800) ~= 0) then
302
		speedx = -speedx;
303
	end
304
	speedx = speedx + memory.readwordsigned(0xFF216A);
305
306
	drawcollisions();
307
308
	if (show_notes) then
309
		drawnotes();
310
	end
311
312
	if (show_cursor) then
313
		drawcursor();
314
	end
315
316
	if (show_pos) then
317
		gui.texta(0,0,string.format("pos x: %s life: %X\npos y: %s maxlife: %X\nspeed x: %s ninja t: %d\nspeed y: %s platform: %d",
318
			postext(posx,8),life,
319
			postext(posy,8),maxlife,
320
			postext(speedx,6),ninjat,
321
			postext(speedy,6),platform));
322
		if (level == 1 and memory.readword(0xFF2148) >= 0x430) then
323
			gui.texta(130,0,"last platform showed","green");
324
		end
325
	end
326
327
	local boss3 = nil;
328
	local boss2 = nil;
329
	local enemycount = 0;
330
	i = 0;
331
	base = memory.readword(0xFFE1C2) + 0xFF0000;
332
	while (1) do
333
		base = memory.readword(base+2) + 0xFF0000;
334
		if (base == 0xFF0000 or i > 80) then
335
			break;
336
		end
337
338
		hp = memory.readwordsigned(base+0x1C);
339
		cb = memory.readbyte(base+0x29);
340
341
		if (base == pbase) then
342
			x,y = drawbbox(base,"#00ff0000");
343
			gui.boxa(px-1,py-1,px+1,py+1,"black","#FF00FF");
344
			if (show_life) then
345
				gui.texta(px+3,py-7,string.format("%d\n%d",hookstate,invtime));
346
			end
347
		elseif (cb == 0xE8) then -- bullet
348
			if (AND(memory.readbyte(base+0x5),2) == 2
349
			and memory.readbyte(base+0x43) > 2) then -- bomb
350
				if (memory.readbyte(base+0x43) == 16 -- ultimate bomb
351
				 or memory.readbyte(base+0x4) ~= 2 -- not land
352
				 or memory.readword(base+0x6) ~= 0) then
353
					x,y = drawbbox(base,"#0000ff00");
354
				else
355
					x,y = drawbbox(base,"#ff000000");
356
				end
357
			elseif (AND(memory.readword(0xFFE196)+memory.readword(base+0x48),1) == 1) then
358
				x,y = drawbbox(base,"#ff000000");
359
			else
360
				x,y = drawbbox(base,"#0000ff00");
361
			end
362
		else
363
			x,y = drawbbox(base,"#0000ff00");
364
		end
365
366
		--if (x == nil and hp ~= 0) then
367
			if (level == 2 and cb == 0xDC) then
368
				x,y = 150,0; -- first boss hack
369
			else
370
				x,y = getpos(base);
371
			end
372
		--end
373
		if (level == 6
374
		and memory.readword(base+0x20) == 0x410C) then
375
		-- Ninja Training Boss
376
			boss2 = base;
377
		end
378
		if (x + scrollx == 0x80
379
		and y + scrolly == 0xC0
380
		and memory.readword(base) == 0xA001
381
		and memory.readword(base+0x20) ~= 0xECA8
382
		and level == 9) then
383
		-- Muddrake Mayhem Boss
384
			boss3 = base;
385
		end
386
		if (AND(memory.readword(base+0x30),0x1000) ~= 0) then
387
			enemycount = enemycount + 1;
388
		end
389
		if (show_life and x ~= nil and hp ~= 0) then
390
			if (x > -30 and x < 350 and y > -30 and y < 254) then
391
				gui.texta(x-5,y,string.format("life %d\ninv %d",hp,memory.readwordsigned(base + 0xA)));
392
			end
393
		end
394
		if (show_life and level == 1 and (cb == 0x97 or cb == 0x98)) then -- totem
395
			if (x < 0) then
396
				gui.texta(0,y-8,string.format("x:%d",memory.readwordsigned(base + 0x12)));
397
			elseif (x > 320) then
398
				gui.texta(320-10,y-8,string.format("x:%d",memory.readwordsigned(base + 0x12)));
399
			else
400
				gui.texta(x-5,y-8,string.format("x:%d",memory.readwordsigned(base + 0x12)));
401
			end
402
		end
403
		if (
404
			(cb == 0xBC and ((level >= 7 and level <= 9) or (level >= 12 and level <= 13)))
405
			or (cb == 0xA0 and level == 17)) then -- wasp or soul
406
			x,y = getpos(base);
407
			x = x - px;
408
			y = y - py;
409
			local len = math.sqrt(x*x+y*y);
410
			x = x*40/len;
411
			y = y*40/len;
412
			gui.linea(px,py,px+x,py+y,"red");
413
			gui.texta(px+x,py+y,string.format("%.0f",len),"red");
414
		end
415
		
416
		if (level == 10
417
		and memory.readword(base+0x20) == 0x6FF8) then
418
		-- the Sacrifice of Maui Boss
419
			drawboss4(base);
420
		end
421
422
		if (level == 13) then
423
		-- Frog Boss
424
			drawboss5(base);
425
		end
426
427
		i = i+1;
428
	end
429
430
	if (boss2) then
431
	-- Ninja Training Boss
432
		base = boss2
433
		gui.texta(150,0,string.format("battle: %2d\ntimer: %3d\nenemy: %3d",
434
			memory.readwordsigned(0xFF2148),
435
			memory.readwordsigned(base+0x6),
436
			enemycount));
437
	end
438
	if (boss3) then
439
	-- Muddrake Mayhem Boss
440
		base = boss3
441
		local resp = "respawn ";
442
		if (memory.readwordsigned(base+0x52)~=0) then
443
			resp = "alive   ";
444
		end
445
		gui.texta(150,0,string.format("left: %d\n%s\n%d:%d\nenemy: %d keep<4",
446
			memory.readwordsigned(base+0x4E),
447
			resp,
448
			memory.readwordsigned(base+0x50),
449
			memory.readwordsigned(base+0x6),
450
			enemycount));
451
	end
452
453
	if (show_ammo) then
454
		local nt = memory.readword(0xFF133E);
455
		if (nt == 0xFFFF) then
456
			nt = 0x999;
457
		end
458
		gui.texta(280, 5,string.format("%3X", nt                      ),"yellow","black");
459
		gui.texta(280,13,string.format("%3X",memory.readword(0xFF1356)),"#CC4400","black");
460
		gui.texta(300, 5,string.format("%3X",memory.readword(0xFF1A20)),"blue"  ,"black");
461
		gui.texta(300,13,string.format("%3X",memory.readword(0xFF1A22)),"white" ,"black");
462
		gui.texta(300,21,string.format("%3X",memory.readword(0xFF1A24)),"red"   ,"black");
463
		gui.texta(300,29,string.format("%3X",memory.readword(0xFF1A26)),"yellow","black");
464
	end
465
466
	drawmessages();
467
end
468
469
memory.registerexec(0x296974,function ()
470
	if (sync) then
471
		drawall();
472
	end
473
end);
474
475
gens.registerbefore(function()
476
	if (sync) then
477
		drawall();
478
	end
479
end);
480
481
gens.registerafter(function()
482
	if (not sync) then
483
		drawall();
484
	end
485
end)
486
487
savestate.registerload(function ()
488
	if (sync) then
489
		gui.draw_info_prev = {idx = 1};
490
		drawall();
491
	else
492
		drawall();
493
	end
494
end)
495
496
function addmsg(msg,color)
497
	local t = {};
498
	local _t = gens.framecount();
499
	t.time = 60;
500
	for i = 1, 100 do
501
		t.i = i;
502
		local was = false;
503
		for k, v in pairs(msgtable) do
504
			if (v.time > 0 and i == v.i) then
505
				was = true;
506
			end
507
		end
508
		if (not was) then
509
			break;
510
		end
511
	end
512
	if (t.i == 100) then
513
		return nil;
514
	end
515
	t.msg = msg;
516
	t.color = color;
517
	msgtable[msgidx] = t;
518
	msgidx = msgidx + 1;
519
	return msgidx-1;
520
end
521
522
function drawmessages()
523
	local t = {};
524
	for k, v in pairs(msgtable) do
525
		if (v.time <= 0) then
526
			t[k] = true;
527
		else
528
			local c = { gui.parsecolor(v.color) };
529
			c[4] = v.time/60*255*2;
530
			if (c[4] > 255) then
531
				c[4] = 255;
532
			end
533
			if (v.unit) then
534
				x,y = getpos(v.unit);
535
				gui.linea(20, 190 + 4 - v.i*8,x,y,c);
536
			end
537
			gui.texta(5, 190 - v.i*8, v.msg, c, {0,0,0,c[4]});
538
			v.time = v.time - 1
539
		end
540
	end
541
	for k, v in pairs(t) do
542
		msgtable[k] = nil;
543
	end
544
end
545
546
function signedword(x)
547
	if (AND(x, 0x8000) ~= 0) then
548
		return -(0x10000-AND(x, 0xFFFF));
549
	else
550
		return AND(x, 0xFFFF);
551
	end
552
end
553
554
memory.registerexec(0x2A2C74,function ()
555
	if (show_dmg ~= true) then
556
		return
557
	end
558
	local dmg = signedword(memory.getregister("d1"));
559
	local a0 = memory.getregister("a0");
560
	local idx = addmsg(string.format("dmg: %d",dmg),"red");
561
	if (idx ~= nil) then
562
		msgtable[idx].unit = AND(a0,0xFFFFFF);
563
	end
564
end)
565
566
memory.registerexec(0x29BB42,function ()
567
	local d0 = memory.getregister("d0");
568
	local idx = addmsg(string.format("platform: %d",AND(d0,3)),"green");
569
end)
570
571
memory.registerexec(0x29D06A,function ()
572
	local d0 = memory.readword(0xFFE196);
573
	local idx = addmsg(string.format("case: %d",AND(d0,7)),"green");
574
end)
575
576
577
memory.registerexec(0x29CC68,function ()
578
	local a0 = memory.getregister("a0");
579
	local n = memory.readword(0xFF2148);
580
	local p = memory.readword(a0+0x12);
581
	local t = "hidden";
582
	if (n >= p) then
583
		t = "showed";
584
	end
585
	local idx = addmsg(string.format("brick: %s",t),"green");
586
end)
587
588
memory.registerexec(0x29DECC,function ()
589
	local idx = addmsg(string.format("spider"),"green");
590
end)
591
592
memory.registerexec(0x297154,function ()
593
	local d0 = memory.getregister("d0");
594
	local d1 = memory.getregister("d1");
595
	addmsg(string.format("random %02X<=%02X",AND(d0,0xFF),AND(d1,0xFF)),"green");
596
end)
597
598
memory.registerexec(0x2A4C62,function ()
599
	local pbase = 0xFFE1CA;
600
	local posx = AND(memory.getregister("d3"),0xFFFF);
601
	local posy = memory.readwordsigned(pbase + 0x14);
602
	local speedx = memory.readwordsigned(pbase + 0x16);
603
	if (speedx == 0) then
604
		speedx = 1;
605
	end
606
	if (AND(memory.readwordsigned(pbase),0x800) ~= 0) then
607
		speedx = -speedx;
608
	end
609
	local wspeedx = speedx;
610
	if (AND(memory.readwordsigned(pbase),0x8) ~= 0) then
611
		wspeedx = speedx + memory.readwordsigned(0xFF216A);
612
	end
613
	local xz = memory.readwordsigned(0xFF133C)-0x10;
614
	if (wspeedx < 0) then
615
		xz = -(xz + 0x10);
616
	end
617
	if (memory.readbyte(0xFF2131) == 0 or
618
		(memory.readbyte(0xFF2131) ~=0 and AND(memory.readbyte(0xFF2132),1) == 1)) then
619
		if (AND(posy, 0xF) < 8) then
620
			posy = posy - 0x10;
621
		end
622
	end
623
	xz = xz + posx;
624
	if (memory.readword(0xFF133A) == 2) then -- small mode
625
		posy = memory.readwordsigned(pbase + 0x14) + 8;
626
	end
627
	m_d0 = xz;
628
	m_d1 = posy;
629
end)
630
631
memory.registerexec(0x2A4CD2,function ()
632
	_d0 = AND(memory.getregister("d0"), 0xFFFF);
633
	_d1 = AND(memory.getregister("d1"), 0xFFFF);
634
end)
635
636
function drawcollisions()
637
	local a1 = memory.readlong(0xFFE124);
638
	local a2 = memory.readlong(0xFFE140);
639
	local a3 = memory.readlong(0xFF1B1E);
640
	for i = -1, 20 do
641
		for j = -1, 14 do
642
			local x = scrollx + i*16 - AND(scrollx,0xF);
643
			local y = scrolly + j*16 - AND(scrolly,0xF);
644
			local d0 = AND(x, 0xFFF0) / 8;
645
			local d1 = AND(y, 0xFFF0) / 4;
646
			if (AND(d0,0x8000) == 0
647
			and AND(d1,0x8000) == 0
648
			and d0 < memory.readword(0xFFE12C)
649
			and d1 < memory.readword(0xFFE12E)) then
650
				local d4 = d0;
651
				local was = false;
652
				for k = 0, 1 do
653
					local d5 = memory.readlong(0xFF0020 + d1 + k*4) + d4;
654
					for l = 0, 1 do
655
						local d0 = memory.readword(a1 + l*2 + AND(d5, 0xFFFF));
656
						local d0 = AND(d0,0xFFFE)/2;
657
						local d3 = memory.readbyte(AND(a2 + d0 + 2, 0xFFFFFF));
658
						local tt = memory.readbyte(0x1FCF14 + d3);
659
						local px = x - scrollx + 8 + l*8;
660
						local py = y - scrolly + 8 + k*8;
661
662
						if (h_collisions) then
663
							if (tt == 0) then
664
							elseif (tt == 1) then
665
								if (x == AND(_d0, 0xFFF0) and y == AND(_d1, 0xFFF0)) then
666
									gui.boxa(px, py, px + 8, py + 8, "#00FFFFFF","#00FFFFFF");
667
								else
668
									gui.boxa(px, py, px + 8, py + 8, "#00FFFF80","#00FFFFA0");
669
								end
670
							else
671
								gui.boxa(px, py, px + 8, py + 8, "#FF000080","#FF0000A0");
672
							end
673
						end
674
675
						if (v_collisions and l == 0 and k == 0) then
676
							local gnd = memory.readword(AND(a2 + d0,0xFFFFFF));
677
							for g = 0, 15 do
678
								local h = memory.readbytesigned(a3 + gnd + g);
679
								if (h ~= 0) then
680
									gui.setpixela(px + g - 8, py + h - 8, "#00FFFF");
681
								end
682
							end
683
							local sp = memory.readlong(0x1FD014 + d3*4);
684
							if (sp ~= 0x293DCA
685
							and sp ~= 0x2A526C) then
686
								if (sp == 0x29498A) then -- spikes
687
									gui.boxa(px-8, py-8, px+8, py+8, "#FF000080","#FF0000A0");
688
								elseif (sp == 0x293E3C) then -- rope
689
									gui.boxa(px, py-8, px+8, py+8, "#00880080","#008800A0");
690
								elseif (sp == 0x29481C) then -- warp
691
									gui.boxa(px-8, py-8, px+8, py+8, "#00FF0080","#00FF00A0");
692
								elseif (sp == 0x29480C
693
									 or sp == 0x294844) then -- warp sides
694
									gui.boxa(px-8, py-8, px+8, py+8, "#00FF0040","#00FF0060");
695
								elseif (sp == 0x2A4AF8) then -- end
696
									gui.boxa(px-8, py-8, px+8, py+8, "#00FF0080","#00FF00A0");
697
								elseif (sp == 0x293E80) then -- bamboo
698
									gui.boxa(px, py-8, px+8, py+8, "#AAAA0080","#AAAA00A0");
699
								elseif (sp == 0x2949F0
700
									 or sp == 0x2949DE) then -- mud
701
									gui.boxa(px-8, py-8, px+8, py+8, "#AA440080","#AA4400A0");
702
								elseif (sp == 0x294956) then -- lava
703
									gui.boxa(px-8, py-8, px+8, py+8, "#FF000080","#FF0000A0");
704
								elseif (sp == 0x2949BA) then -- spikes down
705
									gui.boxa(px-8, py-8, px+8, py+8, "#FF0000C0","#FF0000E0");
706
								else
707
									gui.texta(px, py, string.format("%X",sp));
708
								end
709
							end
710
						end
711
					end
712
				end
713
			end
714
		end
715
	end
716
717
	local d0 = _d0 - scrollx;
718
	local d1 = _d1 - scrolly;
719
	if (h_collisions) then
720
		if (memory.readword(0xFF133A) == 2) then -- small mode
721
			gui.boxa(d0,d1,d0+16,d1+8,"#00FFFF00");
722
		else
723
			gui.boxa(d0,d1,d0+16,d1+16,"#00FFFF00");
724
		end
725
	end
726
727
	if (v_collisions) then
728
		gui.boxa(px-1,py+16-1,px+1,py+16+1,"black","#00FFFF");
729
		if (memory.readword(0xFF133A) ~= 2) then -- not small mode
730
			gui.boxa(px-1,py-24,px+1,py-24+2,"black","#00FFFF");
731
		end
732
	end
733
end
734
735
gui.draw_info = {idx = 1};
736
737
gui.draw_info_prev = {idx = 1};
738
739
gui.texta = function (x,y,text,c,o)
740
	local info = gui.draw_info;
741
	local idx = info.idx;
742
	info.idx = idx + 1;
743
	info[idx] = {f = "text_", x = x, y = y, text = text, c = c, o = o};
744
end
745
746
gui.boxa = function (x1,y1,x2,y2,c,o)
747
	local info = gui.draw_info;
748
	local idx = info.idx;
749
	info.idx = idx + 1;
750
	info[idx] = {f = "box_", x1 = x1, y1 = y1, x2 = x2, y2 = y2, c = c, o = o};
751
end
752
753
gui.linea = function (x1,y1,x2,y2,c)
754
	local info = gui.draw_info;
755
	local idx = info.idx;
756
	info.idx = idx + 1;
757
	info[idx] = {f = "line_", x1 = x1, y1 = y1, x2 = x2, y2 = y2, c = c};
758
end
759
760
gui.setpixela = function (x1,y1,c)
761
	local info = gui.draw_info;
762
	local idx = info.idx;
763
	info.idx = idx + 1;
764
	info[idx] = {f = "pixel_", x1 = x1, y1 = y1, c = c};
765
end
766
767
gui.text_ = function (v)
768
	gui.text(v.x, v.y, v.text, v.c, v.o);
769
end
770
771
gui.box_ = function (v)
772
	gui.box(v.x1, v.y1, v.x2, v.y2, v.c, v.o);
773
end
774
775
gui.line_ = function (v)
776
	gui.line(v.x1, v.y1, v.x2, v.y2, v.c);
777
end
778
779
gui.pixel_ = function (v)
780
	gui.setpixel(v.x1, v.y1, v.c);
781
end
782
783
inpt_prev = {}
784
785
function drawbutton(b)
786
	local inpt = input.get();
787
	local xmouse = inpt.xmouse;
788
	local ymouse = inpt.ymouse;
789
	if (xmouse>b.x1 and xmouse < b.x2
790
	and ymouse>b.y1 and ymouse < b.y2) then
791
		if (b.down
792
		and inpt_prev["leftclick"] == true
793
		and inpt["leftclick"] ~= true) then
794
			if (b.var) then
795
				_G[b.var]=not _G[b.var]
796
			else
797
				b:proc();
798
			end
799
		end
800
		if (inpt["leftclick"] == true
801
		and inpt_prev["leftclick"] ~= true) then
802
			b.down = true;
803
		end
804
	end
805
806
	if (inpt["leftclick"] ~= true) then
807
		b.down = false;
808
	end
809
810
	local color = "#aaaaaa00";
811
	local text =  "#aaaaaaff";
812
813
	if (b.down) then
814
		color = "#ffffff00";
815
		text = "#ffffffff";
816
	end
817
	if (b.var and _G[b.var] == true) then
818
		text = "#ffffffff";
819
	end
820
	if (show_buttons) then
821
		gui.box(b.x1,b.y1,b.x2,b.y2,color);
822
		gui.text((b.x2-b.x1-#b.text*4)/2+b.x1+1,(b.y2-b.y1-8)/2+b.y1,b.text,text);
823
	end
824
end
825
826
gui.register(function ()
827
	if (sync) then
828
		gui.draw_info, gui.draw_info_prev = gui.draw_info_prev,gui.draw_info;
829
	end
830
831
	for k, v in pairs(buttons) do
832
		drawbutton(v);
833
	end
834
835
	for k, v in ipairs(gui.draw_info) do
836
		if (k ~= "idx") then
837
			gui[v.f](v);
838
		end
839
	end
840
	gui.draw_info = {idx = 1};
841
	inpt_prev = input.get();
842
end)