Log In  



Just another mad coder.

We�re all mad. I�m mad. You�re mad, you must be - or you wouldn't have come here.

Cart [#59148#] | Code | 2018-11-18 | No License | Embed

This is much along the same lines as Gembit's remarkable game, "Eternal Tower" HERE:


and Polyphonic's random map generator HERE:


I've always wanted to write the code to a cavern maker where literally each wall is randomly placed and then checked to ensure that the areas around it can be reached.

And now you can ! Guarantees that all points can be reached despite the placement of the walls.

Change DEBUG in beginning to:
0 = Only draw completion
1 = Show the walls being drawn (default)
2 = Show the scanning process for each wall

Running into a bug, let me leave the stairs off for now. Should still run fine.
Got it fixed, should be alright now.

The randomly placed stairs leading up and down are considered FLOOR. That is, if you touch them, you can decide to take them or not. If I try to treat them as walls, they can get stuck in other walls.

Now my question is, can someone optimize this code so it runs considerably faster ?

Thanks, and enjoy !

P#59134 2018-11-18 12:37 ( Edited 2018-11-18 19:19)

Cart [#58876#] | Code | 2018-11-08 | No License | Embed

UPDATED 11-08-18 (11:45am)

Years ago when I started writing business software for the IBM, I rarely ever used the mouse, thinking it to be slow and cumbersome. And as such, I would often write a little sparkle routine should you ever press down the button and drag it across the screen. And back then screens were 640x480 so the glitter was really quite pretty at its tiny size.

I never actually sat down just to write this glitter method all by itself, until now.

The code I wrote years ago would sparkle where the mouse is when the button was pressed, then fade, showing the business app beneath. This particular version is actually one you can draw pictures in with. Young kids and those young at heart might really enjoy doing this.

Use the mouse, press the LEFT button to draw a "glitterific" line or plot.

To test it, try writing the first 4-letters of your name, or maybe a symbol like a heart or diamond.

Press (X) to animate the glitter.
Hold (O) to slowly erase the glitter so you can start a new picture.

Change DEBUG=0 to turn off the number counters at the top.

If you like, post some of your own glitterific pictures to show the world.

Enjoy !

Below is original version:

Cart [#58874#] | Code | 2018-11-08 | No License | Embed

P#58875 2018-11-08 12:07 ( Edited 2018-11-11 03:31)

Cart [#58730#] | Code | 2018-11-03 | No License | Embed

Scrub and me were just messing around, taking a bit of a break from Paint. He thought it would be interesting for us to write a topview Minecraft in Pico. I took it to mean it would be on a dot level and wrote some code to randomly create colors on the screen, bricks to build with.

But when you take out the colors and mirror the screen, you get a very nice Rorschach Test image.


NOTE: Every test picture has exactly 1001 pixels, no more, no less ! (or 2002 if you count the mirror).

What do you see ?

Post some of your favorites if you like and tell us what you think it is !

P#58731 2018-11-03 17:02 ( Edited 2018-11-05 17:44)

Because 7 ate 9.

No, seriously, why is color #6 so close to color #7 ?

I mean, if you look at the decimal values for the three colors of 5, 6, and 7, you have:

N .. Red . Grn . Blu
05 . 095   087   079
06 . 194   195   199
07 . 255   255   255

You can calculate what color #6 should be based on taking each of the color guns and subtracting the difference from 7 and 5 adding the division by 2.

You would get:

N .. Red . Grn . Blu
05 . 095   087   079
06 . 175   171   167
07 . 255   255   255

So why the disparity ? And why are "gray" not matched all across the board ? If you median them out, (adding the 3 together and dividing by 3), you would have:

N .. Red . Grn . Blu
05 . 087   087   087
06 . 171   171   171
07 . 255   255   255

So why the current color disparity between grays ?

P#58722 2018-11-03 15:56 ( Edited 2018-11-04 20:09)

Very simple request really.

Wanted to know if there was a way to get the white noise in PICO to sound as deep as this.


And if not, can future PICO please ?

Also add optional instruments, use MIDI, which has 127.

So it should be possible to get some music like THIS, with the wind effect:


I know PICO is limited, but that music you are hearing now is from SNES which came out in 1990 so that's 28-years ago. Surely we can achieve at least the same level as SNES without affecting current code, SFX, or MUSIC.

P#58420 2018-10-25 16:08 ( Edited 2018-10-26 04:29)


I recently came across this link trying to find a particular cart from PICO.

It's interesting in the fact it shows that in other programming languages capable of directly accessing the internet, you can load up PICO source code and elements.


-- "fireflies" (10-05-18) ----- -- written by dw817 ----------- -- \138 standard pico-8 license - -- big props to remagamer for - -- human movement method ------ s=16 -- ^ speed of rotation -- lower = faster -- higher = slower n=128 -- ^ number of fireflies ring,ok,z,t,a,x,y=0,0,0,{},{},{},{} for i=0,n-1 do t[i]=0 x[i]=rnd()*128 y[i]=rnd()*128 a[i]=rnd()*360 end cls() repeat cls() if ring==1 then circ(64,64,8,2) circ(64,64,16) circ(64,64,24) end for i=0,n-1 do c=1 if t[i]>0 then t[i]-=1 c=10 if t[i]<4 then c=4 elseif t[i]<8 then c=9 end end pset(x[i],y[i],c) a[i]+=(rnd()*2)-1 h=x[i] v=y[i] x[i]+=cos(a[i]/s) y[i]+=sin(a[i]/s) ok=0 if pget(x[i],y[i])>0 and (abs(flr(x[i])-flr(h))>=1 or abs(flr(y[i])-flr(v))>=1) then ok=1 end if x[i]<0 or x[i]>127 or y[i]<0 or y[i]>127 or ok==1 then if (ok==0) a[i]=rnd()*360 x[i]=h y[i]=v if (ok==1) t[i]=16 end if (x[i]<0) x[i]=0 if (x[i]>127) x[i]=127 if (y[i]<0) y[i]=0 if (y[i]>127) y[i]=127 end if (btnp(5)) ring=1-ring if (btn(4)==false) flip() until forever 

Making a change to the address you can use:


to return:

[[email protected]]89504e470d0a1a0a0000000d49484452000000a0000000cd08060000003fa57ba90000120a494441547801ed9d4f6c24e959c69fe7fd2ac8dca2c84891629010bd1bc30e5987dd830fa3b04873e0102d3de1b2121634c8c01cf6c809bc238b78034239ce6144ace0283ee4040e9b0387390cab1ce61016332cbb4eb62321b044243cca268ac44ae9fa5e18be2a4fb95ddd5ddd5dd555d5fd3e92dd55dddfdff7fdbdcf7be5eeee1da43a3c3a1a5cbe2c990810240040557559ef39eaee24c31300855e8d011d9cc68c8185c465b7d78bd2e7cb87c3a3a3c16e6fa7920d85a40715ea9377a1872a92183880319d42e32aef5d0b7404a894cbbb5f7e4fa1aad705ddbfc8dd2b894f7a7f2144a1d084b53ffcbd3ff898aa570180c3af7d7df0c7bd9d501e15c8ab5e4980577f091f00c44065c19750fa101179f625201947ac98fa6bf005170ef02deafe4edcb3fb87102cf4fede7baf5e3dbcfadddfddc157fee6ab3f0500f7cee37707bbbddfa9cc1e84a42601c8dabe00d4c504e07adbd5c5d9617a7f38b8c400eabfff02db41eefd9dc3cb2ffe2abff2b5afdf7590e8eeaf6d7d6669034080a0800e4e444484a2221acabffa535cee9081af8efb0fef484a7df7d7f0f2cee963540ee06515648220146af5c57fad11a40aed7f51080408842493ff20167afbfcbb2eeefe690c52a5dfbd73fa1844b436d8eded2c361e25e9fee10f7067f793ad3cbb09383c3a86b4f5f0f75f3e043e3cc4fd3baf59265bac5602787fff21f0da0fc24be706ee7ffc9665d2005c9ceeecbf82e8c3df0400fce5fe43dcf9f08165725501bcffe5832b7fa3be1bfe7edcfc227bec1ebc8c1b0fd6f1ef3f69277c9fbff5ca549fd979e95fde7bf6bb51efe3d6cbfb2def7ddcbc850198c270e74ff6ae3a54e63d7dce8ecdfb6ea2eb65e6a5baf90f7756d235bef5e0e1b5e7f4f3f3b75ec1b71e3cbcf65e74bd2c6cd3ae338ba2321619e55c65809d7555d355f79c776e16ae590b615e072c05c0220e36ef7ac3aeb98c204d7a1fe758b3b8679920d5d2828b38e23030f7bf7c90fbdd2490f3e699eb3dfb3efd4c61ca8e9fd43e87c7cebace2c22a2b5c16e6fc7fa9a69e13a3c3aaec6014da65a5bb0c964009a0c4093c900341980269301686a64fea379261f1e1dcf7b7d81875fd9e40b50f3fd4bd97bb7b733dbed654e00f194c2c147b50760e6e48713d4758689fb6e6c76717e7652e5ede7bf7fb436ebed3d7c1900ce77fdba00a80fbbabb71f7b924ae0abf7f6e5b6e0a65cbf32a758f2e4374157abb1a56a0d7ca6e504d064009a4c06a0694501dcd8ecd676813af7363504c0f3b393da2e50e7de266bc1e6b606e0eac8dcd600342d5917683580d612dbdf055a0d60d52d7170d131e2ac05d7a768bd6f413000add51b802b9efc49adde005d62002725dfce68005a9b33b51f407391f6a84cb3687c0b36354f659ac54a03686ddf5a706b2ad960350097a6ed980cc0c669551dd600348735004dabeb9a06a0b9a601685a5d19802603304f1b9b5dcbce0ae4a4b1009e9f9d58c61b06561539b116bcc2eed3846237005bd2f2e7856463b3dbc83b1a801312dc7430276970d1b9bc5f9d4e6700b6b03d95a168bddfe8f3198026037092dade06edce2d0770916d7070d169c45a6d6ffdd6826754b4de2f0db269d75a45b73500a74cc45ea77be56f7ffbc6b5ef46413a38b20e73ad480dbbf1891806eaa03f3959c373a2f5130c2e3a231d7163b3bb322dd7002ca814a22c70838b0e0ed627cf3de83f036e70d101b6bbd8df06807c005715bec601d80427c803ef9993e503941bd8646cf80ccfe3d636001bda02170d5f9570a46b57bd8f01b804edb64a1df44fcc0d0dc0c5b89eb9e17889c1576ff2b36e58b5363617b3cf52015855d0e6816fafd31df9d76408cfcf9ae7b48d6fc155046d16f8b2808c9b5b74dc280857ad1d3702c08dcdee58d026fd5e759b9e06a6ecb869e7aea21ad18227c155267cd3b84c3a765680d2b945dbeba25ab101b820579d15bebd4eb7d4769882350eaec1456725215c5a006771cdc1d1fcae37ab1b46ebfd5c200dc025d16847230121e018fd3e987d07cb7d1f3ce9141a7fd0ff7bee6fbf58787c9bdfa58a0d3636bfb0d00bcdb7dff42d7a5645eb7dec3f7ab7708b1d76c5456b63b3d839e71111ad0d767b3b334d3e3c3a06061fb5d8fdd276f71cf6b75f980abe3c88a69d3f697cd505311a0a400b57d51ae6e1279af7b0832320ea3528203339d307d8ebbc30157879608cfbad4df1a872ed61c9dcc9eb858054a9aa0352d469f63a5dec3f7a77e4d883fe090efa2778a3408b3de89f146ec575025256c18ce4a76d155356407e3aa573a7901eac4f1efbc504ae3ada67db1c756e075c74c594e16e9a3877d90e5996c30dafd1f60e537a0bce06646373be20d71d90329c6a56408a42ba4c2db71400b301393f6b7e9b99c7418a003a0a90325cb0e91d66de8269440b4e0352859b2e83830c2e3a8d8b4759b92a04e0a22aa60d6e5a341ef340330c48b4de6f5c0cb2b99a878f42008eab98aa5c6b9efd9ad0629a04cd3cf12812ef791c75ee163c8b6bcd139022fb150d48ea5265b7b845c6a3ea965b7557ca05b0c9012953a94b8d73ab83fe09dee8cce6f27b9d2e0efae515cc32386a210057292007fd13ec4d00acaa78140574991cb5f4165c7640363627bbcdf098710129025819904e0357d178cc0a689b0c449a5631e76793035e644cd905330d8493c059e5969b0be0aa076418ae51f148c78d0231fdad886bed75bad87ff4eecab5dc6145550152e5a1eb2c9814ae3c08c7b5dcbc3347ebfdd6c7635e3e2a01b06901d97ff42eb03dda999871b722ee350eb622f128b2cf346769b381c82ab4dc494e930664b81557a132c06a73cb1d562900b621208b80abac784c827411806c6c9617ab71f12805c0a6b5dc790292823a0fac79f148d72cea7e838bcec280ca8bc7f95979ed7f1c1f8d6cc155396a0ad7a48239e89f94ea98297845e04bc746ebfd52e3310ea83a0d642600dbd072cb68c545dd70381ea97b4deb7aa3c62e53871956b42a2d77f8cc838bce15971907610ac7f07779f1d8eb74b1bf0dec756efc3fc0838b0e0ed69b1f8fba0c642600db1c9000de09b0dd053019c03ce8c639e2309c45201f1c01fb07cfdcaf498054ad42002e53405220d2f65ab43d66f566ffa4d43367e15b960e5354b2ac2db7a8ab8d73b345c463d622a8221e7518482100ab0c881381c0d149721402145e8999b8f01a3ec33881801090049d80607817000c6f74ee722c20109164f3e47b471cf4dfc2def35dec75ba617d02100711f76caf2bfb8ffa249c93301d2e9c894c7646388f246f4e70f7b9dbd8eb7c016ff64f207080b8646f81730444e81ce19c8373929c18089710d039fcc266177061dd70ad3416e1d67400497cea85df06e5d99d91dc8d127e877397e763f20c48b2b70392bb10c93c87b08fb8e4397c2f40b28f3ccb89309c0b2e396b9a9b242721692160ce09909c49b29393c051088a4b929f594cc2e6976310024f86032501097700a1091c0e0eb17a78f11aab0fdc69323109321da07148a0c6a1d6280e9a569e10508250a853d05f260a500db771e14bef01a880128740c50220e69bdf7f0b7fd17f0b7ffa8bb74115801e4a40e0c3be209c23bc0fb1510f100eea15ce11f4212180429cc0c387b32649f3e188501080e7de2fbdca2f7eff9bf8f347ff0a08e19d021a930a6c3cff2abd2695a8ca38f6886385bf84009e20443dfef37b6f815e20509002f7f4bab1870801a790242efff5fedf82eae1e0e06381830742b94255e0d4834e412a0471029f47ecc3fe88158ae00a610c436ca1496e3c400f0f017c0c4ac89582504f48ac617d0f9002814063c2390fc728bafbd28b3720d4b0a6847a85864b1102510d57a4423da149de4f1f3f06e28153818a085421001502a8868aa32a2002aac7a7366fe3c71767a1a234864a8ab284bd1d4105200a2aa0a2903814ac0a833d09f8f3bf7c1b3fba788f1481f830c753012f203438490ab22654bbf01b1da10c49f35420a405108fb79f7c0f7ff6fc6dfcc6273e8d874fde0fc5260a1fd36908089c10eae194aa40700baf4a271eb1170ae854a84e1940a49049ddbcf1fc6d7cee13bfc22ff5ff4e4581fdbffa1050a508a9a19cf8e38b3315218401609150cc1e4a118110203de1010f8113450c155505d5c153c29c18f01a0c57e900afc1ad54e999ccf370705e85021f834a30ec19ee020dc10c700aa03e89af40090a05e2226c7df633149fc44a1c8098a2843aa588822a60a8687892aa3141e09f4fff0d0e8ceebef4d28bf09e4ccb5b54a050f2a9ab28a809f554813a52c4433df94fa7ff42f1de8b0a6221482a9380a98471e159a014fee4c97743c0c1509d4ae85397550f264157a820d432a89e028738cd9028e81d7ef4dfef539c9210f55406ef05418122244dd3569c38327c001b24e03d050429500d15cbe0fd78fbc97b78fb871fe08de76ee3d73ffe3c1e3ef92e097809870d2d5e144207f11e148588426381b8a7c9f14a157851064b00dee8fc163ef7732ff04b1f9ce01f7ff81e152448121e1421e9553ca008edf6e993aa845c7b454c45da3934244a958ea21e14405542fb241072037a2ae902d40a0a3574271021ceb14041150a944a511532f412847428a8a013aa0ac50777a7aa7828844e112be17e062f7df6069f16b557ff34ba424f0805e2155e41384d8000143e38a90a4f1f9ffe5f87f9d8cfc67fd4db510ae0bd50435054a0f000d5073791c4fe3c058eaa0af0afbf7a0cf1ff0302eabd5044559fd2e095a468ac4a092e0c893d54427ba3863625082eb9f1e957f91fef7f33445b0171c1ece17d58404180ea95c1019236ebd3b60b2534341c1fda625889319898a9facbc200bd0fc6180a8b0a55f50154d2d313aa1e185c74b0bf7d23e9e94107fd932bef79daeb74afcd195c7410adf727ce9d551b9b5d9c9f4d3e5be96b466bd8ededccb4fee1d13188686d30cf02187cb4d0a0d499ac3c20f35404d2a6dfb5b0e60430aaf2f24d81ef1bdd97f1dac977e63e5770b0d12e56b5cbb53907a3248d3edd14553e4e59f8ca5efb3aa0a69503b0ca2a6fba8394594006a0c95ab055aa6925016c7babb322b3166cedd00034990c406b8706a0b5439301680eda82331b802be4a045cebc68480d4053ad8565009aac059b0cc0a5d5c66637f77955d4f43bd702e02283727e7692fbbc2ab034fdceb500584650160171de1e55eedb7458ac052f3859797bac222406600b5a9dc900b45667009a5645dfe8bedc0c00ab6e67d62e17af22317fede43bcd00b0ea7666ed72f15a64ccad059b6a55a5002e7bfb5cf6fbb51ec0656f9fcb7e3f6bc12603d0643200276863b36be73300ebd3f9d9899dcf00345731ad10806d7795aa0ba82d05ba142dd80aa8bd056a009a0c4093016832e56a63b36b009aead3f9d98901685a5e45f3afb0665134d503e06e6fc72268b2166c32004d2603d064009a4c06a0c90034990c40930168321980a6e62a9a67f2e9e9a945d084adad2d734093b56093c90034b54b51590b3dfaf6036cdfbc75e5335559efdb376f5dd96fdcf8ec98e17365d7c9bbc3f0dcbcfdf2e64e3a4fdef871eb8f3bab3960016ddfbc7519c0e1cfbcc464c7e7bd0f8fcd5b6f38794513389cecbc7993d69a749f496be5cdcf82690e5820f8c32e352e6979ae36cdfc22eb8d2a84321c7f1298c30e5c74fc2cfbcffbde7a008b56795e858f8263dac0e43958550e52d40d875b6d9178ccb2ffbcef4b09605ec58e73b549c9ca7394ec7a79bf170df470318c5bbf882b151d3b6efd693b401b45446b83dddece4c934f4f4f973a38a662dadada9a69dee1d131c4c267aa5306a0a95645652df4e8db0fb07df3d695cf5465be6fdfbc3572ffe1f1d9cf51e3d3df8a9e3f3b3efbbba9810e984d4cfa5cf4337d1e7ecf267edc7e45cf5774bde1b587cf66aad901c7b9e2a2e60f8f1f0757d1f5ca985b654728eb7d29001c4ed8b81638ad834ee36859779a06a251e72fe3ec4d7f5f4a07cc4bee3440a673a61d5f14bc4963f2d69bd7d54d5745446b83dddece4c934f4f4f2d82266c6d6dcd34eff0e81862e133d52903d064009a0c4093c90034198026d3421595b5d0ebafbf7ef97cefdebd6befd931a3dec7ad376ecfbcfdca7acfee3d6e3f53031c309b88f4390bdbbd7bf7aebd175d2f0fbeec7a79e3c79da7e8ef2968a3f633f81a0460d61566999bfecdbadef0f84990172982aaee6baac801674d683a779ca34de3c079ad326ffc3c909bfb350cc0bc44a59f69b2871d6e92434d82a72c171a3eef2847cd736dd3ec22a2b5c16e6f67a6c9a7a7a7164113b6b6b6669a7778745c9d039a4cb5b66093a988a23aacd7643a3c3ac66eaf1799039a6a83cf5ab0a956f80c4053adf01980a65ae133004db5c267009a6a850f0064b7d78b0e8f8e2d52a685c377e98006a1a90ef800e0724080f06860a15b2d1180264fa442e0186b1cbe9a4345e07baaff053ada786f88d003e500000010744558744c6f6465504e47003230313130323231e359b6c10000000049454e44ae426082[/[email protected]]

Changed cart to [email protected] so it wouldn't convert.

In any case, using these addresses, it should be possible to develop engines outside of PICO to access externally stored carts directly.

What do you think ?

P#58065 2018-10-17 21:52 ( Edited 2018-10-18 01:52)

Cart [#58068#] | Code | 2018-10-18 | No License | Embed


-- written (10-15-18) ---------
-- time to code: 2-hours ------

-- what's new ?? --------------
-- 10-17-18
-- + tricky, got the color of
--   the board to change only
--   if truly achieving 1000
--   pts. can't decrease score
--   to flip it again.
-- + changed the "collision"
--   check to be right ahead of
--   the helicopter instead of
--   below or above - more
--   margin to wiggle in.
-- + fixed the "impossible"
--   corridors. should always
--   be able to fit between no
--   matter how high the level.
-- + added a launch pad for the
--   helicopter to take off
--   from.

-- 10-16-18
-- + must earn 1000 points for
--   bonus color + corridor
--   reset.
-- + added horizontal level
--   try to keep in center for
--   stability in flight.
-- + added descend ❎ key
--   costs 10-points each
--   frame.

-- 10-15-18
-- + scaled down collision
--   check is now in place.

I'm going to make some updates and upgrades to this game and also make additions to my "BOMBER" game found HERE:


What with all the FLAPPER and FLAPPY clones floating around, thought I would bring back a good old QBasic game I wrote years ago based on a DOS machine-language one I found called "Helicopter."

This gravity game is considerably more forgiving than really any other single-key gravity games I've seen for PICO.

Run. Wait a moment. Helicopter's engines are fired up, you are auto put in hover mode for a second. You get the audio signal from your onboard computer - and you are ready for flight ! Press "Z" to adjust your altitude.

Unlike other FLAPPY games where you only control the vertical acceleration, this one also controls the horizontal. You tilt forward slightly when accelerating. Remember this so when you start to fall backwards you can compensate and not rush your helicopter too far forward where you can't see the cavern walls.

If you touch the ceiling, your helicopter is damaged and while your score is still increasing, you start to take a nose dive to the ground, eventually hitting, ending your helicopter run.

Press (Z) to start a new game.

As for the graphics of the helicopter itself, Scrub was working with me on this. He sent some of his samples before I finally settled on drawing my own.




We will be working on a bigger project later, once I finish the PAINT program I'm working on. But I did want to get this out to show its entirely possible to have a type of FLAPPY game where both gravity and acceleration are both very smooth.

High-Score is maintained and saved to the board so you can play again later and try to beat your last score, even if you shut down the game completely and load it up again later. An audio signal is also given if you beat your last score.

How high a score can you get ?

P#57988 2018-10-15 16:57 ( Edited 2018-11-02 04:13)

Cart [#57748#] | Code | 2018-10-09 | No License | Embed

Alright. Sometimes to improve on something you have to redo the whole thing from scratch. That's what I did here and with workable results.

Now I know PICO is capable of more keystrokes than the simple Left, Right, Up, Down, (O), and (X).

But for purists who don't want to dabble with 2- or 3-player controls, there is this.

It's very good for what it does. It can read keystrokes, and by that I mean layered. You can be pressing 3-buttons down at a time and it will still recognize a unique 4th. It's that powerful. Let's go over it.

You have one string to get things going called, "KEYTYPE." It's a string and contains 6-characters which tell the state of reading for the keys in this order [Left, Right, Up, Down, (O), and (X). I.E:


You have an additional global variable called KEYTIME. I suggest you leave it at 8 as this is a good number for delays and the delay before showing extended keystrokes.

Each of the 6-characters can be the following.

-- "o" ... off
-- "a" ... arcade
-- "i" ... input mode
-- "m" ... measured
-- "s" ... single key only
-- "r" ... release only
-- "x" ... release+extended
  • "O" The first is OFF, meaning it will not be read or registered at all.

  • "A" The next is arcade. The simplest mode to understand. If you're pressing it at any time it registers immediately, much like BTN().

It's also important to realize that while it uses the global string KEY, the keys you are pressing can be layered. That is, you can press all six keys down at the same time and get back "LRUDAB." And to check to see if any of these keys (or more) are pressed, you use the function KEYIN() as so.

if (keyin("l")) x-=1
if (keyin("r")) x+=1
if (keyin("u")) y-=1
if (keyin("d")) y+=1

So with this, it is indeed possible to move diagonally by holding down two keys simulataneously.

  • "I" The next is a bit more complex. It's designed for inputting data. When you hit this key, it registers once, waits, then registers again, waits, then does a repeat max speed like BTN().

  • "M" This one is measured. That is it is a bit slower than BTN() but consistent. It's useful if you are working with something that has a small scope, say 16 or so elements across. You don't want the slowness of INPUT or BTNP(), but you also don't want the total speed of BTN(). This is between that.

  • "S" Single key is just that. You hit it, it registers once and will not register again until you release the button and hit it again. Useful for places where that single keystroke can cause a problem if more than one was sent at a time.

  • "R" Release only. With this the key is not registered until you RELEASE your finger from the key. It also does not register at all if you hold it down for any appreciable time as a safety measure. You must TAP to get it to work properly.

  • "X" Extended entry. This is just like "R" but now if you hold down that button you get an extended keystroke. These are listed in the table below:
-- "l" left
-- "r" right
-- "u" up
-- "d" down
-- "a" 🅾️
-- "b" ❎
-- "w" held left
-- "e" held right
-- "n" held up
-- "s" held down
-- "o" held 🅾️
-- "x" held ❎
-- "h" held left + right
-- "v" held up + down
-- "+" held 🅾️ + ❎

Only with "X" mode as one of the characters in KEYTYPE can you get the special "W" "E" "N" "S" and "O" and "X" strokes. And to get this keystroke you must hold the key down for a short time.

If you release the held key that created the special stroke, it is sent again. This makes it useful to have a menu that stays up as long as the key is held and can close again once you release the key.

Three new special strokes are also available for ALL modes except Arcade. That is if you hold the left and right key. The up and down key. And the (O) and (X) key. They each return "H" "V" and "+"

And they don't register immediately so as to not be activated in a misfire. You must hold these two keys down for a short time in order for them to register. Any time "H" "V" or "+" is registered, the routine is set for safety to ignore any other keystrokes until all keys are released.

And that's it ! If you set all six keys to "X" then you are capable of having a unique 15-keystrokes read from the default 6-keys.

If you have any questions, please let me know.

Hope This Helps !

P#57749 2018-10-09 14:26 ( Edited 2018-10-13 15:36)

No it's not.

Have you ever wondered what kind of clock Lexaloffle is using ?

It's been 8-hours since my last post yet I can still bring up the forum and see posts that say to the side my alias and, "Just now."

What gives ?

P#57609 2018-10-06 10:10 ( Edited 2018-10-06 14:14)

Cart [#57568#] | Code | 2018-10-05 | No License | Embed

Years ago I was with my Dad and the MENSA group watching fireworks. There were people all around, it was busy busy, smells of gunpowder and good food were all around.

Everyone was talking noisily and you can hear car radios playing as some sat on top of their vehicle to get a better look.

Right then though, I worried about something. Strange that I would with all the good things and fun around me.

I went to my sister who was sitting on the grass watching the sky.

"What is it ?" she said.

"Where are all the fireflies ?" I asked her.

"Fireflies ?" She looked up and around. "There's no fireflies here. There's no firework called a 'firefly' that I know of."

I pressed the issue, "No, I don't see any fireflies - at all - anymore. Where have they gone ? Are they all in the arctic now ?"

She smiled, "No, you won't have to travel that far to find them." She took a sip of her soda. Looked around, then said, "Come on. I'll show you some."

With that she took a direction completely away from all the activity. Then she ducked into several bushes and kept on. I was afraid we would get lost but I followed her anyways. The bushes were getting thicker and more tangled when suddenly ...

"We're here." she whispered.

"What ?"

She repeated, "Right here, dummy. Take a look."

Somehow, I don't know how I couldn't even hear the fireworks or noise or anything. Only a few crickets chirping. We were in an opening in a huge bush, enough room for only two people, her and me.

And there they were.


All flitting about and each other, lighting up if they bumped into one another.

For a long time I couldn't say anything. I looked to her and she grinned.

Finally she spoke, "Cities have just about driven them out, but you can still find them - if you can find still and quiet places like these. I know this territory and I've been here before."

We watched a few more minutes. She stood up, "Ready to go ?"

I nodded, "Yeah. And - thanks."

"Sure thing." she smiled, and we went back to where Dad and MENSA was to watch more fireworks.

Now these fireflies have a little bonus. They have what I call the, "Friendship Ring." You can turn it on and off with the (X) key. They love the ring and will stay on it, lighting up to show their interest.

To speed up the fireflies, press the (O) key.

Open source to change rotation speed of fireflies and how many there are.

Big props and thanks go to "Remagamer" who with his code showed me a unique way to move an object, by direction and rotation. You can find his amazing cart HERE:


Be certain to give him a star because that's what makes sharing code really interesting is when someone can understand it and apply what they've learned, extending and commending on that intelligent concept or code.

P#57569 2018-10-05 15:08 ( Edited 2018-10-05 23:46)

I have always been a fervent believer of backtracking in technology to learn or experience something that may not be at all available today or even available at all in the future.

Recently I was thinking, is it possible. Can it be done ? HOW would it be done ? To build a fully-working and useful 4-bit assembler ?

That is, a fantasy console that uses only 16-commands and is a fully working and useful computer.

My idea was that it would have a 16x16 pixeled screen, B&W, 8-colored lights, a 3-digit LED - red on the left, green on the right. And can read and react to standard input, U D L R A B, either waiting for the key or strobing it.

Now I might be able to lay out memory. You have only 256-bytes to work in.

The top 32-bytes are reserved to display 8 4-character messages (A-Z, 0-9, etc) where the font is small: 3x5, which could further be displayed by one of the 16-commands available to the 4-bit processor.

You also have a PINK and GREEN pixel overlaying the 16-B&W. These are to be treated as individual sprites. So you cannot have more than one PINK or GREEN pixel at a time. You can hide one or the other, but only their LOCATION is recorded.

The 16x16 B&W screen is a true 32-bytes, so here is the memory layout so far:

$00-$7F ... actual machine-code space and storage, editor allows you to run or stop any position
$80-$8F ... system variables if needed, A, X, Y, etc.
$90-$9F ... pushed/pulled data storage and stack
$A0-$AF ... I'm a little fuzzy here, maybe this would be needed for math or variable use ?
$B0-$B3 ... coordinates of PINK and GREEN pixel
$B4-$B7 ... numeric contents of LED digits (Red on left, green on right, each 3-digit decimal)
$B8-$BF ... Lit status of 8-colored lights, can all be on or off or mixed
$C0-$DF ... Actual 16x16 B&W screen contents

$E0-$FF ... 8 four-character messages. They are each displayed for 1/2 second, called from a single machine-language command, then return back to the standard 16x16 screen with 2-colored sprites. I.E.: You could flip between "BASE" and "BALL" or "WIN" or "LOSE." They are used to relay simple messages only.

So, with that out of the way, HOW would it be possible to make a useful and working fantasy 4-bit assembler where the only machine instruction total you have is 16. Perhaps zero being RTS or BRK ?

How could this be done ? What possible 16-commands for a 4-bit assembler could be formed and still have a fully working computer capable of playing simple games and doing calculations ?

Here are some tests it should be able to do:

  • Draw a square or rectangle.
  • Bounce one of the sprites around on the screen in diagonal movements.
  • Roll one or more 6-sided dice and return the results
  • Have a paint program, the PINK pixel is the plotter, arrow keys (A) and (B) draw or erase
  • Have a rudimentary RPG with weapons, armor, monsters, and dungeons to explore


  • Draw a circle or ellipse
  • Draw a trapezoid, triangle, or other multi-edged object
  • Have the ability to make a 1- or 2-player SNAKE game
  • Play 21 (Blackjack)
  • Calculate and display division in decimal places and remainders

How would you do it ?

And more interestingly, could this be implemented and emulated from PICO ?

P#57402 2018-10-02 17:30 ( Edited 2018-10-02 21:39)

Cart [#57398#] | Code | 2018-10-02 | No License | Embed

Sweet and delicious.

No Halloween is complete without the sugary treat, "Candy Corn."

If you check out the code, you'll see its naught but a bunch of colored circles. A variation from earlier QBasic code I wrote, this cart is easy for anyone to see how the candy is made. :)


P#57396 2018-10-02 15:15 ( Edited 2018-10-02 19:27)

Cart [#57362#] | Code | 2018-10-01 | No License | Embed

While I don't have any immediate plans for a mapper myself, a great many of you out there do. And that's construction work that could be made easier with this cart.

For this is not only a mapper creator and editor, it also has an in-board function quite similar to the MAP() routine - with the unique exception instead of reading the mapper memory, it reads a single string which contains the size of the map its edges, bits of other data, and the actual mapper data itself.

use import {image}.png to import your own 256-character tile/sprite set to use in the mapper.

Commands follow:

Hold (Z) key to bypass logo.

If you are creating a new map, you will have a very small input routine active.

Use the LEFT and RIGHT arrow keys to navigate by 1-character.
Use the UP and DOWN arrow keys to navigate by 3-characters.
Press (O) to type that character.
Press (X) or have the key select on "<" to erase the last typed character.
Have the key select on ">" to accept that input.

At this time NAME OF MAP is not being used or even recorded. I just put it there to test the input routine, you can skip it by selecting the ">" key.

In editor, tap (X) to do three things. One, change keyboard mode to four. Nice delays and speed, no increase with repeat. Two is select the tile beneath the cursor. Three is you will have an option of selecting any of the 256-sprites to draw on the map, but the cursor initially starts on the last tile you had highlighted back in the editor.

Press (O) to select that sprite/tile. (X) to cancel.

In editor, tap (O) to plot that tile/sprite.

Use arrow keys to scroll. If you choose an area that is bigger than the screen, it will scroll to reveal it.

Press both LEFT and RIGHT to see a demo of the Map-player. Use arrow keys to navigate. Use this function, DRAWMAP() in your code.

The function DRAWMAP() can be used directly in your own code. These are the arguments for it.

  T ... ( Map itself, a text string created from this program ,
  H ... the horizontal position to plot on the screen ,
  V ... the vertical position to plot on the screen ,
  X ... the size across to plot the map on the screen ,
  Y ... the size down to plot the map on the screen ,
 DX ... the starting position (top-left LEFT corner) of the map contents to draw ,
 DY ... the starting position (top-left TOP corner) of the map contents to draw )

As the actual code does not draw the entire cropped map, only the visible part, it should be plenty fast for you.

Back to the editor, press both (O) and (X) to save your map as a string to the clipboard.
Replace with the MAPP line near the top of the code to both save and continue working on your code.

Feel free to make changes or updates, especially optimizing code, these are always welcome !

If you have any questions or suggestions for improving the code, please let me know !

P#57363 2018-10-01 18:24 ( Edited 2018-11-19 23:33)

As far back as I can remember, any routine that used Boolean could be evaluated not only as TRUE and FALSE but also zero (0) and (1) or minus one (-1).

Strangely you cannot do this in Pico-8. I'm wondering if there is a reason for this as it would be a simple matter to make global definitions of TRUE to equal 1 and FALSE to equal 0. A conditional statement without an argument would simply be any non-zero number.

if (apple) takeabite()

So this would evaluate true provided the variable apple, boolean or otherwise, evaluated to any number besides zero.

For that matter I am understanding that SGN(0) also reveals 1 whereas all other programming languages I've known show it to be zero. What is the reason for these identities and lack thereof ?

Now NIL is a special case and I kind of understand why it exists. It says that this item has not been defined. Not that it equals zero or empty string of "" ... no, simply NIL. Yet when attempting to evaluate NIL as being less than 1 or equal to zero or less than an empty string of "" or equal to that selfsame empty string "", you get a type mismatch error.

And maybe for NIL, this is a good idea. What are your thoughts on these logical and functional operators ?

P#57347 2018-10-01 13:50 ( Edited 2018-10-02 06:41)

Cart [#57280#] | Code | 2018-09-29 | No License | Embed

Slice mapping example for Scrub. Pretty sure this is what he was trying to do.

P#57279 2018-09-29 16:16 ( Edited 2018-09-29 20:24)

Cart [#57192#] | Code | 2018-09-28 | No License | Embed

Simple coding example for Scrub of a scrolling map handled by code instead of internal mapper (thereby freeing space from mapper and extending beyond 128 tiles across).

P#57193 2018-09-27 23:21 ( Edited 2018-09-28 03:21)

Cart [#57232#] | Code | 2018-09-28 | No License | Embed

UPDATED: 09-28-18
Saving all SRAM now. CSTORE() RELOAD()

Despite the setback of not being able to retain all the sprite images with 8192-bytes of data (the full-screen), you can certainly save 4096-bytes and still retain a good 128 of 8x8 pixels sprite data.

In this program, press LEFT to clear the screen.
RIGHT to add a random colored circle in the recorded screen area.
UP to confirm the sprite area is not overwritten (top 128 sprites).
(O) to save off that screen area.
(X) to load it back. Try rebooting and loading only to confirm it is recorded.

Since 4096-bytes is allocated from the Sprite area and is not to be overwritten by other sprites, this method works.

And is still 16 times bigger storage than the default 256-byte or 64-numbers via DGET() and DSET().

A warning red triangle is placed on the sprite sheet to show your limits (Sprite #127), as mentioned above, 128-sprites, and this should be enough for most carts.

Additionally, no mapper, sprite pointers or flags, sound effects, or music values are overwritten. Only the bottom half of the sprite sheet.

Actually I'm not so sure about the mapper. Doesn't it share some of the sprites ? I'm not sure since I rarely use the mapper myself.

Saved data does not have to be pixels, it can be anything you want - up to 4096 bytes.

This program will run correctly and load/save 4096-bytes of external data in:

  • Immediate editor mode
  • Compiled to EXE/Linux/APP
  • Compiled to HTM/JS
  • Run in Pico-8's own Splore
  • Saved to Online
  • Compiled to Offline file
P#57179 2018-09-27 16:27 ( Edited 2018-09-28 21:20)

As you know, Pico-8 is capable of creating an executable from any cart via:

export (cartname).bin

What you DIDN'T know is that you are put ... well ... I'm not sure exactly where. Try out this program to see for yourself:

for i in all(t) do

Now convert that to EXE. Then run the EXE. Notice the directory.

Just where the heck are we ??

P#57127 2018-09-26 13:57 ( Edited 2018-09-27 03:33)

Cart [#57104#] | Code | 2018-09-26 | No License | Embed


Since copyright was a concern earlier, I would like to state that this code and any other code I have or may produce in the future is licensed for use only under PICO-8. That is, my code is free for anyone and everyone to use entirely as they like for whatever freeware project they have in mind, yet its use is to remain strictly in this programming language PICO-8, and no other languages or derivations are allowed unless permission otherwise is granted from the author.

You can see this copyright and license in usage by the inclusion of the icon above in the SPRITES tab - and you are welcome to use it also for your own packages to denote the self-same copyright and license restrictions and allowances.




  • PROJECT COMPLETE ! See instructions below for usage.
  • Got type "2" working properly.
  • Added option to change type during demo run. Press ❎ and 🅾️ to do so.


  • Got type "1" working properly.


  • Got type "0" (zero) working properly.

So what exactly is this ?

It's a comprehensive function you can call to return the standard 6-keystrokes in many different ways.

If you set KEYTYPE to zero, you have true arcade controls. No staggering for any input, multiple keystrokes can be read via KEYIN("zz") where "zz" is the name of the key you want to see if it appears in that particular stroke.

Possible keys are "L" "R" "U" "D" "A" and "B" and can be returned singly or if multiple keys are held.

IF KEYIN("L") THEN ShipX=ShipX-1
IF KEYIN("R") THEN ShipX=ShipX+1

You can press any number of these keys including holding down the LEFT or RIGHT arrow key and the "O" button. No need to stop pressing one to register another. KEYIN() can return all 6-keystrokes simultaneously if need be.

You can also press UP and DOWN to return "UD" special keystroke.
Press LEFT and RIGHT to return "LR" special keystroke.
And press "O" and "X" (Z and X) to return "AB" special keystroke.

These 3-keystrokes will appear only once in a strobe and and then return no more keystrokes until you release them.

If you want regular input like for menus and selections where all keystrokes are staggered by delays and time held, change KEYTYPE to 1 (one).

Now diagonal movements flip between two keys if both are held. (A) and (B) register once, pause, again, pause, then repeat.

You truly get just one keystroke outside of the 3-special listed above. You can also change the default counting delay of 8 to anything you want. Change global "KEYTIME" shown at the beginning of _INIT()

The KEYTYPE #2 is a very special case indeed. You still have diagonal movements flip between two keys but now (A) and (B) only register when RELEASED. If you hold either down for a short while, you get a new special keystroke called either "A+" or "B+" depending upon which you held.

Continue to hold that key down and you can still navigate with the arrow keys. But if at any point you release (A) or (B), whichever was held, a new keystroke is sent of "A-" or "B-" signifying you have released it, and you can also register that comparison directly in your code.

That's it !

I hope you find this function instrumental and useful in your existing and future carts. I certainly plan to make use of it myself. Thank you for your time !

P#57001 2018-09-22 18:09 ( Edited 2018-09-27 00:59)

Cart [#57097#] | Code | 2018-09-25 | No License | Embed

Details: https://www.lexaloffle.com/bbs/?tid=31927

UPDATED 09-24-18
09-25-18 (final)

  • Decrease chance cars will back up when in a jam


  • Allow traffic to back up if it gets clogged.
  • Traffic level now set default at =3=

Cart [#56995#] | Code | 2018-09-22 | No License | Embed


  • First draft
  • Traffic level set default at =1=

Alright, with that out of the way, what does this cart do ?

It is a simulation of automobiles. I was influenced by my Dad on this. For years ago he was interested in writing programs that simulated human life.

He wrote one in Turbo Pascal that had green dots all over it. They moved around slightly, sometimes traveling in a straight line. Sometimes standing still, sometimes wandering a bit. But if one green dot got too crowed by the other green dots it had a chance of going BERZERK.

A BERZERK dot would turn red and start to kill green dots. When enough bodies were found by green dots though, the green dots would clustered together and 3 of them would make a single blue-dot, a policeman, who would kill a red dot - restoring order to the community.

It was all quite fascinating to watch, and the method I'm using here is very similar to the method he used. Where no actual "dot" had its own identity, it was just chosen as a COMPONENT with one invisible number to state its "brain." You can see that I wrote a "component" type of Space Invaders HERE:


Back in QBasic years ago I wrote a program called Traffic to simulate automobile traffic. 4-cars coming from all directions and yet ... few if any pileups would occur. Why ?


  1. Easy question. Why are there no head-on collisions ?

  2. Difficult. Why are pileups extremely rare at a traffic setting 1 ? (hold (O) to confirm this)

  3. Most difficult. If a pileup does occur, what could be changed in the code so cars would automatically clear it ?
P#56996 2018-09-22 13:02 ( Edited 2018-09-26 03:16)

View Older Posts
About | Contact | Updates | Terms of Use
Follow Lexaloffle:        
Generated 2019-07-16 23:33 | 0.120s | 4194k | Q:168