├── .gitignore
├── 2023-ncl-creative-code-club
└── invite-202307-ncl-creative-code.tic
├── 2024-ncl-creative-code-club
└── invite-20240619-ncl-creative-code.tic
├── 2024-peckham-digital
├── invite-20240720-peckham-digital.tic
└── peckhamdigital-logo.lua
├── bounces.lua
├── emfcamp-invite.tic
├── hosting
└── readme.md
├── house.lua
├── outline.md
├── plasma.gif
├── plasma.lua
├── primitive-house.gif
├── readme.md
├── running
└── readme.md
├── sincos.lua
├── swirly.lua
├── swirly.mp4
├── video1.gif
├── video2.gif
├── video3.gif
└── workshop.md
/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creativenucleus/tic-80-demo-workshop/e75576d6dd6c2a409f77c1039316bf5556dc45ae/.gitignore
--------------------------------------------------------------------------------
/2023-ncl-creative-code-club/invite-202307-ncl-creative-code.tic:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creativenucleus/tic-80-demo-workshop/e75576d6dd6c2a409f77c1039316bf5556dc45ae/2023-ncl-creative-code-club/invite-202307-ncl-creative-code.tic
--------------------------------------------------------------------------------
/2024-ncl-creative-code-club/invite-20240619-ncl-creative-code.tic:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creativenucleus/tic-80-demo-workshop/e75576d6dd6c2a409f77c1039316bf5556dc45ae/2024-ncl-creative-code-club/invite-20240619-ncl-creative-code.tic
--------------------------------------------------------------------------------
/2024-peckham-digital/invite-20240720-peckham-digital.tic:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creativenucleus/tic-80-demo-workshop/e75576d6dd6c2a409f77c1039316bf5556dc45ae/2024-peckham-digital/invite-20240720-peckham-digital.tic
--------------------------------------------------------------------------------
/2024-peckham-digital/peckhamdigital-logo.lua:
--------------------------------------------------------------------------------
1 | local T=0
2 | local SIN=math.sin
3 | local COS=math.cos
4 | local ATAN2=math.atan2
5 | local POLAR={}
6 |
7 | function R(a,b,r)
8 | return COS(r)*a-SIN(r)*b,
9 | SIN(r)*a+COS(r)*b
10 | end
11 |
12 | function BOOT()
13 | cls()
14 | drawLogo(120,68,30)
15 | POLAR=toPolar()
16 | end
17 |
18 | function BDR(y)
19 | vbank(0)
20 | for i=1,15 do
21 | local r=i/15*255
22 | local g=127+SIN(y*.03-T*.03)*127
23 | local b=255-(i/15*255)
24 | rgb(i,r,g,b)
25 | end
26 | end
27 |
28 | function TIC()
29 | poke(0x3ffb,0)
30 | vbank(0)
31 | local zoom=1.1+SIN(T*.01)*.8
32 | local spin=COS(T*.04)*2+COS(T*.03)*2
33 | plotPolar(POLAR,spin,zoom)
34 |
35 | vbank(1)
36 | local txt="Peckham Digital"
37 | local x,y=40,115
38 | print(txt,x-1,y-1,14,false,2)
39 | print(txt,x+1,y+1,13,false,2)
40 | print(txt,x,y,12,false,2)
41 | T=T+1
42 | end
43 |
44 | function drawLogo(xc,yc,sc)
45 | local coR=sc
46 | local ciR=sc*.5
47 | circ(xc,yc,coR,12)
48 | circ(xc,yc,ciR,0)
49 | local barW=sc*.6
50 | local barH=sc*2.75
51 | rect(xc-coR-barW,yc-sc,barW,barH,12)
52 | rect(xc+coR,yc-barH+sc,barW,barH,12)
53 | end
54 |
55 | function toPolar()
56 | local o={}
57 | for dx=-120,119 do
58 | for dy=-68,67 do
59 | o[#o+1]={
60 | a=ATAN2(dy,dx),
61 | d=(dx^2+dy^2)^.5,
62 | c=pix(120+dx,68+dy)
63 | }
64 | end
65 | end
66 | return o
67 | end
68 |
69 | function plotPolar(o,spin,zoom)
70 | for i=1,#o do
71 | local p=o[i]
72 | local d=p.d*zoom
73 | local x=COS(p.a)*d
74 | local y=SIN(p.a)*d
75 | local spinP=spin+p.d*SIN(T*.01)*.1
76 | x,y=R(x,y,spinP)
77 | local c=(p.c>0) and p.d/5 or 0
78 | pix(120+x,68+y,c)
79 | end
80 | end
81 |
82 | function rgb(i,r,g,b)
83 | local a=16320+i*3
84 | poke(a,r)
85 | poke(a+1,g)
86 | poke(a+2,b)
87 | end
88 | --
89 | -- 001:eccccccccc888888caaaaaaaca888888cacccccccacc0ccccacc0ccccacc0ccc
90 | -- 002:ccccceee8888cceeaaaa0cee888a0ceeccca0ccc0cca0c0c0cca0c0c0cca0c0c
91 | -- 003:eccccccccc888888caaaaaaaca888888cacccccccacccccccacc0ccccacc0ccc
92 | -- 004:ccccceee8888cceeaaaa0cee888a0ceeccca0cccccca0c0c0cca0c0c0cca0c0c
93 | -- 017:cacccccccaaaaaaacaaacaaacaaaaccccaaaaaaac8888888cc000cccecccccec
94 | -- 018:ccca00ccaaaa0ccecaaa0ceeaaaa0ceeaaaa0cee8888ccee000cceeecccceeee
95 | -- 019:cacccccccaaaaaaacaaacaaacaaaaccccaaaaaaac8888888cc000cccecccccec
96 | -- 020:ccca00ccaaaa0ccecaaa0ceeaaaa0ceeaaaa0cee8888ccee000cceeecccceeee
97 | --
98 |
99 | --
100 | -- 000:00000000ffffffff00000000ffffffff
101 | -- 001:0123456789abcdeffedcba9876543210
102 | -- 002:0123456789abcdef0123456789abcdef
103 | --
104 |
105 | --
106 | -- 000:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000304000000000
107 | --
108 |
109 | --
110 | -- 000:100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
111 | --
112 |
113 | --
114 | -- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57
115 | --
116 |
117 |
--------------------------------------------------------------------------------
/bounces.lua:
--------------------------------------------------------------------------------
1 | local SIN=math.sin
2 | local COS=math.cos
3 | local ABS=math.abs
4 |
5 | T=0
6 | function TIC()
7 | cls()
8 | for i=1,10 do
9 | local t=T*.1+i*.2
10 | drawSin(10,10,50,50,t,i)
11 | drawCos(70,10,50,50,t,i)
12 | drawSinCos(130,10,50,50,t,i)
13 | drawSinAbs(190,10,50,50,t,i)
14 | drawSin2Cos(10,80,50,50,t,i)
15 | drawSinYCosY(70,80,50,50,t,i)
16 | end
17 |
18 | T=T+1
19 | end
20 |
21 | function drawSin(x,y,w,h,t,c)
22 | local px=x+w/2
23 | local py=y+h/2+SIN(t)*h/2
24 | circ(px,py,3,c)
25 | end
26 |
27 | function drawCos(x,y,w,h,t,c)
28 | local px=x+w/2
29 | local py=y+h/2+COS(t)*h/2
30 | circ(px,py,3,c)
31 | end
32 |
33 | function drawSinCos(x,y,w,h,t,c)
34 | local px=x+w/2+SIN(t)*w/2
35 | local py=y+h/2+COS(t)*h/2
36 | circ(px,py,3,c)
37 | end
38 |
39 | function drawSinAbs(x,y,w,h,t,c)
40 | local px=x+w/2
41 | local py=y+h-ABS(COS(t)*h)
42 | circ(px,py,3,c)
43 | end
44 |
45 | function drawSin2Cos(x,y,w,h,t,c)
46 | local px=x+w/2+SIN(t)*h/2
47 | local py=y+h/2-COS(t*2)*h/2
48 | circ(px,py,3,c)
49 | end
50 |
51 | function drawSinYCosY(x,y,w,h,t,c)
52 | local px=x+w/2
53 | local py=y+h/2+SIN(t)*w/4+SIN(t*2)*w/4
54 | circ(px,py,3,c)
55 | end
56 |
57 | --
58 | -- 001:eccccccccc888888caaaaaaaca888888cacccccccacc0ccccacc0ccccacc0ccc
59 | -- 002:ccccceee8888cceeaaaa0cee888a0ceeccca0ccc0cca0c0c0cca0c0c0cca0c0c
60 | -- 003:eccccccccc888888caaaaaaaca888888cacccccccacccccccacc0ccccacc0ccc
61 | -- 004:ccccceee8888cceeaaaa0cee888a0ceeccca0cccccca0c0c0cca0c0c0cca0c0c
62 | -- 017:cacccccccaaaaaaacaaacaaacaaaaccccaaaaaaac8888888cc000cccecccccec
63 | -- 018:ccca00ccaaaa0ccecaaa0ceeaaaa0ceeaaaa0cee8888ccee000cceeecccceeee
64 | -- 019:cacccccccaaaaaaacaaacaaacaaaaccccaaaaaaac8888888cc000cccecccccec
65 | -- 020:ccca00ccaaaa0ccecaaa0ceeaaaa0ceeaaaa0cee8888ccee000cceeecccceeee
66 | --
67 |
68 | --
69 | -- 000:00000000ffffffff00000000ffffffff
70 | -- 001:0123456789abcdeffedcba9876543210
71 | -- 002:0123456789abcdef0123456789abcdef
72 | --
73 |
74 | --
75 | -- 000:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000304000000000
76 | --
77 |
78 | --
79 | -- 000:100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
80 | --
81 |
82 | --
83 | -- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57
84 | --
85 |
86 |
--------------------------------------------------------------------------------
/emfcamp-invite.tic:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creativenucleus/tic-80-demo-workshop/e75576d6dd6c2a409f77c1039316bf5556dc45ae/emfcamp-invite.tic
--------------------------------------------------------------------------------
/hosting/readme.md:
--------------------------------------------------------------------------------
1 | # Hosting
2 |
3 | I'd love to run this workshop for you!
4 |
5 | Demo making is a great way for people to express their creativity, and TIC-80 is a safe and fun environment to play with.
6 |
7 | The workshop has proven suitable for anyone who has done a little bit of programming before, and also for those who are experienced but would like to get started in creative coding, or learn a new platform for doing so.
8 |
9 | Please get in touch:
10 |
11 | - [Mastodon](https://mastodon.social/@jtruk)
12 |
--------------------------------------------------------------------------------
/house.lua:
--------------------------------------------------------------------------------
1 | function TIC()
2 | cls(11)
3 |
4 | grassY=90
5 |
6 | t=time()/600
7 | x=120+math.sin(-t)*100
8 | y=grassY+20+math.cos(t)*80
9 |
10 | drawSun(x,y)
11 |
12 | rect(0,grassY,240,136-grassY,6)
13 | rect(80,40,80,60,3)
14 | tri(70,40,170,40,120,10,1)
15 |
16 | for x=0,240,6 do
17 | if x<140 or x>160 then
18 | line(x,80,x,110,1)
19 | end
20 | end
21 | line(140,80,160,110,2)
22 |
23 | text="jtruk made this"
24 | x=80+math.sin(t)*60
25 | y=125
26 | print(text,x+1,y+1,0)
27 | print(text,x,y,12)
28 | end
29 |
30 | function drawSun(x,y)
31 | circ(x,y,22,4)
32 | circ(x,y,20,12)
33 | end
34 |
35 | --
36 | -- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57
37 | --
38 |
39 |
--------------------------------------------------------------------------------
/outline.md:
--------------------------------------------------------------------------------
1 | In 2 hours and I'm hoping to hit:
2 |
3 | - Check folks have downloaded TIC-80
4 | - Preamble (outline, expectations, check for photosensitivity requirements)
5 | - What TIC-80 does and why people like it
6 | - Origin and overview of the demoscene
7 | - TIC-80 Setup (i.e. dev menu option) and orientation (including F1-F5)
8 | - TIC-80 capabilities (including Pro and web)
9 | - Hands on: A Primitive House
10 | - Housekeeping: new cart, save, load, run
11 | - Intro to drawing primitives + print
12 | - vars, for, if, selected operators, function, comments
13 | - The secret sauce of Sin and Cos
14 | - (if time) Hands on: Plasma
15 | - Full screen pixels
16 | - time()
17 | - Sizecoding
18 | - Livecoding
19 | - Hands on: Swirly
20 | - atan2
21 | - (x^2+y^2)^.5
22 | - palette wash
23 | - Other stuff (if time)
24 | - reading pix()
25 | - math.random
26 | - vbank
27 | - For more:
28 | - tic80.com
29 | - SURF command
30 | - Monday night ByteJam
31 | - Field-FX Discord
32 | - tcc.lovebyte.party
33 | - Longer form
--------------------------------------------------------------------------------
/plasma.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creativenucleus/tic-80-demo-workshop/e75576d6dd6c2a409f77c1039316bf5556dc45ae/plasma.gif
--------------------------------------------------------------------------------
/plasma.lua:
--------------------------------------------------------------------------------
1 | T=0
2 |
3 | function TIC()
4 | for y=0,135 do
5 | for x=0,239 do
6 | local c=math.sin(y/19+x/15)+math.sin(x/40+T/12)
7 | c=c+math.cos(x/12+y/21)+math.sin(y/10+T/10)
8 | c=c+math.sin(T/100)^2
9 | c=1+(14*c)
10 | pix(x,y,c)
11 | end
12 | end
13 |
14 | T=T+1
15 | end
16 |
17 | --
18 | -- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57
19 | --
20 |
21 |
--------------------------------------------------------------------------------
/primitive-house.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creativenucleus/tic-80-demo-workshop/e75576d6dd6c2a409f77c1039316bf5556dc45ae/primitive-house.gif
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # TIC-80 Workshop
2 |
3 | Hi. Here are some resources for folks who attended my demoscene workshop.
4 |
5 | Please get in touch if you'd like to [host me to run this workshop](./hosting/).
6 |
7 | There are also resources for [running this workshop](./running/) yourself.
8 |
9 | ## Download TIC-80
10 |
11 | [Download Page](https://tic80.com/create) - Skip past 'In the Browser' to the 'Download' heading.
12 |
13 | ## Links
14 |
15 | ### Documentation
16 |
17 | The TIC-80 website has a [Learn page](https://tic80.com/learn) featuring an outline of all commands. For further detail, see the [wiki](https://github-wiki-see.page/m/nesbox/TIC-80/wiki), which is regularly updated.
18 |
19 | ### Sizecoding
20 |
21 | If you're interested in making big effects in the smallest space:
22 |
23 | [Nanogems](https://nanogems.demozoo.org/) showcases some of their favourites across a range of platforms, including TIC-80.
24 |
25 | For variety/technical inspiration, I'd select:
26 |
27 | - [Thrive](https://www.youtube.com/watch?v=qU5EGLvFXd8) - So much going on, and a wonderful use of colour palette [256 bytes]
28 | - [cthulhu128](https://www.youtube.com/watch?v=G-7qy--BEEQ) - A captivating dynamic effect. Just [128 bytes]!
29 | - [Terrain Spotting](https://www.youtube.com/watch?v=brCWRuUw8zw) - Nicely balanced perspective and colour use [256 bytes]
30 | - [House of Mojo](https://www.youtube.com/watch?v=c5U-Sz1zN1s) - Well considered progression across a few effects combined [256 bytes]
31 | - [Martian Madrigal](https://tic80.com/play?cart=3296) - One of mine. They just make me smile. Includes sound [256 bytes]
32 | - [Sunset Cove Moods](https://www.youtube.com/watch?v=VNDYInToM7s) - Another of mine, with a gentle colour palette change [256 bytes]
33 |
34 | Also see [Tiny Code Christmas](https://tcc.lovebyte.party/) for a brilliant set of short tutorials in TIC-80 and another fantasy console, [PICO-8](https://www.lexaloffle.com/pico-8.php).
35 |
36 | [The Sizecoding wiki](http://www.sizecoding.org/wiki/TIC-80) collects together some techniques.
37 |
38 | ### Livecoding
39 |
40 | Some selected examples in [Demozoo's Livecoding section](https://livecode.demozoo.org/)
41 |
42 | Look out for regular Byte Jams (see Field-FX in the community links below) and the competition version (timed/restricted length) Byte Battles in demo parties.
43 |
44 | ### Other
45 |
46 | PSEnough made a [general demoscene getting started doc](https://github.com/psenough/teach_yourself_demoscene_in_14_days). When you're a bit more embedded, they produce [monthly reports](https://www.youtube.com/@psenough) on the demoscene, featuring releases and demoparties.
47 |
48 | ### Sound
49 |
50 | The workshop covered some starting points for visual effects. For sound, see the `music` and `sfx` calls [Under 'sound' in the API](https://github.com/nesbox/TIC-80/wiki/API#sound). There is documenation for the [SFX Editor](https://github.com/nesbox/TIC-80/wiki/SFX-Editor). The Music Editor (Tracker) generally doesn't have a great reputation, but some do get some brilliant things out of it. [PSEnough's Music editor intro tutorial](https://www.youtube.com/watch?v=V9oAccwjeDA) is recommended, and there's an explanation and good guide to the effects modifiers in the [Music Editor documentation](https://github.com/nesbox/TIC-80/wiki/Music-Editor).
51 |
52 | If you'd like to go low-level, and poke/peek stuff, check out the [Sound register documentation](https://github.com/nesbox/TIC-80/wiki/RAM#sound-registers). [The code in this cart](https://tic80.com/play?cart=807) may help you pick it apart. This [music visualiser](https://tic80.com/play?cart=115) may also illuminate.
53 |
54 | ### Communities
55 |
56 | There are many demoscene communities. I've found myself following a number of Discords, which have their own specialisms, but include overlapping groups of people.
57 |
58 | - Field-FX
59 | A community that grew from a demo event at EMF Camp. Very friendly and welcoming, and a good starting point for newcomers.
60 | I recommend the [Discord](https://discord.com/invite/RuSxTNzhZS), and following on [Twitter](https://twitter.com/fx_field) and/or [Mastodon](https://mastodon.online/@FieldFX).
61 | They also run Byte Jams (hour long streams on [Twitch](https://www.twitch.tv/fieldfxdemo) on most Monday evenings) and they have a [YouTube](https://www.youtube.com/@field-fx5751) channel featuring previous streams.
62 | - [Lovebyte](https://lovebyte.party/)
63 | An annual online event for sizecoding, featuring many computer systems, from TIC-80 to obscure hardware from the 1980s
64 | I highly, highly recommend their [Tiny Code Christmas](https://tcc.lovebyte.party/) a series of gentle, but nicely progressive series of tutorials. These are oriented towards sizecoding, but also helpful for general demo tips. This was my entrypoint, and I've loved where it's gone. They also have a [Discord](https://discord.gg/pUS5kCJTzp) - also a very supportive community.
65 | - [NOVA Demoparty](https://novaparty.org/)
66 | The UK's biggest in-person demoparty, down on the Devon coast, annually in June. Also very welcoming!
67 | They don't use their Twitter/Mastodon accounts currently, but do have a [Discord](https://discord.gg/rBJTXJBeq2).
68 |
69 | ### Longer Demos
70 |
71 | - [You Better Walk](https://www.youtube.com/watch?v=HxrIOyLwYXk)
72 | - [GRMA](https://www.youtube.com/watch?v=g136jyMHSUU)
73 | - [AssemblyTV Megademo](https://www.youtube.com/watch?v=KFpohQa8jgk)
74 | - [Life's a Beach](https://www.youtube.com/watch?v=8Kz3_fqToNI)
75 | - [Nullius in Verba](https://www.youtube.com/watch?v=fhqKE_sTXeg)
76 | - [The Welsh Demo](https://www.youtube.com/watch?v=DOI5iUfohY0)
77 | - [Fallspire](https://www.youtube.com/watch?v=tWEU-bOT90w)
78 | - [Cracklebass](https://www.youtube.com/watch?v=KcmTcYuxp9w)
79 | - [You am the robot Zombie](https://www.youtube.com/watch?v=TkpLYwMQHrw)
80 | - [In Search of Love](https://www.youtube.com/watch?v=4m8IF7nwCa0)
81 |
82 | ### Archives
83 |
84 | - [Demozoo](https://demozoo.org/) is a database of productions across the demoscene. They also have [Nanogems](https://nanogems.demozoo.org/) and [Livecode](https://livecode.demozoo.org/) archives.
85 | - [Pouët](https://www.pouet.net/) is a huge archive of productions and associated stuff. It can be a bit aggresive in places, but it's a great resource.
86 |
87 | # Examples of Demoscene Productions
88 |
89 | ## Watchparty
90 |
91 | - [Intrinsic Gravity / ^Still](https://demozoo.org/productions/130155/)
92 | Geometric, colour play.
93 | - [State of the Art / ^Spaceballs](https://demozoo.org/productions/2/)
94 | - 1992 Amiga. Photosensitivity warning.
95 | - [Eon / ^The Black Lotus](https://demozoo.org/productions/202831/)
96 | - [VX2 / ^Spectrals](https://demozoo.org/productions/277304/)
97 | - [ix / ^Moppi](https://demozoo.org/productions/67521/)
98 | - [Remnants / ^Alcatraz](https://demozoo.org/productions/342211/)
99 | - 256b
100 | - [GhostNOP / ^Futurs' and ^Pulpo Corrosivo](https://demozoo.org/productions/342223/)
101 | - Amstrad CPC
102 | - [Empires / ^Conspiracy](https://demozoo.org/productions/342435/)
103 | - Bokeh / fluid / FOV.
104 | - [Legend of Sisyphus / ^ASD](https://demozoo.org/productions/327586/)
105 | - Mocap. Nudity.
106 | - [Batman Rises / ^Batman Group](https://demozoo.org/productions/316180/)
107 | - Amiga OCS
108 | - [Mechasm / ^Fairlight](https://demozoo.org/productions/322662/)
109 | - [In Color / ^Darklite and ^Offence](https://demozoo.org/productions/322396/)
110 | - Spectrum 128k
111 | - [Replay / ^SMFX](https://demozoo.org/productions/325859/)
112 | - Atari ST
113 | - [The Interloper / ^MFX](https://demozoo.org/productions/322661/)
114 | - [Masagin / ^Farbrausch and ^Neuro](https://demozoo.org/productions/4910/)
115 | - [Come Together / ^Melon Dezign](https://demozoo.org/productions/313312/)
116 |
117 | ### Further questions / My resources
118 |
119 | Feel welcome to contact me with any questions, or to share your progress :)
120 |
121 | - [Mastodon](https://mastodon.social/@jtruk)
122 | - [Twitter](https://twitter.com/jtruk)
123 | - [My TIC-80 sketches](https://github.com/creativenucleus/tic-80-sketches)
124 | - [Code on the TIC-80 website](https://tic80.com/dev?id=8568)
125 |
--------------------------------------------------------------------------------
/running/readme.md:
--------------------------------------------------------------------------------
1 | # Running
2 |
3 | You're very welcome to run this workshop yourself. If you use significant parts of it, do mention this in event descriptions on websites, e.g. "...based on jtruk's demoscene workshop". This is welcome, but not necessary for social media promotion.
4 |
5 | Please drop me a line if you do so (see the bottom of this page). I'd be keen to promote your event, and also to gather any improvements.
6 |
7 | # Intro
8 |
9 | - Make sure everyone has a running version of TIC-80 (part way down [tic-80 Create page](https://tic80.com/create))
10 | - Anyone susceptible to photosensitity
11 | - Outline of workshop
12 | - Become familiar with TIC-80
13 | - Drawing primitives
14 | - sin/cos
15 | - poke palette
16 | - full screen effect
17 | - History of the demoscene
18 | - Showcasing some demoscene things
19 | - Jumping off points
20 | - Level of programming experience (above 7 / below 3)
21 | - Anyone know about the demoscene?
22 |
23 | ## Primitives and structures
24 |
25 | `cls, rect, tri, circ, line, elli, pix, print`
26 | (rectb, trib, circb, ellib)
27 |
28 | `function, for, var, if`
29 |
30 | ```lua
31 | function TIC()
32 | T=time()/500
33 |
34 | cls(8)
35 |
36 | for i=0,30 do
37 | x=(i^7)%240
38 | y=(i^5)%68
39 | pix(x,y,12)
40 | end
41 |
42 | circ(
43 | 120+math.sin(T)*100,
44 | 90-math.cos(T)*80,
45 | 20,
46 | 4)
47 |
48 | rect(0,68,240,68,6)
49 |
50 | rect(50,40,80,60,2)
51 | tri(40,40, 90,10, 140,40, 1)
52 |
53 | for x=10,230,10 do
54 | if x<150 or x>=180 then
55 | drawPicket(x)
56 | end
57 | end
58 | end
59 |
60 | function drawPicket(x)
61 | line(x,90, x,110, 12)
62 | end
63 | ```
64 |
65 | ## Sin/Cos
66 |
67 | ```lua
68 | local ATAN2=math.atan2
69 | local PI=math.pi
70 | local TAU=PI*2
71 | local SIN=math.sin
72 |
73 | function TIC()
74 | T=time()
75 |
76 | for y=0,135 do
77 | for x=0,239 do
78 | local p=y*240+x
79 | local dx=120-x
80 | local dy=68-y
81 | local d=(dx^2+dy^2)^.5
82 | local a=(ATAN2(dy,dx)+PI)/TAU
83 | poke4(p,a*16+T*.001)
84 | end
85 | end
86 | end
87 | ```
88 |
89 | ## Contact Me
90 |
91 | Please get in touch:
92 |
93 | - [Mastodon](https://mastodon.social/@jtruk)
94 |
--------------------------------------------------------------------------------
/sincos.lua:
--------------------------------------------------------------------------------
1 | local SIN,COS,PI=math.sin,math.cos,math.pi
2 | local ATAN2=math.atan2
3 | local TAU=PI*2
4 | local MIN,MAX=math.min,math.max
5 |
6 | local ANIM_MUL=0.01
7 | local I_ANIM_MUL_MIN=1
8 | local I_ANIM_MUL_MAX=8
9 | local I_ANIM_MUL=2
10 | local ANIM_T=0
11 | local ANIM_D=50
12 | local ANIM_X=70
13 | local ANIM_Y=ANIM_D+10
14 |
15 | local STAGES={
16 | {
17 | title="TARGET",
18 | func=function()
19 | drawTarget(true, false)
20 | drawHTick(ANIM_X, getAnimYPos(0))
21 |
22 | printValues(true, false, false)
23 | end,
24 | incT=false,
25 | },
26 | {
27 | title="SIN(y)",
28 | func=function()
29 | drawTarget(true, false)
30 | drawHTick(ANIM_X, getAnimYPos(ANIM_T))
31 |
32 | printValues(true, false, false)
33 | end,
34 | incT=true,
35 | },
36 | {
37 | title="SIN(y) with trail",
38 | func=function()
39 | drawTarget(true, false)
40 | drawHTrail(ANIM_T, MIN(ANIM_T,ANIM_X))
41 | drawHTick(ANIM_X, getAnimYPos(ANIM_T))
42 |
43 | printValues(true, false, false)
44 | end,
45 | incT=true,
46 | },
47 | {
48 | title="TARGET 2",
49 | func=function()
50 | drawTarget(true, true)
51 | local x = getAnimXPos(0)
52 | local y = getAnimYPos(0)
53 | drawVTick(x,y)
54 |
55 | printValues(false, true, false)
56 | end,
57 | incT=false,
58 | },
59 | {
60 | title="COS(x)",
61 | func=function()
62 | drawTarget(true, true)
63 | drawVTick(getAnimXPos(ANIM_T),ANIM_Y)
64 |
65 | printValues(false, true, false)
66 | end,
67 | incT=true,
68 | },
69 | {
70 | title="CIRCLE",
71 | func=function()
72 | drawTarget(true, true)
73 | drawHTick(ANIM_X,getAnimYPos(ANIM_T))
74 | drawVTick(getAnimXPos(ANIM_T),ANIM_Y)
75 | circb(getAnimXPos(ANIM_T),getAnimYPos(ANIM_T),8,12)
76 |
77 | printValues(true, true, false)
78 | end,
79 | incT=true,
80 | },
81 | {
82 | title="CIRCLE with trail",
83 | func=function()
84 | drawTarget(true, true)
85 | drawCircTrail(ANIM_T, MIN(ANIM_T,200))
86 | drawHTick(ANIM_X,getAnimYPos(ANIM_T))
87 | drawVTick(getAnimXPos(ANIM_T),ANIM_Y)
88 | circb(getAnimXPos(ANIM_T),getAnimYPos(ANIM_T),8,12)
89 |
90 | printValues(true, true, false)
91 | end,
92 | incT=true,
93 | },
94 | {
95 | title="ATAN2",
96 | func=function()
97 | drawTarget(true, true)
98 | drawHTick(ANIM_X,getAnimYPos(ANIM_T))
99 | drawVTick(getAnimXPos(ANIM_T),ANIM_Y)
100 | circb(getAnimXPos(ANIM_T),getAnimYPos(ANIM_T),8,12)
101 |
102 | printValues(true, true, true)
103 | end,
104 | incT=true,
105 | },
106 | }
107 |
108 | local ISTAGE=1
109 |
110 | function TIC()
111 | cls()
112 | poke(0x3FFB,0) -- cursor begone
113 |
114 | if btnp(0) then -- up
115 | I_ANIM_MUL=MIN(I_ANIM_MUL+1,I_ANIM_MUL_MAX)
116 | elseif btnp(1) then -- down
117 | I_ANIM_MUL=MAX(I_ANIM_MUL-1,I_ANIM_MUL_MIN)
118 | end
119 |
120 | if btnp(3) then -- right
121 | ISTAGE=MIN(ISTAGE+1,#STAGES)
122 | ANIM_T=0
123 | elseif btnp(2) then -- left
124 | ISTAGE=MAX(ISTAGE-1,1)
125 | ANIM_T=0
126 | end
127 |
128 | local stage=STAGES[ISTAGE]
129 | stage.func()
130 |
131 | local text="<= " .. stage.title .. " =>"
132 | local w=print(text,0,150)
133 | print(text,120-w/2,128,14)
134 |
135 | print(I_ANIM_MUL .. "x", 210,128,14)
136 |
137 | if stage.incT then
138 | ANIM_T=ANIM_T+1
139 | end
140 | end
141 |
142 | function drawTarget(doHoriz, doVert)
143 | local hairD=5
144 | if doHoriz then
145 | local y0=ANIM_Y-ANIM_D
146 | local y1=ANIM_Y+ANIM_D
147 | line(ANIM_X-hairD,y0, ANIM_X+hairD,y0,2)
148 | line(ANIM_X-hairD,y1, ANIM_X+hairD,y1,2)
149 | line(ANIM_X,y0, ANIM_X,y1,2)
150 |
151 | print("-1", ANIM_X+10,y0-2,2)
152 | print("1", ANIM_X+10,y1-2,2)
153 | end
154 |
155 | if doVert then
156 | local x0=ANIM_X-ANIM_D
157 | local x1=ANIM_X+ANIM_D
158 | line(x0,ANIM_Y-hairD, x0,ANIM_Y+hairD,6)
159 | line(x1,ANIM_Y-hairD, x1,ANIM_Y+hairD,6)
160 | line(x0,ANIM_Y, x1,ANIM_Y,6)
161 |
162 | print("-1", x0-4, ANIM_Y+8, 6)
163 | print("1", x1-2, ANIM_Y+8, 6)
164 | end
165 |
166 | circ(ANIM_X,ANIM_Y,3,9)
167 | print("0",ANIM_X+10,ANIM_Y-2,9)
168 | end
169 |
170 | function drawHTrail(pos,d)
171 | for i=1,d do
172 | local x=ANIM_X-i
173 | local y=getAnimYPos(pos-i)
174 | circb(x,y,2,15)
175 | end
176 | end
177 |
178 | function drawCircTrail(pos,d)
179 | for i=1,d do
180 | local x=getAnimXPos(pos-i)
181 | local y=getAnimYPos(pos-i)
182 | circb(x,y,2,15)
183 | end
184 | end
185 |
186 | function getAnimMul()
187 | return ANIM_MUL*I_ANIM_MUL
188 | end
189 |
190 | function getAnimXPos(pos)
191 | return ANIM_X+COS(pos*getAnimMul())*ANIM_D
192 | end
193 |
194 | function getAnimYPos(pos)
195 | return ANIM_Y+SIN(pos*getAnimMul())*ANIM_D
196 | end
197 |
198 | function drawHTick(x,y)
199 | tri(x-5,y, x-8,y-3, x-8,y+3, 4)
200 | tri(x+5,y, x+8,y-3, x+8,y+3, 4)
201 | end
202 |
203 | function drawVTick(x,y)
204 | tri(x,y-5, x-3,y-8, x+3,y-8, 5)
205 | tri(x,y+5, x-3,y+8, x+3,y+8, 5)
206 | end
207 |
208 | function printValues(doPrintSin, doPrintCos, doPrintAtan2)
209 | local a=math.fmod(ANIM_T*getAnimMul(), TAU)
210 | local aUnit=a/TAU
211 |
212 | local px=140
213 |
214 | local str=string.format("angle: %.2f",a)
215 | print(str,px,10,12)
216 |
217 | if doPrintSin then
218 | local str=string.format("SIN(angle) = %.2f", SIN(a))
219 | print(str,px,30,12)
220 | end
221 |
222 | if doPrintCos then
223 | local str=string.format("COS(angle) = %.2f", COS(a))
224 | print(str,px,50,12)
225 | end
226 |
227 | if doPrintAtan2 then
228 | local str=string.format("ATAN2(sa,ca) = %.2f", ATAN2(SIN(a), COS(a)))
229 | print(str,px,70,12)
230 | end
231 | end
232 |
233 | --
234 | -- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57
235 | --
236 |
--------------------------------------------------------------------------------
/swirly.lua:
--------------------------------------------------------------------------------
1 | local SIN=math.sin
2 | local ATAN2=math.atan2
3 | local PI=math.pi
4 | local TAU=PI*2
5 | T=0
6 |
7 | function TIC()
8 | for y=0,135 do
9 | for x=0,239 do
10 | local dx=x-120
11 | local dy=y-68
12 | local a=ATAN2(dy,dx)
13 | local d=(dx^2+dy^2)^.5
14 | local c=8+SIN(a-T*.1+d)*7
15 | pix(x,y,c)
16 | end
17 | end
18 |
19 | local text="jtruk"
20 | local x=200
21 | local y=124
22 | print(text,x+1,y+1,2)
23 | print(text,x,y,12)
24 |
25 | T=T+1
26 | end
27 |
28 | function BDR(y)
29 | local t=T
30 | for i=1,15 do
31 | local a=0x3fc0+i*3
32 | local r=128+math.sin(y/100+i*.1+t/30)*127
33 | local g=128+math.sin(1+y/113+i*.12+t/31)*127
34 | local b=128+math.sin(2+y/126+i*.13+t/32)*127
35 | poke(a,r)
36 | poke(a+1,g)
37 | poke(a+2,b)
38 | end
39 | end
40 |
41 | --
42 | -- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57
43 | --
44 |
45 |
--------------------------------------------------------------------------------
/swirly.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creativenucleus/tic-80-demo-workshop/e75576d6dd6c2a409f77c1039316bf5556dc45ae/swirly.mp4
--------------------------------------------------------------------------------
/video1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creativenucleus/tic-80-demo-workshop/e75576d6dd6c2a409f77c1039316bf5556dc45ae/video1.gif
--------------------------------------------------------------------------------
/video2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creativenucleus/tic-80-demo-workshop/e75576d6dd6c2a409f77c1039316bf5556dc45ae/video2.gif
--------------------------------------------------------------------------------
/video3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creativenucleus/tic-80-demo-workshop/e75576d6dd6c2a409f77c1039316bf5556dc45ae/video3.gif
--------------------------------------------------------------------------------
/workshop.md:
--------------------------------------------------------------------------------
1 | # Workshop Schedule
2 |
3 | ## Intro
4 |
5 | - Make sure everyone has a running version of TIC-80 (part way down [tic-80 Create page](https://tic80.com/create))
6 | - Anyone susceptible to photosensitity
7 | - Outline of workshop
8 | - Become familiar with TIC-80
9 | - Drawing primitives
10 | - sin/cos
11 | - poke palette
12 | - full screen effect
13 | - History of the demoscene
14 | - Showcasing some demoscene things
15 | - Jumping off points
16 | - Level of programming experience (above 7 / below 3)
17 | - Anyone know about the demoscene?
18 |
19 | ## Switch Dev mode on
20 |
21 | If Dev mode is off (the default), when you hit ESC, you're taken to a menu. When dev mode is off, it takes you back into the command line, or editor.
22 |
23 | - Run a program (Ctrl-R)
24 | - Hit ESC to break program
25 | - Select (options) in menu
26 | - Move up to 'Dev Mode' and switch it on.
27 | - Select Back
28 | - Press Esc
29 |
30 | ## Learning Stuff
31 |
32 | ### Primitives and structures
33 |
34 | `cls, rect, tri, circ, line, elli, pix, print`
35 | (rectb, trib, circb, ellib)
36 |
37 | `function, for, var, if`
38 |
39 | ```lua
40 | function TIC()
41 | T=time()/500
42 |
43 | cls(8)
44 |
45 | for i=0,30 do
46 | x=(i^7)%240
47 | y=(i^5)%68
48 | pix(x,y,12)
49 | end
50 |
51 | circ(
52 | 120+math.sin(T)*100,
53 | 90-math.cos(T)*80,
54 | 20,
55 | 4)
56 |
57 | rect(0,68,240,68,6)
58 |
59 | rect(50,40,80,60,2)
60 | tri(40,40, 90,10, 140,40, 1)
61 |
62 | for x=10,230,10 do
63 | if x<150 or x>=180 then
64 | drawPicket(x)
65 | end
66 | end
67 | end
68 |
69 | function drawPicket(x)
70 | line(x,90, x,110, 12)
71 | end
72 | ```
73 |
74 | ### Sin/Cos
75 |
76 | ```lua
77 | local ATAN2=math.atan2
78 | local PI=math.pi
79 | local TAU=PI*2
80 | local SIN=math.sin
81 |
82 | function TIC()
83 | T=time()
84 |
85 | for y=0,135 do
86 | for x=0,239 do
87 | local p=y*240+x
88 | local dx=120-x
89 | local dy=68-y
90 | local d=(dx^2+dy^2)^.5
91 | local a=(ATAN2(dy,dx)+PI)/TAU
92 | poke4(p,a*16+T*.001)
93 | end
94 | end
95 | end
96 | ```
97 |
98 |
--------------------------------------------------------------------------------