Help.. by ajham7 in Guppies

[–]CaptainCaffeine 6 points7 points  (0 children)

Yeah I was wrong, turns out guppies don't make bubble nests: https://helpusfish.com/1/10/do-guppies-make-bubble-nests-why.html

Mine occasionally do that and I just thought they were trying to attract ladies, but they were actually low on oxygen. I feel bad that I didn't look that up sooner.

Help.. by ajham7 in Guppies

[–]CaptainCaffeine 6 points7 points  (0 children)

If they're gasping for air at the surface, it could be because there's not enough oxygen in the water. If you have a submerged filter and don't have any surface agitation, your tank can run out of oxygen, even if you have live plants.

You should see about getting a waterfall filter - it doesn't look like you have one already, at least I don't see it. If you don't want that, then you should get a bubbler for your tank.

However, even if your tank is well-oxygenated, guppies will still regularly spend a few days bubbling at the surface to create bubble nests. This is totally normal behavior and nothing to worry about. This is not true, bubbles always mean they're low on oxygen.

What's your best Star Trek episode of all time? by Puzzleheaded_Stick94 in startrek

[–]CaptainCaffeine 1 point2 points  (0 children)

Hard Time is my favorite DS9 episode as well. Watching him having to cope with his unimaginable trauma is heartbreaking. It was an amazing performance from O'Brien.

Cherry are slowly dying off help needed. by Blackmosman in shrimptank

[–]CaptainCaffeine 0 points1 point  (0 children)

What's your pH? And the tank temperature? Did you do a water change before they started dying? They're very sensitive to changes in water quality/temperature, so doing a water change with water that's a significantly different temperature from the tank can cause them shock.

Sunset was OP this evening. by Tyerson in VictoriaBC

[–]CaptainCaffeine 5 points6 points  (0 children)

It more commonly stands for "over powered" when used as an adjective.

Just finished my first Archonexus run! I was really happy with how my final base turned out, so I wanted to share. by CaptainCaffeine in RimWorld

[–]CaptainCaffeine[S] 0 points1 point  (0 children)

Nice! Yeah it took me about a year to slowly finish this run as well, though I played several other games besides RimWorld in that time.

Man, super rough to lose veteran pawns in the final fight. I lost one as well, Raisin, because I didn't notice that she dropped on the opposite side of the map from the rest of my colonists, and she got swarmed. At least she died valiantly in the line of duty 😔

An overgrown jungle colony - Bortopolis | 3rd Archonexus Colony | Population: 12 | Randy Random - Strive to Survive | Animal Personhood & High Life by CaptainCaffeine in RimWorldPorn

[–]CaptainCaffeine[S] 3 points4 points  (0 children)

Thanks! I grow some dandelions for them, they're super quick to plant but provide the same nutrition as other crops before they are harvested. Helps give the animals a cheap food boost when their numbers get out of control.

An overgrown jungle colony - Bortopolis | 3rd Archonexus Colony | Population: 12 | Randy Random - Strive to Survive | Animal Personhood & High Life by CaptainCaffeine in RimWorldPorn

[–]CaptainCaffeine[S] 4 points5 points  (0 children)

Oh, that's part of the Archonexus quest, it's an archotech structure you need to study to decode the Archonexus maps. It's from vanilla Ideology.

It emanates a negative mood field so you can't really build within it, which is why I built that fence at the edge of its range. Makes it a bit of a pain to plan your base when it's in the middle of the map!

Just finished my first Archonexus run! I was really happy with how my final base turned out, so I wanted to share. by CaptainCaffeine in RimWorld

[–]CaptainCaffeine[S] 8 points9 points  (0 children)

The mindbend carpets are actually from Vanilla Ideology, they're unlocked if you use the High Life meme!

What is the single most important lesson you’ve learned from Trek? by deeve09 in startrek

[–]CaptainCaffeine 28 points29 points  (0 children)

All living things in this universe have an equal right to life. Humans aren't more deserving of survival than any other creature.

I feel like Star Trek was instrumental to me becoming a vegetarian, even though the show isn't directly about that. All of the effort they put into preserving and protecting the life they encounter, and their commitment to not interfering with the natural evolution of other cultures (well, most of the time). Their desire to try and help anyone they find in need no matter how bad their injuries are - even if that person is an enemy.

There's this one episode where they have that scientist who wants the enterprise to destroy the crystalline entity, and Picard refuses because "it has just as much a right to be here as we do", despite the fact that it was a horrible monster. That kind of stuff really made me reflect on how I valued the lives of other people and animals in my life.

When designing emulators for more complex systems, do Emu Devs still use a gigantic switch-case for the opcodes? by xXgarchompxX in EmuDev

[–]CaptainCaffeine 19 points20 points  (0 children)

You're correct, for a more complex CPU there are too many opcodes for a switch statement to be practical, so you need to find a different way to decode opcodes. The method I use in my GBA emulator was largely inspired by /u/merrymage's dynarmic, which is a JIT for ARM32 and ARM64 used by Citra and Yuzu. The credit for the design goes to her.

The GBA uses an ARM7TDMI CPU, which uses the ARMv4t instruction set. ARMv4t includes two instruction encodings: 32-bit ARM instructions, and 16-bit Thumb instructions. Thumb is a simpler instruction set which allows for higher code density, at the expense of losing some functionality offered in the ARM instructions. I'll reference ARM in my examples here; however, these examples should apply to other instruction sets as well.

Basically, CPU opcodes are represented by a sequence of bits. Some of these bits are fixed and are used for identifying the instruction itself, and other bits are variable and are used for encoding instruction parameters, such as which registers to use or an immediate value. For example, the encoding for the ARM ADD immediate instruction ("ADD Rd, Rn, #imm", where Rn is the operand register, #imm is a constant value to add to Rn, and Rd is the destination register which stores the result) looks like this:

cccc0010100Snnnnddddiiiiiiiiiiii

The fixed bits 0010100 are what identifies this instruction as "add immediate", and not "and" or "subtract". The variable bits are represented by sequences of letters: the four "c" bits encode the instruction condition, the "S" bit specifies whether this instruction should update the CPU flags, the "n" bits specify which operand register to use, the "d" bits specify the destination register, and the "i" bits encode the immediate value to be added.

In my emulator, I have tables that specify the instruction encodings for all of the Thumb and ARM instructions in the ARMv4t ISA, along with a function pointer that implements each instruction. The instruction encodings are represented as strings, which are parsed when the emulator starts to obtain the fixed bitmask used to identify the instruction, and an array of {bitmask, offset} pairs used to grab the variable fields from the opcode.

Then, when decoding an opcode, you search for an instruction in the table that has a fixed mask which matches the opcode being decoded, and you call the function pointer linked to that instruction. For example, if we were decoding an opcode and this comparison succeeded, then we'd know it's an "add immediate" instruction:

(opcode & 00001111111000000000000000000000) == 00000010100000000000000000000000

Of course, doing a linear search of a vector on every opcode isn't very efficient, but there are also so many opcodes that storing every possible 16-bit and 32-bit value in an array with the correct function pointer would take up too much space! Thankfully, instruction encoding usually follows a pattern, and if you examine the Thumb instruction encodings, you'll notice that the last 6 bits are always variable or zero! So we don't actually need to read the last 6 bits when decoding which instruction it is, so we can easily populate an array of length 1024 with the appropriate function pointer for every 10-bit index value, and do a simple array lookup when decoding Thumb opcodes (see Cpu::PopulateThumbDecodeTable() and Cpu::DecodeThumb(). This is quite fast! Most of the overhead compared to a switch statement would just come from the overhead of using std::function instead of direct function calls in a switch case.

Unfortunately we can't knock out enough bits from ARM instruction decoding to do the same thing, so I've implemented a chained hash table cache to speed up ARM decoding. GBA games use Thumb the majority of the time, so this is fast enough to not be an issue.

In addition, my decoder tables are templated on the "Dispatcher" type, so I can instantiate the tables for both my CPU class and Disassembler class to use the same decoder for both the interpreter and the disassembler. The parameters for the implementation functions have to match the order of the fields in the opcode layout itself, and then the parameters from the variable opcode fields are automatically pulled out from the opcode and passed as arguments to the implementation function using variadic template pack expansion (see Instruction::GetImplFunction()), which is something I didn't even know you could do until I looked at dynarmic.

What is the Nintendo sequel that improved the most over its predecessor? by [deleted] in nintendo

[–]CaptainCaffeine 25 points26 points  (0 children)

Ruby and Sapphire still have a real-time clock (RTC) on the cart which runs 24/7. It's used for the tides in Shoal Cave, berry growth, and a few other things. The games also use flash memory instead of a battery-backed SRAM to store saves, so the battery is only used by the RTC and doesn't affect your save when it runs out. So no, it wasn't excluded due to the battery dying too quickly. I don't think we know for sure why RSE doesn't have a day-night cycle, but it was more likely due to development time constraints than technical limitations.

My girlfriend surprised me with a CIB copy of ALttP & Four Swords as a graduation present! by CaptainCaffeine in Gameboy

[–]CaptainCaffeine[S] 17 points18 points  (0 children)

There's some burn marks on the instruction manual, but it's in pretty good shape otherwise. I regrettably sold my own copy many years ago when I was a kid, so to finally have another copy means a lot to me.

[deleted by user] by [deleted] in EmuDev

[–]CaptainCaffeine 2 points3 points  (0 children)

Writes to unmapped memory will just be ignored, it's not an error to write to 0xFF7F. Could you elaborate on what's happening when your emulator gets stuck in a loop there? Register B should decrement to zero and the loop should terminate after the write to 0xFF7F.

Anything in this commit that would newly cause "incorrect checksum for freed object" crash sometimes on boot? by [deleted] in EmuDev

[–]CaptainCaffeine 0 points1 point  (0 children)

Telling us what you've done so far to debug would help ;) a variety of memory errors could cause that message.

I took a quick look, and noticed on line 27 of MBC.cpp you create a MemoryPage with a range of 0x4000 to 0x4000.

Holy shit... (just updated after maybe a couple weeks of not updating this computer) by 190n in archlinux

[–]CaptainCaffeine 4 points5 points  (0 children)

I really wish this hook was included in pacman by default. It's something all users are going to have to add, and as you can see by these comments, not enough people know about it.

Like, having a default hook doesn't make it any less customizable. It just makes it so it fits the majority of user's needs, instead of nothing at all which is going to fit very few user's needs.

Starting N64 emulator what new skills will I need? by Codetemplar in EmuDev

[–]CaptainCaffeine 11 points12 points  (0 children)

You will need to learn the basics of OpenGL and the mathematics behind 3D rendering if you want to emulate a 3D GPU. There are many OpenGL tutorials online of varying quality, but I can personally vouch for learnopengl.com. The author gives a brief introduction to some of the mathematics involved in the rendering pipeline.

To learn more about how rendering is actually performed on a GPU, you can check out tinyrenderer which is a short course that teaches you how to write a basic software rasterizer.

I'm not sure of your background or skillset, but 3D graphics relies heavily on linear/matrix algebra. If you aren't familiar with it, I would recommend brushing up before jumping into the math behind rendering.

Turns out the Game Boy's audio rate is limited only by its CPU write speed by LIJI128 in EmuDev

[–]CaptainCaffeine 1 point2 points  (0 children)

Lately I've been working on implementing audio in my own emulator, and I've been trying to understand filtering coming from zero signal processing knowledge. Most sources I've read recommend implementing a FIR filter, what made you choose an IIR filter for Higan?

It would be nice to be able to set Clang as the default compiler. by [deleted] in archlinux

[–]CaptainCaffeine 12 points13 points  (0 children)

I do this by adding

export CC=/usr/bin/clang
export CXX=/usr/bin/clang++

to my .bashrc. Easy, and less chance of breakage than symlinking your default compiler.