How does it not replicate the way a game & watch works ?
hashalon
Creator of
Recent community posts
It was inspired by Super Mario 3D World "Cherry" power-up. And the same way that for the dev team, it was a bug that became a feature. I made my characters so that it was easy to implement. I just needed to add a small force so that the clones would push each other to avoid having them on top of one-another.
I just discovered that lua support operator overloading for tables so I had to test it out.
So i tried in TIC-80 and it works, so I though "What about moonscript ?'
It happens that it is that easy:
-- example of the use of lua's metamethods with moonscript's classes class Vector new:(x,y)=> @x = x @y = y __add:(vecA,vecB)-> return Vector(vecA.x + vecB.x, vecA.y + vecB.y) a = Vector 1,2 b = Vector 3,4 c = a + b print "c.x = "..c.x -- prints 4 (1+3 = 4) print "c.y = "..c.y -- prints 6 (2+4 = 6)
So it is possible to change the behavior of operators based on the class of the tables.
If other people are interrested, you can read the lua doc regarding metamethods.
Thanks, I tried your solution and I noticed that there is a bug with the sset function (and surely with the sget function too)
It should be
-- set spriteheet pixel function sset(x,y,c) local addr=0x4000+(x//8+y//8*16)*32 -- get sprite address poke4(addr*2+x%8+y%8*8,c) -- set sprite pixel end
and not
-- set spriteheet pixel function sset(x,y,c) local addr=0x4000+(x//8+y//8*16)*16 -- get sprite address poke4(addr*2+x%8+y%8*8,c) -- set sprite pixel end
I was working on a little projet in TIC-80 and I came accross a problem:
I have a shape made of a circle and a rectangle and I would like to cut pieces of it.So my idea was to draw the shape and simply draw on top of it to remove parts of it. However if I do that, I cannot draw stuff behind of the shape.
So I was wondering if it could be possible to add an optional 'mask' parameter to each paint function:
line x0 y0 x1 y1 color [mask] rect x y w h color [mask] rectb x y w h color [mask] circ x y radius color [mask] circb x y radius color [mask] tri x1 y1 x2 y2 x3 y3 color [mask]
So that the function would only draw on pixels of the color specified by the mask. It would be quite useful for demos.
But if it is too much for a machine that is supposed to be limited, I would like to have some hints on how to draw complex shapes. Like maybe there is a way to draw on the spritesheet and then draw back the sprite on the screen.
https://en.m.wikipedia.org/wiki/Double-precision_f...
If you deal only with integers, your limit is
253=9,007,199,254,740,992
beyond that, you cannot have the direct next natural number:
if I do 253+1 I will get 9,007,199,254,740,994 .
You should definitly use arrays and 'for'-loop, your code is really hard to read.
Use functions to cut your code into multiple simple operations.
Also use comments to explain which part of the code do what.
And beware, TIC implement a more formal LUA than PICO-8. That means that number are double precision floating point number and not 32bit fixed point like in PICO-8. It means that if you increament by a real number, let's say 0.34 every frame and you start from x=0 and you want to check when x==1:
x = 0
while «condition» do
if x==1 then «do a thing» end
x = x + 0.34
end
----execution:
x==0
x==0.34
x==0.68
x==1.02 --x==1 is never checked
if you want to use check points with floating point numbers, use intervals instead of discrete values:
x = 0
while «condition» do
if 0.9<x and x<1.1 then «do a thing» end
x = x + 0.34
end
----execution:
x==0
x==0.34
x==0.68
x==1.02 --> 0.9<1.02<1.1 --> condition is checked !
Here I made an update that allow to see the execution of the automaton in real time.
--[moonscript] --brainfuck interpreter by oSchyns --version 0.3.0 BF="++++ ++++".. "[>+++++ +++++<-]".. ">++++.----- ----- -.--- ---."--.. --uncomment to test error output --"<< force a tape outbound" IN="" --tape to perform computation class Tape new:(l,m)=> @l=l --cell limit @m=m --loop the finite tape @t={} --tape @h=0 --read head --correct values @l-=1 if @l~=nil @m-=1 if @m~=nil --rhead out of the bounds of the tape unbound:=> if @m~=nil then return @h>@m @h<0 --init nil cell to zero init:=> @t[@h]=0 if @t[@h]==nil --move read head to the left mvL:=> @h-=1 if @m~=nil then if @h<0 @h=@m --move read head to the right mvR:=> @h+=1 if @m~=nil then if @h>@m @h=0 --decreament cell decr:=> @init! @t[@h]-=1 if @l~=nil then if @t[@h]<0 @t[@h]=@l --increament cell incr:=> @init! @t[@h]+=1 if @l~=nil then if @t[@h]>@l @t[@h]=0 --ins: insert value in cell --out: get value from cell ins:(i)=> @t[@h]=i if i~=nil out: => @t[@h] or 0 --stack to hold indexes of brackets class Stack new: => @s={} top: => @s[#@s] pop: => @s[#@s]=nil push:(i)=> @s[#@s+1]=i --automaton to execute the program class Automaton new:(p,i,l,m)=> @t=Tape l,m --tape @s=Stack! --stack @r=1 --read head @p="" --program @i=i --input @o="" --output @e=nil --error --strip useless chars of program for c in p\gmatch "[<>%+%-%[%]%.%,]+" @p..=c b=@check! if b~=nil @e="brackets mismatch at "..b --check for brackets mismatch check:=> s=Stack! for i=1,#@p if @program(i)=='[' then s\push i elseif @program(i)==']' return i if #s.s<=0 s\pop! return s\top! if #s.s> 0 return nil --get char from input input:=> if @i==nil or @i=="" then return nil c1=@i\byte! --1st char of i @i=@i\sub 2 --remove 1st char return c1 --output: add char to output --program: get instruction at 'n' --continue: continue execution output: (n)=> @o..=string.char n program:(n)=> @p\sub n,n continue: => @r<=#@p and @e==nil --find matching bracket match:(b)=> m=1 while m>0 and b<=#@p b+=1 if @program(b)=='[' then m+=1 elseif @program(b)==']' then m-=1 return b --opening bracket open:=> --jump to matching bracket if (@t\out!)==0 then @r=@match @r else @s\push @r --closing bracket clos:=> if (@t\out!)==0 then @s\pop! elseif @s\top! ~=nil then @r=@s\top! --automaton's' execution step step:=> switch @program @r when '<' then @t\mvL! when '>' then @t\mvR! when '-' then @t\decr! when '+' then @t\incr! when ',' then @t\ins @input! when '.' then @output @t\out! when '[' then @open! when ']' then @clos! @r+=1 if @t\unbound! @e="tape outbound !" --display to see the execution class Display new:(a,s=1,f=nil)=> @a=a --automaton @s=s/60 --number of update per second @c=0 --counter @f=3 --display format of cells if f=="hexadecimal" then @f=2 elseif f=="character" then @f=1 --execute automaton all at once execute:=> while @a\continue! @a\step! @output! --update automaton at given frame rate update:=> if @a\continue! if @c<1 then @c+=@s else @c=0 @a\step! @draw! --draw automaton state and output draw:=> cls! @tape 8, 2 @program 8,12 @output 4 --draw the tape tape:(w=6,h=0,c=1,a=3)=> rect 0,h,240,w,c l=math.ceil (40/@f)*0.5 p=(w-6)*0.5 q=6*@f b=l-@a.t.h d=15 if @f==2 then d=6 elseif @f==1 then d=3 rect l*q-d,h,6*@f,w,a for i=@a.t.h-l,@a.t.h+l unless i<0 c=15 c=14 if i==@a.t.h v=@a.t.t[i] or 0 if @f==3 then v="%3d"\format v elseif @f==2 then v="%2x"\format v elseif @f==1 then v=string.char v print v,(i+b)*q-d,h+p,c --draw the program program:(w=6,h=6,c=1,a=3)=> rect 0,h,240,w,c rect 117,h, 6,w,a p=(w-6)*0.5 b=20-@a.r for i=@a.r-20,@a.r+20 unless i<1 c=15 c=14 if i==@a.r v=@a\program i print v,(i+b)*6-2,h+p,c --print result of execution output:(s=0)=> i=s o=@a.o.."\n" --print each line for l in o\gmatch "[%S \t]*\n" print l,0,i*6 i+=1 break if i==21 --no more room --print error unless @a.e==nil print @a.e,0,130,6 --create automaton 'TM' using --program : BF --input : IN TM=Automaton BF,IN,128,nil --create display 'DP' using --automaton : TM --frame rate : 30 --cell display : decimal DP=Display TM,30,"decimal" --execute the automaton and display it export TIC=-> DP\update! --http://moonscript.org/reference/ --http://moonscript.org/compiler/ --https://esolangs.org/wiki/Brainfuck --http://zacstewart.com/2013/09/15/learning-cpp-a-brainfuck-interpreter.html
It is possible to change the width of the tapes and their colors. Also we can change the cell's display to see the values as decimal number, hexadecimal numbers or characters directly. This helps coding in BF a lot.
Here the first program I made with TIC:
a BrainF**k interpreter in moonscript
--[moonscript] --brainfuck interpreter by oSchyns --v0.2.0 BF="++++ ++++".. "[>+++++ +++++<-]".. ">++++.----- ----- -.--- ---."--.. --uncomment to test error output --"<< force a tape outbound" IN="" --tape to perform computation class Tape new:(l,m)=> @l=l --cell limit @m=m --loop the finite tape @t={} --tape @h=0 --read head --correct values @l-=1 if @l~=nil @m-=1 if @m~=nil --rhead out of the bounds of the tape unbound:=> if @m~=nil then return @h>@m @h<0 --init nil cell to zero init:=> @t[@h]=0 if @t[@h]==nil --move read head to the left mvL:=> @h-=1 if @m~=nil then if @h<0 @h=@m --move read head to the right mvR:=> @h+=1 if @m~=nil then if @h>@m @h=0 --decreament cell decr:=> @init! @t[@h]-=1 if @l~=nil then if @t[@h]<0 @t[@h]=@l --increament cell incr:=> @init! @t[@h]+=1 if @l~=nil then if @t[@h]>@l @t[@h]=0 --ins: insert value in cell --out: get value from cell ins:(i)=> @t[@h]=i if i~=nil out: => @t[@h] or 0 --stack to hold indexes of brackets class Stack new: => @s={} top: => @s[#@s] pop: => @s[#@s]=nil push:(i)=> @s[#@s+1]=i --automaton to execute the program class Automaton new:(p,i,l,m)=> @t=Tape l,m --tape @s=Stack! --stack @r=1 --read head @p="" --program @i=i --input @o="" --output @e=nil --error --strip useless chars of program for c in p\gmatch "[<>%+%-%[%]%.%,]+" @p..=c b=@check! if b~=nil @e="brackets mismatch at "..b --check for brackets mismatch check:=> s=Stack! for i=1,#@p if @program(i)=='[' then s\push i elseif @program(i)==']' return i if #s.s<=0 s\pop! return s\top! if #s.s> 0 return nil --get char from input input:=> if @i==nil or @i=="" then return nil c1=@i\byte! --1st char of i @i=@i\sub 2 --remove 1st char return c1 --output: add char to output --program: get instruction at 'n' --continue: continue execution output: (n)=> @o..=string.char(n) program:(n)=> @p\sub n,n continue: => @r<=#@p and @e==nil --find matching bracket match:(b)=> m=1 while m>0 and b<=#@p b+=1 if @program(b)=='[' then m+=1 elseif @program(b)==']' then m-=1 return b --opening bracket open:=> --jump to matching bracket if (@t\out!)==0 then @r=@match @r else @s\push @r --closing bracket clos:=> if (@t\out!)==0 then @s\pop! elseif @s\top! ~=nil then @r=@s\top! --automaton's' execution step step:=> switch @program @r when '<' then @t\mvL! when '>' then @t\mvR! when '-' then @t\decr! when '+' then @t\incr! when ',' then @t\ins @input! when '.' then @output @t\out! when '[' then @open! when ']' then @clos! @r+=1 if @t\unbound! @e="tape outbound !" --create automaton 'TM' using --program 'BF' --input 'IN' TM=Automaton BF,IN,128,nil --execute 'TM' while TM\continue! TM\step! --print result of execution cls! i=0 TM.o..="\n" --print each line for o in TM.o\gmatch "[%S \t]*\n" print o,0,i*6 i+=1 --print error unless TM.e==nil print TM.e,0,130,6 export TIC=-> --http://moonscript.org/reference/ --http://moonscript.org/compiler/ --https://esolangs.org/wiki/Brainfuck --http://zacstewart.com/2013/09/15/learning-cpp-a-br...
I also put some pages I used to code it.
Should I post it it the github wiki ?
By own fonts and own color scheme, I meant allowing each user to customize their own TIC.
Like a tiny config file that change the default color palette on boot up (but keeping the 16 colors limitation).
As for the font, a special directory where you can place your custom font so it gets loaded on boot up.
But the font and the color scheme wouldn't be stored in the cartridges (well you can still change the color scheme by playing with the RAM). It would be just a setting for this particular user.
Both LUA and moonscript use ' -- ' as single line comment so maybe a way to allow the use of moonscript would be to use a special tag like "--[moonscript]".
- If the first line of the script as the exact tag "--[moonscript]" then all the code is in moonscript,
- otherwise it is in LUA
--[moonscript]
x = 10
if something
local x
x = 12
print x -- prints 10
Of course moonscript would be optional. TIC like PICO-8 rely on LUA to work.
moonscript is a language that gets converted into LUA to work. (similar to typescript -> javascript or coffeescript -> javascript or Scala -> Java, ...). As such all functions defined in LUA can be used in moonscript (no additional implementation work on that side). However you cannot do an include("moonscript") because the syntax is different than LUA. We should define a comment tag to specify the use of moonscript instead.
Moonscript as it is more complex than LUA shouldn't be the default choice, I agree. But moonscript is also interresting for TIC (and PICO-8) because it requires less lines to do the same things as LUA. And since the screen size is limited, it would help a lot on big project for advanced programmers.
Would it be a good idea to implement moonscript as an alternative Language for TIC ?
moonscript compiles into LUA, it implements classes and shorthand operators. And moonscript code require overall less characters than LUA code.
By that I mean I think it would be more interesting to implement moonscript into TIC rather than implementing shorthands into LUA like how it was done with PICO-8.
What do you think ?
AZERTY keyboards are always a mess to deal with. Sadly that is what most french users use.
The problem is that we need to do combinations such as:
AltGr+2 to get '~'
AltGr+3 to get '#'
AltGr+4 to get '{'
AltGr+5 to get '['
But in TIC, pressing AltGr+5 switch of workplace instead so some characters are writable only through ascii code.
There should be an option to disable such shortcuts and simply rely only on function keys F1,F2,F3,F4,F5 as they have no other uses.
Thank you.