Tapper remake
Tapper remake
Hi retro-people,
As my PSX pet project I choose to try to remake the C64 classic Tapper game.
It will be a very slow project because my free time slots are scarce, but nobody is pushing for a deadline
Find attached a first build: CROSS to tap a beer, UP/DOWN to move the barman.
The sprites are really awful but I really suck at drawing pixels and had to rely on some ready-made free stuff available from another partial remake using the Scratch programming language. I'll find better graphic later, suggestions?
I have a question so far: if you are quick enough tapping beer you'll notice there's just one beer sprite and I'm just relocating that one. In theory I may need N beer sprites running over the tables. What's the suggested way to implement this without allocating static arrays? Should I allocate them at runtime and keep track of them in a dynamic list of beer GsSPRITE objects all initialized from the same GsIMAGE? Thanks for any hint.
As my PSX pet project I choose to try to remake the C64 classic Tapper game.
It will be a very slow project because my free time slots are scarce, but nobody is pushing for a deadline
Find attached a first build: CROSS to tap a beer, UP/DOWN to move the barman.
The sprites are really awful but I really suck at drawing pixels and had to rely on some ready-made free stuff available from another partial remake using the Scratch programming language. I'll find better graphic later, suggestions?
I have a question so far: if you are quick enough tapping beer you'll notice there's just one beer sprite and I'm just relocating that one. In theory I may need N beer sprites running over the tables. What's the suggested way to implement this without allocating static arrays? Should I allocate them at runtime and keep track of them in a dynamic list of beer GsSPRITE objects all initialized from the same GsIMAGE? Thanks for any hint.
You do not have the required permissions to view the files attached to this post.
First update.
I've implemented the beer "generator".
Referring to the question in my previous post, I had to think of something flexible to manage any number of beers. The only thing that came to my mind is a linked list of Beer objects.
I don't know if it's the most performing solution: adding elements to a list and always iterate through it to look for a single element with defined properties or to remove it may have quite a hit on performance. Probably this isn't noticeable on a simple games like this one or on small lists with just a handful of elements.
Each "table" too is defined by a struct defining placement relative to the background sprite.
When a beer reaches the wall the games stops (I will implement a penalty for the player).
I've implemented the beer "generator".
Referring to the question in my previous post, I had to think of something flexible to manage any number of beers. The only thing that came to my mind is a linked list of Beer objects.
I don't know if it's the most performing solution: adding elements to a list and always iterate through it to look for a single element with defined properties or to remove it may have quite a hit on performance. Probably this isn't noticeable on a simple games like this one or on small lists with just a handful of elements.
Each "table" too is defined by a struct defining placement relative to the background sprite.
When a beer reaches the wall the games stops (I will implement a penalty for the player).
You do not have the required permissions to view the files attached to this post.
As you say, linked list with a lot of entries isn't the most efficient thing in the world.
Try implementing a hash table, google is your friend for that.
Cheers, and good luck with your project.
Try implementing a hash table, google is your friend for that.
Cheers, and good luck with your project.
Thanks for the suggestion. I think the linked list isn't an option even for such a small application like mine!fplgenius wrote:As you say, linked list with a lot of entries isn't the most efficient thing in the world.
Try implementing a hash table, google is your friend for that.
I've implemented a test case (attached) where the "drunkards" generated are never freed, they just stop and sit there when they reach the other end of the table.
It is noticeable the terrible frame rate hit (see the cpu/gpu indicators on the upper right corner).
You do not have the required permissions to view the files attached to this post.
I'm a beginner in game programming in general, but I was wondering when I opened your psxiso.bin I saw a file named "main.psx".
I'm confused, how do you open it and what is it at all? and with what do I open it?I can't see no psx exe.
I'm confused, how do you open it and what is it at all? and with what do I open it?I can't see no psx exe.
-
Verified
- Extreme PSXDEV User
- Posts: 131
- Joined: Jul 17, 2013
it's still a psx executable, I don't recall which differences are there from .EXEs(if there are any at all)
Anyway I don't get why you just don't run it as cd image, running the standalone exe doesn't make any sense since it relies on tims in DATA folder.
@jman: those values seem more like cpu and gpu % load, not framerate indicators(unless they're related in a way i'm unaware of)
which kind of condition did you implement to free the objects? polling until they reach the x coordinate corresponding to the end of the table?
Anyway I don't get why you just don't run it as cd image, running the standalone exe doesn't make any sense since it relies on tims in DATA folder.
@jman: those values seem more like cpu and gpu % load, not framerate indicators(unless they're related in a way i'm unaware of)
which kind of condition did you implement to free the objects? polling until they reach the x coordinate corresponding to the end of the table?
As Yagotzirck said it's a disc file image suitable to run on an emulator or be burned into a physical disc.fplgenius wrote:I'm a beginner in game programming in general, but I was wondering when I opened your psxiso.bin I saw a file named "main.psx".
I'm confused, how do you open it and what is it at all? and with what do I open it?I can't see no psx exe.
In order to run that disc file use your emulator of choice, example EPSXE:
Code: Select all
ePSXe.exe -nogui -loadbin psxiso.bin
Code: Select all
NO$PSX.EXE "C:\full\path\to\psxiso.iso"
Those numbers are the VSync delays generated in a function of Orion_'s wrapper when drawing occurs, more or less this is what happens:Yagotzirck wrote:@jman: those values seem more like cpu and gpu % load, not framerate indicators(unless they're related in a way i'm unaware of)
Code: Select all
*cpu = VSync(1);
DrawSync(0);
*gpu = VSync(0);
GsSwapDispBuff();
GsSortClear(ClearColor[0], ClearColor[1], ClearColor[2], ot);
GsDrawOt(ot);
Correct. During the main while() loop of the application I check the whole list of objects, increment the X position of the sprites and remove the item which X coord equals the X coord of the table.Which kind of condition did you implement to free the objects? polling until they reach the x coordinate corresponding to the end of the table?
Last edited by jman on December 7th, 2013, 8:00 am, edited 1 time in total.
-
Verified
- Extreme PSXDEV User
- Posts: 131
- Joined: Jul 17, 2013
Oh, my bad. Thought it was cpu/gpu % use, since it increases as time passes/more objects get generated.Those numbers are the VSync delays generated in a function of Orion_'s wrapper when drawing occurs
About the freeing objects part it could be everything, you could try using printf in critical point(s) to see if the code related to freeing objects gets executed at all(possible error in testing loop condition), or if you're freeing them correctly(the whole part about getting node 1 pointing to node 3 and then freeing node 2)
I could be more helpful if I had the chance to see the code directly, but I assume you're doing this for codeblast and I don't want to sound like a code stealer
LOL! Don't worry this is no secret code. Nobody will win anything with thisYagotzirck wrote:About the freeing objects part it could be everything, you could try using printf in critical point(s) to see if the code related to freeing objects gets executed at all(possible error in testing loop condition), or if you're freeing them correctly(the whole part about getting node 1 pointing to node 3 and then freeing node 2)
I could be more helpful if I had the chance to see the code directly, but I assume you're doing this for codeblast and I don't want to sound like a code stealer
I think the code is working well but I'll investigate why frame rate is getting slower and slower (that's the competition I'm looking for). I'll test the performance replacing with an hash table, as suggested.
Thanks for the suggestion!
I was wondering how to detect collisions between two GsSPRITE objects (on Amiga this was done in hardware ).
I've found this useful piece of code from a Yaroze breakout demo (y-break):
http://read.pudn.com/downloads178/sourc ... in.c__.htm
Create a RECT out of the GsSPRITE coordinates and then check boundaries.
I can simplify for my purposes because I only need to detect collisions over the X axis.
I think I can even directly compare the GsSPRITE coordinates instead of creating a RECT out of it: what's the advantage of having a RECT? Is it faster?
I've found this useful piece of code from a Yaroze breakout demo (y-break):
http://read.pudn.com/downloads178/sourc ... in.c__.htm
Create a RECT out of the GsSPRITE coordinates and then check boundaries.
I can simplify for my purposes because I only need to detect collisions over the X axis.
I think I can even directly compare the GsSPRITE coordinates instead of creating a RECT out of it: what's the advantage of having a RECT? Is it faster?
Another (long due) status update.
After having lost a week worth of code, twice (due to some careless laptop HDD repartion), I could finally go ahead another bit and understand how to properly animate a sprite (again thanks to Orion_ and this forum), implement all the rules for sprite movement, collisions and various reactions (e.g. when the drunkard meets a beer, when a beer or a drunkard reach the end of the table, ...). Nearly 1K lines of code for this only! Am I a bit verbose? :-)
Now that the core logic for playing is mostly done, I can focus on something else:
* Graphics
* Audio/Music
* Auxiliary screens (like "YOU WON!", "YOU LOSE!", ....)
Now, speaking of graphics, is there a volunteer willing to help me? I' need someone able to help me finding the arcade sprites ripped (no success until now) or:
* be able to draw some nice sprite sheets
* have a basic understanding of TIM files
Is there someone up to the task? :-)
Have a taste of the current status: [X] for serving beers, UP/DOWN to move the bartender.
You will notice that at the moment it's impossible to get rid of the drunkards. That's because I still have to calibrate all the game variables according to the difficulty levels available.
Also, I need someone for a test on real hardware. I see something different when running this thing on ePSXe or NO$PSX. On ePSXe the drunkards noticeably pause while advancing towards the bartender. This doesn't happen with NO$PSX. Also on ePSXe the speed of the game is slower.
It is likely something in my code, but I'd to be sure it is not ePSXe fault.
A quick movie filming the game running would be perfect. Thanks!
After having lost a week worth of code, twice (due to some careless laptop HDD repartion), I could finally go ahead another bit and understand how to properly animate a sprite (again thanks to Orion_ and this forum), implement all the rules for sprite movement, collisions and various reactions (e.g. when the drunkard meets a beer, when a beer or a drunkard reach the end of the table, ...). Nearly 1K lines of code for this only! Am I a bit verbose? :-)
Now that the core logic for playing is mostly done, I can focus on something else:
* Graphics
* Audio/Music
* Auxiliary screens (like "YOU WON!", "YOU LOSE!", ....)
Now, speaking of graphics, is there a volunteer willing to help me? I' need someone able to help me finding the arcade sprites ripped (no success until now) or:
* be able to draw some nice sprite sheets
* have a basic understanding of TIM files
Is there someone up to the task? :-)
Have a taste of the current status: [X] for serving beers, UP/DOWN to move the bartender.
You will notice that at the moment it's impossible to get rid of the drunkards. That's because I still have to calibrate all the game variables according to the difficulty levels available.
Also, I need someone for a test on real hardware. I see something different when running this thing on ePSXe or NO$PSX. On ePSXe the drunkards noticeably pause while advancing towards the bartender. This doesn't happen with NO$PSX. Also on ePSXe the speed of the game is slower.
It is likely something in my code, but I'd to be sure it is not ePSXe fault.
A quick movie filming the game running would be perfect. Thanks!
You do not have the required permissions to view the files attached to this post.
-
Shendo Verified
- C Programming Expert
- Posts: 250
- Joined: Mar 21, 2012
- I am a: Programmer
- Motto: Never settle
- PlayStation Model: SCPH-7502
- Discord: ShendoXT
- Location: Croatia, EU
I tested it on my PS2 slim because it can read RWs and it seems to work as it does in emulators-
However CPU and GPU debug info is around 28 instead of 10.
But the game seems to be on godlike difficulty.
Drunkards are moving too fast and when I serve them they only take a step back.
Edit: I see you explained that in your post.
About the speed, I'm assuming the game checks the region of the BIOS to set the PAL or NTSC video mode.
That's where the difference may come because PAL has 50 FPS while NTSC has 60.
NO$PSX with nocash BIOS clone seems to be NTSC.
1K for collision seems too extreme.
You should make drunkard and beer objects with x and y variables.
When beer gets to drunkard.x + drunkard.width and are on the same y then it should be consumed.
I would really recommend a real hardware for development.
The cheapest solution would be to use a simple USB-TTL adapter to
upload your code with PSXSERIAL (the setup I'm using).
Downside to this is that you need to include all data in exe and upload is a tad slow at 115200 bps.
But you get the 100% accuracy so you can be confident that it will work on a real thing.
Also even on a simple project like Sokoban I'm running into issues with different setups (emulators).
Something which works on emulators is totally broken on the real thing or vice versa.
The last problem I had is that ePSXe and pSX would hang on SPU upload because
status flags weren't implemented properly.
Current issue I'm battling with is that pSX stops reading gamepads after checking memory cards,
and I'm using BIOS routines which are working everywhere else (other emulators and real hardware).
Here is a video of my test:
http://www.youtube.com/watch?v=vpPnS6V6 ... e=youtu.be
However CPU and GPU debug info is around 28 instead of 10.
But the game seems to be on godlike difficulty.
Drunkards are moving too fast and when I serve them they only take a step back.
Edit: I see you explained that in your post.
About the speed, I'm assuming the game checks the region of the BIOS to set the PAL or NTSC video mode.
That's where the difference may come because PAL has 50 FPS while NTSC has 60.
NO$PSX with nocash BIOS clone seems to be NTSC.
1K for collision seems too extreme.
You should make drunkard and beer objects with x and y variables.
When beer gets to drunkard.x + drunkard.width and are on the same y then it should be consumed.
I would really recommend a real hardware for development.
The cheapest solution would be to use a simple USB-TTL adapter to
upload your code with PSXSERIAL (the setup I'm using).
Downside to this is that you need to include all data in exe and upload is a tad slow at 115200 bps.
But you get the 100% accuracy so you can be confident that it will work on a real thing.
Also even on a simple project like Sokoban I'm running into issues with different setups (emulators).
Something which works on emulators is totally broken on the real thing or vice versa.
The last problem I had is that ePSXe and pSX would hang on SPU upload because
status flags weren't implemented properly.
Current issue I'm battling with is that pSX stops reading gamepads after checking memory cards,
and I'm using BIOS routines which are working everywhere else (other emulators and real hardware).
Here is a video of my test:
http://www.youtube.com/watch?v=vpPnS6V6 ... e=youtu.be
Dev console: SCPH-7502, FreePSXBoot, CH340 serial cable.
@Shendo: thank you very much for testing!
However, you're right, one cannot trust emulators too much and I don't want to waste time in this respect.
I'll investigate the quickest option to put my modded PSOne at work (I don't have a TV but I have this device).
Do you think the only other option would be to burn a disc (ugh) everytime?
I'll check whether I have an option to quickly deploy into the console my BIN files, test, rinse and repeat.
I couldn't help but laugh when in your video capture I hear you're furiously tapping on the gamepad :-))Shendo wrote: But the game seems to be on godlike difficulty.
Drunkards are moving too fast and when I serve them they only take a step back.
Edit: I see you explained that in your post.
I tried PAL/NTSC ROM switching on both emulators and I dind't see any noticeable difference (although I'm not sure how to check which ROM NO$PSX is using).Shendo wrote: About the speed, I'm assuming the game checks the region of the BIOS to set the PAL or NTSC video mode.
That's where the difference may come because PAL has 50 FPS while NTSC has 60.
NO$PSX with nocash BIOS clone seems to be NTSC.
However, you're right, one cannot trust emulators too much and I don't want to waste time in this respect.
I'll investigate the quickest option to put my modded PSOne at work (I don't have a TV but I have this device).
I'm sorry, I meant 1K lines of code for the whole application so far :-) (excluded Orion_'s wrapper)Shendo wrote: 1K for collision seems too extreme.
I agree wholeheartedly, however refactoring my code in order to include .H files for images is a bit of a nuisance for me.Shendo wrote: I would really recommend a real hardware for development.
The cheapest solution would be to use a simple USB-TTL adapter to
upload your code with PSXSERIAL (the setup I'm using).
Downside to this is that you need to include all data in exe and upload is a tad slow at 115200 bps.
But you get the 100% accuracy so you can be confident that it will work on a real thing.
Do you think the only other option would be to burn a disc (ugh) everytime?
I'll check whether I have an option to quickly deploy into the console my BIN files, test, rinse and repeat.
Speaking of emulators reliability: does the embedded emulator on a PSP is better than those you can run on your PC?
I see that POPstation (the tool to convert PSX ISO to PSP format) has a database of commercial games: is it possible to create a PSP executable with POPstation starting from your PSX homebrew BIN/CUE?
I see that POPstation (the tool to convert PSX ISO to PSP format) has a database of commercial games: is it possible to create a PSP executable with POPstation starting from your PSX homebrew BIN/CUE?
-
Shendo Verified
- C Programming Expert
- Posts: 250
- Joined: Mar 21, 2012
- I am a: Programmer
- Motto: Never settle
- PlayStation Model: SCPH-7502
- Discord: ShendoXT
- Location: Croatia, EU
Yes you can use your homebrew on a CFW PSP.
I don't know about the POPS accuracy however as I haven't done any tests.
I would suggest against CD burning every time you need to test something.
You will end up with a bunch of coasters very quickly, not to mention it will be costly.
But, using PSXSERIAL you could "cheat". If you are programming and testing logic but you
are always using same data from CD, you could burn a CD with required files for your game to load.
Even if you need to update some graphics you will end up with far less disc then without PSXSERIAL.
I don't know about the POPS accuracy however as I haven't done any tests.
I would suggest against CD burning every time you need to test something.
You will end up with a bunch of coasters very quickly, not to mention it will be costly.
But, using PSXSERIAL you could "cheat". If you are programming and testing logic but you
are always using same data from CD, you could burn a CD with required files for your game to load.
Even if you need to update some graphics you will end up with far less disc then without PSXSERIAL.
Dev console: SCPH-7502, FreePSXBoot, CH340 serial cable.
I think you're right here but that's a bit of a nuisance for me. I have to check whether a) I can embed graphics in code with Orion_'s wrapper b) am I able to pick up my solder tool and buy the needed parts, prepare the cable, don't fry the PS...Shendo wrote: But, using PSXSERIAL you could "cheat". If you are programming and testing logic but you
are always using same data from CD, you could burn a CD with required files for your game to load.
Even if you need to update some graphics you will end up with far less disc then without PSXSERIAL.
I'll investigate more.
I'm posting another question while looking around for an answer.
I'm building the application in the most modular way, separating source code for all the "screens" composing it, I will end up with something like this:
game.o
menu.o
highscores.o
memcard.o
....
each of them loads its set of TIM files. I load these TIM files with LoadImage().
I was wondering how to unload from VRAM the TIM files I don't need anymore.
These TIM files, in each modules, are all placed starting from [0,0] coordinates. Loaded separately, these modules work fine. However when I "hotswap" from one module to another (example: the player goes from the menu screen to the main game screen) the background is lost, likely because the position of the new background assigned in VRAM overlaps with the old background.
How do I solve?
Just out of curiosity, in the gears.pdf document (the analysis of FF7 game) there's a mention of game modules (menu module, world map and so on). I'm curious to understand whether those modules are conceptually what I'm implementing.
At first I thought that modules meant separated EXE files, but on a second thought I don't think it's the case since separate EXE files live in really separate worlds and you cannot share data among them.
Thanks
I'm building the application in the most modular way, separating source code for all the "screens" composing it, I will end up with something like this:
game.o
menu.o
highscores.o
memcard.o
....
each of them loads its set of TIM files. I load these TIM files with LoadImage().
I was wondering how to unload from VRAM the TIM files I don't need anymore.
These TIM files, in each modules, are all placed starting from [0,0] coordinates. Loaded separately, these modules work fine. However when I "hotswap" from one module to another (example: the player goes from the menu screen to the main game screen) the background is lost, likely because the position of the new background assigned in VRAM overlaps with the old background.
How do I solve?
Just out of curiosity, in the gears.pdf document (the analysis of FF7 game) there's a mention of game modules (menu module, world map and so on). I'm curious to understand whether those modules are conceptually what I'm implementing.
At first I thought that modules meant separated EXE files, but on a second thought I don't think it's the case since separate EXE files live in really separate worlds and you cannot share data among them.
Thanks
Last edited by jman on January 3rd, 2014, 11:22 pm, edited 1 time in total.
-
LameGuy64 Verified
- Psy-Q Enthusiast
- Posts: 388
- Joined: Apr 10, 2013
- I am a: Hobbyist Game Developer
- Motto: Commercial or not, play it!
- PlayStation Model: H2000/7000
- Location: Philippines
- Contact:
You cannot unload a TIM on VRAM but you can draw a new TIM over an existing one if you no longer really need it. The entire VRAM is treated as a large framebuffer space of 1024x512 16-bit pixels. Parts of it can be addressed for rendering/displaying graphics or for storing textures and CLUTs.
As for the modular thing, I'm not entirely sure about it though.
As for the modular thing, I'm not entirely sure about it though.
Please don't forget to include my name if you share my work around. Credit where it is due.
Dev. Console: SCPH-7000 with SCPH-7501 ROM, MM3, PAL color fix, Direct AV ports, DB-9 port for Serial I/O, and a Xplorer FX with Caetla 0.35.
DTL-H2000 PC: Dell Optiplex GX110, Windows 98SE & Windows XP, Pentium III 933MHz, 384MB SDRAM, ATI Radeon 7000 VE 64MB, Soundblaster Audigy, 40GB Seagate HDD, Hitachi Lite-on CD-RW Drive, ZIP 250 and 3.5" Floppy.
Dev. Console: SCPH-7000 with SCPH-7501 ROM, MM3, PAL color fix, Direct AV ports, DB-9 port for Serial I/O, and a Xplorer FX with Caetla 0.35.
DTL-H2000 PC: Dell Optiplex GX110, Windows 98SE & Windows XP, Pentium III 933MHz, 384MB SDRAM, ATI Radeon 7000 VE 64MB, Soundblaster Audigy, 40GB Seagate HDD, Hitachi Lite-on CD-RW Drive, ZIP 250 and 3.5" Floppy.
-
Shendo Verified
- C Programming Expert
- Posts: 250
- Joined: Mar 21, 2012
- I am a: Programmer
- Motto: Never settle
- PlayStation Model: SCPH-7502
- Discord: ShendoXT
- Location: Croatia, EU
You have two solutions:
1. Use different VRAM coordinates (texture pages) for each module, or
2. Re-upload textures from RAM to VRAM each time you load a new module.
I suggest you give some official game a spin on pSX, Xebra or no$psx with "full VRAM" overview to see
how they deal with textures between different screens.
If you are going for the original arcade look I'm certain that with careful planning you can
fit all your textures in VRAM at the same time. And if you use palletized textures (8 bit) you can cut VRAM usage to half.
1. Use different VRAM coordinates (texture pages) for each module, or
2. Re-upload textures from RAM to VRAM each time you load a new module.
I suggest you give some official game a spin on pSX, Xebra or no$psx with "full VRAM" overview to see
how they deal with textures between different screens.
If you are going for the original arcade look I'm certain that with careful planning you can
fit all your textures in VRAM at the same time. And if you use palletized textures (8 bit) you can cut VRAM usage to half.
Dev console: SCPH-7502, FreePSXBoot, CH340 serial cable.
Who is online
Users browsing this forum: No registered users and 8 guests