diff --git a/BUGS.md b/BUGS.md index a0eba96..5e94e2a 100644 --- a/BUGS.md +++ b/BUGS.md @@ -4,12 +4,16 @@ BUGS This is a list of the software bugs (as opposed to the bugs in the game that you shoot) that still need attention: * The sound is muddy at times on real HW. Especially when lots of stuff is going on, the sound ends up coming out garbled. This isn't happening on emulators where everything is always quite clear. Perhaps I am reaching some limit of the Ensoniq. Do I need to reduce some sampling frequencies perhaps? -* It seems to be possible to both shoot and be killed by the spider in a single frame. Either the spider should be killed by the shot or the spider should kill the player but not both. + * I tried reducing the sampling frequency from 11025 for most of the samples to 5513 and I didn't notice any improvement in the quality of the sound on real HW. Nor did I notice any real degredation on real HW or on an emulator. FIXED ======= + +* It seems to be possible to both shoot and be killed by the spider in a single frame. Either the spider should be killed by the shot or the spider should kill the player but not both. + * Based on the code, I don't think it is possible that this happened in a single frame. Instead, I think what is happening is that the spider is being shot and then goes through a small number of explosion frames. The colour used in those explosion frames were detected as a collision to the player. + * I have changed the colours of the explosion to no longer be detected as a collision for the player. * It is possible to shoot between two segments of a centipede. The problem is that there are black pixels between the segments and if things are timed just right (or just wrong), the shot can slot in at those black pixels and end up missing both segments. * I am not sure how much can be done about this given how collisions are detected. * I have implemented a fix which I believe solves this problem. The shot is a single pixel wide which allows it to slot in between a segment. I have changed the collision code to detect a collision if it is also if there is any pixel on in the byte (ie two pixels wide). That should ensure that the shot cannot pass through a centipede. Note it also makes things slightly easier to hit where before it might have passed right next to. diff --git a/BuGS/gamePlayer.s b/BuGS/gamePlayer.s index 5577bac..e5aad65 100644 --- a/BuGS/gamePlayer.s +++ b/BuGS/gamePlayer.s @@ -57,12 +57,8 @@ initPlayer_loop2 anop bne initPlayer_loop2 initPlayer_done anop - jmp playerSwitch - + jmp scoreSwitchPlayer -playerSwitch entry - jsl scoreSwitchPlayer - rtl playerLevelStart entry stz playerIgnoreFirstPoll diff --git a/BuGS/gameShot.s b/BuGS/gameShot.s index 2313314..bdaf4cd 100644 --- a/BuGS/gameShot.s +++ b/BuGS/gameShot.s @@ -149,8 +149,8 @@ updateShot_collision anop bge updateShot_onScreen rtl updateShot_onScreen anop - and #$3333 - bne updateShot_maybeMushroom + and #$cccc + beq updateShot_maybeMushroom txy txa diff --git a/BuGS/sprites/explosions.s b/BuGS/sprites/explosions.s index 42b6f2b..2816343 100644 --- a/BuGS/sprites/explosions.s +++ b/BuGS/sprites/explosions.s @@ -16,9 +16,9 @@ explosions start spriteSeg explosion1 entry _spriteHeader -; $c - Green -; $4 - Red -; $8 - Off-white +; $1 - Green (c) +; $2 - Red (4) +; $3 - Off-white (8) ; ; ..RR|.R.. ; .OGR|G... @@ -32,22 +32,22 @@ explosion1 entry lda $0,s and #$00ff - ora #$4400 + ora #$2200 sta $0,s lda $2,s and #$fff0 - ora #$0004 + ora #$0002 sta $2,s lda $a0,s and #$00f0 - ora #$c408 + ora #$1203 sta $a0,s lda $a2,s -; and #$ff0f not necessary with pure green - ora #$00c0 + and #$ff0f + ora #$0010 sta $a2,s tsc @@ -55,22 +55,21 @@ explosion1 entry tcs lda $0,s -; and #$ff0f not necessary with pure green - ora #$cc0c + and #$ff0f + ora #$1101 sta $0,s lda $2,s and #$0f00 - ora #$40cc + ora #$2011 sta $2,s - - lda #$cc4c + lda #$1121 sta $a0,s lda $a2,s and #$0f00 - ora #$80cc + ora #$3011 sta $a2,s tsc @@ -79,18 +78,18 @@ explosion1 entry lda $0,s and #$0f00 - ora #$c04c + ora #$1021 sta $0,s lda $2,s -; and #$fff0 not necessary with pure green - ora #$c0cc + and #$fff0 + ora #$1011 sta $2,s - lda #$cc8c + lda #$1131 sta $a0,s - lda #$8ccc + lda #$3111 sta $a0,s tsc @@ -99,22 +98,22 @@ explosion1 entry lda $0,s and #$00f0 - ora #$cc08 + ora #$1103 sta $0,s lda $2,s and #$0f00 - ora #$804c + ora #$3021 sta $2,s lda $a0,s and #$00f0 - ora #$8404 + ora #$3202 sta $a0,s lda $a2,s and #$f0f0 - ora #$0c04 + ora #$0102 sta $a2,s _spriteFooter @@ -124,9 +123,9 @@ explosion1 entry explosion2 entry _spriteHeader -; $c - Green -; $4 - Red -; $8 - Off-white +; $1 - Green +; $2 - Red +; $3 - Off-white ; ; ..GR|G.R. ; .GGG|GGRG @@ -140,61 +139,61 @@ explosion2 entry lda $0,s and #$00ff - ora #$c400 + ora #$1200 sta $0,s lda $2,s and #$0f0f - ora #$40c0 + ora #$2010 sta $2,s lda $a0,s -; and #$00f0 not necessary with pure green - ora #$cc0c + and #$00f0 + ora #$1101 sta $a0,s - lda #$4ccc + lda #$2111 sta $a2,s tsc adc #$143 tcs - pea $c8cc - pea $cc8c + pea $1311 + pea $1131 adc #$a0 tcs - pea $cc8c - pea $c88c + pea $1131 + pea $1331 adc #$a0 tcs - pea $c88c - pea $c88c + pea $1331 + pea $1331 adc #$a0 tcs - pea $cccc - pea $cc8c + pea $1111 + pea $1131 adc #$a0 tcs - pea $c8cc - pea $c48c + pea $1311 + pea $1231 lda $a1,s and #$f0f0 - ora #$040c + ora #$0201 sta $a1,s lda $a3,s -; and #$f0f0 not necessary for pure green - ora #$000c + and #$f0f0 + ora #$0001 sta $a3,s _spriteFooter @@ -204,9 +203,9 @@ explosion2 entry explosion3 entry _spriteHeader -; $c - Green -; $4 - Red -; $8 - Off-white +; $1 - Green +; $2 - Red +; $3 - Off-white ; ; .GOG|RG.. ; G.GG|GGGR @@ -219,43 +218,43 @@ explosion3 entry lda $0,s and #$00f0 - ora #$8c0c + ora #$3101 sta $0,s lda $2,s and #$ff00 - ora #$004c + ora #$0021 sta $2,s lda $a0,s -; and #$000f not necessary with pure green - ora #$ccc0 + and #$000f + ora #$1110 sta $a0,s - lda #$c4cc + lda #$1211 sta $a2,s tsc adc #$140 tcs - lda #$c8cc + lda #$1311 sta $0,s lda $2,s and #$0f00 - ora #$c0c8 + ora #$1013 sta $2,s lda $a0,s and #$0f00 - ora #$804c + ora #$3021 sta $a0,s lda $a2,s -; and #$00f0 not necessary with pure green - ora #$cc0c + and #$00f0 + ora #$1101 sta $a2,s tsc @@ -263,41 +262,41 @@ explosion3 entry tcs lda $0,s -; and #$ff00 not necessary with pure green - ora #$00cc + and #$ff00 + ora #$0011 sta $0,s lda $2,s -; and #$fff0 not necessary with pure green - ora #$000c + and #$fff0 + ora #$0001 sta $2,s - lda #$4cc4 + lda #$2112 sta $a0,s - lda #$cc4c + lda #$1121 sta $a2,s tsc adc #$140 tcs - lda #$cc4c + lda #$1121 sta $0,s lda $2,s -; and #$0f00 not necessary with pure green - ora #$c0cc + and #$0f00 + ora #$1011 sta $2,s lda $a0,s and #$0ff0 - ora #$c008 + ora #$1003 sta $a0,s lda $a2,s and #$f0f0 - ora #$080c + ora #$0301 sta $a2,s _spriteFooter @@ -323,22 +322,22 @@ explosion4 entry lda $0,s and #$000f - ora #$c8c0 + ora #$1310 sta $0,s lda $2,s and #$f0f0 - ora #$0c04 + ora #$0102 sta $2,s lda $a0,s and #$f0f0 - ora #$0c08 + ora #$0103 sta $a0,s lda $a2,s -; and #$0f0f not necessary with pure green - ora #$c0c0 + and #$0f0f + ora #$1010 sta $a2,s tsc @@ -347,22 +346,22 @@ explosion4 entry lda $0,s and #$f000 - ora #$044c + ora #$0221 sta $0,s lda $2,s and #$f0f0 - ora #$0408 + ora #$0203 sta $2,s lda $a0,s and #$0f0f - ora #$40c0 + ora #$2010 sta $a0,s lda $a2,s -; and #$0fff not necessary with pure green - ora #$c000 + and #$0fff + ora #$1000 sta $a2,s tsc @@ -370,23 +369,23 @@ explosion4 entry tcs lda $0,s -; and #$ff00 not necessary with pure green - ora #$00cc + and #$ff00 + ora #$0011 sta $0,s lda $2,s and #$f0ff - ora #$0800 + ora #$0300 sta $2,s lda $a0,s and #$f0f0 - ora #$0404 + ora #$0202 sta $a0,s lda $a2,s and #$00f0 - ora #$c804 + ora #$1302 sta $a2,s tsc @@ -395,22 +394,22 @@ explosion4 entry lda $0,s and #$0f0f - ora #$4080 + ora #$2030 sta $0,s lda $2,s and #$000f - ora #$c440 + ora #$1220 sta $2,s lda $a0,s and #$f000 - ora #$0c4c + ora #$0121 sta $a0,s lda $a2,s and #$0f00 - ora #$80cc + ora #$3011 sta $a2,s _spriteFooter @@ -435,23 +434,23 @@ explosion5 entry ; lda $0,s -; and #$000f not necessary with pure green - ora #$000c + and #$000f + ora #$0001 sta $0,s lda $2,s -; and #$f0f0 not necessary with pure green - ora #$c0c0 + and #$f0f0 + ora #$1010 sta $2,s lda $a0,s and #$00f0 - ora #$8c04 + ora #$3102 sta $a0,s lda $a2,s and #$0ff0 - ora #$c004 + ora #$1002 sta $a2,s tsc @@ -460,22 +459,22 @@ explosion5 entry lda $0,s and #$ff00 - ora #$00c8 + ora #$0013 sta $0,s lda $2,s and #$f00f - ora #$08c0 + ora #$0310 sta $2,s lda $a0,s and #$fff0 - ora #$0004 + ora #$0002 sta $a0,s lda $a2,s and #$0fff - ora #$4000 + ora #$2000 sta $a2,s tsc @@ -484,22 +483,22 @@ explosion5 entry lda $0,s and #$0f0f - ora #$40c0 + ora #$2010 sta $0,s lda $2,s and #$f0f0 - ora #$0404 + ora #$0202 sta $2,s lda $a0,s and #$f0f0 - ora #$0c08 + ora #$0103 sta $a0,s lda $a2,s and #$0ff0 - ora #$800c + ora #$3001 sta $a2,s tsc @@ -508,22 +507,22 @@ explosion5 entry lda $0,s and #$0f00 - ora #$404c + ora #$2021 sta $0,s lda $2,s -; and #$0fff not necessary with pure green - ora #$c000 + and #$0fff + ora #$1000 sta $2,s lda $a0,s -; and #$f0f0 not necessary with pure green - ora #$0c0c + and #$f0f0 + ora #$0101 sta $a0,s lda $a2,s and #$ff00 - ora #$0084 + ora #$0032 sta $a2,s _spriteFooter @@ -549,22 +548,22 @@ explosion6 entry lda $0,s and #$f0f0 - ora #$0c08 + ora #$0103 sta $0,s lda $2,s -; and #$0fff not necessary with pure green - ora #$c000 + and #$0fff + ora #$1000 sta $2,s lda $a0,s and #$0f0f - ora #$c040 + ora #$1020 sta $a0,s lda $a2,s and #$f000 - ora #$0484 + ora #$0232 sta $a2,s tsc @@ -572,37 +571,37 @@ explosion6 entry tcs lda $a0,s -; and #$ff0f not necessary with pure green - ora #$00c0 - sta $a0,s - - lda $a2,s -; and #$0fff not necessary with pure green - ora #$c000 - sta $a2,s - - tsc - adc #$140 - tcs - - lda $0,s - and #$fff0 - ora #$0008 - sta $0,s - - lda $2,s -; and #$f0ff not necessary with pure green - ora #$0c00 - sta $2,s - - lda $a0,s - and #$fff0 - ora #$0008 + and #$ff0f + ora #$0010 sta $a0,s lda $a2,s and #$0fff - ora #$8000 + ora #$1000 + sta $a2,s + + tsc + adc #$140 + tcs + + lda $0,s + and #$fff0 + ora #$0003 + sta $0,s + + lda $2,s + and #$f0ff + ora #$0100 + sta $2,s + + lda $a0,s + and #$fff0 + ora #$0003 + sta $a0,s + + lda $a2,s + and #$0fff + ora #$3000 sta $a2,s tsc @@ -611,22 +610,22 @@ explosion6 entry lda $0,s and #$0f0f - ora #$c040 + ora #$1020 sta $0,s lda $2,s -; and #$f0ff not necessary with pure green - ora #$0c00 + and #$f0ff + ora #$0100 sta $2,s lda $a0,s and #$f0f0 - ora #$0808 + ora #$0303 sta $a0,s lda $a2,s and #$0f0f - ora #$4040 + ora #$2020 sta $a2,s _spriteFooter diff --git a/BuGS/sprites/scores.s b/BuGS/sprites/scores.s index 74b6d75..4ef1dd0 100644 --- a/BuGS/sprites/scores.s +++ b/BuGS/sprites/scores.s @@ -16,9 +16,9 @@ scores start spriteSeg score300 entry _spriteHeader -; $c - Green -; $4 - Red -; $8 - Off-white +; $1 - Green +; $2 - Red +; $3 - Off-white ; ; ....|....|.... ; ....|....|.... @@ -123,9 +123,9 @@ score300 entry score600 entry _spriteHeader -; $c - Green -; $4 - Red -; $8 - Off-white +; $1 - Green +; $2 - Red +; $3 - Off-white ; ; ....|....|.... ; ....|....|.... @@ -231,9 +231,9 @@ score600 entry score900 entry _spriteHeader -; $c - Green -; $4 - Red -; $8 - Off-white +; $1 - Green +; $2 - Red +; $3 - Off-white ; ; ....|....|.... ; ....|....|.... diff --git a/BuGS/sprites/sprites.md b/BuGS/sprites/sprites.md index 396af36..24343a9 100644 --- a/BuGS/sprites/sprites.md +++ b/BuGS/sprites/sprites.md @@ -40,10 +40,14 @@ Each colour is 4 bits wide. All zeros is always black in all the different pall * numbers * letters * symbols + * spider scores (300, 600 and 900) + * bug explosions * solid squares (primarily the all black square) -These sprites generally draw first and overwrite what may have been there before. After the background layer is drawn, other things are drawn in this order: - * spiders/scores +These sprites generally draw first and overwrite what may have been there before. There are exceptions though. Spider scores and bug explosions do generally layer on top of the background but these things still use the "background colours" when drawn. The reason for this is that these background colours are not considered to be a collision if present when the player is drawn. We do not want the player to be considered dead just because it touched a spider score or bug explosion. + +After the background layer is drawn, other things are drawn in this order: + * spiders * scorpions * fleas * centipede segments @@ -63,3 +67,9 @@ An exception to the "background is drawn first" rule though is the non-playable We also need to clip a flea which is dropping down from the top. The solution there is that the game allocates memory before the SHR page, enough for an extra unseen tile above the screen. A partially obscured flea is drawn offscreen into that part of memory before the SHR page. There is a similar problem when the flea reaches the bottom of the screen. I have decided to just not handle it. The flea disappears once it reaches the bottom of the screen. It does not scroll off the bottom. + +## Collisions + +There are two sprites which need to detect collisions. We need to detect if the player has collided with a bug when we draw the player. The way that is done is that any pixel that the player will draw, we check to see if anding that pixel with $c results in a non-zero value. At least one of those two high bits will be set if the pixel has been drawn by a bug. Background sprites never set those bits. From there, we need to figure out if the bug that was collided with is a spider, flea of centipede segment. The player cannot collide with a scorpion because the are always in different parts of the screen. Once we know there is a collision, the code looks for tile overlap between the player and the spider, flea or centipede segment in order to figure out what collided. + +The player's shot also collides with these things but also collides with mushrooms which are a background sprite. So, in this case, any non-zero value in a pixel being drawn to by the shot is considered to be a collision. In fact, the shot is only one pixel wide but a collision is said to occur if either nibble in the byte is non-zero. Once we have the data from the collision, that is anded with $c and if that is zero, that indicates that a mushroom collision may have occurred. Based on the address of the collision, that turns into a tile lookup. Otherwise, that may be a bug collision. As with player collisions, a check for tile overlap is what is used to figure out what kind of bug caused the collision.