Best Language for Game Development
escher
Posts: 138
in Propeller 1
I'm currently working on a custom JAMMA arcade game PCB, with the Propeller 1 as the driving microcontroller due to its high power and built-in video generation ability.
I'm trying to choose between C and Spin for development. I'd rather not have to learn a new language for this project, as I already know C, but I understand that Spin gives you more control over the board.
What's the verdict on this one? Thank you!
I'm trying to choose between C and Spin for development. I'd rather not have to learn a new language for this project, as I already know C, but I understand that Spin gives you more control over the board.
What's the verdict on this one? Thank you!
Comments
The important parts, video driver, sound, sprites, etc... are frequently done in PASM. Assembly language. Typically, these run on one or more of the COGS, with the main game loop running as a larger program on one COG.
All of that can happen In either language.
Since you already know C there is no reason to learn Spin for your project (well, you need to learn at least PASM for the drivers), start with LMM then if the code size is too large and don't need speed, change to CMM. The C language has other advantages like the possibility to use code overlays if your code can't fit, see my post http://forums.parallax.com/discussion/163970/overlay-code-with-gcc
About the control over the board, both languages can control the hardware in the same way, but as potatohead says, your core drivers (video and audio mainly) should be coded in PASM and run in one or more cores as needed. For some examples, see my P8X Game console https://dev.maccasoft.com/propgame/
I do all of my development in Spin (presently working on a 6000-line program for a laser tag controller), but am looking at C as well -- especially the CMM option which might give me a bit more speed with about the same code density as I have now. And then there's Forth. Peter Jackaki keeps showing off amazing things with his Tachyon and I've long been interested in Forth, I just haven't yet wrapped my head around it.
As to which language you should use for game development, I don't think anyone can say with absolute certainty (at best, you're going to get a hung jury and a mistrial in terms of a "verdict"). It depends on your experience, preferences and needs, so I wouldn't write off any language. You might even use one language for one game and another language for another game. Now, there's no question that your existing familiarity with C is a plus for choosing C, and it is faster than SPIN. But it still amazes me how code dense SPIN is; I'm still often pleasantly surprised at how much functionality one can pack in using it. When I code, I often check the number of longs left, and it's clear that the SPIN byte codes are quite efficient space-wise (sorry, I can't give you a percentage compared to C offhand). Having said that, if you were doing a game with a lot of text, then the compactness that SPIN usually provides wouldn't be such an advantage because, as far as I know, a letter/character takes a byte and there's basically nothing SPIN can do about that to optimize storage (and there isn't any compression of text strings or any thing like that, which would slow things down anyway). Nevertheless, general code "boils down" quite nicely in SPIN, maximizing/stretching the precious HUB ram. As far as the readability of high-level languages, I'd much rather write SPINS's "repeat i from 0 to 9" than C's "for (i=0; i<10; i++)", as the latter just seems like glorified assembly language to me, even though one can get used to it quickly. Then again, C offers libraries and stuff to make life easier. Anyway, don't dismiss SPIN completely. As Jon says, at least become familiar with SPIN because, at the very least, it's a useful/necessary "glue" language since PASM drivers generally use SPIN to provide interfaces to the high level code. And most of SPIN is straightforward (though there are "gotchas" to be aware of, such as needing to use "=>" instead of ">=" in a comparison, which Chip will likely change in the P2 chip that's under development). Anyway, overall, I like using SPIN because I'm always bumping up against memory limitations, even though it's slower, as I don't need so much raw speed (BTW, SPIN2 on the P2 currently in design will likely run, on average, at least 20X to 30X faster than SPIN on the P1 (and that's without taking into consideration any possibly speed-up that could be provided by streaming data from the "lazy-Susan" hub memory if SPIN2 is fast enough to keep up with it, which it might not be), if that's a long-term consideration for you). Hey, I'm kind of surprised someone hasn't mentioned a flavor of BASIC yet. I haven't used BASIC on the Prop yet, but I think that there's a version of it with similar code-density to SPIN. I have wondered if it might be more applicable to certain kinds of programs in terms of readability and so on. But like I said, I'm pretty happy with SPIN. --Jim
Cheers,
A C++ guy
I've taken a look at some VGA PASM code, and it's definitely some dense stuff.
I have a somewhat specific implementation in mind, which involves multiplexing between a standard 31kHz VGA signal and 15kHz CGA signal.
Jury's still out on whether I'll go with Spin or not... I don't see any particular reason why any PASM driver I would write wouldn't be just as easy to call from C code as Spin.
I need the "CGA" output for JAMMA boards which are too old to have VGA output, and to develop game boards specifically for "CGA".
Yeah, that's been done.
The lowest, will still display on modern CHA capable displays is 640x480 interlaced. The standard Parallax driver does it non interlaced.
CGA uses the even slower TV sweep frequencies, like you say. (15khz) Should be able to take either a TV driver, or one of the slowest VGA drivers and adjust timing and or signal output.
For old-school analog video, potatohead is the go-to-guy. I think he's committed to preserving NTSC/PAL and component video for generations to come. His circuits/code will likely be powering the media readers of the Third Millennium Archive that's planned for 3080 AD, in Deverapolis, USA 2.0, if I'm not mistaken.
BTW, I wonder how you will "multiplex" between VGA and CGA (assuming a CGA driver/circuit can be built). That is, I wonder if that just entails mechanical or electronic switching between them, or if some kind of overlay is implied. Anyway, that's all beyond my experience. Gee, I even had to google what a "JAMMA arcade game PCB" could refer to.
It's completely false that Spin gives you more control than C - both have access to everything in the Prop. PASM is the only language that gives you full and direct access to everything, and you can use PASM with both Spin and C.
The Elev8-FC firmware is written in C. I was maintaining both Spin and C versions, but the Spin version became too difficult because there are things that Spin simply can't do as well as C (structs, classes, inline functions are examples).
If you're comfortable with C/C++ you should use it. You may have to port some PASM objects across if you want to use them, but if your plan is to write everything from scratch you should use what you know.
I think they just want to be able to change timings.
Heh, I got a broadcast, pro grade CRT for a song. The Prop looks beautiful on it.
640x480 resolution @ 8 bpp = 300K per frame.
Meaning I would need over a quarter megabyte of dual-port SRAM to implement a frame buffer, and over a half a megabyte (600K) to implement the inevitably necessary dual frame buffer. This all of course ignores how expensive a properly sized SRAM IC would be, and the fact that there aren't even enough pins on the Prop1 to be able to interface with the SRAM in addition to all of the arcade controls and video and audio signals necessary.
Am I over or undercomplicating this problem?
https://google.es/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&uact=8&ved=0ahUKEwi8j82KlfPTAhXCCBoKHRcfDX8QFggyMAE&url=https%3A%2F%2Fwww.parallax.com%2Fsites%2Fdefault%2Ffiles%2Fdownloads%2F32360-Hydra-Game-Dev-Manual-v1.0.1.pdf&usg=AFQjCNHX81Gt6_GLi0XZH7Y2QrAVirhjlA&sig2=lhC2B5RoRZZny85c1TMNjg
Outstanding. How did this not come up in my Googling of literally "vga game propeller".
Giving this a read now. Looks likely that its output will be lower resolution, in terms of both pixel count and bpp as mine, but could give me some tangible restrictions.
Thank you!
Full on bitmaps can work at 256x200 or so pixels, and can allow for double buffer, partial, and 4 colors per tile.
Most things are dynamically displayed. Single buffer. Having a few sprite COGS, and a tile / display COG makes this possible.
For VGA, a 64 color screen works nicely. Baggers and I put together a 256x200 64 color VGA driver that would do tiles and quite a few 4x8 sprites per display line. 50 to well over 100, using 2 to 5 COGS. That's an idea of where it can go. More than that can be done.
Lots of tricks are possible too. It's a software driven display. An example might be to do some of a display with 4 colors, other parts more colors.
IMHO working at 640x480 is entirely possible using dynamic display techniques. No full screen bitmaps. Just tiles and sprites. Your color depth is tied to resolution. 2 and 4 color can do 640 pixels easy. Larger depths top out at 320 or fewer pixels without very advanced code..
But, the basic drivers do a lot. Starting there will get you going. External RAM is tough to do fast. It's all about dynamically generating scanlines.
Have fun! You can likely pick up enough SPIN from the many games done so far.
Yes, that driver can be VGA, and it does a lot more than it appears.
Cog 1's serializer outputs the signals for RRRGGGBB, and Cog 2's serializer outputs xxxxxxVH?
As long as the counters driving the two serializers are in sync, such that V and H (vertical and horizontal sync lines) are correctly timed with the RGB video signal, this should be practical?
Set the right sync value ahead of time, while a waitvid is running so the sync instruction does the right thing at the right time. Size your waitvid so one ends right when sync needs to happen.
But two works too. It's fine. Just sync off the counter, and they will run together all day long.
The sync COG can probably do tiles or something as it's largely idle.
ALL you need do is the math for a slightly deeper DAC resistor ladder.
As you are looking for 8bpp, you probably won't need it, but I thought I would clear that up.
There are several tile and sprite drivers out there. The important thing you need to know is the sprite list gets sorted during ot ahead of vblank. You mask in all the sprites ahead of drawing the scanline. Tiles first, then sprites.
Super easy parallel operation happens when you assign one graphics COG to a line. More cogs is more lines ahead of the current line equals more time for them to do their work, equals a lot of sprites. You can get a couple hundred per line that way. Per screen doesn't matter. The only real constraint is your sprite list size.
Sync them all up at end of a scanline with a flag value written to the HUB.
Also, take a hard look at 4 pixel sprites. At 8bpp, these fit into a single long. Super easy to handle.
For your right, left screen masking, just make your buffer area larger than the displayed area. Masking comes for free as the masked data overspills into non displayed regions. This is faster than a boundary check and mask operation per sprite. 0 is beginning of buffer. Screen 0 is begin of buffer + 4, or sprite size.
One layer up, in your sprite lists, bundle them in pairs or groups to make larger objects that move on a single variable update. No need to put that mess in the display kernel. I made that mistake a few times. Keep that dumb and fast.
Because the display code will run independent of game code, the game COG has basically the whole frame for processing. It just needs to have it all done at the start of VBLANK so the display, sprites, position, order are all ready to go. Double buffering this data is an option.
With those things, or most of them happening, you never need a bitmap, nor second buffer. It's all drawing on the fly. Tiles can be stacked to make bitmaps in regions of the screen that may need them, same for sprites.
Your sprite COGS will shift and mask, based on modulo X position. No need for more than one copy of sprite data.
Result is max HUB RAM for display assets.
You can do 8 bit + sync in a single cog, take a look at this invaluable collection of video drivers:
https://github.com/konimaru/waitvid.2048
The drivers under the scanline folder all allows to set the video and sync signals on two different pin groups, allowing 8 bit colors.