gfx_lores.set_screen_mode() is now gfx_lores.graphics_mode()

adding all missing routines from gfx2 to gfx_lores
This commit is contained in:
Irmen de Jong 2024-10-30 19:17:58 +01:00
parent 66b06d6c40
commit 73609636c5
5 changed files with 648 additions and 61 deletions

View File

@ -703,7 +703,7 @@ io_error:
; CommanderX16 extensions over the basic C64/C128 diskio routines: ; CommanderX16 extensions over the basic C64/C128 diskio routines:
; For use directly after a load or load_raw call (don't mess with the ram bank yet): ; For use directly after a load or load_raw call (don't mess with the ram bank yet):
; Calculates the number of bytes loaded (files > 64Kb ar truncated to 16 bits) ; Calculates the number of bytes loaded (files > 64Kb are truncated to 16 bits)
sub load_size(ubyte startbank, uword startaddress, uword endaddress) -> uword { sub load_size(ubyte startbank, uword startaddress, uword endaddress) -> uword {
return $2000 * (cx16.getrambank() - startbank) + endaddress - startaddress return $2000 * (cx16.getrambank() - startbank) + endaddress - startaddress
} }

View File

@ -2,14 +2,18 @@
; bitmap image needs to start at VRAM addres $00000. ; bitmap image needs to start at VRAM addres $00000.
; This is compatible with the CX16's screen mode 128. (void cx16.set_screen_mode(128)) ; This is compatible with the CX16's screen mode 128. (void cx16.set_screen_mode(128))
%import syslib
%import verafx %import verafx
gfx_lores { gfx_lores {
%option ignore_unused %option ignore_unused
sub set_screen_mode() { const uword WIDTH = 320
const ubyte HEIGHT = 240
sub graphics_mode() {
; enable 320x240 256c bitmap graphics mode
cx16.VERA_CTRL=0 cx16.VERA_CTRL=0
cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1 cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1
cx16.VERA_DC_HSCALE = 64 cx16.VERA_DC_HSCALE = 64
@ -20,6 +24,13 @@ gfx_lores {
clear_screen(0) clear_screen(0)
} }
sub text_mode() {
; back to normal text mode
cx16.r15L = cx16.VERA_DC_VIDEO & %00000111 ; retain chroma + output mode
cbm.CINT()
cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11111000) | cx16.r15L
}
sub clear_screen(ubyte color) { sub clear_screen(ubyte color) {
if verafx.available() { if verafx.available() {
; use verafx cache writes to quicly clear the screen ; use verafx cache writes to quicly clear the screen
@ -56,10 +67,10 @@ gfx_lores {
cx16.VERA_CTRL=0 cx16.VERA_CTRL=0
cx16.VERA_ADDR=0 cx16.VERA_ADDR=0
cx16.VERA_ADDR_H = 1<<4 ; 1 pixel auto increment cx16.VERA_ADDR_H = 1<<4 ; 1 pixel auto increment
repeat 240 { repeat HEIGHT {
%asm {{ %asm {{
lda p8v_color lda p8v_color
ldy #320/8 ldy #p8c_WIDTH/8
- .rept 8 - .rept 8
sta cx16.VERA_DATA0 sta cx16.VERA_DATA0
.endrept .endrept
@ -71,24 +82,145 @@ gfx_lores {
cx16.VERA_ADDR_H = 0 cx16.VERA_ADDR_H = 0
} }
asmsub plot(uword x @AX, ubyte y @Y, ubyte color @R0) { sub rect(uword xx, ubyte yy, uword rwidth, ubyte rheight, ubyte color) {
; x in r0, y in r1, color. if rwidth==0 or rheight==0
return
horizontal_line(xx, yy, rwidth, color)
if rheight==1
return
horizontal_line(xx, yy+rheight-1, rwidth, color)
vertical_line(xx, yy+1, rheight-2, color)
if rwidth==1
return
vertical_line(xx+rwidth-1, yy+1, rheight-2, color)
}
sub safe_rect(uword xx, ubyte yy, uword rwidth, ubyte rheight, ubyte color) {
; does bounds checking and clipping
safe_horizontal_line(xx, yy, rwidth, color)
if rheight==1
return
uword bottomyy = yy as uword + rheight -1
if bottomyy<HEIGHT
safe_horizontal_line(xx, lsb(bottomyy), rwidth, color)
safe_vertical_line(xx, yy+1, rheight-2, color)
if rwidth==1
return
safe_vertical_line(xx+rwidth-1, yy+1, rheight-2, color)
}
sub fillrect(uword xx, ubyte yy, uword rwidth, ubyte rheight, ubyte color) {
; Draw a filled rectangle of the given size and color.
; To fill the whole screen, use clear_screen(color) instead - it is much faster.
if rwidth==0
return
repeat rheight {
horizontal_line(xx, yy, rwidth, color)
yy++
}
}
sub safe_fillrect(uword xx, ubyte yy, uword rwidth, ubyte rheight, ubyte color) {
; Draw a filled rectangle of the given size and color.
; To fill the whole screen, use clear_screen(color) instead - it is much faster.
; This safe version does bounds checking and clipping.
if xx>=WIDTH or yy>=HEIGHT
return
if msb(xx)&$80!=0 {
rwidth += xx
xx = 0
}
if xx>=WIDTH
return
if xx+rwidth>WIDTH
rwidth = WIDTH-xx
if rwidth>WIDTH
return
if yy as uword + rheight > HEIGHT
rheight = HEIGHT-yy
if rheight>HEIGHT
return
repeat rheight {
horizontal_line(xx, yy, rwidth, color)
yy++
}
}
sub horizontal_line(uword xx, ubyte yy, uword length, ubyte color) {
if length==0
return
plot(xx, yy, color) ; set starting position by reusing plot routine
; set vera auto-increment to 1 pixel
cx16.VERA_ADDR_H = cx16.VERA_ADDR_H & %00000111 | (1<<4)
%asm {{ %asm {{
clc lda p8v_color
adc times320_lo,y ldx p8v_length+1
sta cx16.VERA_ADDR_L beq +
txa ldy #0
adc times320_mid,y - sta cx16.VERA_DATA0
sta cx16.VERA_ADDR_M iny
lda #0 bne -
adc times320_hi,y dex
sta cx16.VERA_ADDR_H bne -
lda cx16.r0L + ldy p8v_length ; remaining
sta cx16.VERA_DATA0 beq +
rts - sta cx16.VERA_DATA0
dey
bne -
+
}} }}
} }
sub safe_horizontal_line(uword xx, ubyte yy, uword length, ubyte color) {
; does bounds checking and clipping
if yy>=HEIGHT
return
if msb(xx)&$80!=0 {
length += xx
xx = 0
}
if xx>=WIDTH
return
if xx+length>WIDTH
length = WIDTH-xx
if length>WIDTH
return
horizontal_line(xx, yy, length, color)
}
sub vertical_line(uword xx, ubyte yy, ubyte lheight, ubyte color) {
if lheight==0
return
plot(xx, yy, color) ; set starting position by reusing plot routine
; set vera auto-increment to 320 pixel increment (=next line)
cx16.VERA_ADDR_H = cx16.VERA_ADDR_H & %00000111 | (14<<4)
%asm {{
ldy p8v_lheight
lda p8v_color
- sta cx16.VERA_DATA0
dey
bne -
}}
}
sub safe_vertical_line(uword xx, ubyte yy, ubyte lheight, ubyte color) {
; does bounds checking and clipping
if yy>=HEIGHT
return
if msb(xx)&$80!=0 or xx>=WIDTH
return
if yy as uword + lheight > HEIGHT
lheight = HEIGHT-yy
if lheight>HEIGHT
return
vertical_line(xx, yy, lheight, color)
}
sub line(uword x1, ubyte y1, uword x2, ubyte y2, ubyte color) { sub line(uword x1, ubyte y1, uword x2, ubyte y2, ubyte color) {
; Bresenham algorithm. ; Bresenham algorithm.
; This code special-cases various quadrant loops to allow simple ++ and -- operations. ; This code special-cases various quadrant loops to allow simple ++ and -- operations.
@ -214,48 +346,491 @@ gfx_lores {
} }
} }
sub horizontal_line(uword xx, ubyte yy, uword length, ubyte color) { sub circle(uword @zp xcenter, ubyte @zp ycenter, ubyte radius, ubyte color) {
if length==0 ; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen.
; Midpoint algorithm.
if radius==0
return return
plot(xx, yy, color) ; set starting position by reusing plot routine
; set vera auto-increment to 1 pixel
cx16.VERA_ADDR_H = cx16.VERA_ADDR_H & %00000111 | (1<<4)
ubyte @zp xx = radius
ubyte @zp yy = 0
word @zp decisionOver2 = (1 as word)-xx
; R14 = internal plot X
; R15 = internal plot Y
while xx>=yy {
cx16.r14 = xcenter + xx
cx16.r15 = ycenter + yy
plotq()
cx16.r14 = xcenter - xx
plotq()
cx16.r14 = xcenter + xx
cx16.r15 = ycenter - yy
plotq()
cx16.r14 = xcenter - xx
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter + xx
plotq()
cx16.r14 = xcenter - yy
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter - xx
plotq()
cx16.r14 = xcenter - yy
plotq()
yy++
if decisionOver2>=0 {
xx--
decisionOver2 -= xx*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
sub plotq() {
; cx16.r14 = x, cx16.r15 = y, color=color.
plot(cx16.r14, cx16.r15L, color)
}
}
sub safe_circle(uword @zp xcenter, uword @zp ycenter, ubyte radius, ubyte color) {
; This version does bounds checks and clipping, but is a lot slower.
; Midpoint algorithm.
if radius==0
return
ubyte @zp xx = radius
ubyte @zp yy = 0
word @zp decisionOver2 = (1 as word)-xx
; R14 = internal plot X
; R15 = internal plot Y
while xx>=yy {
cx16.r14 = xcenter + xx
cx16.r15 = ycenter + yy
plotq()
cx16.r14 = xcenter - xx
plotq()
cx16.r14 = xcenter + xx
cx16.r15 = ycenter - yy
plotq()
cx16.r14 = xcenter - xx
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter + xx
plotq()
cx16.r14 = xcenter - yy
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter - xx
plotq()
cx16.r14 = xcenter - yy
plotq()
yy++
if decisionOver2>=0 {
xx--
decisionOver2 -= xx*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
sub plotq() {
; cx16.r14 = x, cx16.r15 = y, color=color.
if cx16.r15 < HEIGHT
safe_plot(cx16.r14, cx16.r15L, color)
}
}
sub disc(uword @zp xcenter, ubyte @zp ycenter, ubyte @zp radius, ubyte color) {
; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen.
; Midpoint algorithm, filled
if radius==0
return
ubyte @zp yy = 0
word @zp decisionOver2 = (1 as word)-radius
ubyte last_y3 = ycenter+radius
ubyte last_y4 = ycenter-radius
ubyte new_y3, new_y4
while radius>=yy {
horizontal_line(xcenter-radius, ycenter+yy, radius*$0002+1, color)
horizontal_line(xcenter-radius, ycenter-yy, radius*$0002+1, color)
new_y3 = ycenter+radius
if new_y3 != last_y3 {
horizontal_line(xcenter-yy, last_y3, yy*$0002+1, color)
last_y3 = new_y3
}
new_y4 = ycenter-radius
if new_y4 != last_y4 {
horizontal_line(xcenter-yy, last_y4, yy*$0002+1, color)
last_y4 = new_y4
}
yy++
if decisionOver2>=0 {
radius--
decisionOver2 -= radius*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
; draw the final two spans
yy--
horizontal_line(xcenter-yy, last_y3, yy*$0002+1, color)
horizontal_line(xcenter-yy, last_y4, yy*$0002+1, color)
}
sub safe_disc(uword @zp xcenter, uword @zp ycenter, ubyte @zp radius, ubyte color) {
; This version does bounds checks and clipping, but is a lot slower.
; Midpoint algorithm, filled
if radius==0
return
ubyte @zp yy = 0
word @zp decisionOver2 = (1 as word)-radius
uword last_y3 = ycenter+radius
uword last_y4 = ycenter-radius
uword new_y3, new_y4
while radius>=yy {
uword liney = ycenter+yy
if msb(liney)==0
safe_horizontal_line(xcenter-radius, lsb(ycenter+yy), radius*$0002+1, color)
liney = ycenter-yy
if msb(liney)==0
safe_horizontal_line(xcenter-radius, lsb(ycenter-yy), radius*$0002+1, color)
new_y3 = ycenter+radius
if new_y3 != last_y3 {
if msb(last_y3)==0
safe_horizontal_line(xcenter-yy, lsb(last_y3), yy*$0002+1, color)
last_y3 = new_y3
}
new_y4 = ycenter-radius
if new_y4 != last_y4 {
if msb(last_y4)==0
safe_horizontal_line(xcenter-yy, lsb(last_y4), yy*$0002+1, color)
last_y4 = new_y4
}
yy++
if decisionOver2>=0 {
radius--
decisionOver2 -= radius*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
; draw the final two spans
yy--
if msb(last_y3)==0
safe_horizontal_line(xcenter-yy, lsb(last_y3), yy*$0002+1, color)
if msb(last_y4)==0
safe_horizontal_line(xcenter-yy, lsb(last_y4), yy*$0002+1, color)
}
asmsub plot(uword x @AX, ubyte y @Y, ubyte color @R0) {
; x in r0, y in r1, color.
%asm {{ %asm {{
lda p8v_color clc
ldx p8v_length+1 adc times320_lo,y
sta cx16.VERA_ADDR_L
txa
adc times320_mid,y
sta cx16.VERA_ADDR_M
lda #0
adc times320_hi,y
sta cx16.VERA_ADDR_H
lda cx16.r0L
sta cx16.VERA_DATA0
rts
}}
}
sub safe_plot(uword xx, ubyte yy, ubyte color) {
; A plot that does bounds checks to see if the pixel is inside the screen.
if msb(xx)&$80!=0
return
if xx >= WIDTH or yy >= HEIGHT
return
plot(xx, yy, color)
}
asmsub pget(uword x @AX, ubyte y @Y) -> ubyte @A {
; returns the color of the pixel
%asm {{
jsr p8s_position
lda cx16.VERA_DATA0
rts
}}
}
sub fill(uword x, ubyte y, ubyte new_color) {
; reuse a few virtual registers in ZP for variables
&ubyte fillm = &cx16.r7L
&ubyte seedm = &cx16.r8L
&ubyte cmask = &cx16.r8H
&ubyte vub = &cx16.r13L
&ubyte nvub = &cx16.r13H
ubyte[4] amask = [$c0,$30,$0c,$03] ; array of cmask bytes
; Non-recursive scanline flood fill.
; based loosely on code found here https://www.codeproject.com/Articles/6017/QuickFill-An-efficient-flood-fill-algorithm
; with the fixes applied to the seedfill_4 routine as mentioned in the comments.
const ubyte MAXDEPTH = 100
word @zp xx = x as word
word @zp yy = y as word
word[MAXDEPTH] @split @shared stack_xl
word[MAXDEPTH] @split @shared stack_xr
word[MAXDEPTH] @split @shared stack_y
byte[MAXDEPTH] @shared stack_dy
cx16.r12L = 0 ; stack pointer
word x1
word x2
byte dy
cx16.r10L = new_color
sub push_stack(word sxl, word sxr, word sy, byte sdy) {
if cx16.r12L==MAXDEPTH
return
cx16.r0s = sy+sdy
if cx16.r0s>=0 and cx16.r0s<=HEIGHT-1 {
;; stack_xl[cx16.r12L] = sxl
;; stack_xr[cx16.r12L] = sxr
;; stack_y[cx16.r12L] = sy
;; stack_dy[cx16.r12L] = sdy
;; cx16.r12L++
%asm {{
ldy cx16.r12L
lda p8v_sxl
sta p8v_stack_xl_lsb,y
lda p8v_sxl+1
sta p8v_stack_xl_msb,y
lda p8v_sxr
sta p8v_stack_xr_lsb,y
lda p8v_sxr+1
sta p8v_stack_xr_msb,y
lda p8v_sy
sta p8v_stack_y_lsb,y
lda p8v_sy+1
sta p8v_stack_y_msb,y
ldy cx16.r12L
lda p8v_sdy
sta p8v_stack_dy,y
inc cx16.r12L
}}
}
}
sub pop_stack() {
;; cx16.r12L--
;; x1 = stack_xl[cx16.r12L]
;; x2 = stack_xr[cx16.r12L]
;; y = stack_y[cx16.r12L]
;; dy = stack_dy[cx16.r12L]
%asm {{
dec cx16.r12L
ldy cx16.r12L
lda p8v_stack_xl_lsb,y
sta p8v_x1
lda p8v_stack_xl_msb,y
sta p8v_x1+1
lda p8v_stack_xr_lsb,y
sta p8v_x2
lda p8v_stack_xr_msb,y
sta p8v_x2+1
lda p8v_stack_y_lsb,y
sta p8v_yy
lda p8v_stack_y_msb,y
sta p8v_yy+1
ldy cx16.r12L
lda p8v_stack_dy,y
sta p8v_dy
}}
yy+=dy
}
cx16.r11L = pget(xx as uword, lsb(yy)) ; old_color
if cx16.r11L == cx16.r10L
return
if xx<0 or xx>WIDTH-1 or yy<0 or yy>HEIGHT-1
return
push_stack(xx, xx, yy, 1)
push_stack(xx, xx, yy + 1, -1)
word left = 0
while cx16.r12L!=0 {
pop_stack()
xx = x1
if fill_scanline_left_8bpp() goto skip
left = xx + 1
if left < x1
push_stack(left, x1 - 1, yy, -dy)
xx = x1 + 1
do {
fill_scanline_right_8bpp()
push_stack(left, xx - 1, yy, dy)
if xx > x2 + 1
push_stack(x2 + 1, xx - 1, yy, -dy)
skip:
xx++
while xx <= x2 {
if pget(xx as uword, lsb(yy)) == cx16.r11L
break
xx++
}
left = xx
} until xx>x2
}
sub set_vera_address(bool decr) {
; set both data0 and data1 addresses
position(xx as uword, lsb(yy))
cx16.r0 = cx16.VERA_ADDR
cx16.r1L = cx16.VERA_ADDR_H & 1 | if decr %00011000 else %00010000
cx16.VERA_ADDR_H = cx16.r1L
cx16.VERA_CTRL = 1
cx16.VERA_ADDR = cx16.r0
cx16.VERA_ADDR_H = cx16.r1L
cx16.VERA_CTRL = 0
}
sub fill_scanline_left_8bpp() -> bool {
set_vera_address(true)
cx16.r9s = xx
while xx >= 0 {
if cx16.VERA_DATA0 != cx16.r11L
break
cx16.VERA_DATA1 = cx16.r10L
xx--
}
return xx==cx16.r9s
}
sub fill_scanline_right_8bpp() {
set_vera_address(false)
while xx <= WIDTH-1 {
if cx16.VERA_DATA0 != cx16.r11L
break
cx16.VERA_DATA1 = cx16.r10L
xx++
}
}
}
sub text_charset(ubyte charset) {
; -- select the text charset to use with the text() routine
; the charset number is the same as for the cx16.screen_set_charset() ROM function.
; 1 = ISO charset, 2 = PETSCII uppercase+graphs, 3= PETSCII uppercase+lowercase etc. etc.
cx16.screen_set_charset(charset, 0)
}
const ubyte charset_bank = $1
const uword charset_addr = $f000 ; in bank 1, so $1f000
sub text(uword @zp xx, uword yy, ubyte color, uword textptr) {
; -- Write some text at the given pixel position. The text string must be in an encoding approprite for the charset.
; You must also have called text_charset() first to select and prepare the character set to use.
uword chardataptr
ubyte[8] @shared char_bitmap_bytes_left
ubyte[8] @shared char_bitmap_bytes_right
while @(textptr)!=0 {
chardataptr = charset_addr + (@(textptr) as uword)*8
cx16.vaddr(charset_bank, chardataptr, 1, 1)
repeat 8 {
position(xx,lsb(yy))
yy++
%asm {{
ldx p8v_color
lda cx16.VERA_DATA1
sta P8ZP_SCRATCH_B1
ldy #8
- asl P8ZP_SCRATCH_B1
bcc +
stx cx16.VERA_DATA0 ; write a pixel
bra ++
+ lda cx16.VERA_DATA0 ; don't write a pixel, but do advance to the next address
+ dey
bne -
}}
}
xx+=8
yy-=8
textptr++
}
}
asmsub position(uword x @AX, ubyte y @Y) {
%asm {{
clc
adc times320_lo,y
sta cx16.VERA_ADDR_L
txa
adc times320_mid,y
sta cx16.VERA_ADDR_M
lda #%00010000 ; auto increment on
adc times320_hi,y
sta cx16.VERA_ADDR_H
rts
}}
}
inline asmsub next_pixel(ubyte color @A) {
; -- sets the next pixel byte to the graphics chip.
; for 8 bpp screens this will plot 1 pixel.
; for 2 bpp screens it will plot 4 pixels at once (color = bit pattern).
%asm {{
sta cx16.VERA_DATA0
}}
}
asmsub next_pixels(uword pixels @AY, uword amount @R0) clobbers(A, X, Y) {
; -- sets the next bunch of pixels from a prepared array of bytes.
; for 8 bpp screens this will plot 1 pixel per byte.
; for 2 bpp screens it will plot 4 pixels at once (colors are the bit patterns per byte).
%asm {{
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
ldx cx16.r0+1
beq + beq +
ldy #0 ldy #0
- sta cx16.VERA_DATA0 - lda (P8ZP_SCRATCH_W1),y
sta cx16.VERA_DATA0
iny iny
bne - bne -
inc P8ZP_SCRATCH_W1+1 ; next page of 256 pixels
dex dex
bne - bne -
+ ldy p8v_length ; remaining
+ ldx cx16.r0 ; remaining pixels
beq + beq +
- sta cx16.VERA_DATA0 ldy #0
dey - lda (P8ZP_SCRATCH_W1),y
sta cx16.VERA_DATA0
iny
dex
bne - bne -
+ + rts
}} }}
} }
sub vertical_line(uword xx, ubyte yy, ubyte lheight, ubyte color) { asmsub set_8_pixels_from_bits(ubyte bits @R0, ubyte oncolor @A, ubyte offcolor @Y) clobbers(X) {
if lheight==0 ; this is only useful in 256 color mode where one pixel equals one byte value.
return
plot(xx, yy, color) ; set starting position by reusing plot routine
; set vera auto-increment to 320 pixel increment (=next line)
cx16.VERA_ADDR_H = cx16.VERA_ADDR_H & %00000111 | (14<<4)
%asm {{ %asm {{
ldy p8v_lheight ldx #8
lda p8v_color - asl cx16.r0
- sta cx16.VERA_DATA0 bcc +
dey sta cx16.VERA_DATA0
bra ++
+ sty cx16.VERA_DATA0
+ dex
bne - bne -
rts
}} }}
} }
%asm {{ %asm {{
; multiplication by 320 lookup table ; multiplication by 320 lookup table
times320 := 320*range(240) times320 := 320*range(240)
@ -265,4 +840,3 @@ times320_mid .byte >times320
times320_hi .byte `times320 times320_hi .byte `times320
}} }}
} }

View File

@ -1,7 +1,8 @@
TODO TODO
==== ====
Allow %merge to overwrite existing subs if the signature is identical? Transform gfx2 into gfx_hires
Add a eor mode to gfx_lores / gfx_hires
Improve register load order in subroutine call args assignments: Improve register load order in subroutine call args assignments:
in certain situations, the "wrong" order of evaluation of function call arguments is done which results in certain situations, the "wrong" order of evaluation of function call arguments is done which results

View File

@ -25,7 +25,7 @@ main {
uword[NUM_STARS] @split prev_x uword[NUM_STARS] @split prev_x
ubyte[NUM_STARS] prev_y ubyte[NUM_STARS] prev_y
gfx_lores.set_screen_mode() gfx_lores.graphics_mode()
; init the star positions ; init the star positions
ubyte star ubyte star

View File

@ -1,26 +1,38 @@
%import textio %import textio
%import gfx2
%import gfx_lores
%option no_sysinit %option no_sysinit
%zeropage basicsafe %zeropage basicsafe
main { main {
sub start() { sub start() {
txt.print("sdfdsf") gfx_lores.graphics_mode()
; gfx2.screen_mode(1)
gfx_lores.text_charset(1)
for cx16.r9L in 0 to 10 {
gfx_lores.text(50+cx16.r9L, 20+cx16.r9L, cx16.r9L, sc:"the quick brown fox 12345")
} }
gfx_lores.text_charset(2)
for cx16.r9L in 0 to 10 {
gfx_lores.text(50+cx16.r9L, 40+cx16.r9L, cx16.r9L, sc:"the quick brown fox 12345")
}
gfx_lores.text_charset(3)
for cx16.r9L in 0 to 10 {
gfx_lores.text(50+cx16.r9L, 60+cx16.r9L, cx16.r9L, sc:"the quick brown fox 12345")
}
gfx_lores.text_charset(4)
for cx16.r9L in 0 to 10 {
gfx_lores.text(50+cx16.r9L, 80+cx16.r9L, cx16.r9L, sc:"the quick brown fox 12345")
}
gfx_lores.text_charset(5)
for cx16.r9L in 0 to 10 {
gfx_lores.text(50+cx16.r9L, 100+cx16.r9L, cx16.r9L, sc:"the quick brown fox 12345")
} }
txt {
; merges this block into the txt block coming from the textio library
%option merge
sub print(str text) {
repeat 4 chrout('@')
repeat { repeat {
cx16.r0L = @(text)
if_z break
chrout(cx16.r0L)
text++
}
repeat 4 chrout('@')
} }
} }
}