Camera fix

This commit is contained in:
MaddoScientisto 2024-04-27 17:41:11 +02:00
commit 93f95683c5
4 changed files with 654 additions and 72 deletions

View file

@ -6,78 +6,88 @@ version 2
:: sfx/
:: gfx/0.gfx
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTA0LTA0IDA3OjE5OjM0Iixtb2RpZmllZD0iMjAyNC0w
NC0yNiAxNTozNjo1NCIscmV2aXNpb249OTQ1XV1sejQA9ggAAKo_AADzFHtbMF09e2JtcD1weHUA
QyAQEATw8CxmbGFncz0wLHBhbl94CADaeT0wLHpvb209MTF9LDIA8QivGyPeA34D3iPeA-4JE24D
ThNuI04DfhMA-wOOAz4DTgMuI34jLgOeA-4UAy5eAB3wCfBFTYAtJi1QHWYdBSAdhg0VAB2WHRUN
pgQAww0VAA2WHQUQvQXwE1gAHzNYABXwKlBEgBRPHxRQDxSPHwRALxRPHyRADxQfH0QODxkEQA8U
PhoNDxkOBEANLgoACg0ODARADR4aAAoJDBQAQA5KCQoSAEEOKgAKJQASXiIA714NDA4EUBQ_DRSA
RPAVkwAdkfASoTABHxABHgIAEyAIAA8KAASuDxGhDSAODxwPDAQARA4RAA4MAAQEAPIQIQ4FAQAO
DB4PDA4LDA4RDA4BBQAOCw4LDB4LDgEMAR4AEwsCACABC0MAxQseDB4LDAsBDA4FEBwAYyEOASCu
INsAHzHbABb3BAY-GVBpLllOGQ4ZXlkeeVAeGbADACHADgMAXynAGfAXWwAPD7ECBQ8yAEf8Ac8T
LxEPE18RDxM-EQ8TDB8NACgMTw4AIywvDgC0HA8RfxMMLxE-Ex8gAAAbAB9PDQAO8QA8Di8RLgwt
jh0ODC0ObQ4HACcMXQgAfzwOLD0OHd7IAB3Z9AwPHzQedB40HiQeJAYA8QBEDiQe1B6EHiQOlB6E
DjQEAAYeABCEBAA-DvQJ0gId-0H-FgA2DoYOFgUWDgUmBTYONgUOZgUGDkYOFgVWDgb_AFYORg42
BTYOJgUGDoYOBgUmDgYFZg5GDib_AIYOlgU2DhYFtg52BSYFFg42BZYOVoAAHvIAFQMMDxAMDhwO
DA4MbxUOCgBRHQwdDC0LALEdDgwdDA4tDhwOLQoAUgwtHC0MCgA0Dl0OCgA-DD0MDAACBSIABTYA
BUoAAl8AMy0MTXMAI20MCQA-DP0DxQAd0B8V1B6UDx8kHgQNZB0GAD8UHSQIAAQwdB40BABQDYQe
lA0SACZ0DSAAFzQGAH8EDRQNhB7UigAd4NQfFLQPHwQfFAQfH3QeCAABHgIsBB0IAJAUDiQeVB1U
HlQSAIUOZB0EHoQOBAYACiwAElQGAF4OZB3UHdACD-wDb-EUQF8UcB4PFT8fLkAeDxUOPx8PFQ4N
DiAeDQ4NPx8ODQ4NDhAGAGE8DQ4NHgALADENDhwHABE_BgAhHA4HABEeBgAnDhQaACUUDhoA4CwN
DixeTA4NTA0OAA48FgBSPA4QDixaAEEOIA4MCgBhDQ4cDkAuCgBPHnBeQMsAJAA-AFEuQA4PH0kA
Yw4NLiAOLAsAMRwOEMkAYA4NPAAOTAgAUUwuTC5MogAgFEy2ADccFBzOACwcHucANQ4AHhkACBoB
EiDUAG4NHkAuPC68AA-rAUHQE51QDX8QDVANDl8YDgcAQgw-HgwJAD8LHAsKABISOwgAEFwGAE5_
DVCdaAgPhgAgEzddAD8HHAcKABIeN4UADz0BHg8yAIGQBgcGBx8WBgceCQCxBgcOFh4WHmYHBh4D
AAECAHUWHpYeFgcGAgByHgYHph4WDg4AAygAUlYeFh5WHAAGSQASphwAHwZIAAACKAA8Zh4WSQBf
Fg4mHobEAB32APUB3xgV3hXfFRXeFd4V3QYAf-UC3RXd9QFQAB1P9gANBgIAyi-2AWMBH0cPFg0O
AgA4FQ0OAgBz9QEPEy8MLzsJIB8MdQkZD3YJGQ9dCQ8OAAlxPwwPEy8RLxYANY8THyAAN28RDw4A
Pw8MXxAABAFAACEMPw4AH9_nAyAPMgD--0Vf-xQS0B4CAAYP0gYdT-8UEPA1ACEv0B4CAAcPTwAd
4PBIKLCIYIhgGNAY0AjgAgAQGAYAH2BMAR7DERSQFAAPFA8fBA4PjwmVDg0OBB4NBA0OAgDHBA0e
BK4EDh0ErQQtBAAbDQIAQx0kDQQCADk0DQQCAG8AFJAU8BHmAB47ERTAnAAoMA6aAIAgHgSeIB0E
bQsAWh0EbR4NDQAiBA0OAFINJA0EPRAAMA0ETUYAMcRABBMAIQRQEAAeIJoAD7YCbyIfFBwCD7kC
OD8SwC4CAAIf-psBHh7QngAP0gIrmXAI4AhwFEAIMI8CGgiPAhUIjwIwTghOkQJdTQhNBC0GABQN
AgAYCJkCGAiZAgMaACENAHMAX4AY0BhQ0gFPmGAI4AiAFDAIQOQAGghzAxUY4wAhPhjjACA9GNcA
DAYAA78AJwQY4gAXGOEAAxgAzw0AFDAYMBRwGNAYYJIBHS-w8OQCbC-_ELMAHk-Q-xQQywI5L-4S
TgAdWFA4sCjAAgBvmHB4oEjw8A0fj1AYAGhQ_BDw1AUeAO0BAgIArrA4kFhQiGB48Gh_AA-8AW9h
MDwPHCxgFRLwCAcMDhwwHA4MRwwODDAMDgxnDA4wHhcOAgAyDEAOCQDwISAeIFcADjAeIDcwHkAs
CBwQHkAHLAgcB0AeAAdcBwAeAB4QfBAeIAcMBwwHTHAXAAgAnwxwFxAXkBgQGH8BHvAFIAEsPxwB
UAEcbgFAAQwOEQ4RBw4KACIHDgMAAQwAMhwHHAoA8A8PF0cNDgEwARwnDSceATAxDAcOMVABBwwH
CAcOBwEKAP8mDggOCB4HATABBxxuBwEQARcsXhcBAAEXfAEXARARBwEXAQcRBxFAAQABBwEHAZAB
HAEcAUC2AR8PMgD-GP8ngA8b0B6ATxgOPUA9Am0wvTAdAm0CHSBdAl0gzTAdAk0CLTBNCF0wPQJt
QF0CLWB9cG2QTbAtJQYgDzIA-0f-AAQEBAAfHAAOFx4XDgAeADwAGv8GCAgEgAcwByAHEAfwBAcQ
ByAHMAeAQgAdkAgAOAAIAAgwCAYAgRAIABhQGFAYCgAEFgA-OAAINwEfDzIA5fAUEL8YIA60DgAO
1B5EPEQeJBw-HBwkHiQMXQwkHhQMDVwNDBQIADIMPQwKABEdAgAICgDRJAwdHB0MJB4kHD0cJEUA
n9QOAA60DiC_EL8AHw8yAP------------------------------------------llA9MTF9fQ==
NC0yNyAxNTo0MTowMCIscmV2aXNpb249MTAyNF1dbHo0AD0KAABDQAAA8xR7WzBdPXtibXA9cHh1
AEMgEBAE8PAsZmxhZ3M9MCxwYW5feAgA2nk9MCx6b29tPTExfSwyAPEIrxsj3gN_A94j3gP_CRNu
A04TbiNOA34TAP8DjgM_A04DLiN_Iy4DngP_FAMuXgAd8AnwRU2ALSYtUB1mHQUgHYYNFQAdlh0V
DaYEAMMNFQANlh0FEL0F8BNYAB8zWAAV8CpQRIAUTx8UUA8Ujx8EQC8UTx8kQA8UHx9EDg8ZBEAP
FD4aDQ8ZDgRADS4KAAoNDgwEQA0eGgAKCQwUAEAOSgkKEgBBDioACiUAEl4iAO9eDQwOBFAUPg0U
gETwFZMAHbbwEqEwAa8QASABrgQArg8RoQ0gDg8cDwwEAEQOEQAODAAEBADyECEOBQEADgweDwwO
CwwOEQwOAQUADgsOCwweCw4BDAEeABMLAgAgAQtDAMULHgweCwwLAQwOBRAcAGMhDgEgriDDAB8x
wwAW9wQGPxlQaS5ZThkOGV5ZHnlQHhmwAwAhwA4DAF8pwBnwF1sAHmMSrxMwDhMCABMgCAAPCgAE
8Q8PEa4NIAOvGwMeAAOsAwUOAANMDxRMAw4FAAM8KzwRAAAIABMeDwCPEAOsAw4goyCdAg8PLQMt
-AHPEy8RDxNfEQ8TPxEPEwwfDQAoDE8OACMsLw4AtBwPEX8TDC8RPxMfIAAAGwAfTw0ADvEAPA4v
ES4MLY4dDgwtDm0OBwAnDF0IAH88Diw9Dh3eyAAd2fQMDx80HnQeNB4kHiQGAPEARA4kHtQehB4k
DpQehA40BAAGHgAQhAQAPw70CRwDHf9B-xYANg6GDhYFFg4FJgU2DjYFDmYFBg5GDhYFVg4G-gBW
DkYONgU2DiYFBg6GDgYFJg4GBWYORg4m-gCGDpYFNg4WBbYOdgUmBRYONgWWDlaAAB7yABUDDA8Q
DA4cDgwODG8VDgoAUR0MHQwtCwCxHQ4MHQwOLQ4cDi0KAFIMLRwtDAoANA5dDgoAPww9DAwAAgUi
AAU2AAVKAAJfADMtDE1zACNtDAkAPwz9A8UAHdAfFdQelA8fJB4EDWQdBgA-FB0kCAAEMHQeNAQA
UA2EHpQNEgAmdA0gABc0BgB-BA0UDYQe1IoAHeDUHxS0Dx8EHxQEHx90HggAAR4CLAQdCACQFA4k
HlQdVB5UEgCFDmQdBB6EDgQGAAosABJUBgBfDmQd1B3QAh3xAzYNFg8WbQ8SBg1GDxZNBg0PEhIA
YR0GPQ8SZhoAMyYNJhoAoQYNJg0GDxYNBk0cALA9Bh0PEn8WfxJtDioA8RQOJg0mDB0GHQYNDkYN
BgxtDhYNNgwGXQ5mDC0GLQ4GDUYMbRkAL358bgRP8RRAXxRwHg8VPx8uQB4PFQ4-Hw8VDg0OIB4N
Dg0-Hw4NDg0OEAYAYTwNDg0eAAsAMQ0OHAcAET4GACEcDgcAER4GACcOFBoAJRQOGgDgLA0OLF5M
Dg1MDQ4ADjwWAFI8DhAOLFoAQQ4gDgwKAGENDhwOQC4KAE8ecF5AywAkAD8AUS5ADg8fSQBjDg0u
IA4sCwAxHA4QyQBgDg08AA5MCABRTC5MLkyiACAUTLYANxwUHM4ALBwe5wA1DgAeGQAIGgESINQA
bg0eQC48LrwAD7kBQODwE51QDX8QDVANDl8YDgcAQgw-HgwJAD8LHAsKABISOwgAEFwGAG9_DVCd
8BOGADATN10APwccBwoAEh83hQAvH-AyAIGQBgcGBx8WBgceCQCxBgcOFh4WHmYHBh4DAAECAHUW
HpYeFgcGAgByHgYHph4WDg4AAygAUlYeFh5WHAAGSQASphwAHwZIAAACKAA8Zh4WSQBfFg4mHobE
AB32APUB3xgV3hXfFRXeFd4V3QYAf-UC3RXd9QFQAB1P9gANBgIAyi-2AWMBH0cPFg0OAgA4FQ0O
AgBz9QEPEy8ML60JIB8M5wkZD_gJGQ-PCQ8OAAlxPwwPEy8RLxYANY8THyAAN28RDw4APw8MXxAA
BAFAACEMPw4AH9_nA7QPMgAfTx8UsD4CAAofHuwIHX7-FBDwsP4QNwAP7QAVDzIA-xBf-xQS0B4C
AAYPsQEhDzUAIS-QHgIABw9PAB3g8EgosIhgiGAY0BjQCOACABAYBgAfYEgAHsMRFJAUAA8UDx8E
Dg_0CZUODQ4EHg0EDQ4CAMcEDR4ErgQOHQStBC0EABsNAgBDHSQNBAIAOTQNBAIAbwAUkBTwEZ4A
IBvAnAAoMA6aAIAgHgSeIB0EbQsAWh0EbR4NDQAiBA0OAFINJA0EPRAAMA0ETUYAMcRABBMAIQRQ
EAAeIJoAD2sEcQIcAg_5Ajg-EsAuAgACH-6bAR4e0J4AD9ICK5lwCOAIcBRACDCPAhoIjwIVCI8C
ME4ITpECXU0ITQQtBgAUDQIAGAiZAhgImQIDGgAhDQBzAF_AGNAYUAQCT5hgCOAIgBQwCEDkABoI
cwMVGOMAIT4Y4wAgPRjXAAwGAAO-ACcEGOIAFxjhAAMYAM8NABQwGDAUcBjQGGDgAE8P5AI8DxUH
IE-Q-xQQywI5L-4STgAdWFA4sCjAAgB-mHB4oEjwQEgAHZ-wUBgAaFD4EPC4AR4A7QECAgCvsDiQ
WFCIYHjwaH4AHqoB0xADvxsDEAO_BAD-DtMwBXAFYBUwFZAFEAXAFcAFEAWQFTAVYAVwBfADYgJP
YTA8DxwsYOAS8AgHDA4cMBwODEcMDgwwDA4MZwwOMB4XDgIAMgxADgkA8CEgHiBXAA4wHiA3MB5A
LAgcEB5ABywIHAdAHgAHXAcAHgAeEHwQHiAHDAcMB0xwFwAIAJ8McBcQF5AYEBjIDx7wBSABLD8c
AVABHG4BQAEMDhEOEQcOCgAiBw4DAAEMADIcBxwKAPAPDxdHDQ4BMAEcJw0nHgEwMQwHDjFQAQcM
BwgHDgcBCgD-Jg4IDggeBwEwAQccbgcBEAEXLF4XAQABF3wBFwEQEQcBFwEHEQcRQAEAAQcBBwGQ
ARwBHAFAtAMfDzIA-xj-KIAPG9AegE8YDj1APQJtML0wHQJtAh0gXQJdIM0wHQJNAi0wTQhdMD0C
bUBdAi1gfXBtkE2wLVCZAB8PMgD-R-8ABAQEAB8cAA4XHhcOAB4APAAa-wYICASABzAHIAcQB-AE
BxAHIAcwB4BCAB2QCAA4AAgACDAIBgCBEAgAGFAYUBgKAAQWAD84AAg3AR8PMgDl8BQQvxggDrQO
AA7UHkQ8RB4kHD8cHCQeJAxdDCQeFAwNXA0MFAgAMgw9DAoAER0CAAgKANEkDB0cHQwkHiQcPRwk
RQCf1A4ADrQOIL4QvwAfDzIA-0u3E58QUA4cDiwODA4IACMuDBAAAAgACBoAKjwuGAAiDB4KADFg
DgwiAI9wHkwOgF7wFIgAHvkPFVWABVYFcAVfEAVwBV4FcAUGPgYFcAUWHhYFcAVWBABPgFXwJUwB
Hw8yAP---------------------------------------9JQPTExfX0=
:: gfx/.info.pod
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTA0LTA0IDA3OjE5OjMzIixtb2RpZmllZD0iMjAyNC0w
NC0yNiAxNTozNjo1NCIsc3RvcmVkPSIyMDI0LTA0LTA0IDA3OjE5OjMzIl1dbHo0AAQAAAADAAAA
NC0yNyAxNTo0MTowMCIsc3RvcmVkPSIyMDI0LTA0LTA0IDA3OjE5OjMzIl1dbHo0AAQAAAADAAAA
MG5pbA==
:: map/0.map
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTA0LTA0IDA3OjE5OjMzIixtb2RpZmllZD0iMjAyNC0w
NC0yNiAxNTozNjo1NCIscmV2aXNpb249OTgwXV1sejQArAMAABVCAADwCHt7Ym1wPXVzZXJkYXRh
KCJpMTYiLDMyAwAvIjABAP_DLjEwDAAPAQDVNTU4MAEAPzQ4MAEAXi80MAEACz8xMzABAHMXNAQA
DwEANQ9QACEfM4AAbg8BALoqNDgIAQ8EAwcOIAAPAQA2BIAAHzNgAQAvMzABAE4vNDgYAA8OJAAP
AQA5DmgADwEAch4zgAEPgABgDwEA---------7-1HSIpLGhpZGRlbj1mYWxzZSxuYW1lPSJvYmpl
Y3RzIixwYW5feD0tMTQwLjgzAQABFwBpeT0tMTA1FwCSdGlsZV9oPTE2CgAQdwoAj3pvb209MX0s
hBAJDwEA----mi9hMIAA7Q8BAP--------------Sw_EEAOvZm9yZWdyb3VuZIcQ4i8zOQQAAw8B
AFFjMzIwMDA5BAAaYgwAHzOAAF0aMAwAHzMAAW0WOIwBDwQAAQ_AADYPAQAFHmOUAAgIAB8zgABZ
FzAMAA_AAD0XNQQACAEALzUwAQAIDwABUB8wgADUHzUEAAwEAQAaNQQADwABtg_AAOxqMmIwMDJj
BAAEAQAvMmMEAAQfZIAANz8zNTABAB4vM2KAAGsvMDCAAPwfMoAAO2cyODAwMjkEAB9hAAFIL2Qw
XAAOACgADiQADwEALw5YAA9cAAMvMzIkAAEPAQAvD4AABgz8CA_AASUfM4AAIwF8CBc5BAAPpAEC
DwEALwGAABc1BAAPgAARAywALzMwAQAzDuACDzAADAMcAw4BAA_QAycPiAEDDxwCEw8BAAMPgABH
DZwBD4AA3Q4BAA_AAK4FCAMPBAAkD4cQMUdzb2xpghAvNTKCEAMfMYIQMg8BAP_ECEoCLzkwAQDW
LzFhBAADDwEAVS8xYQQAAy8wMJABUycxYgQAFjkEAC8wOAQACg8BADcfOAQAIg8BADcfOAQAIg_A
ATcfOAQAIw8BADUvMTgEACMPAQA1LzE4BAAjDwEANS8xOAQAIw8BADUvMTgEACMPAQA1LzFiBAAA
BAgEH2IEAAcPAQA2HzgEACIPAQA3HzgEACIPAQA3HzgEACIPAQA3HjgEAA_CEAIbOAQADwEANR44
BAAfM6ILARs4BAAPAQA1HziAAP9sLjFieAQPgAABBBwADoAEDwEANB84BAASDwEARi8xOAQAEw8B
AEUvMTgEABMPAQBFLzE4BAATDwEARh84BAAiDwEANx84BAAiDwkhtkxiYWNrCSFOMTIuM4cQKDI2
FgAPhxAGUG09MX19
NC0yNyAxNTo0MTowMCIscmV2aXNpb249MTA2M11dbHo0AK8EAAARQgAA8Ah7e2JtcD11c2VyZGF0
YSgiaTE2IiwzMgMALyIwAQD-gy4xMAwADwEA1TU1ODABAD80ODABAF4vNDABAAs-MTMwAQBzFzQE
AA8BADUPUAAhHzOAAG4PAQC6KjQ4CAEPBAMHDiAADwEANgSAAB8zYAEALzMwAQBOLzQ4GAAPDiQA
DwEAOQ5oAA8BAHIeM4ABD4AAYA8BAP_EBLQDDhAADwEAUwxwAAcQAB82xQhQLzYwAQDsB3ABDhAA
DwEAUAxwAAwQAA9oBB0IAQAISAAPgAQaD4AAQg8BAP8XDywLJi80MNABPx8zJQQYLzQwAQDU9R0i
KSxoaWRkZW49ZmFsc2UsbmFtZT0ib2JqZWN0cyIscGFuX3g9LTE2MS44MwEAARcAaXk9LTIwORcA
knRpbGVfaD0xNgoAEHcKAI96b29tPTF9LIQQCQ8BAP---5ovYTCAAO0PAQD--------------0sP
hBADpGZvcmVncm91bmSHEFQ3MS4xNgEAEzeFECk3NBUAD4MQsi8zOQQAAw8BAFFjMzIwMDA5BAAa
YgwALzMwgABcGjAMAB8zAAFtFjiMAQ8EAAEPgAA2DwEABR5jlAAICAAfM4AAWRcwDAAPgAA9FzUE
AAgBAC81MAEACA8AAVAfMIAA1B81BAAMBAEAGjUEAA8AAbYPgADsajJiMDAyYwQABAEALzJjBAAE
H2SAADc-MzUwAQAeEzOgBi8zOQQABw_AAEkAAQAqMjAQBSowORAAHzKAAKQiMmLgAQ_AABIPAQAI
AEAHLzJhgAAfUDMzMDAyPAAXOQQAHmGkAA-gAA4AyAIWZAwAHzOAAAUeZIAAHzMoAAANpAAPgAA0
D9wCBQ_AAC4LAQAPgAAVLzAw-AgAHmGkAA_AAEkBPAEXOQQALWQwAQAPgAA2FzUEAA_AABEDLAAP
gAAVIzNlBAAfMAEAAw7gAg_MAwsEHAMMPAANNAMLBAAOAQAPiAEPLjMzoAMPHAIFDRgABwQALzAw
gAAPBFgGDQwDC6ADAZwBF2IEABtkGAATYQgABwwALzMwgAAPLjNjbAAOAQAPgABHDwEARw_AAI8m
MDCoAg8EAEEPgxARX3NvbGlkBSFXLzEwAQD-gB45DAAPuSXSH2EEAAMPAQBVLzFhBAADLzAwkAFT
JzFiBAAWOQQALzA4BAAKDwEANx84BAAiDwEANx84BAAiD4ABNx84BAAjDwEANS8xOAQAIw8BADUv
MTgEACMPAQA1LzE4BAAjDwEANS8xOAQAIw8BADUvMWIEAAAECAQfYgQABw8BADYfOAQAJA8BABUv
ZTABAAsfOAQAJA98ABUEBAAPAQAFHzgEACQXMFwADwQAAQQBAAwQAAwBAB44BAANTg0WYRwABQQA
CFwADwQAAQQBAC9lMAEACx44BAAfM6ILARs4BAAEXAAPBAAFBAEAL2UwAQALHziAAEQMBAAPAQAF
HziAAOsuMWJ4BA_AAAEEHAAJgAQfZQQAGA8BAA0fOAQAFA8BAAEvZTABAC4vMTgEABMPgAD-Ri8w
OAQAFB9lBAAgDwEAER84BAAUH2UEAB4PBSGSSmJhY2sFIQ_HECxQbT0xfX0=
:: map/.info.pod
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTA0LTA0IDA3OjE5OjMzIixtb2RpZmllZD0iMjAyNC0w
NC0yNiAxNTozNjo1NCIsc3RvcmVkPSIyMDI0LTA0LTA0IDA3OjE5OjMzIl1dbHo0AAQAAAADAAAA
NC0yNyAxNTo0MTowMCIsc3RvcmVkPSIyMDI0LTA0LTA0IDA3OjE5OjMzIl1dbHo0AAQAAAADAAAA
MG5pbA==
:: sfx/0.sfx
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTA0LTA0IDA3OjE5OjM0Iixtb2RpZmllZD0iMjAyNC0w
NC0yNiAxNTozNjo1NCIscmV2aXNpb249Nzg5XV1sejQARgEAAGYIAADwJ3B4dQADKAAAAwAED0AQ
NC0yNyAxNTo0MTowMCIscmV2aXNpb249ODUxXV1sejQARgEAAGYIAADwJ3B4dQADKAAAAwAED0AQ
Ag4AAaABIAKgDgAPEAAN8MoBAgMEBQYHAA--kAgJCgsPDA8NDw4PDxAA8AANDxEPEg8TDxQPFQ8W
DxcTAPEBDxgPGQ8aDxsPHA8dDx4PHxQA8QAgDyEPIg8jDyQPJQ8mDycUAPEAKA8pDyoPKw8sDy0P
Lg8vFADxADAPMQ8yDzMPNA81DzYPNxQA-wU4DzkPOg87DzwPPQ8_Dz8AD--w-wEA6-InWgEQBg8g
@ -86,14 +96,14 @@ L-AAMAD--4If-wEAzPEd6A9AAA1ADxcACxoIBggQAgMQBQAGAAgASRcAJggJUP--CfEX-gn8F-4J
8HArAF-_sPBwBAgA-9wf-wEAl1D-----Hw==
:: sfx/.info.pod
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTA0LTA0IDA3OjE5OjMzIixtb2RpZmllZD0iMjAyNC0w
NC0yNiAxNTozNjo1NCIsc3RvcmVkPSIyMDI0LTA0LTA0IDA3OjE5OjMzIl1dbHo0AAQAAAADAAAA
NC0yNyAxNTo0MTowMCIsc3RvcmVkPSIyMDI0LTA0LTA0IDA3OjE5OjMzIl1dbHo0AAQAAAADAAAA
MG5pbA==
:: main.lua
--[[pod_format="raw",created="2024-04-04 07:19:33",modified="2024-04-26 15:36:54",revision=1065]]
--[[pod_format="raw",created="2024-04-04 07:19:33",modified="2024-04-27 15:41:00",revision=1138]]
include("/cirnofarm/src/game.lua")
:: .info.pod
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTA0LTE2IDE5OjQyOjIyIixtb2RpZmllZD0iMjAyNC0w
NC0yNiAxNTozNjo1NCIscnVudGltZT02LHN0b3JlZD0iMjAyNC0wNC0xNiAxOTo0MDowNSIsd29y
NC0yNyAxNTo0MTowMCIscnVudGltZT02LHN0b3JlZD0iMjAyNC0wNC0xNiAxOTo0MDowNSIsd29y
a3NwYWNlcz17e2xvY2F0aW9uPSJtYWluLmx1YSMxIix3b3Jrc3BhY2VfaW5kZXg9MX0se2xvY2F0
aW9uPSJnZngvMC5nZngiLHdvcmtzcGFjZV9pbmRleD0yfSx7bG9jYXRpb249Im1hcC8wLm1hcCIs
d29ya3NwYWNlX2luZGV4PTN9LHtsb2NhdGlvbj0ic2Z4LzAuc2Z4Iix3b3Jrc3BhY2VfaW5kZXg9

561
src/error_explorer.lua Normal file
View file

@ -0,0 +1,561 @@
-- # picotron error explorer
--
-- by kira
--
-- version 0.0.4
--
-- an interactive error screen for picotron.
-- on error, shows the stack, local variables,
-- and the source code when available.
--
-- ## usage
--
-- `include` or `require` `error_explorer.lua`
-- in your program _after_ defining your `_init`,
-- `_update`, and `_draw` functions.
--
-- press `up` and `down` to move up and down on
-- the stack, press `x` or `space` to toggle font
-- size. click on tables in the variable view to
-- expand them.
--
-- ## how it works
--
-- in order to catch errors and inspect runtime
-- state, this script replaces `_init`, `_update`
-- and `_draw` functions with ones that call the
-- original ones inside a coroutine.
--
-- when there's an error, it uses lua's debug
-- library to inspect the coroutine. a copy
-- of the error is also printed to the console
-- with printh if you're running picotron from
-- the command line.
--
-- the following debug apis are used:
--
-- - `debug.getinfo`
-- - `debug.getlocal`
-- - `debug.getupvalue`
-- - `debug.traceback`
--
-- ## version history
--
-- version 0.0.4
--
-- - also catch errors in `_init`
--
-- version 0.0.3
--
-- - automatically choose the right stack frame
-- based on the error message
-- - more thoroughly protect from errors in error
-- explorer itself
--
-- version 0.0.2
--
-- - don't regenerate stack info every draw
-- - scroll stack and variables list with mousewheel
-- - click on stack to switch stack frames
-- - click on tables in variables view to expand them
-- - escape strings when printing them
--
-- version 0.0.1
--
-- - adjust colors
-- - code cleanup
-- - use `btnp` instead of `keyp`
-- - slightly more thorough `reset`
-- - don't show temporaries
--
-- version 0.0.0 (prerelease)
--
-- - initial discord beta
-- ## license
--
-- Copyright 2024 Kira Boom
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the “Software”), to
-- deal in the Software without restriction, including without limitation the
-- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-- sell copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-- DEALINGS IN THE SOFTWARE.
---- util ----------------------------------------
local function filename_of (path)
return path:match ('[^/]*$')
end
local function safe_tostring (value)
if type (value) == 'string' then
return string.format ('%q', value)
else
local success, value_string = pcall (tostring, value)
return success and value_string
or ('error during tostring: ' .. tostring (value_string))
end
end
local function get_lines (text)
local lines = {}
for line in text:gmatch ("(.-)\r?\n") do
table.insert (lines, line)
end
local last_line = text:match ('([^\n]*)$')
if last_line and last_line ~= '' then
table.insert (lines, last_line)
end
return lines
end
local function compare_keys (a, b)
local ta = type (a.key)
local tb = type (b.key)
if ta ~= tb then
return ta < tb
end
if ta == 'number' or ta == 'string' then
return a.key < b.key
else
return safe_tostring (a.key) < safe_tostring (b.key)
end
end
local function sort (t, f)
-- insertion sort
f = f or function (a, b) return a < b end
for i = 1, #t-1 do
local val = t[i+1]
local j = i
while j >= 1 and not f(t[j], val) do
t[j+1] = t[j]
j = j - 1
end
t[j+1] = val
end
end
local function approach (from, to)
return from + (to - from) * 0.25
end
local function round (value)
return math.floor (value + 0.5)
end
local function parse_message_for_location (msg)
local path, line, err = msg:match ('^([^:]+):(%d+):(.*)$')
return path, tonumber (line), err
end
---- state ---------------------------------------
local _G = _G
local error_message
local error_thread
local error_traceback
local init_done = false
local use_small_font = false
local mouse_was_clicked = false
-- stack view
local stack_frames = {}
local current_stack_index = 1
local hovered_stack_index = false
local mouse_over_stack = false
local stack_max_scroll = 0
local stack_scroll = 0
local stack_scroll_smooth = 0
-- variables view
local variables = {}
local hovered_variable = false
local variables_max_scroll = 0
local variables_scroll = 0
local variables_scroll_smooth = 0
local mouse_over_variables = false
-- source view
local source_lines = {}
---- main events ---------------------------------
local W = 480
local H = 270
local function rebuild ()
-- rebuild stack frame info
stack_frames = {}
variables = {}
source_lines = {}
variables_scroll = 0
variables_scroll_smooth = 0
for i = 0, 20 do
local info = debug.getinfo (error_thread, i)
if not info then
break
end
if info.short_src then
table.insert (stack_frames, {
filename = filename_of (info.short_src),
path = info.short_src,
line = info.currentline,
depth = i,
fn_name = (info.name or (filename_of (info.short_src) .. ':' .. tostring (info.linedefined))),
source = info.source,
})
end
end
local frame = stack_frames [current_stack_index]
if not frame then
return
end
-- rebuild variables
do
local local_index = 1
repeat
local name, value = debug.getlocal (error_thread, frame.depth, local_index)
if name then
if name ~= '(temporary)' then
table.insert (variables, {
key = name,
value = value,
})
end
local_index = local_index + 1
end
until not name
local info = debug.getinfo (error_thread, frame.depth)
if info and info.func then
local upvalue_index = 1
repeat
local name, value = debug.getupvalue (info.func, upvalue_index)
if name then
table.insert (variables, {
key = name,
value = value,
})
upvalue_index = upvalue_index + 1
end
until not name
end
end
-- rebuild source lines
local source = frame.source
if source then
if string.sub (source, 1, 1) == '@' then
local filename = string.sub (source, 2, #source)
source = fetch (filename)
end
if source and type (source) == 'string' then
source_lines = get_lines (source)
end
end
end
local function error_update ()
local last_index = current_stack_index
if btnp (5) or keyp 'space' then
use_small_font = not use_small_font
end
if btnp (2) then
current_stack_index = math.max (1, current_stack_index - 1)
stack_scroll = math.min (current_stack_index-1, stack_scroll)
end
if btnp (3) then
current_stack_index = math.min (#stack_frames, current_stack_index + 1)
stack_scroll = math.max ((current_stack_index) - (#stack_frames - stack_max_scroll), stack_scroll)
end
local _, _, click, _, wheel = mouse ()
if mouse_over_stack then
stack_scroll = math.max (0, math.min (stack_scroll - wheel * 2, stack_max_scroll))
end
stack_scroll_smooth = approach (stack_scroll_smooth, stack_scroll)
if mouse_over_variables then
variables_scroll = math.max (0, math.min (variables_scroll - wheel * 2, variables_max_scroll))
end
variables_scroll_smooth = approach (variables_scroll_smooth, variables_scroll)
click = click ~= 0
if click and not mouse_was_clicked then
if hovered_stack_index then
current_stack_index = hovered_stack_index
end
if hovered_variable and type (hovered_variable.value) == 'table' then
if hovered_variable.contents then
hovered_variable.contents = nil
else
local contents = {}
hovered_variable.contents = contents
for k,v in pairs (hovered_variable.value) do
table.insert (contents, {
key = k,
value = v,
})
end
sort (contents, compare_keys)
end
end
end
mouse_was_clicked = click
if current_stack_index ~= last_index then
rebuild()
end
end
local function error_draw ()
local prefix = use_small_font and '\014' or ''
local font_height = (use_small_font and 6 or 11)
local mx, my = mouse()
local over_section = false
local x0, y0, x, y
local function go_to (new_x, new_y)
x0, y0 = new_x, new_y
x, y = x0, y0
end
local function section (sx, sy, sw, sh)
over_section =
mx >= sx and mx < sx + sw and
my >= sy and my < sy + sh
clip (sx, sy, sw, sh)
go_to(sx+2, sy+2)
end
local function print_horizontal (text, color)
local new_x, _new_y = print (prefix .. text, x, y, color)
x = new_x
end
local function print_line (text, color)
local _new_x, new_y = print (prefix .. text, x, y, color)
x = x0
y = new_y
end
-- draw setup
cls (0)
-- lighter dark gray for readability
pal (5, 0xff707070, 2)
color (5)
-- error message
section (0, 0, W, H/2)
mouse_over_stack = over_section
local loc_path, loc_line, err = parse_message_for_location (error_message)
if loc_path then
print_line ('error at ' .. loc_path .. ':' .. loc_line .. ':', 6)
print_line (' ' .. err, 8)
else
print_line ('error:', 6)
print_line (' ' .. error_message, 8)
end
-- stack frames
print_line ('stack:', 6)
section (0, y, W, H/2-y)
local stack_top_y = y
y = y - round (stack_scroll_smooth * font_height)
local last_hovered_stack_index = hovered_stack_index
hovered_stack_index = false
for i, frame in ipairs (stack_frames) do
color (last_hovered_stack_index == i and 7 or
current_stack_index == i and 6 or 5)
local y_before = y
print_line (string.format (' %s:%d in function %s',
frame.filename, frame.line, frame.fn_name ))
if over_section then
if my >= y_before and my < y then
hovered_stack_index = i
end
end
end
stack_max_scroll = #stack_frames - (H/2 - stack_top_y) / font_height
local frame = stack_frames [current_stack_index]
if not frame then
return
end
-- variables
section (0, H/2, W/2, H/2)
mouse_over_variables = over_section
print_line ('variables:', 6)
section (0, y, W/2, H-y)
local variables_top_y = y
y = y - round (variables_scroll_smooth * font_height)
local last_hovered_variable = hovered_variable
hovered_variable = false
local variable_count = 0
local function draw_variable (variable, indent)
variable_count = variable_count + 1
local hovered = variable == last_hovered_variable
local y_before = y
print_horizontal (indent .. variable.key, hovered and 7 or 6)
print_horizontal (': ', variable == last_hovered_variable and 7 or 5)
print_line (safe_tostring(variable.value))
if over_section and type (variable.value) == 'table' then
if mx >= 0 and mx < W/2 and my >= y_before and my < y then
hovered_variable = variable
end
end
if variable.contents then
for _, v in ipairs (variable.contents) do
draw_variable (v, indent .. ' ')
end
end
end
for _, variable in ipairs (variables) do
draw_variable (variable, ' ')
end
variables_max_scroll = variable_count - (H - variables_top_y) / font_height
-- source
section (W/2, H/2, W/2, H/2)
print_line ('source of ' .. frame.path .. ':', 6)
local context = use_small_font and 10 or 5
local i_min = math.max (1, frame.line - context)
local i_max = math.min (#source_lines, frame.line + context)
for i = i_min, i_max do
color (i == frame.line and 6 or 5)
print_horizontal (string.format ('%4d ', i))
print_line (source_lines [i])
end
clip ()
end
---- taking over during errors -------------------
local function reset ()
-- based on reset() from /system/lib/head.lua
-- see that fn for info
note ()
-- picotron segfaults if we call clip() during init
if init_done then
clip ()
end
camera ()
pal ()
palt ()
memset (0x551f, 0, 9)
poke (0x5508, 0x3f)
poke (0x5509, 0x3f)
poke (0x550a, 0x3f)
poke (0x550b, 0x00)
color (6)
fillp ()
poke (0x5f56, 0x40)
poke (0x5f57, 0x56)
poke (0x4000, get (fetch"/system/fonts/lil.font"))
poke (0x5600, get (fetch"/system/fonts/p8.font"))
poke (0x5606, peek (0x5600) * 4)
poke (0x5605, 0x2)
poke (0x5f28, 64)
poke (0x5f29, 64)
end
local function on_error (thread, message)
-- do this first in case we hit another error
error_traceback = debug.traceback (thread, message)
printh (error_traceback)
error_thread = thread
error_message = tostring (message)
reset ()
rebuild ()
-- jump to the proper stack frame if we can
local loc_path, loc_line = parse_message_for_location (error_message)
for i, frame in ipairs (stack_frames) do
if frame.path == loc_path and frame.line == loc_line then
current_stack_index = i
rebuild ()
break
end
end
end
---- install main events that catch errors -------
local user_init = rawget (_G, '_init')
local user_update = rawget (_G, '_update')
local user_draw = rawget (_G, '_draw')
assert (user_draw and user_update,
'please include install_error_handler after defining both _update and _draw')
local function call_error_event (fn, ...)
-- if there's an error in our update or draw, throw the
-- original error as well as the new error
local success, err = pcall (fn, ...)
if not success then
error (error_traceback .. '\n\nerror during error handling: ' .. tostring (err))
end
end
local function call_protected (fn)
-- need to use coresume etc. and not coroutine.resume etc.
-- for picotron compatibility
local thread = cocreate (fn)
local success, message = coresume(thread)
if costatus (thread) ~= 'dead' then
call_error_event (on_error, thread, 'setup_error_display.lua: _update and _draw shouldn\'t yield')
end
if not success then
call_error_event (on_error, thread, message)
end
end
if user_init then
function _init ()
call_protected (user_init)
init_done = true
end
else
init_done = true
end
function _update ()
if error_thread then
call_error_event (error_update)
else
call_protected (user_update)
end
end
function _draw ()
if error_thread then
call_error_event (error_draw)
else
call_protected (user_draw)
end
end

View file

@ -108,18 +108,30 @@ particles = {}
function _draw()
cls(0)
camera(cirnoInstance.x - 240, cirnoInstance.y - 135)
foreach(LAYERS, render_layer)
mouse_debug.draw(4, tile_width, tile_height)
local mx,my = mouse()
camera()
mouse_debug.draw(mx,my,4, tile_width, tile_height)
-- Draw UI
draw_ui()
weapons_manager.debug_draw()
end
function draw_ui()
print(string.format("Actors: %d", count(actors)),0,32+8)
print(string.format("%.4f %dfps",stat(1),stat(7)),2,16,5)
end
include(make_path("error_explorer") .. ".lua")
function spawn_objects()
local width = 32
@ -149,7 +161,6 @@ function spawn_objects()
end
end
function get_actor_from_sprite(sprite)

View file

@ -2,8 +2,8 @@
local map_manager = require(make_path("map"))
M = {}
function debug_mouse(layers_count, tile_width, tile_height)
local mx,my = mouse()
function debug_mouse(mx,my,layers_count, tile_width, tile_height)
--local mx,my = mouse()
local x_offset = 5
local y_offset = 5
@ -36,8 +36,8 @@ function debug_mouse(layers_count, tile_width, tile_height)
end
end
function M.draw(layers_count, tile_width, tile_height)
return debug_mouse(layers_count, tile_width, tile_height)
function M.draw(mx,my,layers_count, tile_width, tile_height)
return debug_mouse(mx,my,layers_count, tile_width, tile_height)
end
return M