gb-tarot/Printing.inc

544 lines
10 KiB
PHP

PUSHS "Printer Variables", WRAM0[PRINTER_VARS_START]
vTooBusyForPrinter: db ; one if we're too busy to use the async thread for printer stuff
vPrinterState: db ; options: NONE, READY, ERROR, FULL, PRINTING
def PS_NONE equ 0
def PS_READY equ 1
def PS_ERROR equ 2
def PS_FULL equ 3
def PS_PRINTING equ 4
vPrinterReturnValue: dw
vPrinterReturnValuePrevious: dw
vPrinterReturnValueChanged: db
vBuildingByte: dw
vPrinterIsReady: db
vPrinterRow: db
vPrinterStart: db
POPS
CheckForPrinter:
ld a, $F
ld hl, ZEROES
ld bc, 0
call SendPacket
ret
UpdatePrintUI:
ld a, [vPrinterState]
cp a, PS_NONE
ld hl, BanishPrinterUI
jp z, Async_Spawn_HL
cp a, PS_READY
ld hl, SummonPrinterUI
jp z, Async_Spawn_HL
cp a, PS_ERROR
ld hl, ShowErrorUI
jp z, Async_Spawn_HL
cp a, PS_PRINTING
ld hl, ShowPrinting
jp z, Async_Spawn_HL
cp a, PS_FULL
ld hl, ShowFull
jp z, Async_Spawn_HL
ld hl, BanishPrinterUI
jp Async_Spawn_HL
UpdatePrintUIImmediate:
ld a, [vPrinterReturnValue]
cp a, $81
call z, SummonPrinterUI
ld a, [vPrinterReturnValue]
cp a, $81
call nz, BanishPrinterUI
ret
BanishPrinterUI:
ld hl, PrinterNotDetected
ld de, _SCRN0 + 32*1 + 17
ld b, 2
ld c, 2
call CopyTilesToMap
ret
ShowErrorUI:
ld hl, PrinterError
ld de, _SCRN0 + 32*1 + 17
ld b, 2
ld c, 2
call CopyTilesToMap
ret
ShowPrinting:
ld hl, PrinterPrinting
ld de, _SCRN0 + 32*1 + 17
ld b, 2
ld c, 2
call CopyTilesToMap
ret
ShowFull:
ld hl, PrinterFull
ld de, _SCRN0 + 32*1 + 17
ld b, 2
ld c, 2
call CopyTilesToMap
ret
SummonPrinterUI:
ld hl, PrinterAvailable
ld de, _SCRN0 + 32*1 + 17
ld b, 2
ld c, 2
call CopyTilesToMap
ret
SendPacket:
; a should be the command byte
; hl shoulld point at data to send
; bc should be the length of data
; squashes de for the checksum.
push af
ld a, $88
call SendByte
ld a, $33
call SendByte
pop af
ld d, 0
ld e, a ; the checksum always starts with a vallue of whatever the command is
call SendByte
ld a, $00
call SendByte
ld a, c
call SendByte
ld a, b
call SendByte
ld a, e
add a, b
ld e, a
ld a, d
adc a, 0
ld d, a
ld a, e
add a, c
ld e, a
ld a, d
adc a, 0
ld d, a
ld a, b
or a, c
jp z, .doneWithByteLoop
.byteLoop
ld a, [hl]
add a, e
ld e, a
ld a, d
adc a, 0
ld d, a
ld a, [hl+]
call SendByte
dec bc
ld a, b
or a, c
jp nz, .byteLoop
.doneWithByteLoop
ld a, e
call SendByte
ld a, d
call SendByte
ld a, $00
call SendByte
ld [vPrinterReturnValue], a
ld a, $00
call SendByte
ld [vPrinterReturnValue+1], a
call UpdatePrinterStatus
ret
UpdatePrinterStatus:
;vPrinterState: db ; options: NONE, READY, ERROR, FULL, PRINTING
ld a, PS_NONE
ld [vPrinterState], a
ld a, [vPrinterReturnValue]
cp a, $81
ret nz ; if the alive byte isn't $81, return with PS_NONE
ld a, PS_ERROR
ld [vPrinterState], a
ld a, [vPrinterReturnValue+1]
and a, $F0
ret nz ; if the top nibble is non-zero, there's some error
ld a, PS_FULL
ld [vPrinterState], a
ld a, [vPrinterReturnValue+1]
bit 2, a
ret nz ; if the FULL bit iis set then it's full\
ld a, PS_PRINTING
ld [vPrinterState], a
ld a, [vPrinterReturnValue+1]
bit 1, a
ret nz ; if the printing bit is set then it's printing
ld a, PS_READY
ld [vPrinterState], a
ret ; if we didn't find any of the bits we check for, it's good to go
PrepNetwork:
ld a, 0
ld [vPrinterStart], a
ld hl, rSC
set 0, [hl]
ret
SendByte:
; waits until the thing is free, then sends the byte in a. puts the receiived
; byte in a anad returns.
push hl
ld hl, rSC
.waitForFree
bit 7, [hl]
jp nz, .waitForFree
ld [rSB], a
set 7, [hl] ; request transfer
.waitForResponse
bit 7, [hl]
jp nz, .waitForResponse
ld a, [rSB]
pop hl
ret
KickOffPrintJob:
ld a, 1
ld [vBlocked], a
ld a, 1
ld [vPrinterStart],a
ld a, 0
ld [vPrinterRow], a
call CardPrintPrep
call CardUpdate
ret
RunPrintJob:
ld a, [vPrinterStart]
cp a, 0
ret z
ld a, [vPrinterRow] ; printer row holds the row of printing we're on; this
; combines the tile row of the card + borders and also when to wait for printing
; to finish. also later we use the register for 'whetther it's a row of the card'
bit 0, a ; on even numbered printer rows just jump to the "wait for printable"
; routine. this should increase the printer row only if the printer is ready
; and return.
jp z, WaitForPrintable
cp a, 1 ; if the print row is 1, then we want the top border
jp nz, :+
call PlanTopRow
call BuildRow
set 7, a ; set bit 7 as a flaag thatt we've already taken one of these branches.
:
cp a, 35 ; if the print row is 35, we want the bottom border
jp nz, :+
call PlanBottomRow
call BuildRow
set 7, a
:
cp a, 37 ; if the row is 37, we want to clear the buffer and reset
jp nz, :+
call ClearBuffer
ld a, 0
ld [vBlocked], a
ld [vPrinterStart],a
ld [vPrinterRow], a
ld a, 1
ld [vPrinterIsReady], a
ret ; don't finish sending the print if we're cleaning up.
:
bit 7, a ; if this bit was set by one of the previous branches, then
; we aren't drawing a row; otherwise the rest of a holds the printer row for
; a card row to draw
jp nz, :+
res 7, a ; get rid of that "drawing a row" bit
srl a ; divide by two to get rid of the "drawing or waiting" bit
dec a ; subtract one to get the row index into card space
call PlanRowA
call BuildRow
ld b, 8 ; pre-increment so that when we pre-decrement in the loop later it works
sla a
sla a
sla a
add a, 24 ; multiply by 8 and add 24 to get from card tile space to sprite space
add a, b ; start from the bottom row of these tiles, a*8 + 7
ld c, a ; c holds the current scanline we're looking at for this inner loop
.addSpriteLinesLoop
dec c
ld a, c
ld [vCurrentScanline], a
call AddSpritesToLine
dec b
jp nz, .addSpriteLinesLoop
.doneAddSpriteLinesLoop
:
call DoubleTheBuffer
call PrintTheBuffer
ld a, [vPrinterRow]
inc a
ld [vPrinterRow], a
ret
PlanTopRow:
; draw the top of a card as tile ids in buffer one
ld hl, CardBrowse.UITilemap
ld bc, 10
ld de, BUFFER_ONE
call CopyRange ; copy tiles for the top row to the first buffer
ld b, b
ret
PlanRowA: ; a should be which row of a tile map we should draw
push af
ld de, BUFFER_ONE
ld a, $0b
ld [de], a
inc de
call FindCardTileMap ; now hl points at the beginning of the tile map
pop af
push af
sla a
sla a
sla a ; multiply row number by 8 for the stride of the tile map
ld b, 0
ld c, a ; advance to the row we're looking for.
add hl, bc
ld b, 8
:
ld a, [hl+]
ld [de], a
inc de
dec b
jp nz, :-
ld a, $0c
ld [de], a
pop af
ret
PlanBottomRow:
; draw the bottom of a card as tile ids in buffer one
ld hl, CardBrowse.UITilemap + 20*17 ;
ld bc, 10
ld de, BUFFER_ONE
call CopyRange ; copy tiles for the top row to the first buffer
ld b, b
ret
BuildRow:
; assuming buffer one contains a sequence of ten tile IDs
; this writes the tile data for each of those tiles sequentially into BUFFER_TWO
push af
ld hl, BUFFER_ONE
ld de, BUFFER_TWO
ld c, 10
.loop
push bc
ld a, [hl+] ; fetch a tile ID
push hl
ld hl, UITiles
cp a, 26
jp c, :+
; if the tile id is greater than 26, then we need to fetch from the card data
sub a, 26 ; and undo the offset encoded into the tile map
call FindCardKeyTiles
:
call FindTileData
; now hl points to tile data, de points to a spot in buffer 2
ld bc, 16
call CopyRange
pop hl
pop bc
dec c
jp nz, .loop
ld b, b
pop af
ret
DoubleTheBuffer:
ld hl, BUFFER_TWO
ld de, BUFFER_ONE
ld a, 10
.topHalfLoop
push hl
push af
call WriteTopHalfDoubledTile
pop af
pop hl
ld bc, 16
add hl, bc
dec a
jp nz, .topHalfLoop
ld hl, BUFFER_TWO
ld a, 10
.bottomHalfLoop
push hl
push af
ld bc, 8
add hl, bc
call WriteTopHalfDoubledTile
pop af
pop hl
ld bc, 16
add hl, bc
dec a
jp nz, .bottomHalfLoop
ld b, b
ret
PrintTheBuffer:
call ClearBuffer
ld a, 4 ; fill buffer
ld hl, BUFFER_ONE
ld bc, $280
call SendPacket
call SendEmpty
call SendPrint
ret
WaitForPrintable:
ld a, $F
ld hl, ZEROES
ld bc, 0
call SendPacket
; NONE, READY, ERROR, FULL, PRINTING
ld a, [vPrinterState]
cp a, PS_PRINTING
ret z
cp a, PS_ERROR
ret z
cp a, PS_NONE
ret z
call ClearBuffer
ld a, [vPrinterState]
cp a, PS_FULL
ret z
ld a, [vPrinterRow]
inc a
ld [vPrinterRow], a
ret
SendEmpty:
ld a, 4
ld hl, ZEROES
ld bc, 0
call SendPacket
ret
SendPrint:
call SendEmpty
ld hl, BUFFER_ONE
ld a, 1 ; number of sheets
ld [hl+], a
ld a, $00 ; margins
ld [hl+], a
ld a, $e4 ; palette
ld [hl+], a
ld a, $7f ; exposure
ld [hl+], a
ld a, 2 ; print
ld hl, BUFFER_ONE
ld bc, 4
call SendPacket
ret
ClearBuffer:
ld a, $1
ld hl, ZEROES
ld bc, 0
call SendPacket
ret
PrinterTiles:
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
db $00,$1c,$00,$0e,$38,$3f,$64,$7f,$7f,$7f,$7f,$40,$7f,$40,$3f,$3f
db $00,$00,$00,$00,$00,$00,$06,$b6,$ff,$ff,$ff,$11,$ff,$11,$fe,$fe
db $00,$00,$00,$80,$0e,$8e,$12,$9e,$24,$bc,$38,$b8,$00,$80,$00,$00
db $00,$00,$00,$00,$5a,$5a,$92,$92,$5a,$5a,$52,$52,$9b,$9b,$00,$00
db $00,$00,$18,$98,$18,$98,$18,$98,$18,$98,$00,$80,$18,$98,$00,$00
db $00,$00,$00,$00,$d8,$d8,$94,$94,$d8,$d8,$94,$94,$d2,$d2,$00,$00
db $00,$00,$00,$80,$19,$99,$15,$95,$19,$99,$11,$91,$11,$91,$00,$00
db $00,$00,$00,$00,$92,$92,$5a,$5a,$96,$96,$52,$52,$52,$52,$00,$00
db $00,$00,$00,$80,$1d,$9d,$11,$91,$19,$99,$11,$91,$11,$91,$00,$00
db $00,$00,$00,$00,$52,$52,$52,$52,$52,$52,$52,$52,$db,$db,$00,$00
PrinterTiles.End: ; $22
PrinterNotDetected:
db $00, $00
db $13, $00
PrinterAvailable:
db $f1, $f2
db $f3, $f4
PrinterPrinting:
db $f1, $f2
db $f7, $f8
PrinterError:
db $f1, $f2
db $f5, $f6
PrinterFull:
db $f1, $f2
db $f9, $fa