mirror of
https://github.com/irmen/prog8.git
synced 2025-11-03 04:17:16 +00:00
added doublebuffering to monogfx (in both lores and hires mode)
This commit is contained in:
@@ -22,18 +22,23 @@ monogfx {
|
||||
const ubyte MODE_STIPPLE = %00000001
|
||||
const ubyte MODE_INVERT = %00000010
|
||||
|
||||
uword buffer_visible, buffer_back
|
||||
|
||||
|
||||
sub lores() {
|
||||
; enable 320*240 bitmap mode
|
||||
buffer_visible = buffer_back = $0000
|
||||
cx16.VERA_CTRL=0
|
||||
cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1
|
||||
cx16.VERA_DC_HSCALE = 64
|
||||
cx16.VERA_DC_VSCALE = 64
|
||||
cx16.VERA_L1_CONFIG = %00000100
|
||||
cx16.VERA_L1_MAPBASE = 0
|
||||
cx16.VERA_L1_TILEBASE = 0
|
||||
cx16.VERA_L1_TILEBASE = 0 ; lores
|
||||
width = 320
|
||||
height = 240
|
||||
lores_mode = true
|
||||
buffer_visible = buffer_back = $0000
|
||||
mode = MODE_NORMAL
|
||||
clear_screen(false)
|
||||
}
|
||||
@@ -46,14 +51,40 @@ monogfx {
|
||||
cx16.VERA_DC_VSCALE = 128
|
||||
cx16.VERA_L1_CONFIG = %00000100
|
||||
cx16.VERA_L1_MAPBASE = 0
|
||||
cx16.VERA_L1_TILEBASE = %00000001
|
||||
cx16.VERA_L1_TILEBASE = %00000001 ; hires
|
||||
width = 640
|
||||
height = 480
|
||||
lores_mode = false
|
||||
buffer_visible = buffer_back = $0000
|
||||
mode = MODE_NORMAL
|
||||
clear_screen(false)
|
||||
}
|
||||
|
||||
sub enable_doublebuffer() {
|
||||
; enable double buffering mode
|
||||
if lores_mode {
|
||||
buffer_visible = $0000
|
||||
buffer_back = $2800
|
||||
} else {
|
||||
buffer_visible = $0000
|
||||
buffer_back = $9800
|
||||
}
|
||||
}
|
||||
|
||||
sub swap_buffers(bool wait_for_vsync) {
|
||||
; flip the buffers: make the back buffer visible and the other one now the backbuffer.
|
||||
; to avoid any screen tearing it is advised to call this during the vertical blank (pass true)
|
||||
if wait_for_vsync
|
||||
sys.waitvsync()
|
||||
cx16.r0 = buffer_back
|
||||
buffer_back = buffer_visible
|
||||
buffer_visible = cx16.r0
|
||||
cx16.VERA_CTRL = 0
|
||||
cx16.r0 &= %1111110000000000
|
||||
cx16.VERA_L1_TILEBASE = cx16.VERA_L1_TILEBASE & 1 | (cx16.r0H >>1 )
|
||||
}
|
||||
|
||||
|
||||
sub textmode() {
|
||||
; back to normal text mode
|
||||
cx16.r15L = cx16.VERA_DC_VIDEO & %00000111 ; retain chroma + output mode
|
||||
@@ -559,6 +590,7 @@ drawmode: ora cx16.r15L
|
||||
sub disc(uword @zp xcenter, uword @zp ycenter, ubyte @zp radius, bool draw) {
|
||||
; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen.
|
||||
; Midpoint algorithm, filled
|
||||
; Note: has problems with INVERT draw mode because of horizontal span overdrawing. Horizontal lines may occur.
|
||||
if radius==0
|
||||
return
|
||||
ubyte @zp yy = 0
|
||||
@@ -597,6 +629,7 @@ drawmode: ora cx16.r15L
|
||||
sub safe_disc(uword @zp xcenter, uword @zp ycenter, ubyte @zp radius, bool draw) {
|
||||
; Does bounds checking and clipping.
|
||||
; Midpoint algorithm, filled
|
||||
; Note: has problems with INVERT draw mode because of horizontal span overdrawing. Horizontal lines may occur.
|
||||
if radius==0
|
||||
return
|
||||
ubyte @zp yy = 0
|
||||
@@ -696,7 +729,7 @@ invert:
|
||||
adc p8v_times40_lsb,y
|
||||
sta cx16.VERA_ADDR_L
|
||||
lda p8v_times40_msb,y
|
||||
adc #0
|
||||
adc p8v_buffer_back+1
|
||||
sta cx16.VERA_ADDR_M
|
||||
|
||||
lda p8v_xx
|
||||
@@ -708,7 +741,6 @@ invert:
|
||||
; width=640 (hires)
|
||||
%asm {{
|
||||
stz cx16.VERA_CTRL
|
||||
stz cx16.VERA_ADDR_H
|
||||
lda p8v_xx
|
||||
and #7
|
||||
pha ; xbits
|
||||
@@ -723,10 +755,15 @@ invert:
|
||||
;xx /= 8
|
||||
xx += yy*(640/8)
|
||||
%asm {{
|
||||
lda p8v_xx+1
|
||||
sta cx16.VERA_ADDR_M
|
||||
lda p8v_xx
|
||||
sta cx16.VERA_ADDR_L
|
||||
lda p8v_xx+1
|
||||
clc
|
||||
adc p8v_buffer_back+1
|
||||
sta cx16.VERA_ADDR_M
|
||||
lda #0
|
||||
rol a ; hi bit carry also needed when double-buffering
|
||||
sta cx16.VERA_ADDR_H
|
||||
plx ; xbits
|
||||
lda p8v_maskbits,x
|
||||
}}
|
||||
@@ -768,11 +805,15 @@ invert:
|
||||
|
||||
%asm {{
|
||||
stz cx16.VERA_CTRL
|
||||
stz cx16.VERA_ADDR_H
|
||||
lda p8v_xx+1
|
||||
sta cx16.VERA_ADDR_M
|
||||
lda p8v_xx
|
||||
sta cx16.VERA_ADDR_L
|
||||
lda p8v_xx+1
|
||||
clc
|
||||
adc p8v_buffer_back+1
|
||||
sta cx16.VERA_ADDR_M
|
||||
lda #0
|
||||
rol a ; hi bit carry also needed when double-buffering
|
||||
sta cx16.VERA_ADDR_H
|
||||
ply ; xbits
|
||||
lda p8s_plot.p8v_maskbits,y
|
||||
and cx16.VERA_DATA0
|
||||
@@ -855,8 +896,8 @@ skip:
|
||||
}
|
||||
|
||||
sub fill_scanline_right() {
|
||||
; TODO maybe this could use vera auto increment, but that requires some clever masking calculations
|
||||
cx16.r9s = xx
|
||||
; TODO maybe this could use vera auto increment, but that requires some clever masking calculations
|
||||
cx16.r9s = xx
|
||||
while xx <= width-1 {
|
||||
if pgetset()
|
||||
break
|
||||
@@ -891,11 +932,15 @@ skip:
|
||||
|
||||
%asm {{
|
||||
stz cx16.VERA_CTRL
|
||||
stz cx16.VERA_ADDR_H
|
||||
lda p8v_xpos+1
|
||||
sta cx16.VERA_ADDR_M
|
||||
lda p8v_xpos
|
||||
sta cx16.VERA_ADDR_L
|
||||
lda p8v_xpos+1
|
||||
clc
|
||||
adc p8v_buffer_back+1
|
||||
sta cx16.VERA_ADDR_M
|
||||
lda #0
|
||||
rol a ; hi bit carry also needed when double-buffering
|
||||
sta cx16.VERA_ADDR_H
|
||||
ply ; xbits
|
||||
lda p8s_plot.p8v_maskbits,y
|
||||
and cx16.VERA_DATA0
|
||||
@@ -942,12 +987,12 @@ _doplot beq +
|
||||
ror a
|
||||
lsr a
|
||||
lsr a
|
||||
clc
|
||||
ldy p8v_yy
|
||||
clc
|
||||
adc p8v_times40_lsb,y
|
||||
sta cx16.VERA_ADDR_L
|
||||
lda p8v_times40_msb,y
|
||||
adc #0
|
||||
adc p8v_buffer_back+1
|
||||
sta cx16.VERA_ADDR_M
|
||||
lda #%00010000 ; autoincr
|
||||
sta cx16.VERA_ADDR_H
|
||||
@@ -975,8 +1020,11 @@ _doplot beq +
|
||||
lda cx16.r0L
|
||||
sta cx16.VERA_ADDR_L
|
||||
lda cx16.r0H
|
||||
clc
|
||||
adc p8v_buffer_back+1
|
||||
sta cx16.VERA_ADDR_M
|
||||
lda #%00010000 ; autoincr
|
||||
lda #%00001000 ; autoincr (1 bit shifted)
|
||||
rol a ; hi bit carry also needed when double-buffering
|
||||
sta cx16.VERA_ADDR_H
|
||||
}}
|
||||
}
|
||||
@@ -1146,15 +1194,11 @@ cdraw_mod2 ora cx16.VERA_DATA1
|
||||
cmp #0
|
||||
beq +
|
||||
lda #255
|
||||
+ ldy #80
|
||||
- sta cx16.VERA_DATA0
|
||||
sta cx16.VERA_DATA0
|
||||
sta cx16.VERA_DATA0
|
||||
sta cx16.VERA_DATA0
|
||||
sta cx16.VERA_DATA0
|
||||
sta cx16.VERA_DATA0
|
||||
sta cx16.VERA_DATA0
|
||||
+ ldy #40
|
||||
-
|
||||
.rept 16
|
||||
sta cx16.VERA_DATA0
|
||||
.endrept
|
||||
dey
|
||||
bne -
|
||||
rts
|
||||
|
||||
@@ -816,6 +816,7 @@ Full-screen lores or hires monochrome bitmap graphics routines, available on the
|
||||
- two resolutions: lores 320*240 or hires 640*480 bitmap mode
|
||||
- optimized routines for monochrome (2-color) graphics
|
||||
- clearing screen, switching screen mode, also back to text mode
|
||||
- doublebuffering option to avoid flicker
|
||||
- drawing and reading individual pixels
|
||||
- drawing lines, rectangles, filled rectangles, circles, discs
|
||||
- flood fill
|
||||
@@ -823,7 +824,7 @@ Full-screen lores or hires monochrome bitmap graphics routines, available on the
|
||||
- can draw using a stipple pattern (alternate black/white pixels) and in invert mode (toggle pixels)
|
||||
|
||||
Read the `monogfx source code <https://github.com/irmen/prog8/tree/master/compiler/res/prog8lib/cx16/monogfx.p8>`_
|
||||
to see what's in there.
|
||||
and the `testmonogfx` example program, to see what's in there.
|
||||
|
||||
|
||||
palette (cx16 only)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
Bug: monogfx circle, plot and line drawing with INVERT mode is broken (garbage pixels)
|
||||
|
||||
|
||||
STRUCTS: are being developed in their own separate branch for now, called "structs".
|
||||
Idea is to make it feature complete in the IR/Virtual target, then merge it to master?, and then start building the 6502 code generation for it.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%import monogfx
|
||||
%import textio
|
||||
%import math
|
||||
%import conv
|
||||
|
||||
%option no_sysinit
|
||||
%zeropage basicsafe
|
||||
@@ -18,8 +18,7 @@ main {
|
||||
sys.wait(2*60)
|
||||
demo2()
|
||||
|
||||
monogfx.textmode()
|
||||
txt.print("done!\n")
|
||||
doublebuffer.demo()
|
||||
}
|
||||
|
||||
sub demofill() {
|
||||
@@ -214,3 +213,40 @@ main {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
doublebuffer {
|
||||
sub demo() {
|
||||
monogfx.lores()
|
||||
monogfx.text_charset(1)
|
||||
monogfx.enable_doublebuffer()
|
||||
uword cx = 100
|
||||
|
||||
repeat {
|
||||
monogfx.clear_screen(false)
|
||||
monogfx.text(50, 10, true, iso:"Double Buffered")
|
||||
monogfx.circle(160, 120, 100, true)
|
||||
monogfx.disc(160, 120, 40, true)
|
||||
|
||||
monogfx.rect(40, 40, 240, 180, true)
|
||||
monogfx.drawmode(monogfx.MODE_STIPPLE)
|
||||
monogfx.fill(50, 50, true, 1)
|
||||
|
||||
monogfx.drawmode(monogfx.MODE_NORMAL)
|
||||
monogfx.fill(250, 50, true, 1)
|
||||
monogfx.fillrect( 10, 50, 20, 100, true)
|
||||
monogfx.line(10, 10, 300, 200, true)
|
||||
|
||||
repeat 200 {
|
||||
monogfx.plot($00e0 + math.randrange(64), 20 + math.randrange(20), true)
|
||||
}
|
||||
|
||||
monogfx.circle(cx, 219, 20, true)
|
||||
monogfx.text(cx+20, 225, true, conv.str_uw(cx))
|
||||
cx++
|
||||
monogfx.swap_buffers()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +1,21 @@
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
|
||||
%import math
|
||||
%import monogfx
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
word w1, w2, w3, w4
|
||||
uword uw1, uw2, uw3
|
||||
monogfx.hires()
|
||||
monogfx.fillrect(100, 100, 200, 100, true)
|
||||
|
||||
w1 = -111
|
||||
w2 = 222
|
||||
w3 = -333
|
||||
w4 = -20
|
||||
sys.wait(60)
|
||||
|
||||
uw1 = 111
|
||||
uw2 = 222
|
||||
uw3 = 333
|
||||
monogfx.drawmode(monogfx.MODE_INVERT)
|
||||
monogfx.circle(150, 120, 80, true) ; TODO INVERT is BROKEN
|
||||
monogfx.line(10, 20, 250, 160, true) ; TODO INVERT is BROKEN
|
||||
|
||||
txt.print_w(w2*w3)
|
||||
txt.spc()
|
||||
w1 = w2 * w3
|
||||
txt.print_w(w1)
|
||||
txt.nl()
|
||||
txt.print_w(w3*w4)
|
||||
txt.nl()
|
||||
repeat 500 {
|
||||
monogfx.plot( math.rnd(), math.rnd(), true) ; TODO INVERT is BROKEN
|
||||
}
|
||||
|
||||
txt.print_uw(uw2*uw3)
|
||||
txt.spc()
|
||||
uw1 = uw2 * uw3
|
||||
txt.print_uw(uw1)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
|
||||
|
||||
w1 = -111
|
||||
w2 = 22222
|
||||
w3 = -333
|
||||
w4 = -17
|
||||
|
||||
uw1 = 111
|
||||
uw2 = 22222
|
||||
uw3 = 333
|
||||
|
||||
txt.print_w(w2/w3)
|
||||
txt.spc()
|
||||
w1 = w2 / w3
|
||||
txt.print_w(w1)
|
||||
txt.nl()
|
||||
txt.print_w(w3/w4)
|
||||
txt.nl()
|
||||
|
||||
txt.print_uw(uw2/uw3)
|
||||
txt.spc()
|
||||
uw1 = uw2 / uw3
|
||||
txt.print_uw(uw1)
|
||||
txt.nl()
|
||||
repeat {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user