It is currently Tue Nov 21, 2017 7:02 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 37 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
PostPosted: Tue Aug 15, 2017 8:47 am 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 873
Location: Sweden
Ah that was the problem. My math was wrong.

Ah good idea Fox. I actually solved it the other way around and combined them:
I changed all the "#(256-MOB_MSPD_L)" and "#(256-MOB_MSPD_H)" to "#<(-(MOB_MSPD_L+(MOB_MSPD_H*256)))" and "#>(-(MOB_MSPD_L+(MOB_MSPD_H*256)))" respectively and now the character moves in the same speed in both directions. But your way makes much more readable code.

Thanks a lot both of you!


I also just solved the jumping problem I think, so that's probably good now.
So I'm done with basic movement for now, next comes collision. I guess I'd need to load a collision map in RAM that matches the level map on screen.


Top
 Profile  
 
PostPosted: Wed Aug 16, 2017 2:08 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 803
Location: cypress, texas
Pokun wrote:
One thing FCEUX is missing though is an OAM viewer.

I used to miss an OAM viewer too; but, after understanding that page 2 is jammed into OAM each frame using the OAM_DMA register, $4014, taking 513 cycles, I just check page 2 in the hex editor to look at OAM. :)

Code:
sprite = $200

Code:
.MACRO update_sprite
lda #>sprite
sta $4014
.ENDM
using asm6

edit: I don't understand most of this thread, but I'm happy your problem is solved! :D


Top
 Profile  
 
PostPosted: Wed Aug 16, 2017 2:27 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 803
Location: cypress, texas
Pokun wrote:
So I'm done with basic movement for now, next comes collision. I guess I'd need to load a collision map in RAM that matches the level map on screen.

No, you can access the collision values from ROM using lda (ptr), y :) Much easier accessing collision values from ROM than loading RAM with an entire screen worth of values. Think tokumaru told me something like that in my thread on page 50. :)


Top
 Profile  
 
PostPosted: Wed Aug 16, 2017 4:53 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10116
Location: Rio de Janeiro - Brazil
Many games use the same map for display and for collisions. It's very reasonable to assume that blocks that look the same will behave the same, so you actually save a lot of space by defining the collision information only once for each type of block, instead of multiple times, once for each instance of each type of block.

Depending on how your levels are compressed, you can read the collision information directly from ROM without problems. If you use something that doesn't allow random access though, such as RLE or LZ, then it does make sense to buffer a small section of the level in RAM, and update that as the player walks around.


Top
 Profile  
 
PostPosted: Wed Aug 16, 2017 6:22 pm 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 873
Location: Sweden
I guess collision map was the wrong term. I didn't mean a separate collision mask, but actual level data: $00 = empty space, $01 = wall, $02 = one-way platform, $03 = water, $04 = spikes, $05 = ladder etc (as an example, currently I only have wall and empty space). Both collisions and the level drawing routine are going to use the same data.
I see, currently I have no compression at all though, I want to figure out how to get things to work first. One advantage I see with RAM, besides compression, is destructible tiles. ROM or RAM is something I can decide on later though, and if I run out of either I'll just use a mapper.

I'm not sure how I can calculate collision positions with level tiles though. With objects I can just compare their coordinates, but with level tiles I have to somehow translate the object coordinates to a position in my level map which is using 16x16 metatiles, one byte per metatile.

unregistered wrote:
Pokun wrote:
One thing FCEUX is missing though is an OAM viewer.

I used to miss an OAM viewer too; but, after understanding that page 2 is jammed into OAM each frame using the OAM_DMA register, $4014, taking 513 cycles, I just check page 2 in the hex editor to look at OAM. :)

Yeah well actually FCEUX is able to show the internal OAM in the hex editor (click on "View"), not only the "shadow OAM" in RAM. But I meant a more visual sprite viewer like in Nintendulator and Mesen. I guess you can't have everything.

unregistered wrote:
I don't understand most of this thread, but I'm happy your problem is solved! :D

Haha thank you. I tried to explain what I'm doing so people don't have to study my code too much, but it's hard to type short and concise text.


Top
 Profile  
 
PostPosted: Wed Aug 16, 2017 7:59 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10116
Location: Rio de Janeiro - Brazil
Pokun wrote:
I see, currently I have no compression at all though, I want to figure out how to get things to work first. One advantage I see with RAM, besides compression, is destructible tiles. ROM or RAM is something I can decide on later though, and if I run out of either I'll just use a mapper.

Even if you're not going to implement the final formats/algorithms for everything now, it helps to have an idea of what you'll want to do in the future to avoid having to throw out everything you're doing now.

If you think you can spare the RAM, it may be a good idea to have your engine working mostly with data from there, because later on when you do implement compression and such, you'll only have to change the code that populates those RAM buffers, while the bulk of the engine will remain the same.

Quote:
I'm not sure how I can calculate collision positions with level tiles though. With objects I can just compare their coordinates, but with level tiles I have to somehow translate the object coordinates to a position in my level map which is using 16x16 metatiles, one byte per metatile.

Converting coordinates between different spaces is something that many games have to do quite often, specially if scrolling is involved. It's true, you will have to convert pixel coordinates into metatile coordinates to find out which blocks the sprites are touching. There's a very simple formula for this conversion:

Offset = (PixelY / 16) * MapWidth + (PixelX / 16)

If you don't have any scrolling (i.e the map width is 16 metatiles and coordinates are 8-bit), the conversion is dead simple:

Code:
  lda PixelY
  and #%11110000
  sta Offset
  lda PixelX
  lsr
  lsr
  lsr
  lsr
  ora Offset
  sta Offset

Now you can just use the offset to load the metatile's index from the map:

Code:
  ldx Offset
  lda LevelMap, x

And that's it. If you do have longer maps and 16-bit coordinates, the code is a bit more complex, but the principle is the same.


Top
 Profile  
 
PostPosted: Wed Aug 16, 2017 8:34 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5824
Location: Canada
Pokun wrote:
Yeah well actually FCEUX is able to show the internal OAM in the hex editor (click on "View"), not only the "shadow OAM" in RAM. But I meant a more visual sprite viewer like in Nintendulator and Mesen. I guess you can't have everything.

tokumaru wrote a really nice lua script that does a pretty good job of it:
viewtopic.php?p=181008#p181008


Top
 Profile  
 
PostPosted: Thu Aug 17, 2017 12:50 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 803
Location: cypress, texas
rainwarrior wrote:
Pokun wrote:
Yeah well actually FCEUX is able to show the internal OAM in the hex editor (click on "View"), not only the "shadow OAM" in RAM. But I meant a more visual sprite viewer like in Nintendulator and Mesen. I guess you can't have everything.

tokumaru wrote a really nice lua script that does a pretty good job of it:
viewtopic.php?p=181008#p181008
Wow, thanks for the link rainwarrior! :D

ps. How did you find the post number? There used to be a permalink button, but I haven't found it in a long while. :(


Top
 Profile  
 
PostPosted: Thu Aug 17, 2017 1:05 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 803
Location: cypress, texas
Pokun wrote:
unregistered wrote:
I don't understand most of this thread, but I'm happy your problem is solved! :D

Haha thank you. I tried to explain what I'm doing so people don't have to study my code too much, but it's hard to type short and concise text.
I don't understand most of this thread because it takes me a lot of concentration to try and understand programming concepts... :oops: I just didn't apply myself; wasn't criticizing your efforts. :)


Top
 Profile  
 
PostPosted: Thu Aug 17, 2017 1:06 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5824
Location: Canada
unregistered wrote:
ps. How did you find the post number? There used to be a permalink button, but I haven't found it in a long while. :(

At the top of any post, there's a line with the subject on the left, and on the right there's a "posted" with a date and a little paper icon next to it. The link is the paper icon.


Top
 Profile  
 
PostPosted: Thu Aug 17, 2017 1:15 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 803
Location: cypress, texas
^Thank you rainwarrior so much!! :D

Pokun, I'll try to write future posts more clearly. Thanks for this learning experience. :)


Top
 Profile  
 
PostPosted: Fri Aug 18, 2017 6:20 am 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 873
Location: Sweden
unregistered wrote:
Pokun wrote:
unregistered wrote:
I don't understand most of this thread, but I'm happy your problem is solved! :D

Haha thank you. I tried to explain what I'm doing so people don't have to study my code too much, but it's hard to type short and concise text.
I don't understand most of this thread because it takes me a lot of concentration to try and understand programming concepts... :oops: I just didn't apply myself; wasn't criticizing your efforts. :)

I know what you mean, I only learned this stuff in this thread myself just before coding it. If you want to understand it, you may need to study signed 16-bit comparisons in the links in the first post.


Thanks everyone. The formula Tokumaru posted worked like a charm and now floor collision works like it should. Although jumping down with high speed makes the player's feet dig into the ground and jumping into the roof makes his head stuck in there so I have to eject him from the tile he collided with. I found a formula for how many pixels to eject in this post. The formula for positive velocity (eject_value = (pixel_coordinate AND $0F) + 1) works for the floor, but doing the the formula for negative velocity (eject_value = (pixel_coordinate EOR $0F) + 1) does not work for the ceiling. The player teleports far above the ceiling whenever he bumps his head into it.

Positive Y-velocity (for floors) Ejection:
Code:
;This code works fine:
  lda #$00
  sta p1_vy+0
  sta p1_vy+1             ;stop velocity when landing on floor
 
  sta p1_y+0
  lda p1_y+1
  and #$0F
  sta temp+1
  lda p1_y+1
  clc
  adc #$08                ;+height
  sec
  sbc temp+1
  sta p1_y+1              ;eject from tile, Y = Y - (Y AND $0F)
 
  lda #$01
  sta p1_ground           ;set state to grounded


Negative Y-velocity (for ceilings) Ejection:
Code:
;This code does not work correctly:
  lda #$00
  sta p1_vy+0
  sta p1_vy+1             ;stop velocity when banging head in ceiling
 
  sta p1_y+0
  lda p1_y+1
  eor #$0F
  sta temp+1
  lda p1_y+1
  clc
  adc temp+1
  sta p1_y+1              ;eject from tile, Y = Y + (Y XOR $0F)

I haven't yet added the +1 in either ejection calculations, but I don't think it would be the cause of the problem.
Did I misunderstand the formula or is the problem somewhere else?


Top
 Profile  
 
PostPosted: Fri Aug 18, 2017 7:40 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10116
Location: Rio de Janeiro - Brazil
Pokun wrote:
The player teleports far above the ceiling whenever he bumps his head into it.

Don't forget to account for the heights of the player and metatiles.


Top
 Profile  
 
PostPosted: Fri Aug 18, 2017 9:34 am 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 803
Location: cypress, texas
small note: when adding and you want to add one more, it's easy to do, just change your clc to sec. Learned that from Kasumi. :D


Top
 Profile  
 
PostPosted: Fri Aug 18, 2017 1:23 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10116
Location: Rio de Janeiro - Brazil
I believe I use a similar trick when calculating sprite coordinates, to compensate for the fact that sprites are positioned one scanline lower than the Y coordinate specified in their OAM entries. Instead of doing SpriteY = ObjectY - CameraY, I do SpriteY = ObjectY - CameraY - 1 by putting a CLC before the subtraction, instead of the usual SEC.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 37 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group