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) {
return ((pix1 & 1) << 0) | ((pix2 & 1) << 1) |
((pix1 & 2) << 1) | ((pix2 & 2) << 2) |
((pix1 & 4) << 2) | ((pix2 & 4) << 3);
return ((pix2 & 1) << 0) | ((pix1 & 1) << 1) |
((pix2 & 2) << 1) | ((pix1 & 2) << 2) |
((pix2 & 4) << 2) | ((pix1 & 4) << 3);
}
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)
selectMip0:
; 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
; 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.
lda #0
sta tmp
lda txColumn
and #$F8 ; retain upper 5 bits
stz tmp
asl
rol tmp ; multiplied by 2
asl
@ -25,7 +24,8 @@ mipReady:
sta pTex+1
ldy pixNum ; get offset into the blit roll for this column
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
@blitOffsets: .byte BLIT_OFF0,BLIT_OFF1,BLIT_OFF2,BLIT_OFF3,BLIT_OFF4,BLIT_OFF5,BLIT_OFF6
@ -39,7 +39,7 @@ selectMip1:
lda txColumn
and #$F0 ; retain upper 4 bits
ldy #>MIP_OFFSET_1 ; adjust to mip level 1
bra mipReady
bne mipReady ; always taken
; Select mipmap level 2 (16x16 pixels = 8x8 bytes)
selectMip2:
@ -54,7 +54,7 @@ selectMip2:
lsr ; div by 4
; no need to add #<MIP_OFFSET_2, since it is zero.
ldy #>MIP_OFFSET_2 ; adjust to mip level 2
bra mipReady
bne mipReady ; always taken
; Select mipmap level 3 (8x8 pixels = 4x4 bytes)
selectMip3:
@ -72,7 +72,7 @@ selectMip3:
clc
adc #<MIP_OFFSET_3
ldy #>MIP_OFFSET_3 ; adjust to mip level 3
bra mipReady
bne mipReady ; always taken
; Select mipmap level 4 (4x4 pixels = 2x2 bytes)
selectMip4:
@ -88,13 +88,13 @@ selectMip4:
: clc
adc #<MIP_OFFSET_4
ldy #>MIP_OFFSET_4 ; adjust to mip level 4
bra mipReady
bne mipReady ; always taken
; Select mipmap level 5 (2x2 pixels = 1x1 bytes)
selectMip5:
; Mip level 5 is super-easy: it's one byte. Not much choice there.
lda #<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
# Main control on size vs. speed
rowInterval = 5
rowInterval = 4
# Height of textures, in pixels
textureHeight = 64
@ -52,9 +52,9 @@ def calcSpace(cmds):
n = 0
for c in cmds:
if c == "L":
space += 3 # LDA (ptr),y / INY
space += 5 # INY / LDA (ptr),y / BPL
elif c == "<":
space += 1 # LSR
space += 3 # ASL / BMI
else:
n += c
space += 3 # STA row,x
@ -90,6 +90,8 @@ class Segment:
global outFile, allLabels, generatedLabels
print("genCode %s, trunc=%r" % (s.label, s.truncPos))
first = grouped
needTransparencyCheck = True
prefix = " "
for i in range(len(s.cmds)):
if i == s.truncPos:
if grouped:
@ -98,32 +100,50 @@ class Segment:
return
if s.refs == 1:
# 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:
# 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:
outFile.write(" jsr %s\n" % s.truncLabel)
outFile.write("%s jsr %s\n" % (prefix, s.truncLabel))
prefix = " "
break
label = calcLabel(s.cmds[i:])
if label not in generatedLabels and (first or label in allLabels):
if prefix != " ":
outFile.write("%s\n" % prefix)
prefix = " "
outFile.write("%s:\n" % label)
generatedLabels.add(label)
needTransparencyCheck = True
first = False
c = s.cmds[i]
if c == 'L':
outFile.write("%s iny\n" % prefix)
prefix = " "
outFile.write(" lda (pTex),y\n")
outFile.write(" iny\n")
needTransparencyCheck = True
elif c == '<':
outFile.write(" lsr\n")
outFile.write("%s asl\n" % prefix)
prefix = " "
needTransparencyCheck = True
else:
assert c < screenHeight
if needTransparencyCheck:
outFile.write(" bmi :+\n")
prefix = ":"
outFile.write(" sta %s*BLIT_STRIDE + blitRoll,x\n" % c)
needTransparencyCheck = False
else:
if grouped:
outFile.write(" rts\n")
outFile.write("%s rts\n" % prefix)
prefix = " "
if grouped:
outFile.write("\n")
if prefix != " ":
outFile.write("%s\n" % prefix)
outFile.flush()
s.generated = True
@ -289,7 +309,7 @@ for (srcHeight, dstHeight, mipLevel, texOff, segs) in allHeights:
outFile.write("expand_%d:\n" % dstHeight)
outFile.write(" jsr selectMip%d\n" % mipLevel)
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)):
seg = allSegs[segs[i]]
if seg.refs == 1 and not(seg.generated):

View File

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

View File

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