@@ -441,6 +441,173 @@ MoveCameraTable: {
441441}
442442}
443443
444+
445+
446+ // Tests that an entity can spawn a new entity and change its entity
447+ // list at the same time.
448+ a16 ()
449+ i16 ()
450+ code ()
451+ Test.add (" GameLoop (Spawn And Change List)" )
452+ function GameLoop_SpawnAndChangeList {
453+ constant _loopsLeft = Test.dpTmp + 0
454+
455+ jsr Entity.Init
456+
457+ lda.w # 0x1000
458+ sta.w Entity.Spawn.xPos
459+ sta.w Entity.Spawn.yPos
460+
461+ ldy.w # Entity.lists.N_LISTS - 1
462+ SpawnLoop :
463+ phy
464+ // Y = listId to spawn entity in
465+ lda.w # SpawnAndChangeListTestEntity.EntityId
466+
467+ jsr Entity.Spawn
468+ bcc Fail
469+ ply
470+ dey
471+ bpl SpawnLoop
472+
473+ jsr _FreeListLength
474+ cmp.w # Entity.N_ENTITIES - Entity.lists.N_LISTS
475+ bne Fail
476+
477+
478+ lda.w # 20
479+ sta.b _loopsLeft
480+
481+ Loop :
482+ jsr Entity.ProcessGameLoop
483+
484+ jsr _TestEntityListsValid
485+ bcc Fail
486+
487+ dec.b _loopsLeft
488+ bne Loop
489+
490+
491+ jmp _TestEntityListsValid
492+
493+
494+ Fail :
495+ clc
496+ rts
497+
498+
499+ namespace SpawnAndChangeListTestEntity {
500+ buildFunctionTable (BaseEntityFunctionTable, SpawnAndChangeListTestEntity)
501+ Entity.useDefaultRenderer ()
502+
503+ constant DELETE_DELAY = 2
504+
505+
506+ // IN: A = entity parameter = entity list id
507+ a16 ()
508+ i16 ()
509+ code ()
510+ function Init {
511+ sep # $20
512+ a8 ()
513+ sta.b BaseEntity.listId
514+
515+ rep # $30
516+ a16 ()
517+ rts
518+ }
519+
520+
521+ a16 ()
522+ i16 ()
523+ code ()
524+ function Process {
525+ // This entity spawns 3 entities:
526+ // * DeleteAfterDelayEntity with listId = listId
527+ // * DeleteAfterDelayEntity with lidtId = listId - 1
528+ // * DeleteAfterDelayEntity with listId = listId + 1
529+ //
530+ // then changes its entity list to the previous list.
531+
532+ lda.b BaseEntity.listId
533+ and .w # 0xff
534+ jsr SpawnDeleteEntity
535+
536+
537+ lda.b BaseEntity.listId
538+ and .w # 0xff
539+ dec
540+ jsr SpawnDeleteEntity
541+
542+
543+ lda.b BaseEntity.listId
544+ and .w # 0xff
545+ inc
546+ jsr SpawnDeleteEntity
547+
548+
549+ lda.b BaseEntity.listId
550+ and .w # 0xff
551+ dec
552+ bpl +
553+ lda.w # Entity.lists.N_LISTS - 1
554+ +
555+ jmp Entity.ChangeEntityListIdAndGotoNextEntity
556+ }
557+
558+
559+ // IN: A = listId to spawn DeleteAfterDelayEntity in.
560+ a16 ()
561+ i16 ()
562+ code ()
563+ function SpawnDeleteEntity {
564+ // ensure entity is spawned
565+ ldx.w Camera.xPos
566+ stx.w Entity.Spawn.xPos
567+ ldx.w Camera.yPos
568+ stx.w Entity.Spawn.yPos
569+
570+ // wrap list id if necessary
571+ tay
572+ bpl +
573+ // A < 0
574+ lda.w # Entity.lists.N_LISTS - 1
575+ +
576+ cmp.w # Entity.lists.N_LISTS
577+ bcc +
578+ lda.w # 0
579+ +
580+
581+ clc
582+ adc.w # Entities.DeleteAfterDelayEntity.EntityId_0
583+ ldy.w # DELETE_DELAY
584+ jmp Entity.Spawn
585+ }
586+
587+
588+ a16 ()
589+ i16 ()
590+ code ()
591+ Destructor :
592+ ProcessCollision :
593+ function NULL {
594+ rts
595+ }
596+
597+
598+ rodata (EN_RomData)
599+ RomData :
600+ dw FunctionTable
601+ db 0 // initialListId
602+ db 0 // defaultPalette
603+ dw 0 // frameSetId
604+
605+ rodata (EN_EntityList)
606+ constant EntityId = (pc () - Entity.Data.EntityList) / 2
607+ dw RomData
608+ }
609+ }
610+
444611}
445612
446613// vim: ft=bass-65816 ts=4 sw=4 et:
0 commit comments