Skip to content

Instantly share code, notes, and snippets.

@ISSOtm
Created September 19, 2020 14:37
Show Gist options
  • Select an option

  • Save ISSOtm/9f960cf08b8d4d4a9bd9c3397c57b79d to your computer and use it in GitHub Desktop.

Select an option

Save ISSOtm/9f960cf08b8d4d4a9bd9c3397c57b79d to your computer and use it in GitHub Desktop.

Revisions

  1. ISSOtm created this gist Sep 19, 2020.
    285 changes: 285 additions & 0 deletions pal_fade_dmgbc.asm
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,285 @@

    FadeDMGToWhite:
    ld c, LOW(hBGP)
    ld hl, wBGP
    .fadeDMGPalToWhite
    ld a, [hli]
    ld b, 4
    .fadeDMGColorToWhite
    ld e, a
    and $C0
    sub d
    jr nc, .DMGNotWhite
    xor a
    .DMGNotWhite
    xor e
    and $C0
    xor e
    rlca
    rlca
    dec b
    jr nz, .fadeDMGColorToWhite
    ldh [c], a
    ld a, c
    inc c
    cp LOW(hOBP1)
    jr nz, .fadeDMGPalToWhite
    ret

    FadePaletteBuffers:: ;; --------- ENTRY POINT ------
    ld hl, wFadeSteps
    dec [hl]
    jr nz, .keepGoing
    ld a, [wFollowingState]
    ld [wNextState], a
    .keepGoing
    inc hl
    assert wFadeSteps + 1 == wFadeStep

    ld a, [hli]
    ld e, a
    assert wFadeStep + 1 == wFadeAmount
    add a, [hl]
    jr z, .clamp ; 0 is an illegal value
    ld d, a
    rra ; Get carry into bit 7
    xor e ; Expect bit 7 of offset to match carry
    add a, a
    ld a, d
    jr nc, .noOverflow
    .clamp
    ; If we got an overflow, clamp depending on bit 7 of offset
    ; If the offset is positive, clamp at $FF; otherwise, at 1
    sla e ; Bit 7 (sign) into carry
    sbc a, a ; 0 or $FF
    and 2 ; 0 or 2
    dec a ; $FF or 1
    .noOverflow
    ld [hli], a
    assert wFadeAmount + 1 == wBGPaletteMask
    add a, a ; Test sign bit
    ld c, LOW(rBCPS)
    jr nc, .fadeToBlack

    ld d, a
    ld a, [hConsoleType]
    and a
    jr nz, FadeDMGToWhite
    .fadeBufferToWhite
    ld a, $80
    ldh [c], a
    inc c
    ld a, [hli] ; Read palette mask
    scf
    adc a, a
    .fadePaletteToWhite
    ldh [hPaletteMask], a
    jr nc, .noWhiteFade
    ld b, 4
    ld a, c
    cp LOW(rOCPD)
    jr nz, .fadeColorToWhite
    dec b
    ; Do two dummy writes to advance index
    ; The index is increased even if the writes fail
    ldh [c], a
    ldh [c], a
    .fadeColorToWhite
    ld a, [hli] ; Read green
    add a, d
    jr nc, .notFullGreen
    sbc a, a ; ld a, $FF
    .notFullGreen
    rlca
    rlca
    ld e, a
    wait_vram
    ld a, [hli] ; Read red
    add a, d
    jr nc, .notFullRed
    sbc a, a ; ld a, $FF
    .notFullRed
    rra
    rra
    rra
    xor e
    and $1F
    xor e
    ldh [c], a
    wait_vram
    ld a, [hli] ; Read blue
    add a, d
    jr nc, .notFullBlue
    sbc a, a ; ld a, $FF
    .notFullBlue
    rra
    xor e
    and $FC ; $7C works just as well, but $FC gets bit 7 always cleared
    xor e
    ldh [c], a
    dec b
    jr nz, .fadeColorToWhite
    .fadedPaletteWhite
    ldh a, [hPaletteMask]
    add a, a
    jr nz, .fadePaletteToWhite
    inc c
    ld a, c
    cp LOW(rOCPS)
    jr z, .fadeBufferToWhite
    ret

    .noWhiteFade
    dec c
    ldh a, [c]
    add a, 4 * 2
    ldh [c], a
    inc c
    ld a, l
    add a, 4 * 3
    ld l, a
    adc a, h
    sub l
    ld h, a
    jr .fadedPaletteWhite

    .fadeToBlack
    cpl
    inc a
    ld d, a
    ldh a, [hConsoleType]
    and a
    jr nz, .fadeDMGToBlack
    .fadeBufferToBlack
    ld a, $80
    ldh [c], a
    inc c
    ld a, [hli] ; Read palette mask
    scf
    adc a, a
    .fadePaletteToBlack
    ldh [hPaletteMask], a
    jr nc, .noBlackFade
    ld b, 4
    ; OBJ palettes only have 3 colors
    ld a, c
    cp LOW(rOCPD)
    jr nz, .fadeColorToBlack
    dec b
    ; Do two dummy writes to advance index
    ; The index is increased even if the writes fail
    ldh [c], a
    ldh [c], a
    .fadeColorToBlack
    ld a, [hli] ; Read green
    sub d
    jr nc, .stillSomeGreen
    xor a
    .stillSomeGreen
    rlca
    rlca
    ld e, a
    wait_vram
    ld a, [hli] ; Read red
    sub d
    jr nc, .stillSomeRed
    xor a
    .stillSomeRed
    rra
    rra
    rra
    xor e
    and $1F
    xor e
    ldh [c], a
    wait_vram
    ld a, [hli] ; Read blue
    sub d
    jr nc, .stillSomeBlue
    xor a
    .stillSomeBlue
    rra
    xor e
    and $FC ; $7C works just as well, but $FC gets bit 7 always cleared
    xor e
    ldh [c], a
    dec b
    jr nz, .fadeColorToBlack
    .fadedPaletteBlack
    ldh a, [hPaletteMask]
    add a, a
    jr nz, .fadePaletteToBlack
    inc c
    ld a, c
    cp LOW(rOCPS)
    jr z, .fadeBufferToBlack
    ret

    .noBlackFade
    dec c
    ldh a, [c]
    add a, 4 * 2
    ldh [c], a
    inc c
    ld a, l
    add a, 4 * 3
    ld l, a
    adc a, h
    sub l
    ld h, a
    jr .fadedPaletteBlack

    .fadeDMGToBlack
    ld c, LOW(hBGP)
    ld hl, wBGP
    .fadeDMGPalToBlack
    ld a, [hli]
    ld b, 4
    .fadeDMGColorToBlack
    ld e, a
    and $C0
    add a, d
    jr nc, .DMGNotBlack
    sbc a, a ; ld a, $FF
    .DMGNotBlack
    xor e
    and $C0
    xor e
    rlca
    rlca
    dec b
    jr nz, .fadeDMGColorToBlack
    ldh [c], a
    ld a, c
    inc c
    cp LOW(hOBP1)
    jr nz, .fadeDMGPalToBlack
    ret

    PUSHS
    SECTION UNION "Scratch buffer", HRAM

    hPaletteMask: db

    SECTION "Fade state memory", WRAM0

    wFadeSteps:: db ; Number of fade steps to take
    wFadeStep:: db ; Value to add to wFadeAmount on each step

    ; 00 = bugged equivalent of 00, do not use
    ; 01-7F = 01 is fully black, 7F is barely faded
    ; 80 = not faded
    ; 81-FF = FF is fully white, 81 is barely faded
    wFadeAmount:: db

    wBGPaletteMask:: db ; Mask of which palettes to fade (01234567)
    wBGPaletteBuffer:: ; 24-bit GRB, in this order
    ds 8 * 4 * 3 ; 8 palettes, 4 colors, 3 bytes
    wOBJPaletteMask:: db
    wOBJPaletteBuffer:: ; Same as above
    ds 8 * 3 * 3 ; Same, but only 3 colors

    wBGP:: db
    wOBP0:: db
    wOBP1:: db
    POPS