HNHacker News
TopNewBestAskShowJobs

TapamN

468 karma · joined April 8, 2015

submissionscomments
TapamN··on Classic 3D videogame shadow techniques
>Possibly the earliest shipping game with stencil shadows is Severance: Blade of Darkness from 2001 whose shadows look great.

Revolte, for the PowerVR PCX1, had stencil shadows in 1996.

https://www.youtube.com/watch?v=7BvtML5dIuI

The PowerVR PCX1 had hardware support for shadow volumes, which were implemented more efficiently than standard stencil shadows. Rather than drawing the scene multiple times, it basically did a depth-only pre-pass (in hardware, to an on-chip depth/stencil buffer) to determine visible pixels and test the shadow volumes to determine what pixels are in shadow, then it preformed texture sampling and shading afterwards, with lighting brightness adjusted by shadow volume results. It would only shade visible pixels, overdraw would not waste bandwidth on unnecessary texture fetches.

The Dreamcast, based on the successor to the PCX1, also had many games with shadow volumes. The Dreamcast's implementation was more flexible, and its volumes could adjust more than lighting, such as what texture is used, UV mapping, or even what blending equation is used for transparent polygons.

I've managed to get soft shadows on the DC (https://imgur.com/a/DyaqzZD at the end), although it's pretty fill rate heavy, since it falls back to a more standard stencil method and redraws the shadow multiple times.

TapamN··on Detecting when LLMs are uncertain
An LLM does have a model of reality. An LLM's reality is built on the experiences (words) it's been feed.

Humans are similar. A human's reality is built on the experiences (senses) it's been feed. There definitely are several major differences, the obvious one being that we have a different sensory input than an LLM, but there are others, like human's having a instinctual base model of reality, shaped by the effects of natural selection over our ancestors.

Just like an LLM can't tell if the reality it's been fed actually corresponds to the "truer" outside reality (you could feed an LLM lies like the sky is plaid in such a way that it would report that it's true), a human can't tell if the reality it's been fed actually corresponds to a "truer" outside reality (humans could be feed lies like we are in true reality, when we're actually all NPCs in a video game for a higher level).

The LLM can't tell if it's internal reality matches an outside reality, and humans can't tell if their internal reality matches an outside reality, because both only have the input they've received to go on, and can't tell if it's problematic or it's incomplete.

TapamN··on Linux/4004: booting Linux on Intel 4004 for fun, art, and no profit
It's not really the addressing modes, but the instruction format. Immediate values on RISC-V are not stored contiguously on certain RISC-V instructions.

On all MIPS instructions, the bits for a immediate add, load constant, branch, etc value are always stored in order.

On RISC-V, the bits are (sometimes) jumbled around. For example, on a unconditional branch, the bits for the destination offset are stored in the order of bit 19, bits 9-0, bit 10, bits 18-11. In hardware, reordering that is free, you just run your wires the right way to decode it. In software, you have to do a ton of bit manipulation to fix it up.

The reason RISC-V does that is to simplify the hardware design.

TapamN··on A Friendly Introduction to Assembly for High-Level Programmers
>Are delay slots unique to mips?

No, several other architectures of that period have delay slots (80s/90s), and modern VLIWs/DSPs still often have them. Sometimes the slots longer than a single instruction.

TapamN··on Microwave spontaneously turned on by its LED display
Normal fluorescent lights will glow in a microwave.

Mr. Wizard demonstrates:

https://www.youtube.com/watch?v=n_iQ54aQ_-I

TapamN··on Playstation 2 GS emulation – the final frontier of Vulkan compute emulation
That seems to be what I remembered. I did try a few searches; But I didn't find it in the first few results of "byte magazine gpu" on Google, and my search on IA wasn't completing. I didn't feel like spending more time than that...
TapamN··on Playstation 2 GS emulation – the final frontier of Vulkan compute emulation
I think I remember seeing the term GPU used in a Byte article from the 80s? It was a while ago when I saw it (~15 years), so I can't really remember any details.
TapamN··on Atkinson Dithering (2021)
I could have sworn I read on folklore.org that it was for speed, but I'm not finding it. You do have a point. Maybe Atkinson thought his dithering was more elegant without the multiplies or preferred how it looked on his test images.

I only used a B&W Mac a few times, but I do remember Windows 3.1 doing on-the-fly ordered dithering when running with palettized color (and being very surprised at NOT seeing the dithering on the blue gradient of a setup program once I started using high color modes). Windows 1.0 apparently was capable of doing it as well.

TapamN··on Atkinson Dithering (2021)
The point of Atkinson is that it's much faster than Floyd-Steinberg on old CPUs. Floyd-Steinberg requires multiplying most source pixel by a small number (3, 5, 7) and doing a right shift by 4. Atkinson is just doing a right shift by 3. On the original Macintosh's Motorola 68000, I could see Atkinson being more than twice as fast.
TapamN··on SimCity in the web browser using WebAssembly and OpenGL
I worked on a port of Micropolis to the Sega Dreamcast, but never finished it.

https://www.youtube.com/watch?v=MlFu-y1LDbs

One thing I really disliked about the SNES port of SimCity Classic was how slow the interface was. Having to access the menu for everything was a pain. For my port, the cursor would move faster, and snap instantly to the next tile if it was tapped. The analog stick could be used for fast cross map movement. The menuing was replaced by mapping every command to a button combination, with different palettes of commands available depending on what shoulder buttons were pressed.

If you weren't holding a shoulder button, the ABXY buttons were set up for A (primary action button) for roads, X (secondary action) for rail, Y (the green button) for parks, and B (cancel button) for bulldozer. Holding L was reserved for system commands, you could zoom in or out with A or Y, and adjust the speed with X and B. Holding R completely would allow building zones, color coded to the controller's buttons, with the red (A) button to build residential, blue (B) for commercial, and yellow (X) for industrial. There were two more palettes, accessed by either pressing L+R, or half pressing the R button, for infrequently built things like power plants and airports. It might sound complicated from the description, but I think it would be pretty easy to get used to if you actually tried it a bit.

I did a bit more work after I made the video, like adding map overlays (pollution, traffic, etc) and a display of what the current face button palette is, to help learn the combinations.

I was also adding split screen, for multiplayer. I was planning for you to be able either build a city together with someone else, or do competitive city building, like race to clear a scenario, or get the highest population or funds in a certain amount of time. I think I got the split screen two different cameras on the same city working, but no controls for anyone besides player 1.

I spent some time optimizing the simulation, because I wanted absolute solid 60 FPS. There would be occasional 1 or 2 frame stutters on large cities went certain phases of the simulation ran. The worst was when it calculated power.

The power grid connectivity is calculated in a bizarre way. Instead of a regular, scanline based flood fill, it basically has a Logo turtle walk the power grid. It uses the exact same class that the monster uses for movement, tracking the facing of the turtle, with functions to turn, take one step forward, etc. The version of GCC I was using was not automatically inlining the movement functions (they were in .CPP files, and no LTO), so it added a ton of overhead to an already slow algorithm. I moved the functions into the header so they would be inlined, which helped a lot, but was still planning to replace the whole thing with a real flood fill.

Even after inlining the walker, there were still single frame stutters. A lot of the map data for things like pollution and land value have filters applied to them, and the filter has a slow implementation. It does X and Y bounds checking on every tap of the filter, even in the middle when it can't go out of bounds. A better filter implementation would have helped.

The C++ simulation seemed to have some kind of bug, which would cause periodic mass abandonment, that I never figured out. I never noticed the Java version having the same problem.

TapamN··on POV-Ray – The Persistence of Vision Raytracer (2021)
It's older than that. I remember that from ~2002, when I used POV-Ray for a class project.
TapamN··on Tom 7: Badness 0 (Three ways)
I read the Epsom's Version PDF before the video was released, and the typesetting was absolutely terrible.

https://imgur.com/a/wjK5br5

After the opening on how he's bothered by minor errors, I thought it had to be part of a joke, and it was a setup for a punchline to be revealed later in the paper. But eventually I realized, no, the PDF must not being displayed the way it was intended. I was reading it in Evince at first, but muPDF gave much better output.

TapamN··on Deutsche Bahn introduces "MetaWindow"
I didn't realize that thread was totally paywalled. Here are direct links to two of the images:

https://lpix.org/4545647/IMG_8335.jpeg https://lpix.org/4545648/IMG_8336.jpeg

TapamN··on Deutsche Bahn introduces "MetaWindow"
There are a few here that are actually pretty good:

https://forums.somethingawful.com/showthread.php?threadid=40...

TapamN··on Inside the Super Nintendo cartridges
It looks like they're compressed sizes. If I gzip SMW.SMC, I get a 347 KB file. It's very misleading.

There are other issues in there. The writer makes it sound like MVG was the one who discovered that the pause in SFA2 was from loading audio data, when it was already known LONG before his video. https://forums.nesdev.org/viewtopic.php?p=70474#p70474

He also seems very confused about the RTC. It's obviously so that the clock keeps going even when the console is off and the cartridge is unplugged, like in the GBC/GBA Pokemon games, but he says something about how it might be because of the NTSC clock drifting? ??? What?

TapamN··on The Rise and Fall of 3M's Floppy Disk (2023)
I don't have a source, but I think I remember reading somewhere that Switch games are some kind of archival flash, designed for 50+ year retention.
TapamN··on Screen Space Reflection
MDK2 on the Dreamcast did render-to-texture to do mirrors.

https://youtu.be/-nVw_q3yEA4?t=210

The PC version lacked all R2T effects. The developers went with "Chaotic Insane", and replaced the mirrors with a colored noise texture, adding a sign saying, "Your reflection is not available at this time --Management".

https://youtu.be/xuONTSKjfNE?t=259

On a related note, R2T was also used in a cutscene. A video broadcast used R2T on the Dreamcast, and on other versions they just flattened the character placed it inside the monitor, and tweaked the camera work to try to hide it.

Dreamcast version:

https://youtu.be/-nVw_q3yEA4?t=14

PC version:

https://youtu.be/xuONTSKjfNE?t=15

TapamN··on Ant Geopolitics
https://en.wikipedia.org/wiki/Microsoft_Ants
TapamN··on Porting to GCC 14: C language issues
I was wondering if pointer size is still a problem. Hopefully this explanation is clearer:

  int compare_char (const char *a, const char *b) {
          return strcmp(a, b);
  }
  
  int compare_void (const void *a1, const void *b1) {
          const char *a = a1;
          const char *b = b1;
          return strcmp (a, b);
  }
  
  int (*call_void)(const void *a1, const void *b1) = &compare_char; //not valid in current C standard
Why can't the standard be changed so that it is valid to set call_void to &compare_char, so we don't need to write the longer compare_void? Are there architectures are still in active use where not all pointers are the same size in plain C (not worrying about C++) that would disallow this?

AFAIK, x86, ARM, MIPS, SPARC, Alpha, and SuperH would all work fine calling compare_char though call_void. There could be some other issues, like near/far on 16-bit x86, but that would be orthogonal to implicit function pointer void* casting, and could still occur if call_void was set to compare_void. Do one of the more obscure embedded CPUs still in use have a varying pointer size?

TapamN··on Porting to GCC 14: C language issues
>The reason for that is that C does not offer a generic function pointer type, and standard C disallows casts between function pointer types and object pointer types.

I've wondered why this hasn't been relaxed a bit when void* is used. Say you have these functions (modified from the link)

  int compare (const char *a, const char *b) {
          return strcmp(a, b);
  }
  
  int compare (const void *a1, const void *b1) {
          const char *a = a1;
          const char *b = b1;
          return strcmp (a, b);
  }
And then you have some FP of type int(*compare)(const void *a1, const void *b1) somewhere...

If you have correct pointer const-ness, why isn't the first method the PREFERRED way of doing this? It's shorter, more clear, safer (calling compare directly and not through a FP still gets you proper type checking (you wouldn't call either of these example functions directly, but for others you might)), and IDE suggestions can better explain what the function is. I've thought several times about suggesting to compiler writers/the C committee to bless the first method. Is there some obscure hardware that the first would be incorrectly compiled or something (i.e. the calling convention for void* and foo* is different)?

TapamN··on The SuperH-3, part 1: Introduction (2019)
It's not because of their temperature. One version of the SH3 (single issue, at 80 MHz) is speced at 260 mW. The SH4 used in the Dreamcast (dual issue at 200 MHz), seems to be 4W.

Hitachi apparently had a trademark on "Cool Engine" for the SuperH (https://www.cpushack.com/CIC/embed/announce/HitachiSH7709.ht...).

TapamN··on The SuperH-3, part 1: Introduction (2019)
Yes, I do Dreamcast homebrew, and even with GCC 12.2, the compiler does such stupid, stupid things.

The SH has addressing modes for postincrement reads and predecrement writes, so something like

  var = *ptr++;
can be compiled down to a single instruction. But GCC almost always does something moronic. I've seen it generate code equivalent to:

  ptr++; tmp = ptr; tmp -= 16; var = tmp[15];
Insane.

Older versions of GCC (3.x) are generally much better at low level instruction selection, but newer versions are better at big-picture stuff like optimizing across function calls, so speed-wise, across a whole program, they aren't too dissimilar. Newer versions are still worth it for the feature set (better warnings, modern standards like C23/C++23, etc).

TapamN··on IBM pauses advertising on X after ads show up next to antisemitic content
I have a German magazine/pamphlet from 1985 for IBM's 75th anniversary. It omits any reference to IBM's involvement in genealogical processing, and instead mentions things like the the Mark I, the Z3, and von Neumann.

Low effort photos of the pages for the 30s and 40s:

https://imgur.com/a/m65RCr3

TapamN··on Why ACPI?
I haven't done much on it since then. While it's something I would like to finish, I realized that there are other, higher priority things that I should do first.
TapamN··on Why ACPI?
I do Dreamcast homebrew, and my opinion is the SH ISA is way over-optimized for 90's embedded applications. It wastes the tiny instruction space on useless things like read-modify-write bit operations, intended for setting hardware registers, and has a laughably small displacement for function calls (+/-2KB, with pretty much all calls requiring manually loading a function pointer from RAM). There are parts that are still nice compared to something like RISC-V, like post-increment loads and pre-decrement stores (but hardware designers seem to hate things like that, since they require an extra write port on the register file), and the code density can be pretty good (although GCC's output is awful), but there are so many ways the ISA could be easily improved.
TapamN··on Apple's Blue Ocean
These "advantages" to sealing the battery are incredibly weak/false.

The weight difference from sealing the battery is negligible. If it saved several hundred of grams, it would one thing, but a replaceable battery adds at most tens of grams.

Even if the sticker price of device is cheaper, I would still have to pay more to replace the entire device once the battery is worn. This is the primary reason for most companies sealing the battery, to force buying an entire phone. Having a replaceable battery would save me money.

Sealing the battery was not responsible for waterproof phones. There were already waterproof phones with replaceable batteries.

TapamN··on How the creator of Alone in the Dark came back to games
On the topic of the Dreamcast: the writer of the article, Jörg Tittel, appeared in the Dreamcast comedy horror game, Illbleed.

https://illbleed.fandom.com/wiki/Jorg_S_Baker

TapamN··on A guy preserving the new history of PC games, one Linux port at a time
On Firefox, go to View, Page Style, No Style to make it readable without JavaScript.
TapamN··on Hacking the Timex m851
Ruputer/OnHand PC? Another smartwatch from late 90's/early 2000s. The specs were on part with the original Mac, 128KB RAM, with 102x64 pixel display and 2MB of flash, but VERY sluggish OS and poor battery life (but still better than modern smartwatches).

Maybe Palm and Psion devices count? I would exclude WinCE...

TapamN··on Hacking the Timex m851
Fun fact: It's possible to password protect apps using the PC software with a two character password (there's no encryption, it's just intended to slow down anyone from casually examining user data if they happen to find the watch unattended). When the DLU boots up, it initializes the password variable to "NS".

It doesn't really mean much, since all apps default to unprotected on boot, so you can never use it, but it's interesting.

← PreviousPage 2 of 4Next →