/r/retrogamedev
Developing homebrew games for systems from 70s, 80s, 90s, and early 00s. Whether it be in assembly, C/C++, or BASIC... 8-bit, 16-bit, 32-bit, we've got them all. Discuss, share tips and tutorials, show off projects. Learn more about coding techniques of olde through reverse-engineering existing classic games and understanding hardware details.
Developing homebrew games for systems from 70s (or even older!), 80s, 90s, and early 00s. Whether it be in assembly, C/C++, BASIC or a high-level language library… 8-bit, 16-bit, 32-bit, we've got them all.
Come here to discuss, share tips and tutorials, show off projects and your workflow -- that is dev/graphic/sound tools you use (or you made yourself). Take part in vintage game-making jams.
Learn more about arcane coding techniques of olde through reverse-engineering existing classic games. Understand intricate hardware details about your childhood consoles and computers.
(Warning! Some crafty individuals present here are living in an alternate timeline by creating new retro-inspired hardware architectures and writing "classic" software for them...)
Keywords: how make/write/program own Nintendo gameboy, nes, Commodore c64, new game homebrew? easy with our help, make own Gameboy gb nes cartridge cart
/r/retrogamedev
Hi guys,
I'm wondering if anyone has resources to learn how to program for thr Genesis? I can code but I don't know where to start.
Thanks
This is Rhythmites! Rhythmites is the first monster tamer rhythm game with creatures based on folklore, and cryptids! Stay tuned for the kickstarter!
Hey, Bipedal Studios here. I just wanted to share all of my homebrew releases so far, all of which were developed for Game Boy or GBC. Here are the four games released by Bipedal this year:
This is a short game for the original Game Boy that combines the gameplay of Snake and Sokoban. The challenge here is pushing the boxes to their corresponding goals while avoiding to crash into walls. Placing a box on of the goals not only increases your length, but also turns the formerly movable obstacle into yet another brick wall to be avoided. This is the only Bipedal game with a save feature, which is implemented every four levels.
A card game that sounds complicated at first but ends up becoming easy to get a hang of once you understand the rules. Galacard, which was one of the many games featured in SAGE 2024, takes place in the small Planet Ack, where its native inhabitants (Ackians) teach you their traditional card game. Even though luck is somewhat involved, strategy is the name of the game, since you need to take your cards into account when choosing the goal at the start and carefully manage them throughout each round. Since the rules aren't all that easy to explain, I'd strongly recommend reading the manual.
Made with the GBC in mind, this is a pretty straightforward sequel to Galacard. There's a significant graphical upgrade, and Ackians are now more distinguishable thanks to the different hats they wear and the names they're randomly given out of a list of 36. But that's not all. There is also a shop you can access after each round where you can buy helpful items such as hands of cards for the next game. This makes the experience more balanced and removes part of the luck-based aspect.
There's not much to say about this one, since it's a fairly straightforward puzzle game developed in late 2023, even before Anctrayl. Instead of moving the pieces like in most puzzle games, players have to decide how the pieces will be arranged beforehand and drop them from the top of the playfield. Crystal Clear originally had some game breaking bugs that prevented it from being released and it's been a while since then, so got help from a fellow homebrew developer, Kyuchumimo, who found and fixed all of them. The game works on the original Game Boy as well as the GBC, since crystals have distinct shapes and colors.
If you wanna check out these games, you can get them here: https://bipedal-studios.itch.io/
Hi all, I'm trying to create my own DOOM style engine running on a PCEm emulated 486DX66. It runs the original DOOM fine, so should be good enough for this project. The most important function in Doom is R_DrawColumn which draws a vertical column of pixels (used to draw walls).
I'm using DJGPP 12.2.0 and cross-compiling from Windows. I've also tried the same demo with the Open Watcom compiler and DOS4GW with essentially identical results. I'm using VGA Mode Y (320x200 8bpp 4 planes), like the original DOS DOOM did. This gives me some C code that looks like:
void vga_put_vertical_post(int x, int y_min, int y_max, char color) {
int count = y_max - y_min;
if (count <= 0) {
return;
}
// select the correct plane for the x coordinate (because Mode Y)
outportb(SC_INDEX, MAP_MASK);
outportb(SC_DATA, 1 << (x & 0x0003));
// calculate the offset to write to in the VGA buffer.
int step_y = SCREEN_WIDTH >> 2;
int offset = g_vga.back_buffer_offset + (y_min * step_y) + (x >> 2);
uint8_t *dst = (uint8_t *) (__djgpp_conventional_base + VGA_BUFFER + offset);
do {
*dst = color;
dst += step_y;
} while (--count);
}
I'm using the well known DJGPP nearptr hack outside this function to get direct access to the video memory.
The problem is: my code is far too slow. It seems my code can't even draw about 50% of the screen and hold the desired 35 fps. I'm testing this with a simple test loop that fills an area of the screen using my vga_put_vertical_post
.
ASSERT(__djgpp_nearptr_enable() != 0, "Cannot enable near pointers!");
for (i = 0; i < 320; ++i) {
vga_put_vertical_post(i, 0, 100, (uint8_t) i); // 50% coverage, gives 20ish fps :-(
}
__djgpp_nearptr_disable();
vga_page_flip();
What I can't figure out is why. The inner do { .. } while
loop in vga_put_vertical_post
generates really simple ASM:
518: 88 18 mov %bl,(%eax)
51a: 83 c0 50 add $0x50,%eax // 320/4 = 80 = 0x50
51d: 39 d0 cmp %edx,%eax
51f: 75 f7 jne 518
Doesn't get much simpler than that right? I've also tried unrolling the loop 4x by hand, but that didn't make any difference. I've looked at the DOOM source code assembly and it's like mine but does more stuff (like texture mapping). I think mine should be faster: they unroll the loop 4x (EDIT: actually 2x, looking at the ASM), but as I said that made no difference when I tried it in my code.
I'm using a pretty simple "page flip":
void vga_page_flip(void) {
// swap front and back buffer offsets
uint16_t old_back = g_vga.back_buffer_offset;
g_vga.back_buffer_offset = g_vga.front_buffer_offset;
g_vga.front_buffer_offset = old_back;
// calculate the values for the address registers: the front-buffer should be drawn.
// NOTE: we choose addresses for the front/back buffer so the low byte is always 0x00
uint16_t high_address = HIGH_ADDRESS | (g_vga.front_buffer_offset & 0xFF00);
// set the address registers for the VGA system: these will latch on VETRACE.
// NOTE: no need to set the LOW_ADDRESS: it's always 0x00
outportw(CRTC_INDEX, high_address);
// we must see the VETRACE bit go from low to high, that lets us know our new address has
// been latched.
while ((inportb(INPUT_STATUS) & VRETRACE) != 0) {}
while ((inportb(INPUT_STATUS) & VRETRACE) == 0) {}
}
I wonder if this could be the problem: is my CPU spending all its time waiting for this VETRACE latch? Not sure how else you could do it without tearing.
Anyhow, all thoughts gratefully received :-)
UPDATE: And it turns out the answer is: when I went and re-measured the fps in DOOM I found I only got around 10fps. I must have changed the graphics card along the way, and it turns out that makes a huge difference. Thanks for all the input people: mystery solved.
I was trying to make an invincibility cheat for the 1st nes zelda and settled on taking 7B90, comparing A5 and replacing it with 60. When I tried to save that as a code it changed my address to FB90, does anyone know why did it happen and how to fix it?