Advertisement
ISSOtm

NPC redrawing code

Jul 19th, 2019
486
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     ; Redraw NPCs
  2.     ld hl, wPlayer
  3.     ld de, wShadowOAM + 2 * 4 ; Reserve two objects for player shifting
  4. .redrawNPC
  5.     call GetCameraRelativePosition
  6.     ldh a, [hCameraRelativePosition]
  7.     add a, (256 - SCRN_Y) / 2
  8.     ldh a, [hCameraRelativePosition+1]
  9.     adc a, 0
  10.     jr nz, .npcCulledOut
  11.     ldh a, [hCameraRelativePosition+2]
  12.     add a, (256 - SCRN_X) / 2
  13.     ldh a, [hCameraRelativePosition+3]
  14.     adc a, 0
  15.     jr nz, .npcCulledOut
  16.     ld a, [hli] ; Read display type
  17.     add a, a ; Double for upcoming ptr computation
  18.     ; (assuming that the object has no more than 128 different types)
  19.     ld c, a
  20.     push hl ; Save this pointer to do write-back later
  21.     ld a, [hli] ; Read display counter
  22.     ld b, a
  23.     ld a, [hli]
  24.     ldh [hNPCTileID], a
  25.     ld a, [hli]
  26.     ldh [hNPCAttr], a
  27.     ld a, [hli] ; Read draw struct bank
  28.     rst bankswitch
  29.     ld a, [hli] ; Read draw struct ptr
  30.     ld h, [hl]
  31.     add a, c ; Add display type offset
  32.     ld l, a
  33.     adc a, h
  34.     sub l
  35.     ld h, a
  36.     ld a, [hli]
  37.     ld h, [hl]
  38.     ld l, a
  39.     ld c, [hl] ; Read anim length (don't inc to improve upcoming loop)
  40.     ld a, b ; Get display counter
  41.     inc a
  42.     sub c
  43.     jr nc, .wrapAnimCnt
  44.     add a, c
  45. .wrapAnimCnt
  46.     ld c, a
  47.     ; Use current value, because increment should only affect next frame
  48.     ; Important for player tile loading to work correctly
  49.     ld a, b
  50. .seekAnimFrame
  51.     inc hl ; Advance to length
  52.     sub [hl]
  53.     inc hl ; Skip anim counter
  54.     inc hl ; Skip one byte of ptr (so we can still read efficiently below)
  55.     jr nc, .seekAnimFrame
  56.     ld a, [hld]
  57.     ld l, [hl]
  58.     ld h, a
  59.     ; Now, write the OAM entries
  60.     ld a, [hli] ; Read nb of OAM entries
  61. .writeOAMEntry
  62.     ldh [hNPCRemainingEntries], a
  63.     ldh a, [hCameraRelativePosition]
  64.     add a, [hl]
  65.     inc hl
  66.     dec a
  67.     cp SCRN_Y + 16 - 1
  68.     jr nc, .offscreen
  69.     inc a
  70.     ld [de], a
  71.     inc e ; inc de
  72.     ldh a, [hCameraRelativePosition+2]
  73.     add a, [hl]
  74.     inc hl
  75.     dec a
  76.     cp SCRN_X + 8 - 1
  77.     jr nc, .offscreenCancel
  78.     inc a
  79.     ld [de], a
  80.     inc e ; inc de
  81.     ldh a, [hNPCTileID]
  82.     add a, [hl]
  83.     inc hl
  84.     ld [de], a
  85.     inc e ; inc de
  86.     ldh a, [hNPCAttr]
  87.     xor [hl]
  88.     ld [de], a
  89.     inc e ; inc de
  90.     ld a, e
  91.     cp $A0
  92.     jr nc, .filledOAM
  93.     ; Carry is set here
  94. .skipOffscreen ; This gets jumped to with carry set
  95.     inc hl ; Skip attr (this is common to all code paths)
  96.     ldh a, [hNPCRemainingEntries]
  97.     dec a
  98.     jr nz, .writeOAMEntry
  99. .filledOAM ; This gets jumped to on NC
  100.     ; Here: NC <=> OAM is full
  101.     pop hl
  102.     ld [hl], c ; Write back new anim cnt
  103.     jr nc, .OAMFull ; Prevent overflowing OAM
  104. .npcCulledOut ; This gets jumped to on C if the NPC isn't drawn, which can't have overflowed OAM, therefore NC <=> OAM isn't full
  105.     ; Advance to next NPC, if it exists
  106.     ld a, l
  107.     or sizeof_NPC - 1
  108.     inc a
  109.     ld l, a
  110.     cp LOW(wNPCArrayEnd)
  111.     jr nz, .redrawNPC
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement