SHARE
TWEET

NPC redrawing code

ISSOtm Jul 19th, 2019 81 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
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top