Hi everyone.
For a long time I've been very interested in the way sprite scaling worked back in the day, on the hardware that could actually do it.
I've been researching this topic for the last few months, with the intention of creating a sprite scaling routine for the CPC.
After running into a lot of dead-ends, I stumbled across the technique used by the Neo Geo console.
The Neo Geo created its huge sprites out of 16x16 pixel tiles, and each tile could be shrunk (by the hardware) to any one of 16 "magnifications".
I thought that maybe I had finally found a technique that would be viable for the CPC.
However, this has been an extremely challenging project, and there is still a long way to go.
The first thing I had to figure out was how to split a byte into individual pixel colours, and then plot that pixel colour individually where it is required. That's not so bad, admittedly (even though I was quite chuffed when I figured it out).
Then I had to figure out how to build a large sprite from lots of tiles. Again, not so bad.
The tricky part was figuring out how to scale each tile, even armed with the knowledge of how the Neo Geo did it.
So I turned to BlitzMAX, and got to work on a prototype.
That was a much easier way to figure out the finer points of the scaling algorithm, and when I finally got it working, I was very pleased with the results.
For the last few weeks I've been porting the prototype to SDCC (via cpctelera).
I now have something that runs, and produces the same results as my BlitzMAX prototype.
HOWEVER...
The current version is in unoptimised C, with only a few lines of z80 asm.
Also, each individual operation is currently a function call, because I had to break everything down into small pieces in order to make sense of the code as I was writing it.
As a result, this first version is SLOW.
When I say SLOW, I mean SLOW... like a snail crawling uphill through treacle.
Possibly slower.
We're talking 3 seconds per frame (yes, SPF, not FPS), when displaying the sprite at its largest size.
It does get faster as the sprite is scaled down (as it has less work to do), but if you're interested in trying the initial version of the program, please run it on the fastest speed that your emulator of choice provides.
Z scales the sprite down, and X scales it up.
Now to optimise!!!
I have written this article (https://64nops.wordpress.com/2010/04/18/zoom-initiation/)a long time ago, but it is still relevant. Using fixed-point arithmetic to zoom a sprite is a good basis for a generic sprite zoom (you can see the result in the asteroid zoom in the introduction in Orion Prime!)
Heck, I even use this technique to play samples!
Hi @ervin (https://www.cpcwiki.eu/forum/index.php?action=profile;u=82),
it's really interesting, even for real time animation it's too slow (for now) it could be really useful to have different sprite size without keeping in memory.
How many memory your scaling code takes ?
Really impressive work so far ervin.
Quote from: ervin on 16:32, 26 June 21The Neo Geo created its huge sprites out of 16x16 pixel tiles, and each tile could be shrunk (by the hardware) to any one of 16 "magnifications".
Have you considered using look up tables? You could have a 256 byte table of bytes pre-calculated for each of the magnifications and reading the table would be really quick.
Quote from: Targhan on 17:18, 26 June 21
I have written this article (https://64nops.wordpress.com/2010/04/18/zoom-initiation/)a long time ago, but it is still relevant. Using fixed-point arithmetic to zoom a sprite is a good basis for a generic sprite zoom (you can see the result in the asteroid zoom in the introduction in Orion Prime!)
Heck, I even use this technique to play samples!
That's a
fantastic article - thanks for the link!
I've gone for a slightly different approach.
I actually used Bresenham's algorithm to help me determine which pixels to draw at each of the 16 magnification levels.
Also, I have another table which I use to determine which
tile to change at each magnification level.
The sprite consists of 8x8 tiles, so I used Bresenham to create another table for 8 magnification levels.
Here is the 16x16 table:
u8 const scale_16[]={
0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,
0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,
0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,
0,1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,
0,1,0,1,0,0,1,0,0,1,0,1,0,0,1,0,
0,1,0,1,0,1,0,1,0,0,1,0,1,0,1,0,
1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,
1,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,
1,0,1,1,0,1,0,1,1,0,1,1,0,1,0,1,
1,0,1,1,0,1,1,1,0,1,1,0,1,1,0,1,
1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,
1,1,0,1,1,1,1,1,0,1,1,1,1,0,1,1,
1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,
1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
};
However, I've got a working prototype of a technique that should result in a large speedup, even without optimisations.
I'm going to use a function for each of the 16 magnification levels, and those functions won't rely on the 16x16 lookup table.
Quote from: Arnaud on 17:21, 26 June 21
Hi @ervin (https://www.cpcwiki.eu/forum/index.php?action=profile;u=82),
it's really interesting, even for real time animation it's too slow (for now) it could be really useful to have different sprite size without keeping in memory.
How many memory your scaling code takes ?
The entire BIN file is 10,087 bytes, but that includes 8K of sprite data.
So the program itself is less than 2K.
But that also includes a couple of small lookup tables.
Also, I'm using an 8K buffer to draw into, and then that buffer is doubled vertically to fill the screen.
So I'm effectively working with a 128x128 resolution.
The sprites are drawn at (mode 0) pixel accuracy, rather than at byte-aligned positions.
Quote from: redbox on 17:40, 26 June 21
Really impressive work so far ervin.
Have you considered using look up tables? You could have a 256 byte table of bytes pre-calculated for each of the magnifications and reading the table would be really quick.
Yes, I am using some lookup data for the 16 magnification levels.
I've described it a bit better in my reply to Targhan.
8)
Have you spoken to Optimus?
Optimus created a fantastic demo that involved walking through a Doom style labyrinth with real time sprite scaling. You controlled this manually too.
Quote from: sigh on 11:56, 27 June 21
Have you spoken to Optimus?
Optimus created a fantastic demo that involved walking through a Doom style labyrinth with real time sprite scaling. You controlled this manually too.
Is this the demo you mean?
https://www.youtube.com/watch?v=V0NXGO5b25k (https://www.youtube.com/watch?v=V0NXGO5b25k)
It is indeed very impressive, especially considering it is written in C!
It looks as though it is drawing byte-width "pixels" (forgive me if I am mistaken), whereas I'm going for actual mode 0 width pixels.
Yes, it's in C, so it hasn't even been optimised and you can already see the potential if it were to be put into assembly. It's an old demo.
There was also another example shown on this forum and its was 3D scaling but you were walking through a gallery of sprites. That was amazing too.
When you say "...I'm going for actual mode 0 width pixels" what is the difference between the two?
Quote from: sigh on 09:17, 28 June 21When you say "...I'm going for actual mode 0 width pixels" what is the difference between the two?
One byte holds two pixels in Mode 0. They're interleaved within the byte which complicates things...
Quote from: sigh on 09:17, 28 June 21
Yes, it's in C, so it hasn't even been optimised and you can already see the potential if it were to be put into assembly. It's an old demo.
There was also another example shown on this forum and its was 3D scaling but you were walking through a gallery of sprites. That was amazing too.
When you say "...I'm going for actual mode 0 width pixels" what is the difference between the two?
That other project... do you mean this one?
http://www.cpcwiki.eu/forum/games/chunk-pixel-curator/ (http://www.cpcwiki.eu/forum/games/chunk-pixel-curator/)
That's something I worked on many years ago. 8)
The "pixels" in that were byte-width.
redbox's explanation of the difference between byte-width and pixel-width is spot on.
Quote from: redbox on 13:23, 28 June 21
One byte holds two pixels in Mode 0. They're interleaved within the byte which complicates things...
I'm glad my scrawling in MS Paint lives on. :laugh:
There seems to be some ways to scale in hardware on the CPC but I don't know the specifics. There is a SNES mode-7 type scroller in either The Demo or The Terrific Demo (sorry I can't remember which one) which is pretty cool that might be able to be used for sprites. I also used some CRTC outs from an Amstrad Action which doubled the size of all display objects automatically which was kind of cool.
Is there a wiki page that at least at the high level outlines which hardware tricks can be used on the CPC in general? (can a CPC display like an Atari 2600 for example with almost no video RAM and direct writes to the video chips)?
Quote from: ervin on 12:52, 27 June 21
Is this the demo you mean?
It is indeed very impressive, especially considering it is written in C!
It looks as though it is drawing byte-width "pixels" (forgive me if I am mistaken), whereas I'm going for actual mode 0 width pixels.
That's a specialized vertical column scaler and indeed in byte only, also the zooming sprite in this video was just a brute force code as far as I remember, not well optimized yet. The rendering parts are in assembly even if the whole project is in C. I have other ideas for optimizing that sprite rendering with different unrolled assembly code, but not tried yet.
I think the fastest method I've done, especially if you want pixel perfect Mode 0 instead of Byte, is in my old demo X-Kore
https://www.cpc-power.com/index.php?page=detail&num=7691 (https://www.cpc-power.com/index.php?page=detail&num=7691)I lament I didn't use that method for way more effects I was thinking and with better graphics at the time.
But anyway, this is as good I could get it, the trick is that I do waste memory here, I have stored the bitmap in 4 different configurations, with shifted pixels or 2X scaled pixels, and in such a way that later a series of unrolled LDIs (different for different zoom levels) will go through the bitmap, and with INC/DEC H (or DEC L to delay for more scaling) will traverse through the precalced bytes and use them accordingly. So, this method will eat 4x your bitmap data, and some more space (maybe less than 16k) for a series of unrolled codes. This way, while the scaling will be pixel precise, the real code will copy bytes and avoid wasting CPU for merging left/right pixels, etc.
This is the fastest I could find to scale horizontally, and then you have control on the vertical which bitmap line to copy and where, so you can do a regular 2d scale or also the pseudo-3d effects or sine distorts/cylinder in the demo. The negatives are of course way more memory consumption, also this method is not gonna work if you want zooming sprites with transparent parts that should blend with the background. The method is more for solid bitmap lines over a black background.
I've found an old early assembly preview of the X-scaler which I'll try to attach. It's a bit dirty code, you'll see the series of LDIs for different zoom levels and then the bitmap lines replicated 4 times. One is like "12 34 56" the next is shifted right like "*1 23 45" then the two scaled versions "11 33 55" and "22 44 66" so the LDI source will be very near on top of these 4 lines and copy and traverse vertically with the fewest steps.
p.s. The code or idea might be intimidating or hard to read or generate other data for it. I've been recently rewriting the thing in a C project, which generates the bitmap and zoom data on the fly, to make it easier and more automatic for a future demo or game. I was thinking of using it to do some pseudo scaled road for a futuristic racing game with more scaling and offset data, but it's on hold right now. The issue is always the memory with this technique. Maybe on GX4000 with extra cartidge and on top hardware sprites for free this would work better.
Quote from: Optimus on 09:59, 29 June 21
but it's on hold right now.
:'( :(
I would love to see this technique used to create a third person game on the CPC. I could imagine it looking like a souped up version of Xybots.
Quote from: zhulien on 09:08, 29 June 21
There seems to be some ways to scale in hardware on the CPC but I don't know the specifics.
Is there a wiki page that at least at the high level outlines which hardware tricks can be used on the CPC in general? (can a CPC display like an Atari 2600 for example with almost no video RAM and direct writes to the video chips)?
There's nothing that can do scaling of objects on the screen. You can use rasters to repeat parts of the screen, even to an individual line, which can give a full screen vertical scale/warp effect seen in demos.
So a non-integer scaling factor routine for sprites would be all software - and a bit of a pain on a Z80 with the CPC screen layout. You'd presumably use 4.4 fixed point integer maths which would limit your scaling choices but it'd be a lot of overhead especially horizontally - but maybe you could design different width sprites for the same object and only scale the appropriate sprite vertically if you can accept a bit of oddness.
If you want bigger scaling graphics, you might choose to not use a bitmap, but a list of line-oriented drawing instructions (skip x pixels, plot x pixels, change colour, end of line), you can scale the x, and skip/repeat lines as necessary to scale the y. Again, not trivial, and there's only so much the CPC can draw in a frame or two anyway so really large scaled objects are not viable anyway.
is this 3d scroll and ball scroll a SNES mode 7-like effect or a software effect?
https://www.youtube.com/watch?v=4VJtG44cscw
It is only rasters, used in a clever way :). Trailblazer uses the same technic.
Quote from: Targhan on 09:43, 02 July 21
It is only rasters, used in a clever way :) . Trailblazer uses the same technic.
quick guess: 3x6 "font" and a screen that is filled with black left and right and in the middle 3 sized columns with color 1,2,3 which are then set on every scan line to make the impression of moving text? and every now and then the screen is filled with a different form of the columns.
Yes, exactly. Using a hardware pause would reveal the underlying graphics.
Hi everyone.
I've been working on speeding this up, and have made it quite a bit faster.
However, there is still a lot of work to do, and 99% of the code is still in C.
There are a *lot* of things I can do to make it run much faster.
8)
If you're interested, I've attached scale_1.dsk to the original post.
This is faster. It really speeds up when you zoom out to 1 pixel.
How much faster do you think you could potentially get this too run?
Quote from: sigh on 10:47, 04 July 21
This is faster. It really speeds up when you zoom out to 1 pixel.
How much faster do you think you could potentially get this too run?
There are *many* things left to do.
My loops are extremely innefficient (still prototype quality), my screen redraw is slow, and most important of all, almost everything is in C.
So there is immense potential for a huge speed up.
8)
Alrighty.
The loops have been made much more efficient, as I am now pre-determining the routine to run for each column of the sprite (8 columns), and storing that routine in an array of function pointers (previously I was making that determination for every row of every tile, which was extremely inefficient, both in terms of speed and code size).
Also, the screen redraw has been changed from being LDIR based, to stack-abuse based (though that code can be improved further).
These changes have resulted in an 8% speed improvement.
The next job is to try to improve the screen redraw code a bit more.
Then it will be time to start converting the scaling routines to asm, and then we'll see some real speed-ups.
Hopefully.
;D
Looking forward to the update.
Hi, I recall that I actually wrote an article on sprite scaling for Amstrad Action back in the day. As I recall it was pretty good. Might be worth looking at.
https://www.cpcwiki.eu/imgs/7/79/Amstrad_Action108_21.jpg (https://www.cpcwiki.eu/imgs/7/79/Amstrad_Action108_21.jpg)
It actually creates its own self modifying code, so its not too slow. If anyone tries it let me know if it works or is any good :)
Quote from: Trebmint on 17:55, 05 July 21
Hi, I recall that I actually wrote an article on sprite scaling for Amstrad Action back in the day. As I recall it was pretty good. Might be worth looking at.
https://www.cpcwiki.eu/imgs/7/79/Amstrad_Action108_21.jpg (https://www.cpcwiki.eu/imgs/7/79/Amstrad_Action108_21.jpg)
It actually creates its own self modifying code, so its not too slow. If anyone tries it let me know if it works or is any good :)
I remember reading it back in the day and thinking it was a pretty cool approach, if that counts. :laugh:
Quote from: Trebmint on 17:55, 05 July 21Hi, I recall that I actually wrote an article on sprite scaling for Amstrad Action back in the day. As I recall it was pretty good. Might be worth looking at.
https://www.cpcwiki.eu/imgs/7/79/Amstrad_Action108_21.jpg (https://www.cpcwiki.eu/imgs/7/79/Amstrad_Action108_21.jpg)
It actually creates its own self modifying code, so its not too slow. If anyone tries it let me know if it works or is any good
That definitely went over my head at the time!
Did you have a game in mind when you wrote that Rob?
Quote from: Skunkfish on 06:49, 06 July 21
That definitely went over my head at the time!
Did you have a game in mind when you wrote that Rob?
I don't think so. I think I might of been planning to use it for title screen, but its so long ago I can barely remember.
Out of interest, how difficult would it be to create a 'Wing Commander' type game using this method and your gallery method? They also look like they could work for on rail shooters.
Hi folks.
I've uploaded scale_2.dsk to the original post.
It runs quite a lot faster than the previous versions, but it's still slow.
There is still much work to be done, but I think there is still a lot more speed to be gained.
Quote from: sigh on 11:44, 07 July 21
Out of interest, how difficult would it be to create a 'Wing Commander' type game using this method and your gallery method? They also look like they could work for on rail shooters.
My apologies if you are asking this question of Trebmint.
In the case of my program however...
For very large sprites it's hard to say.
For smaller sprites (and certainly a smaller, spectrum-sized screen), it might be quite doable.
I've built into the program the ability to have a sprite sized anywhere from 1 tile up to 8x8 tiles, and any combination in between (e.g. 1x2 tiles, 5x3 tiles etc).
Quote from: ervin on 14:29, 07 July 21
My apologies if you are asking this question of Trebmint.
In the case of my program however...
For very large sprites it's hard to say.
For smaller sprites (and certainly a smaller, spectrum-sized screen), it might be quite doable.
I've built into the program the ability to have a sprite sized anywhere from 1 tile up to 8x8 tiles, and any combination in between (e.g. 1x2 tiles, 5x3 tiles etc).
Yes - I was thinking about your chunky pixel curator and also what you are attempting now. The reason I was thinking of Wing Commander style is because the actual play area is quite small as most of the game is taken up by the hud. Also, there aren't any real backgrounds as it's just stars, so the only things that really scale are the enemies and bullets as I don't think that the explosions scales.
In many ways, you have already started this with the chunky pixel curator; black background and animated characters?
https://www.youtube.com/watch?v=mfRvCSBD4q0
Hmmm, I think a simplified version of Wing Commander's presentation may indeed be possible.
However, with the larger pixels in Chunky Pixel Curator, it would be a lot faster, as those pixels are all byte-sized (pardon the pun!).
No byte-splitting or rotating is required for pixels of that size, and I wouldn't need different code paths for masked vs unmasked tiles.
Unmasked tiles are of course faster to draw.
I might do a byte-sized version of my current project once I feel I can't make it any faster.
[EDIT] In either case, for a project like Wing Commander (or anything with sprites that can go off-screen), clipping would need to be taken into account.
And that's much harder with the project I'm working on.
It's certainly possible (in fact I had it working in my BlitzMax prototype), but it would be very difficult, and all the extra code (for every clipping case) would take up a lot of memory.
Writing a generic clipping routine would take up much less RAM of course, but would run a lot slower.
Although it could be done quite efficiently with self-modifying code (which is what I did in Chunky Pixel Curator)... hmmm...
Would you be able to achieve this on a 64kb machine?
Quote from: sigh on 23:01, 08 July 21
Would you be able to achieve this on a 64kb machine?
The program is currently running on a 464, but with more graphics the available RAM will run out quite quickly.
Also, as I expand the code to make it faster (by removing asm CALLs and inlining code), the code size is growing rapidly.
So it's hard to say...
Alrighty, I've uploaded scale_3.dsk to the original post.
I'm afraid I will no longer develop this particular program.
While it is now much, much faster than the original program, it is still nowhere near as fast as what I was hoping to achieve.
The main reason is the byte-splitting/combining required to achieve pixel accurate scaling.
The overhead is just too great.
Instead I will use the ideas from this program in a new project.
I'm interested in seeing how much faster this scaling technique can be without needing to split/combine bytes.
So I'll try a program that draws large "pixels" that are one byte in width, and therefore 4 rasters in height.
It will look very blocky of course, but should run much faster.
Quote from: ervin on 16:08, 09 July 21
Instead I will use the ideas from this program in a new project.
I'm interested in seeing how much faster this scaling technique can be without needing to split/combine bytes.
So I'll try a program that draws large "pixels" that are one byte in width, and therefore 4 rasters in height.
It will look very blocky of course, but should run much faster.
Your last upload was much faster.
If you are worried about it looking blocky, would you consider to use mode 1 instead? That would also give you extra ram for graphics.
Quote from: sigh on 10:52, 10 July 21
Your last upload was much faster.
If you are worried about it looking blocky, would you consider to use mode 1 instead? That would also give you extra ram for graphics.
I could use mode 1, except that I want large graphics that take up the same amount of screen real estate, no matter what mode is used.
And that means that the sprites will take up the same amount of RAM, no matter which mode is used.
:(
In any case, I'll see what sort of speed I can achieve with the larger "pixels".
The speed difference should be significant.
I'm considering entering this year's cpcretrodev with a simple game that requires high-speed sprite scaling, and if large pixels make that possible, then that's what I will need to focus on.
Hi folks.
Well, I haven't been able to leave this alone, and have done a lot of work on it over the last few months.
I have discovered a number of improvements, mainly to do with the scaling algorithm.
Not only is the program a lot faster, but it is a lot smaller as well.
I think it is now fast enough for a game to be feasible!
Not really sure what sort of game... maybe something to do with going down into the ground, or a well, or the ocean?
Anyway, if you're interested, have a look at the attached dsk.
:)
[EDIT] Oops, I forgot to mention... use Z and X to scale the sprite.
Have you looked at pitfighter on cpc. It almost universally trashed as an unplayable bad port. It does however demonstrate what one sprite scaling method could work like. In reality that game could have been better, even by turning off the audience it might have gotten better.
Another possibility is since we now have sdcards and lots of ram, you could prerender lots of things, like wolfenstein 3d did on ms dos. The prerendering will still benefit from the fastest methods that you can implement.
Then we have some virtual memory algorithms that can work in conjunction with the 64k extra memory and sdcards, (im still waiting for the maxam on emucpc bug to be resolved so I can finish that), but the vm routines really just aid you as a developer to handle megabytes of ram easier.
An example how they could be used. Imagine you have x sprites all prescaled and stored on sdcard, but you can only fit some of the sprites into physical ram at once. Imagine as you walked from room to room, you accessed a different set of scaled sprites.. logically from a different memory bank, but actually automatically paged in when required. So you are handling a list of a subset of scaled sprites per room.
I know what I said mostly takes the realtime out of realtime sprite scaling, but in the end it is more to do with the result you give the user, not the method. Unless it is a pure tech demo and it must absolutely be realtime.
I have looked into paging sprites in as required, even creating a buffer for the most recently used sprite magnifications, and extracting compressed compiled sprites to the buffer in real-time using LZ48 and also with LZX0 (I had written a tool in BlitzMax to create the different magnifications for each 16x16 tile and then convert those to compiled sprite code).
That technique worked very well, and was comparable in speed to what I'm doing now, but of course RAM was the issue.
With my current technique I only have 2 copies of each tile, one positioned on the left pixel of the starting byte, and one positioned on the right pixel (i.e. pre-shifted).
So RAM is no longer a problem.
The 464 has always been my target with this project, as I'd really like to enter another game to cpcretrodev (hopefully a completed game this time!).
I'm reasonably confident that it should be possible. 8)
[EDIT] Tile preparation is now a bit smaller and faster, so there is now less overhead for each tile.
Quote from: sigh on 11:44, 07 July 21Out of interest, how difficult would it be to create a 'Wing Commander' type game using this method and your gallery method? They also look like they could work for on rail shooters.
there is no point using this method for a wing commander like game, you need only to store sprites at different sizes
Quote from: roudoudou on 07:51, 07 March 22there is no point using this method for a wing commander like game, you need only to store sprites at different sizes
And the result will be better (visual and speed)
Hi folks.
I've added 3d-based positioning to the program, so that the sprite recedes into the distance correctly when moving away from it.
If you interested in having a look, please try attached file.
At the bottom of the screen is some diagnostic information.
S represents the speed of movement, which ranges from 1 to 32.
This can be changed using the left and right arrow keys.
D represents the distance from the sprite, which ranges from 0 to 1031.
This can be changed using the up and down arrow keys.
Enjoy!
Hi folks.
I've continued to work on this, with optimisation being a major focus.
I have now pushed the speed as far as my current skill level allows - I have no other ideas on how to make it faster.
Having said that, I'm very very happy with how it runs.
Please forgive the graphics - they are just placeholders and are completely awful!
I've also added concentric rectangles to give a better impression of movement.
I'm now very confident that this technique can be used in a game.
:D
[EDIT] I just realised that I recorded my mouse pointer in the video!
:laugh:
Looking good, maybe a game flying through hoops (Pilotwings CPC!) is possible.
Or a graphically superior Star Wars trench game.
I'm thinking of a downward into-the-well style of game.
Something like Bounder in 3D.
Wow, that looks really fast, Ervin!
Each number is a bunch of 16 colour square shaped sprites?
It seems to be close to 50Hz.
Yeah, that looks impressively quick for what it is doing.
Yes, they are 16x16 sprites in mode 0. However the sprites are then stretched to be 32 rasters tall (everything is doubled when drawing the screen, otherwise it would be too slow). It's a compromise I've had to accept for performance reasons. Based on some basic calculations, I think I'm getting 15 to 20 fps, but that will go down a bit with game logic put in. 😊
That is just simple gorgeous!
I have to say - despite not being a fan of FPS shooters, I would seriously welcome one on the CPC rather than a 3D bounder.
I can just picture a Doom game in my head right now! Or even a 3D racing game, or even a game that involves a 2D sprite you control in a 3D world which would make for an interesting third person game!
Thanks ;D
I agree, something like the games you suggested would indeed be incredible, but I don't have the skill to implement any of those sort of games.
Maybe one day I'll try to adapt this sprite scaling idea into something else.
Small update: The program is now around 5% faster due to vastly improved division and modulus calculations.
Have you seen this 48k first person shooter spectrum game? I think it's using scaling too...
https://www.youtube.com/watch?v=12mYShb_VD4&t=234s
Yeah that's a mighty impressive game for sure.
However it looks as though it is using pre-defined tiles for everything rather than scaling.
Regardless, it looks absolutely brilliant.
Hi folks.
I had a surprising amount of trouble getting this just right.
But I'm finally happy with how it works.
Bouncing!
At the moment, you can't fall through a floor layer, as the collision is based on hitting a layer.
The next step is to narrow down collisions to tiles.
When I've got that working it will be possible to fall through the empty parts of a floor layer.
The white square is a placeholder for the player sprite.
I find that concentrating on the player sprite enhances the sense of 3D, which I'm very pleased about.
https://www.youtube.com/watch?v=NU_etWgXkAE
Quote from: ervin on 02:00, 28 May 22However it looks as though it is using pre-defined tiles for everything rather than scaling.
Definitely! In order to fill a screen like that you just need to move 32*24 bytes on the spectrum for the shapes plus the same amount for the colors, as everything is based on a characters. On the CPC we have to move 8 times the total amount of bytes to do the same! So that's not a fair comparison.
Quote from: ervin on 12:37, 21 June 22I had a surprising amount of trouble getting this just right.
But I'm finally happy with how it works.
Looks impressive. Thumbs up!
Hi folks.
I now have the most basic foundations of a game, as tile-based collisions are working!
It's now possible to fall past an object if your sprite doesn't touch it.
Touching a tile (even a little) will still cause a bounce.
8)
Next task... implementing different types of tiles, that will have different effects on the player sprite.
Hi folks.
New features:
Capacity for 16 block types and 8 food types.
Food can be "eaten" (i.e. collected) upon landing on it, to reveal the block underneath.
All blocks and foods can do different things, simulated here with the change of border colour.
The player (represented here with a white square) can touch up to 4 blocks at a time, and the effects of all 4 blocks (whether food or floor) can be applied at the same time.
I want Space Harrier ! :)
Me too, but that's a whole new level of challenge.
:)
The current engine doesn't implement sprite clipping, which would be required for a game like space harrier.
Quote from: ervin on 06:03, 26 July 22Me too, but that's a whole new level of challenge.
:)
The current engine doesn't implement sprite clipping, which would be required for a game like space harrier.
if there is only clipping missing, go for it, clipping will be for final release :P
I would love to do a game like that, but there is so much more that would need to be added to the engine. :(
Especially enemy sprites, bullets, explosions etc (in addition to sprite clipping!)
Looks good!
I can see a Bounder style game working here, or a puzzler (rotate/move the blocks to get the bouncing ball to the exit).
Quote from: ervin on 10:08, 26 July 22I would love to do a game like that, but there is so much more that would need to be added to the engine. :(
Especially enemy sprites, bullets, explosions etc (in addition to sprite clipping!)
Have you considered making a game similar to Blob on the Amiga?
http://hol.abime.net/148
Quote from: Sykobee (Briggsy) on 14:30, 26 July 22Looks good!
I can see a Bounder style game working here, or a puzzler (rotate/move the blocks to get the bouncing ball to the exit).
Yep, Bounder is the main inspiration.
Quote from: Devlin on 14:45, 26 July 22Quote from: ervin on 10:08, 26 July 22I would love to do a game like that, but there is so much more that would need to be added to the engine. :(
Especially enemy sprites, bullets, explosions etc (in addition to sprite clipping!)
Have you considered making a game similar to Blob on the Amiga?
http://hol.abime.net/148
I actually remembered Blob about 3 weeks ago (I played it back in the day).
It did occur to me how similar the viewpoint is, but the main difference is that Blob's playfield scrolls in all directions, but mine will only scroll "into" the screen.
It may have be an subconscious inspiration... dunno.
This looks great!
@ervin - Well done! Very impressive. Reminds me of Mode 7 on the SNES. Not sure how much juice would be left in the CPC if this was to ever make it into a game but, as a technical achievement, fanstastic bit of development.
Quote from: IndyUK on 21:20, 01 August 22@ervin - Well done! Very impressive. Reminds me of Mode 7 on the SNES. Not sure how much juice would be left in the CPC if this was to ever make it into a game but, as a technical achievement, fanstastic bit of development.
Thanks!
It is indeed being used for a game, but it's only a very simple game with no enemies or bullets.
I can imagine that it would indeed slow down if those sorts of things were added.
The white square that you have on the screen - have you tried playing an animation of it rotating to see the impact of the speed it would have?
It would probably be best to make it a sprite animation (8 frames) rather than an actual calculation.
The player graphic is now something other than a white square.
;D
Quote from: ervin on 14:34, 02 August 22The player graphic is now something other than a white square.
;D
Does it animate? If so - is there a hit to the speed?
Yes, there is animation, although it's only a few frames.
There is no hit to speed because is simply cycling through the appropriate sprite data for each frame.
Quote from: ervin on 00:18, 03 August 22Yes, there is animation, although it's only a few frames.
There is no hit to speed because is simply cycling through the appropriate sprite data for each frame.
So, as a test - have you tried using the sprite scaling while something is animating? For instance, the player graphic that you have made?
Yes, it makes no difference to the speed.
All the program is doing is changing the pointer to the sprite data.
The sprite routine runs the same no matter what frame it is pointing to.
Hopefully I'll have something to show soon.
8)
Update time!
New features:
- Goatfish sprite
- Tail swishing animation (placeholder only at the moment, indicated by the yellow line through the middle of Goatfish)
- Scoring, shown in an ugly placeholder font under the play area
- Small delay when collecting food, to enhance player feedback
- Scoring when collecting food (score increase depends on which food item is collected)
- Angry Red Block(!)
- Goatfish death upon hitting Angry Red Block(!)
I've figured out how to handle collisions while bouncing back up.
I was able to use existing routines (with some extra parameters) to check for collisions, and also to very briefly display the tiles being bumped into. It was a relief to get it working after thinking about how to do it for several days!
It makes a surprising difference to the feel of the game. Things "feel" more solid and more 3D with this feature.
The progress you are making is excellent.
Brief update time.
After 5 days of being stuck, I've figured out how to make the angry red faces (that cause goatfish to lose a life) move up/down or left/right, using the current data structures.
Should hopefully allow for some more interesting level design.
Very impressive scaling. I wonder if you can warp in realtime using a progressive zoom from no scaling one side of the sprite to scaling on the other so you effectively get a wolfenstein 3d type view.
That's a very interesting idea, and one I might explore someday.
It would need a lot of rework in the scaling code, but it could certainly be possible.
Quick update on the game I'm working on:
At the moment I'm writing a level editor (in Blitz3D on PC) to allow me to design levels much more quickly.
In the CPC code, I've also got larger "angry" blocks, which can also move around the screen in a limited fashion.
Wow... where did that month go?!?!
A quick update...
The level editor has been completed and works "well enough".
It's rather clunky and not terribly user friendly, but it will allow me to design levels and create the level data much, much, much more quickly than typing the data in by hand!
In the CPC code, I've had a lot of trouble with bugs, memory usage etc.
Collision detection has been particularly tricky - hopefully I've identified and fixed all the bugs!
Optimisation has been a big focus - if the game is too slow no one will want to play it.
Anyway, the only things left to do are to create the levels and finish the music!
In other words, the game is feature complete, which I am very excited about! ;D
[EDIT] I've only got 2 weeks left to finish, as I will enter this game into cpcretrodev.
Been following this thread for long time, Ervin, your improvement is really awesome.
Nice to see you are close to the goal of make it possible in a game.
Good luck with the CPCRetrodev contest!!
Thanks!
Really looking forward to submitting the game.
I'm also really glad I took the time to write a level editor.
Something to keep in mind for future projects as well.
Alrighty!
Level 1 is done!
(There will be 3 levels in the game).
I'm very happy to report that the game runs at a playable speed despite all the sprite scaling that is going on.
That was always a big concern, and I finally feel that I will have a somewhat decent game at the end of this.
Whether or not other people like it is another question! :laugh:
However, the game was a little dull a few days ago, which had me worried.
Adding moving urchins at various points in the level made it much more enjoyable (and a bit more stressful), thankfully.
Also, goatfish's movement into the depths of the ocean was a little slow-paced and potentially tedious, so I played with the idea of a "dive" feature, where pressing space or fire results in doubling the maximum speed, but also doubles energy consumption as well as damage when colliding with an urchin.
It works really well and adds some subtle strategy to the game.
It allows the player to go through familiar areas more quickly, but with a bit of added risk.
It also affects the bounce height, which has pros and cons.
To finish the game, I have 2 more levels to design, and the music to finish.
Can't wait to finally finish this thing!
Well, this is a remarkably weird feeling.
The game is out in the wild.
https://poppichicken.itch.io/goatfish2
I still need to create and upload the mandatory CDT file, but other than that, it's done!
Enjoy!
Well done, and with loads of time to spare :P .
I look forward to trying it out when I get the time.
Well done Ervin, lookin forward to test it too!! Thanks so much for keeping our belowed micros happy with any new development. Best wishes on the contest!
Quote from: ervin on 15:23, 01 November 22Well, this is a remarkably weird feeling.
The game is out in the wild.
https://poppichicken.itch.io/goatfish2
I still need to create and upload the mandatory CDT file, but other than that, it's done!
Enjoy!
good gods, yes. I love it. I need more levels :3
Quote from: ervin on 14:54, 14 August 22Update time!
New features:
- Goatfish sprite
- Tail swishing animation (placeholder only at the moment, indicated by the yellow line through the middle of Goatfish)
- Scoring, shown in an ugly placeholder font under the play area
- Small delay when collecting food, to enhance player feedback
- Scoring when collecting food (score increase depends on which food item is collected)
- Angry Red Block(!)
- Goatfish death upon hitting Angry Red Block(!)
Spectacular ! Hey, we are on cpc men !
Excellent, I just tested your game on my cpc+, it's really impressive. As much as I loved the first goatfish, this one is also a success.
Cheer !!!
Quote from: awergh on 16:13, 01 November 22Well done, and with loads of time to spare :P .
I look forward to trying it out when I get the time.
Yes it was a bit close to the deadline wasn't it?
:laugh:
Quote from: SpDizzy on 16:39, 01 November 22Well done Ervin, lookin forward to test it too!! Thanks so much for keeping our belowed micros happy with any new development. Best wishes on the contest!
Thanks! I hope you enjoy it.
Quote from: Devlin on 19:44, 01 November 22Quote from: ervin on 15:23, 01 November 22Well, this is a remarkably weird feeling.
The game is out in the wild.
https://poppichicken.itch.io/goatfish2
I still need to create and upload the mandatory CDT file, but other than that, it's done!
Enjoy!
good gods, yes. I love it. I need more levels :3
Oh wow, have you already finished it?
Quote from: Ast on 21:03, 01 November 22Quote from: ervin on 14:54, 14 August 22Update time!
New features:
- Goatfish sprite
- Tail swishing animation (placeholder only at the moment, indicated by the yellow line through the middle of Goatfish)
- Scoring, shown in an ugly placeholder font under the play area
- Small delay when collecting food, to enhance player feedback
- Scoring when collecting food (score increase depends on which food item is collected)
- Angry Red Block(!)
- Goatfish death upon hitting Angry Red Block(!)
Spectacular ! Hey, we are on cpc men !
Thanks!
Quote from: GOB on 22:04, 01 November 22Excellent, I just tested your game on my cpc+, it's really impressive. As much as I loved the first goatfish, this one is also a success.
Cheer !!!
Thank you!
Glad to hear it works properly on a real machine.
I haven't been able to test it on a real CPC.
Quote from: ervin on 23:36, 01 November 22Quote from: Devlin on 19:44, 01 November 22Quote from: ervin on 15:23, 01 November 22Well, this is a remarkably weird feeling.
The game is out in the wild.
https://poppichicken.itch.io/goatfish2
I still need to create and upload the mandatory CDT file, but other than that, it's done!
Enjoy!
good gods, yes. I love it. I need more levels :3
Oh wow, have you already finished it?
That I did. Have yet to put it on my 464 but will try it tomorrow
Quote from: Devlin on 00:00, 02 November 22Quote from: ervin on 23:36, 01 November 22Quote from: Devlin on 19:44, 01 November 22Quote from: ervin on 15:23, 01 November 22Well, this is a remarkably weird feeling.
The game is out in the wild.
https://poppichicken.itch.io/goatfish2
I still need to create and upload the mandatory CDT file, but other than that, it's done!
Enjoy!
good gods, yes. I love it. I need more levels :3
Oh wow, have you already finished it?
That I did. Have yet to put it on my 464 but will try it tomorrow
Wow, well done!
Looks like I made the game too easy!
:laugh:
Thanks for playing the game, it means a lot to me that you enjoyed it enough to play it all the way to the end.
cool to see your (fast) routines in a game 8)
Quote from: roudoudou on 12:50, 02 November 22cool to see your (fast) routines in a game 8)
Thanks!
I also want to thank you for your work on RASM - it made data handling and compression much easier.