Bugged (not bugged) End_level Boss code, solved but why was it happened?

By thegeps

Champion (278)

thegeps's picture

29-11-2019, 19:42

Hi guys, need your hints, cause this "bug-not-bug" gave me about a week of headaches...
well, it all started when I decided to write the end level boss code. First of all I've copied my midlevel boss sprite setting routine, renaming it, cause wanted to use it but eventually managing more than 4 bicoloured sprites (as I do in the mid level boss). But still started using 4 sprites just to check the code. Well, I copied and renamed it, wrote a little movement pattern (to say the truth, the sprites haven't to move) using the same "notation" I used for mid level boss and suddenly a horrible bug showed up! here's a short video of the bug:

https://youtu.be/SbCltTYjbCE

I checked the code (but I did a copy/paste action, it couldn't be broken/bugged) and obviously I didn't found the problem... well, maybe I wrote a bugged pattern notation! Try to call from sprites setting routine the mid level boss pattern! And all works fine! Wow, I did it!!! (yeah, I was sure...)
the video of "all seems to work fine"

https://youtu.be/UNh0joLYbU0

I was really happy, then I copied the pattern data of mid level boss, instead of end level boss pattern data. I have to continue my test, after all... But WTF??? Bugged again??? It is the same pattern data block! I just used and it worked fine, why it is bugged again now?
a video proof of growing headache:

https://youtu.be/EbAfTB3Pxn0

So I had a mad idea? Can data be affected by their memory allocation? The pattern was the same, but in different location (in the same bank!!!). And the bug showed up, ever during third (or fourth, I don't remember exactly right now) movement segment. So I cutted some data from the previous part of the megarom bank I was using and pasted it AFTER end level boss pattern data. So pattern data were moved 384 bytes before (from 0a355h to 0a1d5h) and magically all started to work fine again. Here's the last video:

https://youtu.be/WlqWjDa08qM

Why can it be possible? Code compiled with Glass (I think the last version, downloaded when I had problems to compile a megarom with prec version) and tested with openMSX. Not tested in real hardware til now. Probably I'll do tomorrow or sunday.

Oh, I almost forgot! Did you noticed the bullets where fired only from object 1 and 3? I don't know why it happens. To decide wich enemy has to fire I use this random number generator I found somewhere in this forum (and I saw that ARTRAG used it in Uridium, so...) but probably I did'nt get it properly...

call rand8
and 6 ; <---- I think this is to force numbers to be from 0 to 6 (so 7 values), am I right?
jp z,coord_from1
dec a
jp z,coord_from2
dec a
jp z,coord_from3
dec a
jp z,coord_from4
dec a
jp z,coord_from5
dec a
jp z,coord_from6
coord_from7:
(here's the code to set bullet coordinates from 7th enemy etc)

rand8:
push hl
ld hl,(randSeed)
add hl,hl
sbc a,a
and 083h
xor l
ld l,a
ld (randSeed),hl
pop hl
ret

thank you for read.

Login or register to post comments

By Pencioner

Paladin (990)

Pencioner's picture

29-11-2019, 21:43

thegeps wrote:

and 6 ; <---- I think this is to force numbers to be from 0 to 6 (so 7 values), am I right?

i don't have any opinion on above bugs yet, but this line is not correct. ANDing with 6 is ANDing with binary 00000110 and it strips any incoming number to a set of numbers 0,2,4,6 (...{0000, 0010, 0100, 0110} in binary) which is exactly not what you want and exactly why it shoots from only a pair of objects

BTW, i think above bugs should have some similar exaplanation and no mystic, but i would recommend to search and read some article or tutorial on using bitwise OR,AND,XOR and NOT first (until you understand why XORing with itself gives zero, and XORing with FF is same as applying NOT to all bits) Wink

By thegeps

Champion (278)

thegeps's picture

29-11-2019, 22:23

You are right! I didn't think enough when I copied this random number generator. I saw that someone used a AND to limit the range and didn't look "how" it works and simply I did the "same" but not doing the same. Thank you for opening my eyes. I'll patch it!

By thegeps

Champion (278)

thegeps's picture

01-12-2019, 22:43

Bullet bug fixed in no time (again, Pencioner, thank you to help me think what I was doing).
But still I have no clues about that "not-bug" I fixed moving data. Anyone, hints?

By thegeps

Champion (278)

thegeps's picture

01-12-2019, 23:21

level1_end_boss:
ld a,100
ld (boss_hp),a
ld a,1
ld (bossbattle),a
ld hl,elb1_eventlist
ld (evlist),hl
ld hl,10
ld (boss_pos),hl
ld hl,ELB_data1
ld (ELB_data),hl
xor a
ld (event),a
jp End_Level_Boss

End_Level_Boss:
ld a,1
ld (speed),a ;set scrolling speed (in pixels)
ELB_loop:
LD hl,chstart-704
LD (nametable),hl
ld a,(event) ;actual event nr in reg a
ld hl,(evlist) ;event nr of event list in hl regs
cp (hl) ;are the same?
call z,ELB_spmove ;yes, call boss movement change
call putboss ;put boss on screen
call CNGChR ;draw shifted screen
ld a,(lives) ;check lives left
cp 0 ;
jp z,gameover ;if zero go to gameover routine
ld a,(boss_hp) ;check boss hp
or a ;
jp z,just_killed_ELB ;if 0 we have killed him
call shot_or_not ;check if enemy will shot (it will change bullet_flag)
ld a,(bullet_flag) ;check bullet flag
dec a ;
call z,set_bullet ;if it is 1 then go to set bullet params
ld a,(dead_flag) ;check if we were killed and so respawn
dec a ;
jp z,ELB_skip_control ;if so skip joystick check (can't move during respawn)
call control ;check keyboard or joystick inputs
ELB_skip_control:
call cshot_collision ;check central shot collisions
call lshot_collision ;check left shot collisions
call rshot_collision ;check right shot collisions
ld a,(power) ;check weapon level
cp 8 ;
jp c,ELB_no_pod ;if level<8 then we have no pod and ignore its collisions
call pod_collision ;check pod collisions with bullets
ELB_no_pod:
ld a,(respawn_time) ;check respawn_time variable
or a ;
jp nz,ELB_loop ;if not zero restart end level boss loop without collisions check
ELB_main_collision:
call ship_collision ;check collisions between airship and enemies
call bullet_collision ;check collisions between airship and enemy bullets
jp ELB_loop ;loop again

just_killed_ELB:
xor a ;we have killed the boss
ld (bossbattle),a ;reset bossbattle flag
jp prepare_to_next_level

ELB_spmove:
ld a,(hl) ;load in A eventlist value
inc a ;if value <> 255
jp nz,ELB_event ;go to check event else ret
ret
ELB_event:
inc hl
ld a,(hl)
ld hl,actpat+36 ;a table, 3 values per sprite (so here start form sprite 12,
ld b,8 ;first enemy sprite)
ELB_actloop:
ld (hl),1 ;set sprite active flag
inc l
ld (hl),a ;movement pattern nr
inc l
ld (hl),0 ;actual position in pattern nr
inc l
djnz ELB_actloop
ld hl,(evlist)
inc l
inc l
ld de,ramspttbl+48 ;SAT address of sprite 12
ld bc,32
ldir
ld hl,(evlist)
ld de,34
add hl,de
ld (evlist),hl
ret

elb1_eventlist: ;datas I had to move 384 bytes before (copied here only 2 segment but there were more)
db 1,15 ; event nr, pattern nr
db 16,88,64,1,16,88,68,13 ; object1 data, sprite 12 y,x,shape nr,color/sprite13 y,x,shape,color
db 16,160,72,1,16,160,76,13 ;object2 data
db 64,112,64,1,64,112,68,13 ;object3 data
db 64,134,64,1,64,134,68,13 ;object4 data

db 8,15 ;event nr, pattern nr
db 16,88,64,1,16,88,68,13
db 16,160,72,1,16,160,76,13
db 64,112,64,1,64,112,68,13
db 64,134,64,1,64,134,68,13