Adding transparency and switching to plain 6502.

This commit is contained in:
Martin Haye 2013-11-10 11:19:29 -08:00
parent 858973dc68
commit fddd8a503f
6 changed files with 6408 additions and 5661 deletions

View File

@ -187,11 +187,14 @@ class PackMap
} }
} }
// The renderer wants bits of the two pixels interleaved // The renderer wants bits of the two pixels interleaved in a special way.
// Given input pix1=00000xyz and pix2=00000qrs, the output will be 00xqyrzs.
// So the renderer uses mask 00101010 to extract pix1, and 00010101 for pix2.
//
def combine(pix1, pix2) { def combine(pix1, pix2) {
return ((pix1 & 1) << 0) | ((pix2 & 1) << 1) | return ((pix2 & 1) << 0) | ((pix1 & 1) << 1) |
((pix1 & 2) << 1) | ((pix2 & 2) << 2) | ((pix2 & 2) << 1) | ((pix1 & 2) << 2) |
((pix1 & 4) << 2) | ((pix2 & 4) << 3); ((pix2 & 4) << 2) | ((pix1 & 4) << 3);
} }
def writeImage(stream, image) def writeImage(stream, image)

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,4 @@
.pc02
; Select mipmap level 0 (64x64 pixels = 32x32 bytes) ; Select mipmap level 0 (64x64 pixels = 32x32 bytes)
selectMip0: selectMip0:
; pTex is already pointing at level 0, no need to adjust its level. ; pTex is already pointing at level 0, no need to adjust its level.
@ -8,9 +6,10 @@ selectMip0:
; is 0..255 pixels, which we need to translate to 0..31 columns; that's ; is 0..255 pixels, which we need to translate to 0..31 columns; that's
; a divide by 8. But then we need to multiply by 32 bytes per column, ; a divide by 8. But then we need to multiply by 32 bytes per column,
; so (1/8)*32 = 4, so we need to multiply by 4 after masking. ; so (1/8)*32 = 4, so we need to multiply by 4 after masking.
lda #0
sta tmp
lda txColumn lda txColumn
and #$F8 ; retain upper 5 bits and #$F8 ; retain upper 5 bits
stz tmp
asl asl
rol tmp ; multiplied by 2 rol tmp ; multiplied by 2
asl asl
@ -25,7 +24,8 @@ mipReady:
sta pTex+1 sta pTex+1
ldy pixNum ; get offset into the blit roll for this column ldy pixNum ; get offset into the blit roll for this column
ldx @blitOffsets,y ldx @blitOffsets,y
ldy #0 ; default to copying from top of column ldy #$FF ; default to copying from top of column (will be 0 after initial INY in unrolled code)
clv ; so code can use BVC to branch always without BRA
rts rts
@blitOffsets: .byte BLIT_OFF0,BLIT_OFF1,BLIT_OFF2,BLIT_OFF3,BLIT_OFF4,BLIT_OFF5,BLIT_OFF6 @blitOffsets: .byte BLIT_OFF0,BLIT_OFF1,BLIT_OFF2,BLIT_OFF3,BLIT_OFF4,BLIT_OFF5,BLIT_OFF6
@ -39,7 +39,7 @@ selectMip1:
lda txColumn lda txColumn
and #$F0 ; retain upper 4 bits and #$F0 ; retain upper 4 bits
ldy #>MIP_OFFSET_1 ; adjust to mip level 1 ldy #>MIP_OFFSET_1 ; adjust to mip level 1
bra mipReady bne mipReady ; always taken
; Select mipmap level 2 (16x16 pixels = 8x8 bytes) ; Select mipmap level 2 (16x16 pixels = 8x8 bytes)
selectMip2: selectMip2:
@ -54,7 +54,7 @@ selectMip2:
lsr ; div by 4 lsr ; div by 4
; no need to add #<MIP_OFFSET_2, since it is zero. ; no need to add #<MIP_OFFSET_2, since it is zero.
ldy #>MIP_OFFSET_2 ; adjust to mip level 2 ldy #>MIP_OFFSET_2 ; adjust to mip level 2
bra mipReady bne mipReady ; always taken
; Select mipmap level 3 (8x8 pixels = 4x4 bytes) ; Select mipmap level 3 (8x8 pixels = 4x4 bytes)
selectMip3: selectMip3:
@ -72,7 +72,7 @@ selectMip3:
clc clc
adc #<MIP_OFFSET_3 adc #<MIP_OFFSET_3
ldy #>MIP_OFFSET_3 ; adjust to mip level 3 ldy #>MIP_OFFSET_3 ; adjust to mip level 3
bra mipReady bne mipReady ; always taken
; Select mipmap level 4 (4x4 pixels = 2x2 bytes) ; Select mipmap level 4 (4x4 pixels = 2x2 bytes)
selectMip4: selectMip4:
@ -88,13 +88,13 @@ selectMip4:
: clc : clc
adc #<MIP_OFFSET_4 adc #<MIP_OFFSET_4
ldy #>MIP_OFFSET_4 ; adjust to mip level 4 ldy #>MIP_OFFSET_4 ; adjust to mip level 4
bra mipReady bne mipReady ; always taken
; Select mipmap level 5 (2x2 pixels = 1x1 bytes) ; Select mipmap level 5 (2x2 pixels = 1x1 bytes)
selectMip5: selectMip5:
; Mip level 5 is super-easy: it's one byte. Not much choice there. ; Mip level 5 is super-easy: it's one byte. Not much choice there.
lda #<MIP_OFFSET_5 lda #<MIP_OFFSET_5
ldy #>MIP_OFFSET_5 ldy #>MIP_OFFSET_5
bra mipReady bne mipReady ; always taken

View File

@ -5,7 +5,7 @@
import copy, math, os, re, sys import copy, math, os, re, sys
# Main control on size vs. speed # Main control on size vs. speed
rowInterval = 5 rowInterval = 4
# Height of textures, in pixels # Height of textures, in pixels
textureHeight = 64 textureHeight = 64
@ -52,9 +52,9 @@ def calcSpace(cmds):
n = 0 n = 0
for c in cmds: for c in cmds:
if c == "L": if c == "L":
space += 3 # LDA (ptr),y / INY space += 5 # INY / LDA (ptr),y / BPL
elif c == "<": elif c == "<":
space += 1 # LSR space += 3 # ASL / BMI
else: else:
n += c n += c
space += 3 # STA row,x space += 3 # STA row,x
@ -90,6 +90,8 @@ class Segment:
global outFile, allLabels, generatedLabels global outFile, allLabels, generatedLabels
print("genCode %s, trunc=%r" % (s.label, s.truncPos)) print("genCode %s, trunc=%r" % (s.label, s.truncPos))
first = grouped first = grouped
needTransparencyCheck = True
prefix = " "
for i in range(len(s.cmds)): for i in range(len(s.cmds)):
if i == s.truncPos: if i == s.truncPos:
if grouped: if grouped:
@ -98,32 +100,50 @@ class Segment:
return return
if s.refs == 1: if s.refs == 1:
# singletons aren't generated near their target # singletons aren't generated near their target
outFile.write(" jmp %s\n" % s.truncLabel) outFile.write("%s jmp %s\n" % (prefix, s.truncLabel))
prefix = " "
else: else:
# non-singletons are generated near their target # non-singletons are generated near their target
outFile.write(" bra %s\n" % s.truncLabel) outFile.write("%s bvc %s\n" % (prefix, s.truncLabel))
prefix = " "
else: else:
outFile.write(" jsr %s\n" % s.truncLabel) outFile.write("%s jsr %s\n" % (prefix, s.truncLabel))
prefix = " "
break break
label = calcLabel(s.cmds[i:]) label = calcLabel(s.cmds[i:])
if label not in generatedLabels and (first or label in allLabels): if label not in generatedLabels and (first or label in allLabels):
if prefix != " ":
outFile.write("%s\n" % prefix)
prefix = " "
outFile.write("%s:\n" % label) outFile.write("%s:\n" % label)
generatedLabels.add(label) generatedLabels.add(label)
needTransparencyCheck = True
first = False first = False
c = s.cmds[i] c = s.cmds[i]
if c == 'L': if c == 'L':
outFile.write("%s iny\n" % prefix)
prefix = " "
outFile.write(" lda (pTex),y\n") outFile.write(" lda (pTex),y\n")
outFile.write(" iny\n") needTransparencyCheck = True
elif c == '<': elif c == '<':
outFile.write(" lsr\n") outFile.write("%s asl\n" % prefix)
prefix = " "
needTransparencyCheck = True
else: else:
assert c < screenHeight assert c < screenHeight
if needTransparencyCheck:
outFile.write(" bmi :+\n")
prefix = ":"
outFile.write(" sta %s*BLIT_STRIDE + blitRoll,x\n" % c) outFile.write(" sta %s*BLIT_STRIDE + blitRoll,x\n" % c)
needTransparencyCheck = False
else: else:
if grouped: if grouped:
outFile.write(" rts\n") outFile.write("%s rts\n" % prefix)
prefix = " "
if grouped: if grouped:
outFile.write("\n") outFile.write("\n")
if prefix != " ":
outFile.write("%s\n" % prefix)
outFile.flush() outFile.flush()
s.generated = True s.generated = True
@ -289,7 +309,7 @@ for (srcHeight, dstHeight, mipLevel, texOff, segs) in allHeights:
outFile.write("expand_%d:\n" % dstHeight) outFile.write("expand_%d:\n" % dstHeight)
outFile.write(" jsr selectMip%d\n" % mipLevel) outFile.write(" jsr selectMip%d\n" % mipLevel)
if (texOff != 0): if (texOff != 0):
outFile.write(" ldy #%d\n" % texOff) outFile.write(" ldy #%d\n" % (texOff-1)) # -1 because we always do initial INY before LDA (ptr,Y)
for i in range(len(segs)): for i in range(len(segs)):
seg = allSegs[segs[i]] seg = allSegs[segs[i]]
if seg.refs == 1 and not(seg.generated): if seg.refs == 1 and not(seg.generated):

View File

@ -3,10 +3,10 @@
; Constants ; Constants
TOP_LINE = $2180 ; 24 lines down from top TOP_LINE = $2180 ; 24 lines down from top
NLINES = 128 NLINES = 128
SKY_COLOR_E = $11 ; blue SKY_COLOR_E = $22 ; blue
SKY_COLOR_O = $11 ; blue SKY_COLOR_O = $22 ; blue
GROUND_COLOR_E = $14 ; orange GROUND_COLOR_E = $28 ; orange
GROUND_COLOR_O = $10 ; hi-bit black GROUND_COLOR_O = $20 ; hi-bit black
TEX_SIZE = $555 ; 32x32 + 16x16 + 8x8 + 4x4 + 2x2 + 1x1 TEX_SIZE = $555 ; 32x32 + 16x16 + 8x8 + 4x4 + 2x2 + 1x1
; Byte offset for each pixel in the blit unroll ; Byte offset for each pixel in the blit unroll

View File

@ -1,7 +1,7 @@
.org $7000 .org $7000
.pc02 ; Enable 65c02 ops .pc02
; This code is written bottom-up. That is, simple routines first, ; This code is written bottom-up. That is, simple routines first,
; then routines that call those to build complexity. The main ; then routines that call those to build complexity. The main
@ -80,11 +80,15 @@ texAddrHi: .res MAX_TEXTURES
.if DEBUG .if DEBUG
php php
pha pha
phx tya
phy pha
txa
pha
jsr rdkey jsr rdkey
ply pla
plx tay
pla
tax
pla pla
plp plp
.endif .endif
@ -131,7 +135,7 @@ _writeStr:
: inc @ld+1 : inc @ld+1
bne @ld bne @ld
inc @ld+2 inc @ld+2
bra @ld bne @ld ; always taken
@done: @done:
lda @ld+2 lda @ld+2
pha pha
@ -184,7 +188,7 @@ umul_bb_b:
tya tya
tax tax
ldy tmp ldy tmp
bra @x_lt_4 ; then re-use code jmp @x_lt_4 ; then re-use code
;------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------
; Calculate log2 of a 16-bit number. ; Calculate log2 of a 16-bit number.
@ -358,7 +362,7 @@ castRay:
bmi @negX bmi @negX
inc mapX inc mapX
iny ; also the Y reg which indexes the map iny ; also the Y reg which indexes the map
bra @checkX jmp @checkX
@negX: @negX:
dec mapX dec mapX
dey dey
@ -416,7 +420,7 @@ castRay:
adc mapWidth adc mapWidth
bcc @checkY bcc @checkY
inc pMap+1 inc pMap+1
bra @checkY bne @checkY ; always taken
@negY: @negY:
dec mapY dec mapY
sec sec
@ -804,20 +808,21 @@ clearBlit:
makeDecodeTbls: makeDecodeTbls:
ldx #0 ldx #0
@shiftA: @shiftA:
; bit 4 controls the high bit (orange/blue vs green/purple) ; bit 5 controls the high bit (orange/blue vs green/purple)
txa txa
asl asl
asl asl
asl
and #$80 and #$80
sta tmp+1 sta tmp+1
; extract only bits 0 and 2 for the pixel data ; extract only bits 1 and 3 for the pixel data
txa txa
and #4 and #8 ; bit 3
lsr
lsr lsr
sta tmp sta tmp
txa txa
and #1 and #2 ; bit 1
lsr
ora tmp ora tmp
@decodeTo01: @decodeTo01:
ora tmp+1 ora tmp+1
@ -921,14 +926,18 @@ bload:
jsr @doMLI jsr @doMLI
lda @mliCommand+5 ; get handle and put it in place lda @mliCommand+5 ; get handle and put it in place
sta @mliCommand+1 sta @mliCommand+1
ply ; save ret addr pla ; save ret addr
plx tay
pla
tax
pla pla
sta @mliCommand+2 ; load addr lo sta @mliCommand+2 ; load addr lo
pla pla
sta @mliCommand+3 ; load addr hi sta @mliCommand+3 ; load addr hi
phx ; restore ret addr txa ; restore ret addr
phy pha
tya
pha
lda #$CA ; read lda #$CA ; read
sta @mliCommand+5 ; also length (more than enough) sta @mliCommand+5 ; also length (more than enough)
ldx #4 ldx #4
@ -956,7 +965,8 @@ bload:
; Copy pTmp -> pDst (advancing both), length in X(lo) / Y(hi) ; Copy pTmp -> pDst (advancing both), length in X(lo) / Y(hi)
copyMem: copyMem:
phx txa
pha
tya tya
ldy #0 ldy #0
tax tax
@ -971,8 +981,9 @@ copyMem:
dex dex
bne @pageLup bne @pageLup
@lastPg: @lastPg:
plx pla
beq @done beq @done
tax
@byteLup: @byteLup:
lda (pTmp),y lda (pTmp),y
sta (pDst),y sta (pDst),y
@ -987,16 +998,16 @@ copyMem:
@done: @done:
rts rts
; Read a byte from pTmp and advance it ; Read a byte from pTmp and advance it. No regs except A are disturbed.
readPtmp: readPtmp:
phy lda pTmp
ldy #0 sta @ld+1
lda (pTmp),y lda pTmp+1
ply sta @ld+2
inc pTmp inc pTmp
bne :+ bne @ld
inc pTmp+1 inc pTmp+1
: cmp #0 @ld: lda $100
rts rts
;------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------
@ -1140,7 +1151,7 @@ loadFiles:
sta setAuxWr sta setAuxWr
jsr copyMem ; copy the texture to aux mem jsr copyMem ; copy the texture to aux mem
sta clrAuxWr sta clrAuxWr
bra @cpTex ; next texture jmp @cpTex ; next texture
@cpTexDone: @cpTexDone:
DEBUG_STR "Loaded " DEBUG_STR "Loaded "
DEBUG_BYTE nTextures DEBUG_BYTE nTextures
@ -1234,15 +1245,13 @@ renderFrame:
tax ; map row ptr now in X(lo) / Y(hi) tax ; map row ptr now in X(lo) / Y(hi)
.if DEBUG .if DEBUG
phx
phy
stx tmp stx tmp
sty tmp+1 sty tmp+1
DEBUG_STR "Initial pMap=" DEBUG_STR "Initial pMap="
DEBUG_WORD tmp DEBUG_WORD tmp
DEBUG_LN DEBUG_LN
ply ldx tmp
plx ldy tmp+1
.endif .endif
lda #0 lda #0
@ -1254,10 +1263,12 @@ renderFrame:
@oneCol: @oneCol:
stx pMap ; set initial map pointer for the ray stx pMap ; set initial map pointer for the ray
sty pMap+1 sty pMap+1
phy ; save map row ptr
phx
pha ; save ray offset pha ; save ray offset
tay ; ray offset where it needs to be tay ; ray offset where it needs to be
lda pMap+1 ; save map row ptr
pha
txa
pha
jsr castRay ; cast the ray across the map jsr castRay ; cast the ray across the map
lda pixNum lda pixNum
bne :+ bne :+
@ -1265,8 +1276,8 @@ renderFrame:
: jsr drawRay ; and draw the ray : jsr drawRay ; and draw the ray
.if DEBUG .if DEBUG
DEBUG_STR "Done drawing ray " DEBUG_STR "Done drawing ray "
pla tsx
pha lda $103,x ; retrieve ray offset
lsr lsr
lsr lsr
jsr prbyte jsr prbyte
@ -1291,8 +1302,10 @@ renderFrame:
inc byteNum inc byteNum
@nextCol: @nextCol:
pla pla
plx tax
ply pla
tay
pla
clc clc
adc #4 ; advance to next ray adc #4 ; advance to next ray
cmp #$FC ; check for end of ray table cmp #$FC ; check for end of ray table
@ -2569,8 +2582,8 @@ precast_15:
.byte $7E,$07,$05,$56 .byte $7E,$07,$05,$56
.res 4 ; to bring it up to 256 bytes per angle .res 4 ; to bring it up to 256 bytes per angle
wLog256: .word 0800 wLog256: .word $0800
wLogViewDist: .word 0E3F wLogViewDist: .word $0E3F
; Movement amounts when walking at each angle ; Movement amounts when walking at each angle
; Each entry consists of an X bump and a Y bump, in 8.8 fixed point ; Each entry consists of an X bump and a Y bump, in 8.8 fixed point