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 checkedif 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.




