wirelyre's recent activity

  1. Comment on What programming/technical projects have you been working on? in ~comp

    wirelyre
    Link
    For the past 11 months my hobby project has basically been developing tools to play Tetris™ really fast. I should probably measure how fast, but it's really fast. There's a web interface as a...

    For the past 11 months my hobby project has basically been developing tools to play Tetris™ really fast. I should probably measure how fast, but it's really fast.

    There's a web interface as a little toy that uses the library.

    This has been such a cool project — it's got colors, it's got Coding and Algorithms, I learned a lot about multicore programming and vectorization and Rust's type system, I rented a machine with 96 cores, I expanded the state of the art for this problem domain a little bit, and I wrote my own concurrent hash map. And best of all, it's all in service of an actual specific question I have, so I'll know when I'm done!

    I intend to write a series of technical blog posts about this, because I think it's really interesting, but I'm holding out until I've actually done some research work. The tools are pretty much done, now I need to use them.

    7 votes
  2. Comment on Ocarina of Time's source code has been reverse engineered in ~games

    wirelyre
    Link
    I'm not sure I believe that decompiling isn't copying the ROM in some sense. The goal of the project is to produce C source that, when compiled with the original toolchain, produces byte-identical...

    I'm not sure I believe that decompiling isn't copying the ROM in some sense.

    The goal of the project is to produce C source that, when compiled with the original toolchain, produces byte-identical binaries to those in the ROM. If you copy the game assets, compile the reverse-engineered source, and link them together, you should get a 100%-identical ROM.


    But this is very valuable!

    Before this project, in order to modify game functionality, you had to

    • write new code
    • make the ROM bigger so you can paste the code at the end
    • modify an instruction in ROM to jump out to your new code
    • modify your new code to jump back to the old code.

    This is tricky to do except when writing directly in assembly, which is very tedious.

    After this project, you can simply write new code, and when linked everything will shuffle around safely.

    2 votes
  3. Comment on Ocarina of Time's source code has been reverse engineered in ~games

    wirelyre
    Link Parent
    (I'm assembling my folk knowledge so some of the below is definitely slightly wrong.) Historically, N64 CPU emulation has been pretty good. There aren't many cases where tiny CPU details matter...

    (I'm assembling my folk knowledge so some of the below is definitely slightly wrong.)

    Historically, N64 CPU emulation has been pretty good. There aren't many cases where tiny CPU details matter for correct emulation.

    Graphics and sound are a bit different because the N64 has a co-processor, named the RCP, which deals with graphical and audio output. It has a custom instruction set, and for games the details of instruction timing matter a lot.

    In the past the instruction set was not emulated directly. There are only a few microcode libraries that actually show up in ROMs, because Nintendo's development kit included those libraries. (Studios would modify them a bit, however.) You can actually get reasonable results — certainly playable — just by rendering triangles that show up in the right place in memory.

    I think there are efforts to properly emulate the RCP, but I don't know how far they are or how common they are in system emulators. At this level the CPU races the RCP a lot, so cycle-level details matter.

    4 votes
  4. Comment on Taking the warts off C, with Andrew Kelley, creator of the Zig programming language in ~comp

    wirelyre
    Link Parent
    Zig is a better C. The syntax is strongly inspired by C but it's been tweaked, really expertly in fact. Writing types is easier; writing expressions is easier. Also it's 100% compatible with C —...

    Zig is a better C.

    The syntax is strongly inspired by C but it's been tweaked, really expertly in fact. Writing types is easier; writing expressions is easier.

    Also it's 100% compatible with C — you can import C headers into Zig and export Zig functions as a C library. (Zig-exclusive features aside.)

    For anything you'd already use C for, I'd strongly consider using Zig instead.

    6 votes
  5. Comment on Taking the warts off C, with Andrew Kelley, creator of the Zig programming language in ~comp

    wirelyre
    Link
    I played with Zig a while ago and I tripped on the compile-time stuff. When you do generics by constructing types in functions, you basically do compile-time reflection. It works fine but the...

    I played with Zig a while ago and I tripped on the compile-time stuff.

    When you do generics by constructing types in functions, you basically do compile-time reflection. It works fine but the values are all anonymous ad-hoc "structures" and kinda hard to deal with.

    I remember getting frustrated with the io library because I couldn't tell which values satisfied which interfaces. (Or even what the interfaces were, but I see the stdlib documentation is getting much better.) I think that was because they are all again basically untyped ad-hoc structures.

    Without a higher-kind interface/typeclass/trait system I can't see myself writing generic Zig code. My brain isn't big enough to do that without making a lot of mistakes.

    1 vote
  6. Comment on Taking the warts off C, with Andrew Kelley, creator of the Zig programming language in ~comp

    wirelyre
    Link Parent
    The C memory model as standardized makes these checks quite difficult — fixing it would require a new ABI, among other things. For example, it's legal to cast any valid object pointer to any other...

    The C memory model as standardized makes these checks quite difficult — fixing it would require a new ABI, among other things.

    For example, it's legal to cast any valid object pointer to any other (appropriately aligned) object pointer type, regardless of whether you can legally use that new pointer. So you'd have to store type information within memory, and then check validity a lot.

    There are other complications. For example, the pointer to a structure type can be cast directly into a pointer to its first member. And if you copy a structure byte by byte to another (well-aligned) location, the copy needs to work too.

    The upshot is that all C structures, including arrays, are very closely tied to memory layout. If you want to make a library with these kinds of safety checks, it's almost easier to put a new language on top.

    9 votes
  7. Comment on An introduction to jq, the command-line JSON processor in ~comp

    wirelyre
    Link
    Great introduction, great structure. The "what I learned" sections condense the information really well. The final "what I learned" summary should be on the jq homepage. It took me a while to...

    Great introduction, great structure. The "what I learned" sections condense the information really well. The final "what I learned" summary should be on the jq homepage.

    It took me a while to figure this out: a jq filter applies to a sequence, or stream, of JSON values. At any point in a jq program there can be multiple values coming through, one after another. Not a single array, but multiple values. The filter processes them one by one.

    [0, 1]
    "a"
    
    > jq "." >
    
    [0,1]
    "a"
    

    So when you do something to an array (a single value), first you unpack it into a sequence of values:

    [0, 1, 2]
    
    > jq " .[] " >
    
    0
    1
    2
    

    … each of which goes into the next filter:

    [0, 1, 2]
    
    > jq " .[] + 1 " >
    
    1
    2
    3
    

    … which can finally be repackaged into an array.

    [0, 1, 2]
    
    > jq " [.[] + 1] " >
    
    [1,2,3]
    

    So + 1 is itself a filter that received three values in a row.

    And you might think that the select function works on arrays. Nope! It works on individual values in a stream. It emits zero or one values for each input.

    0
    1
    2
    
    > jq " select(. > 0) " >
    
    1
    2
    

    That's why select has to go inside map to process an array. You unpack the elements of an array, select some of them, then pack them back up.

    [0, 1, 2]
    > jq " map(select(. > 0)) " >
    [1,2]
    
    equivalent:
    jq " [.[] | select(. > 0)] "
    
    4 votes
  8. Comment on What's the best way to learn piano without an in-person teacher? in ~hobbies

    wirelyre
    Link Parent
    One thing that's easy to miss: teachers can help you contextualize your goals and successes. Sometimes you get hung up on challenges. You wrestle them what seems like forever until you overcome...

    One thing that's easy to miss: teachers can help you contextualize your goals and successes.

    Sometimes you get hung up on challenges. You wrestle them what seems like forever until you overcome them, but afterwards all you remember is how hard you worked. You can lose sight of what you accomplished — it had a purpose!

    Part of what a teacher is for is to give you feedback even when it seems like you're not making progress.

    You can get some of that without a teacher, though. You can celebrate small things by showing off 10 seconds to your friend, or by recording 10 seconds and listening back to it yourself.

    @tvl, the biggest advice I think I'd give is: let yourself be the four-year-old proudly showing off your painting; and also let yourself be the proud parent who puts it up on the refrigerator. The more little paintings you make, the faster they'll improve!

    6 votes
  9. Comment on ARM or x86? ISA doesn’t matter in ~comp

    wirelyre
    Link Parent
    I did a bit of high-performance programming recently, and it got me thinking: the predictions I had to make about how the compiler would transform the code are kind of like the predictions I had...

    I did a bit of high-performance programming recently, and it got me thinking: the predictions I had to make about how the compiler would transform the code are kind of like the predictions I had to make about how the CPU would run it.

    Also, when I started putting the computation on multiple cores, I kind of had to imagine the programming language and microarchitecture levels at the same time. 'Cause of cache magic.

    3 votes
  10. Comment on ARM or x86? ISA doesn’t matter in ~comp

    wirelyre
    Link Parent
    Huh, yeah, I guess Thumb alone is a better measure of the ISA capabilities at that level.

    Huh, yeah, I guess Thumb alone is a better measure of the ISA capabilities at that level.

  11. Comment on ARM or x86? ISA doesn’t matter in ~comp

    wirelyre
    Link Parent
    Right, so doesn't the fact that the same ISA works for both powerful and low-power chips mean that it's a nicer and more flexible design?

    Right, so doesn't the fact that the same ISA works for both powerful and low-power chips mean that it's a nicer and more flexible design?

  12. Comment on ARM or x86? ISA doesn’t matter in ~comp

    wirelyre
    Link Parent
    A cynical take: The article says that microarchitecture is the only meaningful difference between modern CPUs. The binary interface doesn't matter. So there's actually no reason to use anything...

    A cynical take: The article says that microarchitecture is the only meaningful difference between modern CPUs. The binary interface doesn't matter. So there's actually no reason to use anything except an open instruction set.

  13. Comment on ARM or x86? ISA doesn’t matter in ~comp

    wirelyre
    Link
    Are there x86 processors similar to the ARM Cortex-M ones? They use an instruction set that's a subset of larger ARM chips. Maybe that's a sign that the ARM ISA has a better base for today's...

    Are there x86 processors similar to the ARM Cortex-M ones?

    They use an instruction set that's a subset of larger ARM chips. Maybe that's a sign that the ARM ISA has a better base for today's requirements than a similarly small x86.

  14. Comment on What does analog have that digital doesn't? in ~talk

    wirelyre
    Link Parent
    I think it's probably related to older keyboard designs. Modern pianos are very resonant and sustain notes for a long time; on older instruments the effect is more subtle (aside from the...

    It's one of those things which probably wasn't intentional

    I think it's probably related to older keyboard designs. Modern pianos are very resonant and sustain notes for a long time; on older instruments the effect is more subtle (aside from the sustaining).

    Many pianos have a center "sostenuto" pedal, which sustains only the notes currently pressed.

    Do more modern electric pianos attempt to simulate these sympathetic vibrations?

    Their marketing materials say that they do! :-)

    Apparently some fancy ones try to simulate each string individually. I haven't played any of those in person, but I've heard virtual (MIDI) instruments that do something similar, and it's very convincing.

    The biggest difference for me playing electronic pianos is in the key touch. The force through different heights on a piano key is nonlinear, and it's quite distinctive. I know that recent electronic keyboards have more accurate mechanisms than just levers but I haven't tried one in a while.

    4 votes
  15. Comment on PAC-MAN 99 | Announcement trailer in ~games

    wirelyre
    Link Parent
    Seems to be a theme with these retros royals. IIRC the details of Tetris 99's garbage and game speed mechanics were determined through frame-by-frame analysis.

    Seems to be a theme with these retros royals. IIRC the details of Tetris 99's garbage and game speed mechanics were determined through frame-by-frame analysis.

  16. Comment on What programming/technical projects have you been working on? in ~comp

    wirelyre
    Link Parent
    Very cool! Is the Roman alphabet already in the ROM or will you need to draw your own?

    Very cool! Is the Roman alphabet already in the ROM or will you need to draw your own?

    2 votes
  17. Comment on The revolution in classic Tetris - A younger generation is utilizing the internet to master the NES game in months, surpassing milestones that previously took decades in ~games

    wirelyre
    Link
    I wonder if retro games naturally produce healthier communities. There's a filter right away when the community grows from nothing, since it's mostly people coming back to a game for nostalgia...

    I wonder if retro games naturally produce healthier communities.

    There's a filter right away when the community grows from nothing, since it's mostly people coming back to a game for nostalgia rather than competition. The initial draw isn't that strong, so if the community isn't pleasant and constructive, people will just leave and it'll fizzle. The tone is kind of naturally selected from the start.

    5 votes
  18. Comment on Fortnightly Programming Q&A Thread in ~comp

    wirelyre
    Link
    Does anyone know of a good introduction / overview of LL parsers and table construction? I've got a library nearby, so I can go get a textbook if it has pictures, but I don't want to wade through...

    Does anyone know of a good introduction / overview of LL parsers and table construction?

    I've got a library nearby, so I can go get a textbook if it has pictures, but I don't want to wade through pages and pages of Greek letters and follow sets to get the intuition. I already did that with LR.

    2 votes