View difference between Paste ID: 6CQaBLJH and UCZhkJZc
SHOW: | | - or go back to the newest paste.
1
-- Donald starring in Maui Mallard (E)[!]
2
-- Script for TAS
3
-- 2013, 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-
input.registerhotkey(2, function()
48+
49-
	local p = {down=true};
49+
[11]={text="hex",x1=286,y1=168,x2=308,y2=178,down=false,var="show_hex"},
50-
	local a = {down=false};
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-
	-- draw cursor pos
58+
59-
	inpt = input.get();
59+
60-
	xmouse = inpt.xmouse;
60+
61-
	ymouse = inpt.ymouse;
61+
62
			break;
63-
	gui.text(xmouse,ymouse,string.format("%d\n%d",scrollx+xmouse,scrolly+ymouse));
63+
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-
				gui.text(x,y,text,color);
75+
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-
	gui.box(x+x1,y+y1,x+x2,y+y2,color);
103+
104
105
			x = x - scrollx;
106
			y = y - scrolly;
107-
gens.registerafter(function ()
107+
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-
	drawnotes();
130+
		local x1 = memory.readbytesigned(bb + 0);
131
		local x2 = memory.readbytesigned(bb + 1);
132-
	gui.drawtext(0,0,string.format("pos x: %.3f    life: %X\npos y: %.3f maxlife: %X\nspeed x: %.3f ninja t: %d\nspeed y: %.3f",
132+
		local y1 = memory.readbytesigned(bb + 2);
133-
		posx/0x100,life,
133+
		local y2 = memory.readbytesigned(bb + 3);
134-
		posy/0x100,maxlife,
134+
		bb = bb + 6;
135-
		speedx/0x100,ninjat,
135+
		if (AND(XOR(memory.readword(offs),memory.readword(offs+0x30)),0x800) ~= 0) then
136-
		speedy/0x100));
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-
			gui.box(px-1,py-1,px+1,py+1,"black","#FF00FF");
151+
152-
			gui.text(px+3,py-7,string.format("%d\n%d",hookstate,invtime));
152+
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-
		if (x ~= nil and hp ~= 0) then
164+
			x = string.format("-%X:%02X",AND(-x,0xFFFF00)/0x100,AND(-x,0xFF));
165
		else
166-
				gui.text(x-5,y,string.format("life %d\ninv %d",hp,memory.readwordsigned(base + 0xA)));
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-
			gui.line(px,py,px+x,py+y,"red");
178+
	local r = 1;--0xFFFF;
179-
			gui.text(px+x,py+y,string.format("%.0f",len),"red");
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-
	nt = memory.readword(0xFF133E);
184+
		r = 0xFFFF;
185-
	if (nt == 0xFFFF) then
185+
186-
		nt = 0x999;
186+
	if (AND(XOR(r,ws),0x8000) == 0) then
187
		if (AND(ws,0x8000) == 0) then
188-
	gui.text(280, 5,string.format("%3X", nt                      ),"yellow","black");
188+
			ws = ws + 4;
189-
	gui.text(280,13,string.format("%3X",memory.readword(0xFF1356)),"#CC4400","black");
189+
			if (ws > 0x1C) then
190-
	gui.text(300, 5,string.format("%3X",memory.readword(0xFF1A20)),"blue"  ,"black");
190+
				ws = 0x1C;
191-
	gui.text(300,13,string.format("%3X",memory.readword(0xFF1A22)),"white" ,"black");
191+
192-
	gui.text(300,21,string.format("%3X",memory.readword(0xFF1A24)),"red"   ,"black");
192+
193-
	gui.text(300,29,string.format("%3X",memory.readword(0xFF1A26)),"yellow","black");
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-
	t.time = _t + 60;
201+
			return 4;
202
		else
203
			return 0xFFFC;
204
		end
205
	end
206-
			if (t.time - _t > 0 and i == v.i) then
206+
207-
					was = true;
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-
		if (v.time - gens.framecount() <= 0) then
227+
		w = w + 0xFEC0;
228
	else
229
		w = w + 0x120;
230
	end
231-
			c[4] = (v.time - gens.framecount())/60*255*2;
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-
				gui.line(20, 190 + 4 - v.i*8,x,y,c);
237+
		local y2 = y1+math.sin(angle)*len;
238
		gui.linea(x1,y1,x2,y2,"#FFFFFF");
239-
			gui.text(5, 190 - v.i*8, v.msg, c, {0,0,0,c[4]});
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-
		return 0x10000-AND(x, 0xFFFF);
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
	end
323
324-
						local px = x - scrollx + l*8 + 8;
324+
	local boss3 = nil;
325-
						local py = y - scrolly + k*8 + 8;
325+
	local boss2 = nil;
326-
						if (tt == 0) then
326+
	local enemycount = 0;
327-
						elseif (tt == 1) then
327+
328-
							gui.box(px, py, px + 8, py + 8, "#00FFFF80","#00FFFFA0");
328+
329-
						else
329+
330-
							gui.box(px, py, px + 8, py + 8, "#FF000080","#FF0000A0");
330+
331
		if (base == 0xFF0000 or i > 80) then
332-
						--gui.text(px, py, string.format("%02X",tt));
332+
333
		end
334-
						if (l == 0 and k == 0) then
334+
335
		hp = memory.readwordsigned(base+0x1C);
336
		cb = memory.readbyte(base+0x29);
337
338
		if (base == pbase) then
339-
									gui.setpixel(px + g - 8, py + h - 8, "#00FFFF");
339+
340
			gui.boxa(px-1,py-1,px+1,py+1,"black","#FF00FF");
341
			if (show_life) then
342
				gui.texta(px+3,py-7,string.format("%d\n%d",hookstate,invtime));
343
			end
344
		else
345
			x,y = drawbbox(base,"#0000ff00");
346
		end
347
348
		--if (x == nil and hp ~= 0) then
349-
	_d0 = _d0 - scrollx;
349+
350-
	_d1 = _d1 - scrolly;
350+
351
			else
352-
		gui.box(_d0,_d1,_d0+16,_d1+8,"#00FFFF00");
352+
353
			end
354-
		gui.box(_d0,_d1,_d0+16,_d1+16,"#00FFFF00");
354+
355
		if (level == 6
356
		and memory.readword(base+0x20) == 0x410C) then
357-
	gui.box(px-1,py+16-1,px+1,py+16+1,"black","#00FFFF");
357+
		-- Ninja Training Boss
358-
	if (memory.readword(0xFF133A) ~= 2) then -- not small mode
358+
			boss2 = base;
359-
		gui.box(px-1,py-24,px+1,py-24+2,"black","#00FFFF");
359+
360
		if (x + scrollx == 0x80
361-
end
361+
		and y + scrolly == 0xC0
362
		and memory.readword(base) == 0xA001
363
		and memory.readword(base+0x20) ~= 0xECA8
364
		and level == 9) then
365
		-- Muddrake Mayhem Boss
366
			boss3 = base;
367
		end
368
		if (AND(memory.readword(base+0x30),0x1000) ~= 0) then
369
			enemycount = enemycount + 1;
370
		end
371
		if (show_life and x ~= nil and hp ~= 0) then
372
			if (x > -30 and x < 350 and y > -30 and y < 254) then
373
				gui.texta(x-5,y,string.format("life %d\ninv %d",hp,memory.readwordsigned(base + 0xA)));
374
			end
375
		end
376
		if (show_life and level == 1 and (cb == 0x97 or cb == 0x98)) then -- totem
377
			if (x < 0) then
378
				gui.texta(0,y-8,string.format("x:%d",memory.readwordsigned(base + 0x12)));
379
			elseif (x > 320) then
380
				gui.texta(320-10,y-8,string.format("x:%d",memory.readwordsigned(base + 0x12)));
381
			else
382
				gui.texta(x-5,y-8,string.format("x:%d",memory.readwordsigned(base + 0x12)));
383
			end
384
		end
385
		if (
386
			(cb == 0xBC and ((level >= 7 and level <= 9) or (level >= 12 and level <= 13)))
387
			or (cb == 0xA0 and level == 17)) then -- wasp or soul
388
			x,y = getpos(base);
389
			x = x - px;
390
			y = y - py;
391
			local len = math.sqrt(x*x+y*y);
392
			x = x*40/len;
393
			y = y*40/len;
394
			gui.linea(px,py,px+x,py+y,"red");
395
			gui.texta(px+x,py+y,string.format("%.0f",len),"red");
396
		end
397
		
398
		if (level == 10
399
		and memory.readword(base+0x20) == 0x6FF8) then
400
		-- the Sacrifice of Maui Boss
401
			drawboss4(base);
402
		end
403
404
		if (level == 13) then
405
		-- Frog Boss
406
			drawboss5(base);
407
		end
408
409
		i = i+1;
410
	end
411
412
	if (boss2) then
413
	-- Ninja Training Boss
414
		base = boss2
415
		gui.texta(150,0,string.format("battle: %2d\ntimer: %3d\nenemy: %3d",
416
			memory.readwordsigned(0xFF2148),
417
			memory.readwordsigned(base+0x6),
418
			enemycount));
419
	end
420
	if (boss3) then
421
	-- Muddrake Mayhem Boss
422
		base = boss3
423
		local resp = "respawn ";
424
		if (memory.readwordsigned(base+0x52)~=0) then
425
			resp = "alive   ";
426
		end
427
		gui.texta(150,0,string.format("left: %d\n%s\n%d:%d\nenemy: %d keep<4",
428
			memory.readwordsigned(base+0x4E),
429
			resp,
430
			memory.readwordsigned(base+0x50),
431
			memory.readwordsigned(base+0x6),
432
			enemycount));
433
	end
434
435
	if (show_ammo) then
436
		local nt = memory.readword(0xFF133E);
437
		if (nt == 0xFFFF) then
438
			nt = 0x999;
439
		end
440
		gui.texta(280, 5,string.format("%3X", nt                      ),"yellow","black");
441
		gui.texta(280,13,string.format("%3X",memory.readword(0xFF1356)),"#CC4400","black");
442
		gui.texta(300, 5,string.format("%3X",memory.readword(0xFF1A20)),"blue"  ,"black");
443
		gui.texta(300,13,string.format("%3X",memory.readword(0xFF1A22)),"white" ,"black");
444
		gui.texta(300,21,string.format("%3X",memory.readword(0xFF1A24)),"red"   ,"black");
445
		gui.texta(300,29,string.format("%3X",memory.readword(0xFF1A26)),"yellow","black");
446
	end
447
448
	drawmessages();
449
end
450
451
memory.registerexec(0x296974,function ()
452
	if (sync) then
453
		drawall();
454
	end
455
end);
456
457
gens.registerbefore(function()
458
	if (sync) then
459
		drawall();
460
	end
461
end);
462
463
gens.registerafter(function()
464
	if (not sync) then
465
		drawall();
466
	end
467
end)
468
469
savestate.registerload(function ()
470
	if (sync) then
471
		gui.draw_info_prev = {idx = 1};
472
		drawall();
473
	else
474
		drawall();
475
	end
476
end)
477
478
function addmsg(msg,color)
479
	local t = {};
480
	local _t = gens.framecount();
481
	t.time = 60;
482
	for i = 1, 100 do
483
		t.i = i;
484
		local was = false;
485
		for k, v in pairs(msgtable) do
486
			if (v.time > 0 and i == v.i) then
487
				was = true;
488
			end
489
		end
490
		if (not was) then
491
			break;
492
		end
493
	end
494
	if (t.i == 100) then
495
		return nil;
496
	end
497
	t.msg = msg;
498
	t.color = color;
499
	msgtable[msgidx] = t;
500
	msgidx = msgidx + 1;
501
	return msgidx-1;
502
end
503
504
function drawmessages()
505
	local t = {};
506
	for k, v in pairs(msgtable) do
507
		if (v.time <= 0) then
508
			t[k] = true;
509
		else
510
			local c = { gui.parsecolor(v.color) };
511
			c[4] = v.time/60*255*2;
512
			if (c[4] > 255) then
513
				c[4] = 255;
514
			end
515
			if (v.unit) then
516
				x,y = getpos(v.unit);
517
				gui.linea(20, 190 + 4 - v.i*8,x,y,c);
518
			end
519
			gui.texta(5, 190 - v.i*8, v.msg, c, {0,0,0,c[4]});
520
			v.time = v.time - 1
521
		end
522
	end
523
	for k, v in pairs(t) do
524
		msgtable[k] = nil;
525
	end
526
end
527
528
function signedword(x)
529
	if (AND(x, 0x8000) ~= 0) then
530
		return -(0x10000-AND(x, 0xFFFF));
531
	else
532
		return AND(x, 0xFFFF);
533
	end
534
end
535
536
memory.registerexec(0x2A2C74,function ()
537
	if (show_dmg ~= true) then
538
		return
539
	end
540
	local dmg = signedword(memory.getregister("d1"));
541
	local a0 = memory.getregister("a0");
542
	local idx = addmsg(string.format("dmg: %d",dmg),"red");
543
	if (idx ~= nil) then
544
		msgtable[idx].unit = AND(a0,0xFFFFFF);
545
	end
546
end)
547
548
memory.registerexec(0x29BB42,function ()
549
	local d0 = memory.getregister("d0");
550
	local idx = addmsg(string.format("platform: %d",AND(d0,3)),"green");
551
end)
552
553
memory.registerexec(0x29D06A,function ()
554
	local d0 = memory.readword(0xFFE196);
555
	local idx = addmsg(string.format("case: %d",AND(d0,7)),"green");
556
end)
557
558
memory.registerexec(0x2A4C62,function ()
559
	local pbase = 0xFFE1CA;
560
	local posx = AND(memory.getregister("d3"),0xFFFF);
561
	local posy = memory.readwordsigned(pbase + 0x14);
562
	local speedx = memory.readwordsigned(pbase + 0x16);
563
	if (speedx == 0) then
564
		speedx = 1;
565
	end
566
	if (AND(memory.readwordsigned(pbase),0x800) ~= 0) then
567
		speedx = -speedx;
568
	end
569
	local wspeedx = speedx;
570
	if (AND(memory.readwordsigned(pbase),0x8) ~= 0) then
571
		wspeedx = speedx + memory.readwordsigned(0xFF216A);
572
	end
573
	local xz = memory.readwordsigned(0xFF133C)-0x10;
574
	if (wspeedx < 0) then
575
		xz = -(xz + 0x10);
576
	end
577
	if (memory.readbyte(0xFF2131) == 0 or
578
		(memory.readbyte(0xFF2131) ~=0 and AND(memory.readbyte(0xFF2132),1) == 1)) then
579
		if (AND(posy, 0xF) < 8) then
580
			posy = posy - 0x10;
581
		end
582
	end
583
	xz = xz + posx;
584
	if (memory.readword(0xFF133A) == 2) then -- small mode
585
		posy = memory.readwordsigned(pbase + 0x14) + 8;
586
	end
587
	m_d0 = xz;
588
	m_d1 = posy;
589
end)
590
591
memory.registerexec(0x2A4CD2,function ()
592
	_d0 = AND(memory.getregister("d0"), 0xFFFF);
593
	_d1 = AND(memory.getregister("d1"), 0xFFFF);
594
end)
595
596
function drawcollisions()
597
	local a1 = memory.readlong(0xFFE124);
598
	local a2 = memory.readlong(0xFFE140);
599
	local a3 = memory.readlong(0xFF1B1E);
600
	for i = -1, 20 do
601
		for j = -1, 14 do
602
			local x = scrollx + i*16 - AND(scrollx,0xF);
603
			local y = scrolly + j*16 - AND(scrolly,0xF);
604
			local d0 = AND(x, 0xFFF0) / 8;
605
			local d1 = AND(y, 0xFFF0) / 4;
606
			if (AND(d0,0x8000) == 0
607
			and AND(d1,0x8000) == 0
608
			and d0 < memory.readword(0xFFE12C)
609
			and d1 < memory.readword(0xFFE12E)) then
610
				local d4 = d0;
611
				local was = false;
612
				for k = 0, 1 do
613
					local d5 = memory.readlong(0xFF0020 + d1 + k*4) + d4;
614
					for l = 0, 1 do
615
						local d0 = memory.readword(a1 + l*2 + AND(d5, 0xFFFF));
616
						local d0 = AND(d0,0xFFFE)/2;
617
						local d3 = memory.readbyte(AND(a2 + d0 + 2, 0xFFFFFF));
618
						local tt = memory.readbyte(0x1FCF14 + d3);
619
						local px = x - scrollx + 8 + l*8;
620
						local py = y - scrolly + 8 + k*8;
621
622
						if (h_collisions) then
623
							if (tt == 0) then
624
							elseif (tt == 1) then
625
								if (x == AND(_d0, 0xFFF0) and y == AND(_d1, 0xFFF0)) then
626
									gui.boxa(px, py, px + 8, py + 8, "#00FFFFFF","#00FFFFFF");
627
								else
628
									gui.boxa(px, py, px + 8, py + 8, "#00FFFF80","#00FFFFA0");
629
								end
630
							else
631
								gui.boxa(px, py, px + 8, py + 8, "#FF000080","#FF0000A0");
632
							end
633
						end
634
635
						if (v_collisions and l == 0 and k == 0) then
636
							local gnd = memory.readword(AND(a2 + d0,0xFFFFFF));
637
							for g = 0, 15 do
638
								local h = memory.readbytesigned(a3 + gnd + g);
639
								if (h ~= 0) then
640
									gui.setpixela(px + g - 8, py + h - 8, "#00FFFF");
641
								end
642
							end
643
							local sp = memory.readlong(0x1FD014 + d3*4);
644
							if (sp ~= 0x293DCA
645
							and sp ~= 0x2A526C) then
646
								if (sp == 0x29498A) then -- spikes
647
									gui.boxa(px-8, py-8, px+8, py+8, "#FF000080","#FF0000A0");
648
								elseif (sp == 0x293E3C) then -- rope
649
									gui.boxa(px, py-8, px+8, py+8, "#00880080","#008800A0");
650
								elseif (sp == 0x29481C) then -- warp
651
									gui.boxa(px-8, py-8, px+8, py+8, "#00FF0080","#00FF00A0");
652
								elseif (sp == 0x29480C
653
									 or sp == 0x294844) then -- warp sides
654
									gui.boxa(px-8, py-8, px+8, py+8, "#00FF0040","#00FF0060");
655
								elseif (sp == 0x2A4AF8) then -- end
656
									gui.boxa(px-8, py-8, px+8, py+8, "#00FF0080","#00FF00A0");
657
								elseif (sp == 0x293E80) then -- bamboo
658
									gui.boxa(px, py-8, px+8, py+8, "#AAAA0080","#AAAA00A0");
659
								elseif (sp == 0x2949F0
660
									 or sp == 0x2949DE) then -- mud
661
									gui.boxa(px-8, py-8, px+8, py+8, "#AA440080","#AA4400A0");
662
								elseif (sp == 0x294956) then -- lava
663
									gui.boxa(px-8, py-8, px+8, py+8, "#FF000080","#FF0000A0");
664
								elseif (sp == 0x2949BA) then -- spikes down
665
									gui.boxa(px-8, py-8, px+8, py+8, "#FF0000C0","#FF0000E0");
666
								else
667
									gui.texta(px, py, string.format("%X",sp));
668
								end
669
							end
670
						end
671
					end
672
				end
673
			end
674
		end
675
	end
676
677
	local d0 = _d0 - scrollx;
678
	local d1 = _d1 - scrolly;
679
	if (h_collisions) then
680
		if (memory.readword(0xFF133A) == 2) then -- small mode
681
			gui.boxa(d0,d1,d0+16,d1+8,"#00FFFF00");
682
		else
683
			gui.boxa(d0,d1,d0+16,d1+16,"#00FFFF00");
684
		end
685
	end
686
687
	if (v_collisions) then
688
		gui.boxa(px-1,py+16-1,px+1,py+16+1,"black","#00FFFF");
689
		if (memory.readword(0xFF133A) ~= 2) then -- not small mode
690
			gui.boxa(px-1,py-24,px+1,py-24+2,"black","#00FFFF");
691
		end
692
	end
693
end
694
695
gui.draw_info = {idx = 1};
696
697
gui.draw_info_prev = {idx = 1};
698
699
gui.texta = function (x,y,text,c,o)
700
	local info = gui.draw_info;
701
	local idx = info.idx;
702
	info.idx = idx + 1;
703
	info[idx] = {f = "text_", x = x, y = y, text = text, c = c, o = o};
704
end
705
706
gui.boxa = function (x1,y1,x2,y2,c,o)
707
	local info = gui.draw_info;
708
	local idx = info.idx;
709
	info.idx = idx + 1;
710
	info[idx] = {f = "box_", x1 = x1, y1 = y1, x2 = x2, y2 = y2, c = c, o = o};
711
end
712
713
gui.linea = function (x1,y1,x2,y2,c)
714
	local info = gui.draw_info;
715
	local idx = info.idx;
716
	info.idx = idx + 1;
717
	info[idx] = {f = "line_", x1 = x1, y1 = y1, x2 = x2, y2 = y2, c = c};
718
end
719
720
gui.setpixela = function (x1,y1,c)
721
	local info = gui.draw_info;
722
	local idx = info.idx;
723
	info.idx = idx + 1;
724
	info[idx] = {f = "pixel_", x1 = x1, y1 = y1, c = c};
725
end
726
727
gui.text_ = function (v)
728
	gui.text(v.x, v.y, v.text, v.c, v.o);
729
end
730
731
gui.box_ = function (v)
732
	gui.box(v.x1, v.y1, v.x2, v.y2, v.c, v.o);
733
end
734
735
gui.line_ = function (v)
736
	gui.line(v.x1, v.y1, v.x2, v.y2, v.c);
737
end
738
739
gui.pixel_ = function (v)
740
	gui.setpixel(v.x1, v.y1, v.c);
741
end
742
743
inpt_prev = {}
744
745
function drawbutton(b)
746
	local inpt = input.get();
747
	local xmouse = inpt.xmouse;
748
	local ymouse = inpt.ymouse;
749
	if (xmouse>b.x1 and xmouse < b.x2
750
	and ymouse>b.y1 and ymouse < b.y2) then
751
		if (b.down
752
		and inpt_prev["leftclick"] == true
753
		and inpt["leftclick"] ~= true) then
754
			if (b.var) then
755
				_G[b.var]=not _G[b.var]
756
			else
757
				b:proc();
758
			end
759
		end
760
		if (inpt["leftclick"] == true
761
		and inpt_prev["leftclick"] ~= true) then
762
			b.down = true;
763
		end
764
	end
765
766
	if (inpt["leftclick"] ~= true) then
767
		b.down = false;
768
	end
769
770
	local color = "#aaaaaa00";
771
	local text =  "#aaaaaaff";
772
773
	if (b.down) then
774
		color = "#ffffff00";
775
		text = "#ffffffff";
776
	end
777
	if (b.var and _G[b.var] == true) then
778
		text = "#ffffffff";
779
	end
780
	if (show_buttons) then
781
		gui.box(b.x1,b.y1,b.x2,b.y2,color);
782
		gui.text((b.x2-b.x1-#b.text*4)/2+b.x1+1,(b.y2-b.y1-8)/2+b.y1,b.text,text);
783
	end
784
end
785
786
gui.register(function ()
787
	if (sync) then
788
		gui.draw_info, gui.draw_info_prev = gui.draw_info_prev,gui.draw_info;
789
	end
790
791
	for k, v in pairs(buttons) do
792
		drawbutton(v);
793
	end
794
795
	for k, v in ipairs(gui.draw_info) do
796
		if (k ~= "idx") then
797
			gui[v.f](v);
798
		end
799
	end
800
	gui.draw_info = {idx = 1};
801
	inpt_prev = input.get();
802
end)