| | Shadow Account closed
Registered: Apr 2002 Posts: 355 |
Proposal - The sprite font compo!
Last year there was the hugely successful 128b font competition, which had a very good turnout.
Lots of people who could compete since it was pretty simple code, and the result were lots of nice fonts which can be a good tool to have for sizecoding stuff.
It got me thinking about arranging a similar compo, but for sprite fonts!
But before kicking the compo off, I'd like some input on the rules etc.
Here's what I have so far:
* The object of the competition is to generate a sprite-font, in 256 bytes or less code.
* The code should be placed at $0900 and up, but no further than $09ff and must end with an RTS.
* The sprites should be placed at $2000-$2fff, so sprite number $80-$bf.
* 64 sprites are viewed, but it is up to the coder to decide how many he want to generate, but to be considered a font, at least sprite $81-$9b should be readable as the letters A-Z.
* For the other sprites, you can of course generate the appropriate numbers/punctuation characters, or spaceships or whatever, or not generate them at all and spend all your bytes on doing fancier A-Z, it's up to you to decide what will impress the voters most! :)
* Since the code to actually view the sprites would take quite some space, and the competition should not be about that optimizing the viewer code (or who can do the coolest looking viewer) I will provide the code that displays the 64 sprites on screen, it will occupy $0801-$08ff, and will perform a JSR to $0900 where your font generation code should be.
* The viewer has a number of tweakable parameters that are placed on $0810-$0814:
$0810 - $00=Sprites should be singlecolor. $ff=Sprites should be multicolor
$0811 - Bakground and border color.
$0812 - Sprite base color ($d027-$d02e will be set to this)
$0813 - Sprite multicolor1 ($d025 will be set to this)
$0814 - Sprite multicolor2 ($d026 will be set to this)
Simply change these bytes directly in the viewer code (if you compile it) or in the final binary if you use that, they should not be set from you generator code, as this is also not something that should steal your precious space.
* The generator code may *not* depend on A,X,Y holding specific startup values, or memory being initialized to something specific (you may for example not pull data from the viewer code and use etc.).
* Max three entries per coder
* Voting will be done using the CSDb system (yeah, I'm not as cool as lft!)
* No prizes except eternal glory.
Here's the viewer code for Kick Assembler usage, with a place to put your generator code at the end:
.pc =$0801 "Basic Starter"
:BasicUpstart($0820)
.pc=$0810 "Constants"
multicol:
.byte $00
bgcol:
.byte $06
sprcol:
.byte $0e
sprmcol1:
.byte $00
sprmcol2:
.byte $00
.pc = $0820 "Code"
sei
lda multicol
sta $d01c
lda bgcol
sta $d020
sta $d021
lda sprmcol1
sta $d025
lda sprmcol2
sta $d026
lda sprcol
ldx #$07
!loop:
sta $d027,x
dex
bpl !loop-
ldx #$00
lda #$20
!loop:
sta $0400,x
sta $0500,x
sta $0600,x
sta $0700,x
inx
bne !loop-
lda #$ff
sta $d015
lda #$80
sta $d010
ldx #$07
ldy #$00
lda #$18+44
!loop:
sta $d000,y
clc
adc #29
iny
iny
dex
bpl !loop-
jsr generatefont
lda #$35
sta $01
mainloop:
lda #$2f
sta ycoord
lda #$80
sta spridx
yloop:
lda ycoord
!wait:
cmp $d012
bne !wait-
clc
adc #4
ldx #$07
ldy #$00
!loop:
sta $d001,y
iny
iny
dex
bpl !loop-
ldx #$00
ldy spridx
!loop:
tya
sta $07f8,x
iny
inx
cpx #8
bne !loop-
clc
lda spridx
adc #8
sta spridx
lda ycoord
adc #25
sta ycoord
cmp #$2f+8*25
bne yloop
jmp mainloop
ycoord:
.byte 0
spridx:
.byte 0
.pc=$0900 "Font generation code"
generatefont:
rts
Yes, code is neither pretty nor optimal, but that's not the point here, the pretty code should be written by YOU! :D
If you prefer some other assembler, here's the prebuilt binary for the $0801-$08ff portion:
sprite_font_view_base.prg
Here are some simple examples I've done to prove that it actually works:
Sprites using ROM font scaled to 3x3 pixel size. $0810 params set to : $00,$06,$0e,$00,$00
example1.prg
Exact same font but with multicolor params set (works this way as well!) $0810 params set to : $ff,$0b,$0c,$0f,$0f
example2.prg
So does these rules make sense?
I've been thinking a lot about the 256 byte limit, but I think it should be large enough to do some interesting things. My naive implementation of scaling up the ROM font is $9a bytes, which leaves plenty of space for actually tweaking the font, and I am sure some smart coders can do it in way less space.
I've been thinking on the possibility of generating a font from scratch using partial segments, not sure yet if it's doable in 256 bytes.
Unless someone has some compelling arguments, the 256 byte limit stands.
What's an appropriate time for such an event? Two months? Three?
And finally, does this seem like fun? Anyone think they will participate? :) |
|
... 17 posts hidden. Click here to view all posts.... |
| | Compyx
Registered: Jan 2005 Posts: 631 |
Argh, goddammit, I saw some potential in abusing that code. :)
So I suppose also no using the SP or SR state? |
| | Shadow Account closed
Registered: Apr 2002 Posts: 355 |
Correct, no specific state of anything is to be assumed! I'll make an alternate, secret viewer, that loads somewhere completely else in memory and abuses stack and registers etc. before calling the $0900 code, and if your sprites don't look the same way then, it will be disqualified! :)
My reasoning is that it would be nice if these fonts could actually be just dropped in and used in for example a 4k intro or something where you happen to need sprites, and it's a bit cumbersome if the code you call suddenly doesn't work because it's dependent on something obscure.
The one thing I'll allow is that the code can be assumed to be running in SEI state, as almost all programs will do that anyway, so that is not necessary to do in your own code. |
| | ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Quoting ShadowCorrect, no specific state of anything is to be assumed! I'll make an alternate, secret viewer, that loads somewhere completely else in memory and abuses stack and registers etc. before calling the $0900 code, and if your sprites don't look the same way then, it will be disqualified! :)
Oh, nice. My only question then is how do we know what memory is safe to use as working space? |
| | Smasher
Registered: Feb 2003 Posts: 520 |
Quote: Not so sure if the output will vary a big deal from CharROM Font Compo as many people might use ROM again and the only difference is the code to transform stuff into sprite data, so indeed rather a coder compo. But maybe there'll be surprises. Anyway, bring it on :)
what ZeRyk said. I am sceptical and think generated sprite font will be quite similar to the ones seen in the charROM compo, just a bit bigger. but let's go with the compo and prove me wrong! and sure count me in, I want the last place! :) |
| | ws
Registered: Apr 2012 Posts: 251 |
Quoting ChristopherjamMy only question then is how do we know what memory is safe to use as working space?
Since the sprite code is called with a JSR, wouldn't the general area where the viewer code is located, be obtainable from the stack (unless the jsr is proxied for no reason)? Additionally any Zeropage plus a reasonable amount of stack should be free to use?
(for some reason i am now reminded of core war.) |
| | Shadow Account closed
Registered: Apr 2002 Posts: 355 |
Quote: Quoting ShadowCorrect, no specific state of anything is to be assumed! I'll make an alternate, secret viewer, that loads somewhere completely else in memory and abuses stack and registers etc. before calling the $0900 code, and if your sprites don't look the same way then, it will be disqualified! :)
Oh, nice. My only question then is how do we know what memory is safe to use as working space?
Hmm.. That's a good question, this is the kind of stuff that's the reason I opened this topic before starting the compo - there's things I simply haven't thought about!
At first I thought about no limits on what memory could be used, but I think keeping the spirit that it's supposed to be called from an intro or something, it would make sense to not allow it to totally overwrite all memory.
Perhaps:
zeropage is free to use as see fit.
stack can be used, but remember that this routine will be jsr:ed from some other place, so don't mess up the stackpointer!
Memory from $09xx-$3fff is free to allowed to be used by your code if needed.
Sounds good? |
| | ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Sounds good to me, Shadow.
(also, haha core war. Now there's a can of worms...) |
| | Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: what ZeRyk said. I am sceptical and think generated sprite font will be quite similar to the ones seen in the charROM compo, just a bit bigger. but let's go with the compo and prove me wrong! and sure count me in, I want the last place! :)
what ze smasher said. only idea I have is having some stencil extra 128 byte should allow for that. |
| | ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Um, a project template for ca65...
# This is a shell archive. Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file". Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
# Makefile
# disp.s
# font.s
# mem.cfg
#
echo x - Makefile
sed 's/^X//' >Makefile << 'END-of-Makefile'
XAS=ca65 --cpu 6502X
XLD=ld65
X
Xall: go.prg
Xrun: go.prg
X open $<
X
Xgo.prg: disp.o font.o
X $(LD) -o $@ -m init.map -C mem.cfg $(AFLAGS) $^
X
X%.o: %.s
X $(AS) $(AFLAGS) $<
Xclean:
X rm -f *.o *.prg *.map
END-of-Makefile
echo x - disp.s
sed 's/^X//' >disp.s << 'END-of-disp.s'
X .import generatefont
X .export fontbase
X
Xfontbase=$2000
X
X .segment "STARTUP"
X .word basicstub ; load address
Xbasicstub:
X .byte $0b,$08,$0a,$00,$9e,$32,$30,$38,$30,0,0,0 ; sys 2080
X .res 3
Xmulticol:
X .byte $00
Xbgcol:
X .byte $06
Xsprcol:
X .byte $0e
Xsprmcol1:
X .byte $00
Xsprmcol2:
X .byte $00
X .res 11
X
X sei
X lda multicol
X sta $d01c
X lda bgcol
X sta $d020
X sta $d021
X lda sprmcol1
X sta $d025
X lda sprmcol2
X sta $d026
X lda sprcol
X ldx #$07
X:
X sta $d027,x
X dex
X bpl :-
X ldx #$00
X lda #$20
X:
X sta $0400,x
X sta $0500,x
X sta $0600,x
X sta $0700,x
X inx
X bne :-
X lda #$ff
X sta $d015
X lda #$80
X sta $d010
X ldx #$07
X ldy #$00
X lda #$18+44
X:
X sta $d000,y
X clc
X adc #29
X iny
X iny
X dex
X bpl :-
X jsr generatefont
X lda #$35
X sta $01
Xmainloop:
X lda #$2f
X sta ycoord
X lda #$80
X sta spridx
Xyloop:
X lda ycoord
X:
X cmp $d012
X bne :-
X clc
X adc #4
X ldx #$07
X ldy #$00
X:
X sta $d001,y
X iny
X iny
X dex
X bpl :-
X ldx #$00
X ldy spridx
X:
X tya
X sta $07f8,x
X iny
X inx
X cpx #8
X bne :-
X clc
X lda spridx
X adc #8
X sta spridx
X lda ycoord
X adc #25
X sta ycoord
X cmp #$2f+8*25
X bne yloop
X jmp mainloop
X
Xycoord:
X .byte 0
Xspridx:
X .byte 0
X
END-of-disp.s
echo x - font.s
sed 's/^X//' >font.s << 'END-of-font.s'
X .export generatefont
X .import fontbase
X .segment "ZEROPAGE"
Xzp:
X .res 2
X
X .segment "FONT"
Xgeneratefont:
X lda#<fontbase
X sta zp
X lda#>fontbase
X sta zp+1
X rts
X
X
END-of-font.s
echo x - mem.cfg
sed 's/^X//' >mem.cfg << 'END-of-mem.cfg'
X
XMEMORY {
X ZP: start = $02, size = $fe, type = rw, define = yes;
X RAM: start = $07FF, size = $0201, define = yes, file = %O;
X}
XSEGMENTS {
X STARTUP: load = RAM, type = ro;
X FONT: load = RAM, type = ro, align=256;
X ZEROPAGE: load = ZP, type = zp;
X}
END-of-mem.cfg
exit
|
| | JackAsser
Registered: Jun 2002 Posts: 2014 |
@cjam: You don't really have to explicitly import exported symbols. |
Previous - 1 | 2 | 3 - Next | |