mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2025-01-12 12:29:53 +00:00
Update; tool is compiling while referencing new rederer pipeline
This commit is contained in:
parent
7f6e5d1b1f
commit
01e92a7b62
13688
demos/tool/Zelda.TileSet.s
Normal file
13688
demos/tool/Zelda.TileSet.s
Normal file
File diff suppressed because it is too large
Load Diff
1
demos/zelda/.gitignore
vendored
Normal file
1
demos/zelda/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
GTEZelda
|
@ -36,3 +36,6 @@ _GTESetBG0Origin MAC
|
||||
_GTERender MAC
|
||||
UserTool $D00+GTEToolNum
|
||||
<<<
|
||||
_GTELoadTileSet MAC
|
||||
UserTool $E00+GTEToolNum
|
||||
<<<
|
||||
|
@ -12,7 +12,9 @@
|
||||
},
|
||||
"scripts": {
|
||||
"test": "npm run build && build-image.bat %npm_package_config_cadius% && %npm_package_config_gsport%",
|
||||
"build": "%npm_package_config_merlin32% -V %npm_package_config_macros% ./src/Master.s"
|
||||
"build": "%npm_package_config_merlin32% -V %npm_package_config_macros% ./src/Master.s",
|
||||
"build:debug": "%npm_package_config_merlin32% -V %npm_package_config_macros% ./src/Debug.s",
|
||||
"debug": "%npm_package_config_crossrunner% ./src/Debug160 -Source ./src/Debug160_S02__Output.txt -Debug -CompatibilityLayer"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
1053
src/Render.s
1053
src/Render.s
File diff suppressed because it is too large
Load Diff
29
src/Tiles.s
29
src/Tiles.s
@ -1,5 +1,22 @@
|
||||
; Basic tile functions
|
||||
|
||||
; Copy tileset data from a pointer in memory to the tiledata back
|
||||
; X = high word
|
||||
; A = low word
|
||||
_LoadTileSet
|
||||
sta tmp0
|
||||
stx tmp2
|
||||
ldy #0
|
||||
tyx
|
||||
:loop lda [tmp0],y
|
||||
stal tiledata,x
|
||||
dex
|
||||
dex
|
||||
dey
|
||||
dey
|
||||
bne :loop
|
||||
rts
|
||||
|
||||
|
||||
; Low-level function to take a tile descriptor and return the address in the tiledata
|
||||
; bank. This is not too useful in the fast-path because the fast-path does more
|
||||
@ -10,8 +27,8 @@
|
||||
; The address is the TileID * 128 + (HFLIP * 64)
|
||||
_GetTileAddr
|
||||
asl ; Multiply by 2
|
||||
bit #2*TILE_HFLIP_BIT ; Check if the horizontal flip bit is set
|
||||
beq :no_flip
|
||||
bit #2*TILE_HFLIP_BIT ; Check if the horizontal flip bit is set
|
||||
beq :no_flip
|
||||
inc ; Set the LSB
|
||||
:no_flip asl ; x4
|
||||
asl ; x8
|
||||
@ -199,12 +216,12 @@ _SetTile
|
||||
bra :out
|
||||
|
||||
:fast
|
||||
; lda FastTileProcs,y
|
||||
; stal TileStore+TS_BASE_TILE_DISP,x
|
||||
lda FastTileProcs,y
|
||||
stal TileStore+TS_BASE_TILE_DISP,x
|
||||
:out
|
||||
|
||||
; txa ; Add this tile to the list of dirty tiles to refresh
|
||||
; jmp _PushDirtyTileX ; on the next call to _ApplyTiles
|
||||
txa ; Add this tile to the list of dirty tiles to refresh
|
||||
jmp _PushDirtyTileX ; on the next call to _ApplyTiles
|
||||
|
||||
:nochange rts
|
||||
|
||||
|
23
src/Tool.s
23
src/Tool.s
@ -3,7 +3,6 @@
|
||||
; Ref: Toolbox Reference, Volume 2, Appendix A
|
||||
; Ref: IIgs Tech Note #73
|
||||
|
||||
; use Load.Macs.s
|
||||
use Mem.Macs.s
|
||||
use Misc.Macs.s
|
||||
use Util.Macs
|
||||
@ -51,6 +50,7 @@ _CallTable
|
||||
adrl _TSSetTile-1
|
||||
adrl _TSSetBG0Origin-1
|
||||
adrl _TSRender-1
|
||||
adrl _TSLoadTileSet-1
|
||||
_CTEnd
|
||||
|
||||
; Do nothing when the tool set is installed
|
||||
@ -223,9 +223,20 @@ xPos equ FirstParam+2
|
||||
; Render()
|
||||
_TSRender
|
||||
_TSEntry
|
||||
; jsr _Render
|
||||
jsr _Render
|
||||
_TSExit #0;#0
|
||||
|
||||
; LoadTileSet(Pointer)
|
||||
_TSLoadTileSet
|
||||
TSPtr equ FirstParam
|
||||
|
||||
_TSEntry
|
||||
|
||||
lda TSPtr+2,s
|
||||
tax
|
||||
lda TSPtr,s
|
||||
jsr _LoadTileSet
|
||||
_TSExit #0;#4
|
||||
|
||||
; Insert the GTE code
|
||||
|
||||
@ -235,11 +246,17 @@ _TSRender
|
||||
put Timer.s
|
||||
put Graphics.s
|
||||
put Tiles.s
|
||||
; put Render.s
|
||||
put Render.s
|
||||
put tiles/DirtyTileQueue.s
|
||||
put tiles/FastRenderer.s
|
||||
put blitter/Horz.s
|
||||
put blitter/Vert.s
|
||||
put blitter/BG0.s
|
||||
put blitter/BG1.s
|
||||
put blitter/Template.s
|
||||
put blitter/TemplateUtils.s
|
||||
put blitter/Tables.s
|
||||
put blitter/Blitter.s
|
||||
put blitter/TileProcs.s
|
||||
put blitter/Tiles00000.s
|
||||
; put blitter/Tiles.s
|
||||
|
@ -4,26 +4,15 @@
|
||||
_TBFillPEAOpcode
|
||||
sep #$20
|
||||
lda #$F4
|
||||
sta: $0000,y
|
||||
sta: $0003,y
|
||||
sta $1000,y
|
||||
sta $1003,y
|
||||
sta $2000,y
|
||||
sta $2003,y
|
||||
sta $3000,y
|
||||
sta $3003,y
|
||||
sta $4000,y
|
||||
sta $4003,y
|
||||
sta $5000,y
|
||||
sta $5003,y
|
||||
sta $6000,y
|
||||
sta $6003,y
|
||||
sta $7000,y
|
||||
sta $7003,y
|
||||
]line equ 0
|
||||
lup 8
|
||||
sta: $0000+{]line*$1000},y
|
||||
sta: $0003+{]line*$1000},y
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rep #$20
|
||||
rts
|
||||
|
||||
|
||||
; Copy tile data into the direct page compositing buffer. The main reason to do this in full passes is
|
||||
; because we can avoid needing to use both the X and Y registers during the compositing process and
|
||||
; reserve Y to hold the code field address.
|
@ -37,16 +37,7 @@
|
||||
;
|
||||
; It is simply too slow to try to horizontally reverse the pixel data on the fly. This still allows
|
||||
; for up to 512 tiles to be stored in a single bank, which should be sufficient.
|
||||
|
||||
; Use some temporary space for the spriteIdx array (maximum of 4 entries)
|
||||
|
||||
stkSave equ tmp9
|
||||
screenAddr equ tmp10
|
||||
tileAddr equ tmp11
|
||||
spriteIdx equ tmp12
|
||||
|
||||
|
||||
|
||||
;
|
||||
; Given an address to a Tile Store record, dispatch to the appropriate tile renderer. The Tile
|
||||
; Store record contains all of the low-level information that's needed to call the renderer.
|
||||
;
|
||||
@ -128,7 +119,7 @@ dirty_sprite_dispatch
|
||||
|
||||
; This is very similar to the code in the dirty tile renderer, but we can't reuse
|
||||
; because that code draws directly to the graphics screen, and this code draws
|
||||
; to a temporary budder that has a different stride.
|
||||
; to a temporary buffer that has a different stride.
|
||||
|
||||
; ldy TileStore+TS_VBUFF_ARRAY_ADDR,x ; base address of the VBUFF sprite address array for this tile
|
||||
;
|
||||
@ -692,138 +683,10 @@ _CopyBG1Tile
|
||||
; TileStore+TS_SPRITE_ADDR_15
|
||||
; TileStore+TS_SPRITE_ADDR_16
|
||||
|
||||
|
||||
; TileStore+
|
||||
;TileStore ENT
|
||||
; ds TILE_STORE_SIZE*11
|
||||
|
||||
; A list of dirty tiles that need to be updated in a given frame
|
||||
DirtyTileCount ds 2
|
||||
DirtyTiles ds TILE_STORE_SIZE ; At most this many tiles can possibly be update at once
|
||||
|
||||
_ClearDirtyTiles
|
||||
bra :hop
|
||||
:loop
|
||||
jsr _PopDirtyTile
|
||||
:hop
|
||||
lda DirtyTileCount
|
||||
bne :loop
|
||||
rts
|
||||
|
||||
|
||||
; Append a new dirty tile record
|
||||
;
|
||||
; A = result of _GetTileStoreOffset for X, Y
|
||||
;
|
||||
; The main purpose of this function is to
|
||||
;
|
||||
; 1. Avoid marking the same tile dirty multiple times, and
|
||||
; 2. Pre-calculating all of the information necessary to render the tile
|
||||
PushDirtyTile ENT
|
||||
phb
|
||||
phk
|
||||
plb
|
||||
jsr _PushDirtyTile
|
||||
plb
|
||||
rtl
|
||||
|
||||
; alternate version that is very slightly slower, but preserves the y-register
|
||||
_PushDirtyTile
|
||||
tax
|
||||
|
||||
; alternate entry point if the x-register is already set
|
||||
_PushDirtyTileX
|
||||
ldal TileStore+TS_DIRTY,x
|
||||
bne :occupied2
|
||||
|
||||
inc ; any non-zero value will work
|
||||
stal TileStore+TS_DIRTY,x ; and is 1 cycle faster than loading a constant value
|
||||
|
||||
txa
|
||||
ldx DirtyTileCount ; 4
|
||||
sta DirtyTiles,x ; 6
|
||||
inx ; 2
|
||||
inx ; 2
|
||||
stx DirtyTileCount ; 4 = 18
|
||||
rts
|
||||
:occupied2
|
||||
txa ; Make sure TileStore offset is returned in the accumulator
|
||||
rts
|
||||
|
||||
; Remove a dirty tile from the list and return it in state ready to be rendered. It is important
|
||||
; that the core rendering functions *only* use _PopDirtyTile to get a list of tiles to update,
|
||||
; because this routine merges the tile IDs stored in the Tile Store with the Sprite
|
||||
; information to set the TILE_SPRITE_BIT. This is the *only* place in the entire code base that
|
||||
; applies this bit to a tile descriptor.
|
||||
PopDirtyTile ENT
|
||||
phb
|
||||
phk
|
||||
plb
|
||||
jsr _PopDirtyTile
|
||||
plb
|
||||
rtl
|
||||
|
||||
_PopDirtyTile
|
||||
ldy DirtyTileCount
|
||||
bne _PopDirtyTile2
|
||||
rts
|
||||
|
||||
_PopDirtyTile2 ; alternate entry point
|
||||
dey
|
||||
dey
|
||||
sty DirtyTileCount ; remove last item from the list
|
||||
|
||||
ldx DirtyTiles,y ; load the offset into the Tile Store
|
||||
lda #$FFFF
|
||||
stal TileStore+TS_DIRTY,x ; clear the occupied backlink
|
||||
rts
|
||||
|
||||
; Run through the dirty tile list and render them into the code field
|
||||
ApplyTiles ENT
|
||||
phb
|
||||
phk
|
||||
plb
|
||||
jsr _ApplyTiles
|
||||
plb
|
||||
rtl
|
||||
|
||||
; The _ApplyTiles function is responsible for rendering all of the dirty tiles into the code
|
||||
; field. In this function we switch to the second direct page which holds the temporary
|
||||
; working buffers for tile rendering.
|
||||
_ApplyTiles
|
||||
tdc
|
||||
clc
|
||||
adc #$100 ; move to the next page
|
||||
tcd
|
||||
|
||||
bra :begin
|
||||
|
||||
:loop
|
||||
; Retrieve the offset of the next dirty Tile Store items in the X-register
|
||||
|
||||
jsr _PopDirtyTile2
|
||||
|
||||
; Call the generic dispatch with the Tile Store record pointer at by the X-register.
|
||||
|
||||
phb
|
||||
jsr _RenderTile2
|
||||
plb
|
||||
|
||||
; Loop again until the list of dirty tiles is empty
|
||||
|
||||
:begin ldy DirtyTileCount
|
||||
bne :loop
|
||||
|
||||
tdc ; Move back to the original direct page
|
||||
sec
|
||||
sbc #$100
|
||||
tcd
|
||||
rts
|
||||
|
||||
; To make processing the tile faster, we do them in chunks of eight. This allows the loop to be
|
||||
; unrolled, which means we don't have to keep track of the register value and makes it faster to
|
||||
; clear the dirty tile flag after being processed.
|
||||
|
||||
; _ApplyTilesUnrolled
|
||||
tdc ; Move to the dedicated direct page for tile rendering
|
||||
clc
|
||||
adc #$100
|
||||
|
64
src/tiles/DirtyTileQueue.s
Normal file
64
src/tiles/DirtyTileQueue.s
Normal file
@ -0,0 +1,64 @@
|
||||
|
||||
; A list of dirty tiles that need to be updated in a given frame
|
||||
DirtyTileCount ds 2
|
||||
DirtyTiles ds TILE_STORE_SIZE ; At most this many tiles can possibly be update at once
|
||||
|
||||
_ClearDirtyTiles
|
||||
bra :hop
|
||||
:loop
|
||||
jsr _PopDirtyTile
|
||||
:hop
|
||||
lda DirtyTileCount
|
||||
bne :loop
|
||||
rts
|
||||
|
||||
|
||||
; Append a new dirty tile record
|
||||
;
|
||||
; A = result of _GetTileStoreOffset for X, Y
|
||||
;
|
||||
; The main purpose of this function is to
|
||||
;
|
||||
; 1. Avoid marking the same tile dirty multiple times, and
|
||||
; 2. Pre-calculating all of the information necessary to render the tile
|
||||
_PushDirtyTile
|
||||
tax
|
||||
|
||||
; alternate entry point if the x-register is already set
|
||||
_PushDirtyTileX
|
||||
ldal TileStore+TS_DIRTY,x
|
||||
bne :occupied2
|
||||
|
||||
inc ; any non-zero value will work
|
||||
stal TileStore+TS_DIRTY,x ; and is 1 cycle faster than loading a constant value
|
||||
|
||||
txa
|
||||
ldx DirtyTileCount ; 4
|
||||
sta DirtyTiles,x ; 6
|
||||
inx ; 2
|
||||
inx ; 2
|
||||
stx DirtyTileCount ; 4 = 18
|
||||
rts
|
||||
:occupied2
|
||||
txa ; Make sure TileStore offset is returned in the accumulator
|
||||
rts
|
||||
|
||||
; Remove a dirty tile from the list and return it in state ready to be rendered. It is important
|
||||
; that the core rendering functions *only* use _PopDirtyTile to get a list of tiles to update,
|
||||
; because this routine merges the tile IDs stored in the Tile Store with the Sprite
|
||||
; information to set the TILE_SPRITE_BIT. This is the *only* place in the entire code base that
|
||||
; applies this bit to a tile descriptor.
|
||||
_PopDirtyTile
|
||||
ldy DirtyTileCount
|
||||
bne _PopDirtyTile2
|
||||
rts
|
||||
|
||||
_PopDirtyTile2 ; alternate entry point
|
||||
dey
|
||||
dey
|
||||
sty DirtyTileCount ; remove last item from the list
|
||||
|
||||
ldx DirtyTiles,y ; load the offset into the Tile Store
|
||||
lda #$FFFF
|
||||
stal TileStore+TS_DIRTY,x ; clear the occupied backlink
|
||||
rts
|
@ -8,9 +8,7 @@
|
||||
_RenderTileFast
|
||||
ldx TileStore+TS_VBUFF_ADDR_COUNT,y ; How many sprites are on this tile?
|
||||
beq NoSpritesFast ; This is faster if there are no sprites
|
||||
|
||||
lda TileStore+TS_TILE_ID,y ; Check if the tile has
|
||||
jmp (fast_dispatch,x)
|
||||
jmp (fast_dispatch,x) ; Dispatch to the other routines
|
||||
fast_dispatch
|
||||
da NoSpritesFast
|
||||
da OneSpriteFast
|
||||
@ -31,6 +29,16 @@ NoSpritesFast
|
||||
; ENGINE_MODE_DYN_TILES are both off.
|
||||
FastTileProcs dw _TBCopyDataFast,_TBCopyDataFast,_TBCopyDataVFast,_TBCopyDataVFast
|
||||
|
||||
; Pointers to sprite data and masks
|
||||
spritedata_0 equ tmp0
|
||||
spritedata_1 equ tmp2
|
||||
spritedata_2 equ tmp4
|
||||
spritedata_3 equ tmp6
|
||||
spritemask_0 equ tmp8
|
||||
spritemask_1 equ tmp10
|
||||
spritemask_2 equ tmp12
|
||||
spritemask_3 equ tmp14
|
||||
|
||||
; Where there are sprites involved, the first step is to call a routine to copy the
|
||||
; tile data into a temporary buffer. Then the sprite data is merged and placed into
|
||||
; the code field.
|
||||
@ -47,19 +55,15 @@ OneSpriteFast
|
||||
tay
|
||||
plb ; set the code field bank
|
||||
|
||||
]line equ 0
|
||||
lup 8
|
||||
lda blttmp+{]line*4}
|
||||
andl spritemask+{]line*SPRITE_PLANE_SPAN},x
|
||||
oral spritedata+{]line*SPRITE_PLANE_SPAN},x
|
||||
sta: $0004+{]line*$1000},y
|
||||
OneSpriteToCodeField 0
|
||||
OneSpriteToCodeField 1
|
||||
OneSpriteToCodeField 2
|
||||
OneSpriteToCodeField 3
|
||||
OneSpriteToCodeField 4
|
||||
OneSpriteToCodeField 5
|
||||
OneSpriteToCodeField 6
|
||||
OneSpriteToCodeField 7
|
||||
|
||||
lda blttmp+{]line*4}+2
|
||||
andl spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
oral spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
sta: $0001+{]line*$1000},y
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rts
|
||||
|
||||
TwoSpritesFast
|
||||
@ -81,25 +85,15 @@ TwoSpritesFast
|
||||
tay
|
||||
plb ; set the code field bank
|
||||
|
||||
]line equ 0
|
||||
lup 8
|
||||
ldy #{]line*SPRITE_PLANE_SPAN}
|
||||
lda blttmp+{]line*4}
|
||||
andl [spritemask_1],y
|
||||
oral [spritedata_1],y
|
||||
andl [spritemask_0],y
|
||||
oral [spritedata_0],y
|
||||
sta: $0004+{]line*$1000},x
|
||||
TwoSpritesToCodeField 0
|
||||
TwoSpritesToCodeField 1
|
||||
TwoSpritesToCodeField 2
|
||||
TwoSpritesToCodeField 3
|
||||
TwoSpritesToCodeField 4
|
||||
TwoSpritesToCodeField 5
|
||||
TwoSpritesToCodeField 6
|
||||
TwoSpritesToCodeField 7
|
||||
|
||||
ldy #{]line*SPRITE_PLANE_SPAN}+2
|
||||
lda blttmp+{]line*4}+2
|
||||
andl [spritemask_1],y
|
||||
oral [spritedata_1],y
|
||||
andl [spritemask_0],y
|
||||
oral [spritedata_0],y
|
||||
sta: $0001+{]line*$1000},x
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rts
|
||||
|
||||
ThreeSpritesFast
|
||||
@ -125,27 +119,13 @@ FourSpritesFast
|
||||
tay
|
||||
plb ; set the code field bank
|
||||
|
||||
]line equ 0
|
||||
lup 8
|
||||
ldy #{]line*SPRITE_PLANE_SPAN}
|
||||
lda blttmp+{]line*4}
|
||||
andl [spritemask_2],y
|
||||
oral [spritedata_2],y
|
||||
andl [spritemask_1],y
|
||||
oral [spritedata_1],y
|
||||
andl [spritemask_0],y
|
||||
oral [spritedata_0],y
|
||||
sta: $0004+{]line*$1000},x
|
||||
ThreeSpritesToCodeField 0
|
||||
ThreeSpritesToCodeField 1
|
||||
ThreeSpritesToCodeField 2
|
||||
ThreeSpritesToCodeField 3
|
||||
ThreeSpritesToCodeField 4
|
||||
ThreeSpritesToCodeField 5
|
||||
ThreeSpritesToCodeField 6
|
||||
ThreeSpritesToCodeField 7
|
||||
|
||||
ldy #{]line*SPRITE_PLANE_SPAN}+2
|
||||
lda blttmp+{]line*4}+2
|
||||
andl [spritemask_2],y
|
||||
oral [spritedata_2],y
|
||||
andl [spritemask_1],y
|
||||
oral [spritedata_1],y
|
||||
andl [spritemask_0],y
|
||||
oral [spritedata_0],y
|
||||
sta: $0001+{]line*$1000},x
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rts
|
Loading…
x
Reference in New Issue
Block a user