Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 09:33 19 Feb 2026 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : PicoMite V6.02.00 release candidates - Structured types

     Page 10 of 14    
Author Message
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5703
Posted: 09:57am 19 Jan 2026
Copy link to clipboard 
Print this post

Peter,

Thank you for the update. I knew the moment would arrive some time. Not that I do not want to "crunch" the games. But that will have to wait for a big "overhaul", where I also want to implement Geoff's menu system (that automatically adds programs to the menu when they are added to the drive in GameMite folder).

I will search for the best release for Game*Mite until then. One that does not have the ON ERROR SKIP bug, not the DIM bug, and provides sufficient A:/ drive, and heap. Maybe this is all wasted time, since the installed base of the Game*Mite is small. I think the 3 units I have may be more than 10% of the total.

Geoff has a good archive of releases to pick from, and I still have a backup of 5.09.00rc5. One of these will become the default version for Game*Mite.

Volhout
Edited 2026-01-19 20:10 by Volhout
PicomiteVGA PETSCII ROBOTS
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10965
Posted: 10:15am 19 Jan 2026
Copy link to clipboard 
Print this post

Your choice, of course, but it seems crazy for the sake of 64K of A: drive. I have committed to keeping 6.02.00 updated and bug free for the RP2040 irrespective of any further changes to the code in the future so it will be a LTS version for the RP2040. Does anyone but you actually still use the Game*Mite?

Since it has gone over the page I will rerun my response for ksinger

Hi ksinger - welcome on board.
  Quote  
sprite(b,spritenum,0...3) is quite great because in case of collision you can just move the sprite back with the given numbers to avoid the collision again.


Please can you explain more. Suppose I have a sprite 10x5 vertically above another sprite 10x5. I move the top sprite down in the y direction so that it overlaps the bottom sprite by 1 pixel in the Y direction. However, because they are both 10 pixels wide they overlap 10 pixels in the x direction.
How exactly do I use your proposed function and what does it return? Please write some pseudo code so I can properly understand.
The basic concept seems interesting and if we can make it work properly I'm happy to include something in this next release.
 
bfwolf
Senior Member

Joined: 03/01/2025
Location: Germany
Posts: 166
Posted: 10:15am 19 Jan 2026
Copy link to clipboard 
Print this post

  Mixtel90 said  Just musing:

On a Picomite you probably can't have DLLs as the user program is in flash and RAM is tight, unless you give up screen resolutions, layers etc. There's nowhere to load them from disk and there's no OS to keep track of them.
...
Just a thought.


Yes, I completely agree with you: RAM is the bottleneck, especially with the RP2040.

But who says that a DLL (like on a PC) has to run in RAM?

With the Amiga, a large part of AmigaOS was in ROM. This consisted not only of the kernel (which was actually very small) but also of DLLs, which were then executed directly from ROM. During the boot process, the ROM was searched for DLLs (which initially had defined tags and were stored sequentially as linked lists) and then linked in a kind of "directory" in RAM. Additionally, a small amount of RAM was needed for each DLL for its variables and the jump tables of its functions—but nothing more.

Furthermore, there was a search path for DLLs (configurable), just like for EXE files. The ROM was then at the end of the search path, so that one could have other/newer versions of the DLLs on the floppy/HD/RAM disk.


  matherp said  
...
As to DLLs - forget it. Software would have to be compiled separately, position independent and then somehow loaded into flash. There is zero chance that this is ever going to be looked at by me.


Yes, of course, @Peter: It's not entirely trivial. And the code would logically have to be compiled position-independently, but modern CPUs and compilers allow that.

There's already a partition where the BASIC libraries are stored. Perhaps C libraries could also be located there?

Let some time pass and "let water flow down the Thames" — maybe some ideas will take shape in your mind during that time.

Perhaps the explanations for AmigaOS will help; in my opinion, it was solved very elegantly, resource-efficiently, and with high performance there.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10965
Posted: 10:22am 19 Jan 2026
Copy link to clipboard 
Print this post

The Amiga approach achieves nothing. The dlls would still be in flash (rom) and therefore there would be no change in the flash footprint. Because of Geoff's elegant architecture, there is no impact on performance of adding a new command.
The one thing I could do to solve Harm's issue is make the number of flash slots configurable via an Option command. So for Game*Mite he could set it to 1 just for the library.
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5703
Posted: 10:35am 19 Jan 2026
Copy link to clipboard 
Print this post

@Peter,

I have absolutely no knowledge of the internal working of MMBasic, but the one thing that I can think of that could help is the size of the flash slots.

Not the number of slots. Game*Mite uses 2 or 3 slots (1 is fixed for the menu system) depending what games are run.

But the games that use flash slots that I know are developed on VGA (i.e. Petscii Robots), and thus use 100kbyte maximum of that flash slot/library.
They do not have to be 132kbyte in size. But maybe that is beneficial for the underlying basic parser.
I am not sure if there are others that do use the full size of the flash slots of 124/132kbyte.

Volhout
Edited 2026-01-19 20:37 by Volhout
PicomiteVGA PETSCII ROBOTS
 
ksinger
Regular Member

Joined: 06/01/2026
Location: United Kingdom
Posts: 70
Posted: 10:41am 19 Jan 2026
Copy link to clipboard 
Print this post

  matherp said  
Please can you explain more. Suppose I have a sprite 10x5 vertically above another sprite 10x5. I move the top sprite down in the y direction so that it overlaps the bottom sprite by 1 pixel in the Y direction. However, because they are both 10 pixels wide they overlap 10 pixels in the x direction.
How exactly do I use your proposed function and what does it return? Please write some pseudo code so I can properly understand.
The basic concept seems interesting and if we can make it work properly I'm happy to include something in this next release.


I wrote the function majorly to cope with testing of non-sprite content but as I use
blitstoreptr it also works for sprite collisions.

In the current implementation it detects pixel accurate overlap.
The functions sprite(b,spriteno,0...3) should return the amount to shift the sprite to avoid overlap.
0:left
1:right
2:top
3:bottom

lets have a short example
  X
---X---

----- being a background lets say the floor
and X being a sprite
   X

so assuming the overlap is 4 pixel sprite (b,spritexno,3) would return 4.

The current implementation detects collision pixel accurate. In order to give the pixel accurate correction number a bit of more refinement would be needed in case the sprite is having some background pixels on the sides. Currently for the correction number the code assumes that the sprite filles the whole area. but it is an easy line search so can be implemented cost effectively.

How about me preparing a basic demo and finalizing the patch to see it in action...
Edited 2026-01-19 21:10 by ksinger
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10965
Posted: 11:05am 19 Jan 2026
Copy link to clipboard 
Print this post

The patch doesn't help me as I have made major changes in the sprite code. I have hated the whole patch approach ever since Dec used to provide updates to the RSX11 OS components as patches and I had to spend hours applying them..
I now understand the 0,,3 in your concept. But don't you also need to specify the object that you want to analyse against? If I move a sprite so it touches two others one on the left and one on the right, if I understand your syntax 0 and 1 will both show overlaps. Whereas if I first identify the objects that have caused the collision I can interrogate them separately.
Next thought, It may be better to make this a sub command rather than a function. That way it could return all 4 parameters with a single call

SPRITE COLLISION mysprite, hitsprite, left, right, top, bottom
Edited 2026-01-19 21:05 by matherp
 
ksinger
Regular Member

Joined: 06/01/2026
Location: United Kingdom
Posts: 70
Posted: 11:24am 19 Jan 2026
Copy link to clipboard 
Print this post

  matherp said  The patch doesn't help me as I have made major changes in the sprite code. I have hated the whole patch approach ever since Dec used to provide updates to the RSX11 OS components as patches and I had to spend hours applying them..
I now understand the 0,,3 in your concept. But don't you also need to specify the object that you want to analyse against?


in the current implementation it basically just checks what is drawn up to the point where the check sprite(b,spriteno) is performed. So any sprite that is not drawn yet is not detected. But it is enough to avoid e.g. two player bumping into each other.

  matherp said   If I move a sprite so it touches two others one on the left and one on the right, if I understand your syntax 0 and 1 will both show overlaps. Whereas if I first identify the objects that have caused the collision I can interrogate them separately.

you are completely right it would not tell you which sprite collided. But for those things we have the sprite(c,...) functions. They work not pixel accurate.

  matherp said  
Next thought, It may be better to make this a sub command rather than a function. That way it could return all 4 parameters with a single call

SPRITE COLLISION mysprite, hitsprite, left, right, top, bottom



The function approach has the advantage that you can directly use the function call in the correction code such as:
x=x-sprite(b,1,1)
and sprite(b,1,1) being zero when there is no collision. It made the mario like game
implementation very beautiful (I also wanted the code to look in basic appealing to
the students...)
Another reason is that this sprite logic must be very fast and variable lookup in basic is much slower than the function approach.

I also could think of an alternative way:
I do not care about pixel accuracy at all and just detect if some pixel are in the area where the sprite is drawn, even if some of the pixel might be on a transparent region of the sprite. This has one advantage:
I could leave transparent boundary regions around the sprite and detect collisions before they happen. This safes me one sprite show command. And I might have to do a corrective draw e.g. just when running fast. I should mention that I would still rely in the correction information, which now would just give the maximal value of the pixel distance to the edges of the sprite.

I think this is actually more beneficial than the pixel accurate version. It is also faster as I do not have to access the sprite pixels at all.

When writing the mario game I realized this would be so convenient, as you do not move down the sprite due to gravity, detect that it is standing on the floor, move up again.

I guess the best way for you is that I implement this functionality on top of your current release candidate, to avoid all this patching mess. But I have no idea how to access it.

Final though maybe on wants just the two functionalities. Pixel accurate collision detection and the versions that allows for the transparent boundary region.
Edited 2026-01-19 21:37 by ksinger
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10965
Posted: 11:36am 19 Jan 2026
Copy link to clipboard 
Print this post

  Quote  I could leave transparent boundary regions around the sprite and detect collisions before they happen. This safes me one sprite show command.

In which case wouldn't it be better to have a SPRITE TEST constuct that evaluates a move before making it. My problem with your approach is that it only works in simple cases. x=x-sprite(b,1,1) is all well and good but what about when x=x+sprite(b,1,0) also returns a result and movement isn't always orthogonal. For example I move in direction y but it triggers left and/or right.
 
ksinger
Regular Member

Joined: 06/01/2026
Location: United Kingdom
Posts: 70
Posted: 11:46am 19 Jan 2026
Copy link to clipboard 
Print this post

  matherp said  
  Quote  I could leave transparent boundary regions around the sprite and detect collisions before they happen. This safes me one sprite show command.

In which case wouldn't it be better to have a SPRITE TEST constuct that evaluates a move before making it. My problem with your approach is that it only works in simple cases. x=x-sprite(b,1,1) is all well and good but what about when x=x+sprite(b,1,0) also returns a result and movement isn't always orthogonal. For example I move in direction y but it triggers left and/or right.


Collisions on both sides are basically meaning that some other object needs to be corrected. But when iteratively checking these conditions one should not get into such a state.

I agree sprite test is a good approach and it would allow for all different types of tests. And basically mimic the sprite show command. that would allow to test for different layers. But I think the information of how much it overlaps to all sides is important to generate in c as in basic it was to slow to give me smooth scrolling experience.

I still think that the current approach (sprite(b,...)) has some benefits as it relies on the data that are generated by a sprite show command anyway.

In typical game loops collisions are much less than movement. So it means we do not
have to generate these datas twice. With sprite test it means we have to generate nearly the same data structures as for sprite show. Then in case of a negative collision we need to generate them again for sprite show.
Edited 2026-01-19 21:47 by ksinger
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4344
Posted: 11:47am 19 Jan 2026
Copy link to clipboard 
Print this post

Hi Peter,

Since we are talking sprites I thought I'd mention a shortcoming of the current functions:

SPRITE(C, [#]n )
SPRITE(C, [#]n, m)


You have to be very careful if you call the first form to get the number of collided sprites and then iterate using the second form to identify and handle the collision, because if in handling the collision you eliminate the collision (move/remove one of the collided sprites) then you've changed the number of collisions and the indexes of those collisions which screws up the iteration.

Might be better if there was a command/function that would read all the sprite collision data at an instance into an array ?

That said I'm not that bothered as I'm mostly lurking and working on my own stuff and am experiencing something of a sinking feeling every-time MMBasic changes at the moment .

Best wishes,

Tom
Edited 2026-01-19 21:48 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10965
Posted: 12:10pm 19 Jan 2026
Copy link to clipboard 
Print this post

ksinger:
I'll go with your approach. If you want to implement it on my development branch, the easiest thing is if I post Draw.c here (and other affected files) together with two key test programs and you re-post when you have implemented your change.
The major change to sprites is the implementation of static objects. These are effectively sprites but they don't move and have no image data associated with them. So, for example in a game you could draw a box on the screen using standard graphics commands and then define it as a static object. This would enable the full collision detection between the object and any sprite that moves to touch it. It also allows an additional 64 elements that can be included and static objects have their own interrupt routine that makes coding sprite/sprite vs sprite/static interactions simpler.
Your code will need enhancing to deal with the new static objects.

Tom:
I'll look at your idea when I get the code back from ksinger.
 
bfwolf
Senior Member

Joined: 03/01/2025
Location: Germany
Posts: 166
Posted: 12:32pm 19 Jan 2026
Copy link to clipboard 
Print this post

  matherp said  The Amiga approach achieves nothing. The dlls would still be in flash (rom) and therefore there would be no change in the flash footprint. Because of Geoff's elegant architecture, there is no impact on performance of adding a new command.


I would have preferred to store the DLL code in Flash slot 3, where (BASIC) libraries are anyway already stored. This would allow the general interpreter code to be fixed in size. As I've seen, there's now the command 'FLASH DISK LOAD f$ [,O]', which might even be suitable for this purpose.

At some point, the RP2040 (with only 2MB of flash memory) will have to have its features reduced (compared to the Pico2), otherwise less and less memory (e.g., on drive A:) will be available. Perhaps there will then be additional builds (and corresponding .uf2 files) – a "memory-saving version" with fewer features and a "full version" where the space on drive A: or in the flash slots will be smaller.

Otherwise, I would put the "DLLs" issue aside for now, as it's not relevant for the upcoming release 6.02.00.

If you ever want to know more about the basic implementation on the Amiga, feel free to ask me, should it become interesting in the future. I don't know all the details either, but I think I understand the principle, even though it's been a long time.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10965
Posted: 12:42pm 19 Jan 2026
Copy link to clipboard 
Print this post

ksinger
Here are the files for the changes to sprites. Other than Draw.c the changes are just the closing of the sprites so trivial. Please make sure the two demoes run when you have finished with the changes. Please post Draw.c and an appropiate test program for the new functionality on this thread. I would like to get this finished fairly quickly as this release is oven ready.

Sprites.zip
 
ksinger
Regular Member

Joined: 06/01/2026
Location: United Kingdom
Posts: 70
Posted: 12:59pm 19 Jan 2026
Copy link to clipboard 
Print this post

  matherp said  ksinger
Here are the files for the changes to sprites. Other than Draw.c the changes are just the closing of the sprites so trivial. Please make sure the two demoes run when you have finished with the changes. Please post Draw.c and an appropiate test program for the new functionality on this thread. I would like to get this finished fairly quickly as this release is oven ready.

Sprites.zip


thanks, we are also on a time pressure as the event is approaching...
I did some testing and pixel exactness is needed especaially when walking on ramps. everything else looks not good.
 
ksinger
Regular Member

Joined: 06/01/2026
Location: United Kingdom
Posts: 70
Posted: 10:01am 20 Jan 2026
Copy link to clipboard 
Print this post

Dear Peter,
I just submitted the merge with your zip file to the git.
Only Draw.h and Draw.c are changed.

Due to your changes in other files which are not yet commited to the git it does not compile but if you branch to one revision before on my pullrequest it works now nicely. The git commits infos contain a lot of valuable infos that might be needed if
some errors occur. So one can go back and check where the behaviour occurred.

I am attaching the demo program. Don't worry that the top figure does not fully drop down. I did not implement the stopping on right edge in the basic code. but on the screen print out you can see that now both boundary collision detection and pixel exact collision detection work.

I was able to make the code very efficient by just scanning through the background at the cost of 4 arrays to store outlines of the sprite. If that is not what you want,
the computational costs would basically double per collision test.

here is the new syntax:
sprite(b,spriteno)
0: no collisions
1: only boundary collisions
2: pixel exact overlap collisions happened

sprite(b,sprtno,0...7)
   with
   0:how many pixels background enters sprite rect from left edge
   1:how many pixels background enters sprite rect from right edge
   2:how many pixels background enters sprite rect from top edge
   3:how many pixels background enters sprite rect from bottom edge
   4:how many pixels background overlaps with sprite's nontransparent area from left edge
   5:how many pixels background overlaps with sprite's nontransparent area from right edge
   6:how many pixels background overlaps with sprite's nontransparent area from top edge
   7:how many pixels background overlaps with sprite's nontransparent area from bottom edge

One final plead:
Could you please reopen the pull request and merge it into your code for the final release. If errors occur I highly rely on git bisect and the commit history to efficiently track down bugs otherwise. If one does proper branching then your working tree can stay clean and work in progress can always be merged in by pull requests from forks. But we would not have a situation like now where I cannot compile the file.

I have some todo list for the rest of the code base such as proper dead key handling
and west european fonts, which I have prepared. Also the gamepad usb code needs a bit work. But it would be preferable to work with git instead of sending zip files because it is very hard to track down regression bugs otherwise.

HINT:first put your files to git, then apply the pull request. Otherwise it would look as if I have done all the changes that you did.

Draw.zip
Edited 2026-01-20 20:08 by ksinger
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10965
Posted: 10:41am 20 Jan 2026
Copy link to clipboard 
Print this post

I'll apply the changes to my code and post a new RC8 when I've tested it. Sorry but I'm not messing around with git. I will just dump my dev environment onto git when I do the release. I use dropbox to track my changes. I can go back to any historical version and then difference it against my current status using winmerge. I can restore the entire environment or a specific file to any given date etc.

How do I know if your test program is working?
Edited 2026-01-20 21:18 by matherp
 
ksinger
Regular Member

Joined: 06/01/2026
Location: United Kingdom
Posts: 70
Posted: 10:55am 20 Jan 2026
Copy link to clipboard 
Print this post

It would be basically one step more:
Submitting your changes without my changes and then do the pullrequest. This would keep the revision history.

Git also works with credit points and if you contribute to projects with a successful pull request you can at some point get free access to e.g. github copilot.

I was hesitant with git in the beginning. But it has one killer feature which is git bisect. So you can do binary search on the revision history. And you can find the the breaking commit in 1000 with only 10 checkouts.

Anyway I think I did not ask for too much.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10965
Posted: 11:19am 20 Jan 2026
Copy link to clipboard 
Print this post

How do I know if your program is working

Issues Found in getspritebounds
1. CRITICAL: Memory Allocation Size Mismatch (Buffer Overflow)
At Draw.c:5134-5135:

spritebuff[bnbr].boundstop = (short *)GetMemory(h * sizeof(short));
spritebuff[bnbr].boundsbottom = (short *)GetMemory(h * sizeof(short));


But boundstop and boundsbottom are indexed by x (width), not by y (height):

At Draw.c:5136-5140:
for (int x = 0; x < w; ++x)
{
   spritebuff[bnbr].boundstop[x] = SHRT_MAX;
   spritebuff[bnbr].boundsbottom[x] = -1;
}

If w > h, this writes beyond allocated memory, causing a buffer overflow.

Fix: Change the allocation to use w instead of h:
If w > h, this writes beyond allocated memory, causing a buffer overflow.

Fix: Change the allocation to use w instead of h:

spritebuff[bnbr].boundstop = (short *)GetMemory(w * sizeof(short));
spritebuff[bnbr].boundsbottom = (short *)GetMemory(w * sizeof(short));


2. Nibble Processing Logic Error
At Draw.c:5141-5155, the pointer c is incremented inside the conditional:

if (nib)
{ // odd x upper nipple
   if ((*c++ & 0xf0) == sprite_transparent2)
       continue;
}
else
{ // even x lower nipple
   if ((*c & 0x0f) == sprite_transparent)
       continue;
}

The *c++ only happens when nib == 1 (odd x). For even x where the pixel is NOT transparent, c is never incremented before moving to the next pixel. This causes misalignment in reading pixel data.

The increment should happen unconditionally after processing both nibbles, not conditionally inside the branch.

3. Initial nib Value Misalignment
The variable nib starts at 1 (line 5141) and is toggled with nib ^= 1 at the start of the inner loop (line 5149). So:

First iteration: nib = 0 (lower nibble, even x=0) ✓
Second iteration: nib = 1 (upper nibble, odd x=1) ✓
This appears correct, but the comments say "odd x upper nipple" and "even x lower nipple" - this is backwards from the typical byte layout where lower nibble is for even indices and upper nibble for odd indices. Verify this matches your actual sprite data format.

4. Missing Bounds Check in Usage
At Draw.c:7286-7307, when using the bounds arrays:
if (x >= spritebuff[bnbr].boundsleft[y] && x <= spritebuff[bnbr].boundsright[y])
...
if (y >= spritebuff[bnbr].boundstop[x] && y <= spritebuff[bnbr].boundsbottom[x])

If boundstop[x] or boundsbottom[x] remain at their sentinel values (SHRT_MAX or -1), the comparison will never match, which is correct. However, there's no guard against accessing x >= w which would be out of bounds if the allocation bug (#1) is fixed but a different sprite's bounds were accessed.
Edited 2026-01-20 21:43 by matherp
 
ksinger
Regular Member

Joined: 06/01/2026
Location: United Kingdom
Posts: 70
Posted: 12:06pm 20 Jan 2026
Copy link to clipboard 
Print this post

i checked it in the revision that I could access. And it performed nicely.
Maybe I should check the merged version. but as said I have no sources...

Obviously you are right. Maybe it did not crash because the sprite was higher than wide...
Edited 2026-01-20 22:10 by ksinger
 
     Page 10 of 14    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2026