Jump to content
IGNORED

Vertical PM movement in Action!


kensu

Recommended Posts

I have a simple ball-bouncing program which started out as a BASIC program, which was itself derived from the De Re Atari Player-Missile example (which can be found here)

 

Here is the releveant snippet of code:

        BALLX = VECTORX + BALLX
        IF VECTORY = -1 THEN
        MoveBlock(MYPMBASE+639+BALLY,MYPMBASE+640+BALLY,3)
        ZERO(MYPMBASE+642+BALLY,1)        
        ELSE
        MoveBlock(MYPMBASE+640+BALLY,MYPMBASE+639+BALLY,3)
        FI
        BALLY = VECTORY + BALLY    

 

(Ballx and BallY are the coordiantes of the ball, VectorX and VectorY are the direction it's moving (in this case -1 for up, 1 for down)).

So this code works fine when the ball is moving upwards, but once it hits the top of the screen and starts moving downwards (the Else clause) it just vanishes from the screen. I suspect there's something I missed when I translated the FOR loop from the BASIC code. (see the De Re Atari example above)

Note: there should be a zero command in the Else clause to keep the ball from leaving a trail on the screen, but that's irrelevant to this problem.

 

If I change the else clause to: 

MoveBlock(MBASE+637+BALLY,MYPMBASE+636+BALLY,3) the ball will bounce and continue on for about 3 bytes, gradually disappearing.

 

Link to comment
Share on other sites

Not an Action expert but I would guess the problem is with the move direction.

When you move memory from a higher to lower start address you should go from start to finish.

When you move from a lower to higher address you should go from finish to start (backwards) to avoid overwrite.

 

Likely what you're getting is the PM area overwritten with whatever is at the start address - likely 00.

Link to comment
Share on other sites

It seems that Action! does not have a reverse MoveBlock for such situations.

 

A workaround is to always move from another source to the P/M area. That source should have at least N zero bytes at each side, where N is the number of the maximum "vertical speed".

 

So, your code should look like:

 

        BALLX = VECTORX + BALLX
        BALLY = VECTORY + BALLY
        MoveBlock(SPRITEDATA,MYPMBASE+640+BALLY,3)

 

You have to fine-tune the 640 and the 3 to adjust the N number I said. Probably 639 (640-N) and 5 (3+2*N) if N=1 (one pixel at a time).

 

 

Link to comment
Share on other sites

Thanks to everyone who replied, the issue was that it was overwriting itself. (I assumed MoveBlock moved it as a discrete block, but it must do it byte-by-byte like the De Re Atari exampl). I fixed the problem by zeroing out the player graphics at the current position and redrawing them (from the array where I originally defined it) in the final position. I also padded it with zeroes, an arcane practice I've been seeing in code examples but haven't understood until now.   It appears the way I did it now is the way it's done in most examples.

 

I'm beginning to realize that Action! is even closer to the metal then C is, never before have I found myself wondering how malloc works so I could write my own.

 

Link to comment
Share on other sites

MoveBlock()-like functions typically have some intricacies. For example, they can expect specific direction of the movement, specific requirements for overlapping or can be abused to populate a block of memory with a single, selected value.

I remember abusing TBXL's MOVE to quickly zeroing out screen memory.

Link to comment
Share on other sites

4 hours ago, kensu said:

Thanks to everyone who replied, the issue was that it was overwriting itself. (I assumed MoveBlock moved it as a discrete block, but it must do it byte-by-byte like the De Re Atari exampl). I fixed the problem by zeroing out the player graphics at the current position and redrawing them (from the array where I originally defined it) in the final position. I also padded it with zeroes, an arcane practice I've been seeing in code examples but haven't understood until now.   It appears the way I did it now is the way it's done in most examples.

 

I'm beginning to realize that Action! is even closer to the metal then C is, never before have I found myself wondering how malloc works so I could write my own.

 

I think that is fairly correct. You can write C in a manner that is very bare metal too, but you have to do it on purpose. I think Action! and C code such as mentioned are very similar in 'height' above bare metal...so then it gets down to which has better code generation and optimization...and I'm sure that's been explored in one of the language benchmarking threads here.

 

Malloc functions are very interesting and fundamental routines, you would learn a lot if you worked your way through writing your own.

Edited by danwinslow
Link to comment
Share on other sites

4 hours ago, danwinslow said:

I think that is fairly correct. You can write C in a manner that is very bare metal too, but you have to do it on purpose. I think Action! and C code such as mentioned are very similar in 'height' above bare metal...so then it gets down to which has better code generation and optimization...and I'm sure that's been explored in one of the language benchmarking threads here.

 

Malloc functions are very interesting and fundamental routines, you would learn a lot if you worked your way through writing your own.

 

It's been years since I used Action so perhaps this is off base a bit.

 

Action, I believe, is more efficient by default - the features of the language are geared towards 8bit programming.  With most C compilers on the 8bit you have to deliberately avoid using certain language features to write efficient code.  Going so far as writing your C code as if it were a verbose assembler.

 

Link to comment
Share on other sites

22 hours ago, kensu said:

Thanks to everyone who replied, the issue was that it was overwriting itself. (I assumed MoveBlock moved it as a discrete block, but it must do it byte-by-byte like the De Re Atari exampl). I fixed the problem by zeroing out the player graphics at the current position and redrawing them (from the array where I originally defined it) in the final position. I also padded it with zeroes, an arcane practice I've been seeing in code examples but haven't understood until now.   It appears the way I did it now is the way it's done in most examples.

 

I'm beginning to realize that Action! is even closer to the metal then C is, never before have I found myself wondering how malloc works so I could write my own.

 

I'm a little surprised Action! doesn't have a command that lets you move blocks in reverse order.  Even Turbo Basic had this.   I thought Action was designed with game programming in mind?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...