Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
deathofmusic
Jan 3, 2001
What started as a some scripts and a basic php page to simplify allocating and connecting audio channels over a network of Linux machines, has ended up a Python based modular REST controlled server application with a user-customisable JS front end to build custom controls for multimedia environments.

Here's some screens of the web interface controlling various audio/video/multimedia environments:

A workspace to control a single area, with two audio zones and a video screen.


A multi-room workspace, controlling four different video screens on four different nodes, with drop downs to choose what's showing on each screen and buttons to open media players and link to other pages.


Mobile scaled workspaces.


A workspace with media player controls, drop down multi-zone audio selections, and sliders for zone gain control.

Adbot
ADBOT LOVES YOU

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself

Grump posted:

Here's my proof-of-concept for a dinky little drink suggestion app that I've been working on live

The only cocktails in the database so far are Gin and Tonic and Screwdriver. I'm very much a front-end developer, and this was my first time working with Python, Flask, and Docker, so I'm pretty happy with how this is turning out. The API supports a lot more things like users, user preferences, and all the CRUD operators for ingredients and cocktails, so I still need to flesh out the front-end to consume all of it

I need to get my hands on a cocktail recipe book



The detail screen is fleshed out, you can search by cocktail name, login, contact form, and forms to create new ingredients and cocktails. Go try it!

(I still have to go through the grueling process of adding all the cocktails)

teen phone cutie fucked around with this message at 04:29 on Jul 3, 2019

Loezi
Dec 18, 2012

Never buy the cheap stuff

Grump posted:

Updates on https://barcart.net. The detail screen is fleshed out, you can search by cocktail name, login, contact form, and forms to create new ingredients and cocktails. Go try it!

(I still have to go through the grueling process of adding all the cocktails)



Does it recognize that if I have "an orange", I can use it to make juice, peels, slices etc?

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself

Loezi posted:

Does it recognize that if I have "an orange", I can use it to make juice, peels, slices etc?

Lol nope and it’s because i’m not good at database design or backend development in general

Loezi
Dec 18, 2012

Never buy the cheap stuff

Grump posted:

Lol nope and it’s because i’m not good at database design or backend development in general

It's my pet peeve with these kinds of apps so apparently you are on-par with the pros! :)

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Kennel posted:

This came up in the chart & graph thread and the people seemed to like it, so I'll repost it here.



There's a chart & graph thread?? Anyone have a link? Search is not finding it.....


Also, those images are awesome.

SupSuper
Apr 8, 2009

At the Heart of the city is an Alien horror, so vile and so powerful that not even death can claim it.

Lumpy posted:

There's a chart & graph thread?? Anyone have a link? Search is not finding it.....
Here you go: https://forums.somethingawful.com/showthread.php?noseen=0&threadid=3745614&perpage=40

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Thank you!

Ranzear
Jul 25, 2013

Grump posted:

Lol nope and it’s because i’m not good at database design or backend development in general

You just need a three column table: id, item, derived.

Then you just throw a ton of one-way graph edges in there of things you can derive from something, and it's multi-row relations:

Orange -> Orange Peel
Orange -> Orange Juice
Orange -> Orange Zest
Orange -> Orange Slice

etc. You can make many rows with 'Orange' because the id column handles uniqueness.

Then you just pull all rows from that table for each thing you have, and add those related things to what you have, or keep it separate in a 'derived' set, or even iterate, but probably just a few times else you could make or have to avoid loops.

Xerophyte
Mar 17, 2008

This space intentionally left blank
I updated my SDF fractal hack branch of the pathtracer I work on a whim last Friday, and fixed a couple of leftover bugs over the weekend. It's faster, and unlike the shots I posted last time there aren't a bunch of epsilon issues causing half the rays to go straight through the fractal. I've been running high detail renders overnight all week.

Red anodized aluminium mandelbox:


Tiny walnut mandelbox :


My shading is a bit limited since I didn't really hack in any sort of UV projection or iteration count coloring like people normally do so I'm limited to fixed colors or procedural volumetric textures. I also accidentally interrupted the wood render early so that image isn't really converged. Still pretty happy with the output.

Now I just gotta make a GPU implementation and add better detail controls so interaction and setting up shots isn't quite as pants...

Athas
Aug 6, 2007

fuck that joker
I'm writing a a ray tracer (a port of Ray Tracing: the Next Week to another language). I put together part of the famous Cornell box scene. This is what my ray tracer produces when run sequentially or on the GPU on my Linux system:



This is what it produces when run on macOS with OpenCL (using either of the two GPUs on the Macbook):



I have no idea where that dirty-concrete look comes from, but I kind of like it. I use a deterministic RNG that should be the same on all platforms.

steckles
Jan 14, 2006

Athas posted:

I'm writing a a ray tracer (a port of Ray Tracing: the Next Week to another language). I put together part of the famous Cornell box scene. This is what my ray tracer produces when run sequentially or on the GPU on my Linux system:



This is what it produces when run on macOS with OpenCL (using either of the two GPUs on the Macbook):



I have no idea where that dirty-concrete look comes from, but I kind of like it. I use a deterministic RNG that should be the same on all platforms.
Sweet. Everyone should write a path tracer.

The striations you’re seeing are almost certainly due to correlation from multiple paths getting the same random numbers. You can either wrap your RNG in a mutex or something, or use a differently seeded generator per thread.

Multithreaded RNG bugs are super dependent on timing and often don’t show up in obvious ways, so that's probably why you’re only seeing them on one platform.

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

The wrong one has so much character! Now you need to figure out what is happening so you can do it on purpose.

Not Operator
Jan 1, 2009

Not A doctor, THE Doctor!
Yeah, it has a painterly style. It's very cool.

Good Sphere
Jun 16, 2018

I wonder how it would appear animated? Meaning, not moving the camera, but a still shot of the same scene.

Athas
Aug 6, 2007

fuck that joker

steckles posted:

Sweet. Everyone should write a path tracer.

The striations you’re seeing are almost certainly due to correlation from multiple paths getting the same random numbers. You can either wrap your RNG in a mutex or something, or use a differently seeded generator per thread.

Multithreaded RNG bugs are super dependent on timing and often don’t show up in obvious ways, so that's probably why you’re only seeing them on one platform.

You were quite right: I had actually fixed the bug in the library I use for RNGs, but I forgot to update it on macOS. I wrote up my ray tracer experiences along with a pretty picture. My interest is more in the code than in cool scenes, so I'm just using the same final scene as the book I followed:

Now I need to figure out how to reproduce that concrete look without just using a buggy RNG!

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
Porting an old somewhat popular Mac game.

Got to the title screen! :toot:

(Might seem minor, but getting this far is probably 20%-30% of getting the whole thing working...)

steckles
Jan 14, 2006

OneEightHundred posted:

Porting an old somewhat popular Mac game.

Got to the title screen! :toot:

(Might seem minor, but getting this far is probably 20%-30% of getting the whole thing working...)


Holy moly, that brings back memories! I think Glider was the first program we installed on our first Mac back in like 1991. Didn’t know the source was released, I’m definitely gonna scope it out.

Good Sphere
Jun 16, 2018

OneEightHundred posted:

Porting an old somewhat popular Mac game.

Got to the title screen! :toot:

(Might seem minor, but getting this far is probably 20%-30% of getting the whole thing working...)



You're doing God's work. One of the best Glider games.

Polio Vax Scene
Apr 5, 2009



Update us when its finished. That garfield-lookin' rear end in a top hat and I have a score to settle.
e: I looked it up on youtube and the version I had is apparently different from that one.

Polio Vax Scene fucked around with this message at 00:35 on Dec 24, 2019

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
It'll probably be 100% playable a while before it's completely finished.

A lot of the remaining work is rolling a window manager to deal with all of the prefs dialogs and editor mode, changing the resolution (ideally while in-game, which I think the existing code doesn't support), enough of a QuickTime subset to get the TVs working, other random things like gamepad support, and purging a few things with questionable IP status.

The depot is here if you want to follow it or take it for a whirl:
https://github.com/elasota/GlidePort

I'm guessing it'll be mostly playable - but with a lot of broken draw functions - by the end of the week, and most of the draw functions fixed by the new year.

OneEightHundred fucked around with this message at 08:13 on Dec 25, 2019

MrMoo
Sep 14, 2000

Project update, old image, scroll right if you have a small screen. No live data yet, too cheap.



http://ahyoomee.miru.hk/zignage-sports7/build/default/www/3840-bloom.html

Or, for regular version with logos:

http://ahyoomee.miru.hk/zignage-sports7/build/default/www/3840-basis.html


This took a long time to get to and derived from several other projects. The server side is nothing special, just a WebSocket streaming out sports stats via polling a website. The client side is a beast using a variety of oddly named projects:

  • THREE.js for WebGL integration instead of PIXI.js which targets 2D. Three can be pushed into a WebWorker however Chrome has some major performance caveats that make it useless. PIXI.js however properly supports texture atlases, when you share a big graphic across multiple visual entities. APIs are not terribly distant apart, easy to port. Both now support WebGL versions 1 and 2, with the latter allegedly dropping CPU usage by 5%. I have never seen such improvements, only the inconvenience of rewriting GLSL shaders.
  • LitHTML x LitElement for browser renderer thread containment in webcomponents. Basically make a new <ticker> html tag and drive that with ES6 classes. LitElement forces a subset of what was available in a project called Polymer for a nats crotch of improved performance, however it actually works unlike v2 and v3 of the Polymer project. It can now be accelerated by the browser, with older browsers supported via polyfills.
  • Rollup and polymer tool for building a bundle. The Polymer project has lovely dependencies on paths that cannot be avoided without a build step.
  • ES10, somehow I keep on stumbling upon APIs only available in new and newerer releases of javascript. From async/await to Promise.finally, and Object.fromEntries. The latter helps converting a Map into an Object to send across a WebSocket.
  • Comlink, an API that makes JavaScript intra-thread communication convenient for spawning remote objects. Error traces are impressively unhelpful.
  • Basis for GPU independent GPU "super compressed" images. Compressing in the GPU means smaller files, faster CPU to GPU transfer and allegedly happier GPU when rendering. Every platform has different preferences however in WebGL it's all pretty lovely and not updated. I learnt that if you take a standard .basis file with mimaps you can end up with 328 different images when unpacking. Google sponsored this project to make it open source. There are papers on "GPU super compression", and all I can tell is that it's just more crappy lossy image compression like JPEG. Miami Marlins standard logo looks terrible when GPU compressed.
  • WASM for a browser based Basis transcoder. Download Basis files, pump into a transcoder, and send off via THREE.js to the GPU. THREE.js actually has a loader example that does all this with great convenience.
  • MSDF for fonts, scalable font textures that preserve hard edges via GL quads. Source textures look funky:



You can upload very basic SVGs through THREE.js to render on the GPU however all the logos I have tend to look rear end due to additional SVG features that presumably don't translate.
code:
 35193 Jan  3 03:59 NYY.basis
323152 Dec 30 21:44 NYY.png
 92028 Dec 28 12:35 NYY.svg
 88078 Jan  1 20:07 NYY.webp
Most of the time SVGs are actually the smallest file, I have the Basis, PNGs and WebP files crushed and optimised as high as possible.

Fonts can also be rendered as shapes in THREE.js but tends to be terrible on layout, conformant sizing, and surprisingly performance.

Render performance seems to be sub-1ms per frame. A fullscreen pass for bloom or FXAA however requires a decent GPU for large screen sizes. I tried to use FXAA on the Basis encoded logos but just ended up giving the fonts weird edges and not really doing anything to the logos, go figure.

MrMoo fucked around with this message at 03:21 on Jan 4, 2020

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Here's a screenshot of that unpractical Python interpreter project I've been working on. I finally got it to a point where I feel like I can show it off with some pride to people that could appreciate what it means.


I have two contexts running in the environment. The first one is a Python script alternating the "Random Blips" in the first and second positions in an infinite loop with a sleep. This sleep doesn't block the application. The second is the REPL that's running stuff on demand. You can see it at the end engage with the mock dialog subsystem to post its own dialog. The result is the index in the list of choices that I had selected. The REPL will block when it's doing a blocking operation, but you see that the loop in the background keeps running.

This is all happening in a custom-built interpreter I wrote in C# that's running in one thread and using async-await under the hood to switch the interpreter between different frames as the different frames block/unblock. My ultimate goal is to embed this into Unity to get some debug consoles up while also enabling Python scripting.

I don't have much of the language implemented at all but clearly I can run a loop with some basic logic.

Forseeable Fuchsia
Dec 28, 2011
Front-end project work, so not as cool as some of the other stuff in the thread but I've been working on something only SA would probably enjoy to play around with Vue.js.

I'm a big dumb nerd who likes reading Let's Plays and the mobile experience of the LPArchive isn't fantastic. So I've put together a basic LP reading web app so I can read stuff on my long commutes on my phone, just scraping the HTML from the LPArchive pages, it also has a dark mode! Is it possibly the worst way to make something from existing content? Absolutely, but it works enough to make mobile LP reading possible.



This is the first time I've made anything using dynamic Vue Router routes so it was a fun and useful project to get myself across that. No LP searching yet, it just grabs the LP Master List from the site itself and displays that as the initial page and it's fuckin' mess:



Possibly the most useless personal project I've worked on but it's fun!

Drist
Jan 19, 2007

This is an alarm, stay where you are...
I'm developing a procedurally-generated pixel art skyline generator. It's still far from done, I just wanted to show off some screens and see if anyone has any questions/suggestions:




Done in Unity/C# - initially the project was in Javascript on HTML canvas but JS's object handling deficiencies were annoying me too much.

Xerophyte
Mar 17, 2008

This space intentionally left blank
That's really cool! Works well for a simple effect.

I think the one thing that breaks the illusion for me right now is that buildings I read as in the same plane can have wildly different floor heights and room scales, sometimes smaller than buildings "behind" them. Dunno if you have a depth generated -- would be neat for parallax and things -- but if this is straight painter's algorithm then it seems to me like the first batch of buildings should be drawn as dimmer and with smaller dimensions to read at distant, then make them larger and brighter as they get "closer".

Drist
Jan 19, 2007

This is an alarm, stay where you are...

Xerophyte posted:

That's really cool! Works well for a simple effect.

I think the one thing that breaks the illusion for me right now is that buildings I read as in the same plane can have wildly different floor heights and room scales, sometimes smaller than buildings "behind" them. Dunno if you have a depth generated -- would be neat for parallax and things -- but if this is straight painter's algorithm then it seems to me like the first batch of buildings should be drawn as dimmer and with smaller dimensions to read at distant, then make them larger and brighter as they get "closer".

Thank you! The three layers are individual sprites, it currently does a basic parallax motion but since it's not yet clipped to the pixel grid, it moves at sub-pixel resolution and looks odd, which is something I'm going to fix soon.

Each layer is aware of its 'zIndex' and draws from a weighted RNG table for all of the random elements in the design. There are different weights per layer, so the rear buildings tend towards more tiers with smaller windows, but a rear-layer building could still roll a maximum-size window. Here's a screenshot with the weights skewed much more heavily towards large windows at the front and small at the back (also the WTC apparently):


Thanks for the suggestion - I will review the weight tables like you suggested.

Pigmassacre
Nov 23, 2010

GARBAGE DAY

Randomizing the intensity of the lights in the windows could probably be nice as well. It's a bit static right now.

Also, there's something about the window sizes being so different that looks off to me. Seems like it should be true to life though but to me it doesn't look that great.

Cool project!

Sereri
Sep 30, 2008

awwwrigami

Pigmassacre posted:

Randomizing the intensity of the lights in the windows could probably be nice as well. It's a bit static right now.

No idea what it would look like but maybe randomly modify the base window light color on a per-building basis to be a bit more blue or red.

Drist
Jan 19, 2007

This is an alarm, stay where you are...

Pigmassacre posted:

Randomizing the intensity of the lights in the windows could probably be nice as well. It's a bit static right now.

Also, there's something about the window sizes being so different that looks off to me. Seems like it should be true to life though but to me it doesn't look that great.

Cool project!

I get what you mean here, I've experimented with tweaking window sizes, making them a little more distinct and uniform per layer. I also removed two of the window variations, the vertical double and the quad connected windows, which in practice made some of the windows look a little chunky. I think it looks better like this, thank you for the suggestion.

Sereri posted:

No idea what it would look like but maybe randomly modify the base window light color on a per-building basis to be a bit more blue or red.

I was actually already doing exactly this, but variations were hard to see. I've changed them up a bit in these shots, as well as varying window brightness just a touch. I've also tried varying the massive 'moon' colour for some contrast. Some other changes were brightening the city layer in general while increasing contrast between the layers and adding a divider between the land and water.



RIP Syndrome
Feb 24, 2016

Looks nice! Like Xerophyte pointed out, I think getting the depth cues right is important for this kind of scene. I think a little bit of ground haze could help. An economical implementation would be a straight vertical gradient with a higher blending factor closer to the ground and farther from the observer. City haze is also an opportunity to add some color (sodium streetlight/neon goodness if you want to go in that direction).

Happy Thread
Jul 10, 2005

by Fluffdaddy
Plaster Town Cop
Looks neat

Remember that ceiling heights are somewhat standardized across buildings

Kilson
Jan 16, 2003

I EAT LITTLE CHILDREN FOR BREAKFAST !!11!!1!!!!111!

Dumb Lowtax posted:

Looks neat

Remember that ceiling heights are somewhat standardized across buildings

There's definitely a realistic range, but that range could be larger than many think!

Vista Tower in Chicago is 101 floors in 1191 feet, for 11.8 ft/floor.

One Vanderbilt in NYC is 1301 feet and 67 floors, for 19.4 ft/floor.

Of course these measurements are complicated by the ways they actually measure these buildings. I tried to find measurements of top usable floor, but YMMV.

hendersa
Sep 17, 2006

Hello all. It's been a while since I posted anything, but I always seem to be working on a few embedded projects here and there. I've been messing around with the Super Nintendo and Super Famicom for a few years now, and I recently have been studying the Satellaview add-on for the SFC. With the impending expiration of the Satellaview patent, I had decided to start researching it to maybe engineer a replacement for it with modern parts. Now that the patent actually has expired, the first step was to get one of these bad boys for reverse-engineering and comparison purposes. I had one shipped over to me from Japan:



Through some awesome dumb luck, the 8M memory pack included with my Satellaview unit contained the previously undumped Satellaview title Tactics Ogre (BS Version)! I contacted the folks over at The Video Game History Foundation to notify them and request their assistance. After a few introductions with people that could help, I bought some dumping hardware, made a verified-good memory pack dump, and submitted it for archival and release:



https://www.youtube.com/watch?v=tCyhdSikNho

Now that the long-lost game was saved for posterity, it was time to get to work. I took some measurements for the proprietary expansion port connector on the SFC and SNES:



I ordered a few connectors from Digikey and got to work cutting and sanding them in various configurations before I got something that matched the size and pitch of the connector. I soldered on a wiring harness, padded the edges with folded paper for a snug fit, and began capturing the bus traffic coming from the SFC expansion port with my logic analyzer:



Since I only want my makeshift Satellaview clone to respond to a specific range of memory-mapped I/O registers, I needed a way to filter bus traffic so that I'm not overwhelmed by all of the chatter. Gating out the address lines to filter the traffic was needed, but I didn't want to fiddle with a bunch of 7400-series logic gate ICs. So, I used the pretty awful WinCUPL tool to design an MMIO address filter on an Atmel ATF1504 using CUPL:



The simulations and tests look good so far, but I'm still waiting on an adapter for PLCC ICs so that I can wire a socket into the final design and skip adding an on-board JTAG programmer for the CPLD. I'll just pop the CPLD out of the socket for reprogramming.

The general idea is that I'm using the CPLD to filter traffic to a manageable level. Whatever makes it through the filter goes into a BeagleBone Black for processing. I can use firmware running on both of the two Programmable Real-Time Units (PRUs) on the BBB to handle the GPIOs making up the address and data buses. A kernel driver handles the actual device logic. I can mux out just enough pins on the BBB to support the buses and a few control lines using PRU-enhanced GPIOs. Those pins toggle in a single PRU clock cycle (5 ns). Slower GPIO signals (like RESET) can be handled using a standard GPIO by the kernel driver.

I've played around with the PRUs to talk with SNES gamepads in the past, and they are fast. In fact, I just had an article on PRU interfacing published in issue #28 of HackSpace Magazine. You can download a free PDF copy of the magazine here, but I haven't found a retail place here in the US that sells paper copies (since HackSpace is a UK-based magazine). The article is on pages 104-109:



That's the latest and greatest! I chip away at this stuff here and there when I have time. I'm still in the breadboarding/prototype stages with most of it, but I'm taking pictures as I go for my own notes and for an eventual write-up down the road (if it all pans out).

:science:

csammis
Aug 26, 2003

Mental Institution

Awesome! I’m glad you’re back, your projects are always cool.

I can’t quite read the Logic screenshot but it looks like you’ve got a bus analyzer active. Is it using a common protocol?

Neurion
Jun 3, 2013

The musical fruit
The more you eat
The more you hoot


Not to gloss over all the cool tech stuff you've done, but Tactics Ogre is legit one of my favorite games. What's the difference between the SFC and the BS versions?

hendersa
Sep 17, 2006

csammis posted:

Awesome! I’m glad you’re back, your projects are always cool.

I can’t quite read the Logic screenshot but it looks like you’ve got a bus analyzer active. Is it using a common protocol?
The only analyzer running is a simple parallel bus analyzer. I was looking at the secondary 8-bit address bus (called the "B-Bus"), which is used for peripherals and co-processors. The analyzer was just stitching together the eight lines into a hex representation of the address. I wanted to make sure I was getting valid addresses on the bus, since there are a set of common ones for co-processor I/O that are easy to spot.

Neurion posted:

Not to gloss over all the cool tech stuff you've done, but Tactics Ogre is legit one of my favorite games. What's the difference between the SFC and the BS versions?
Well, the BS version looks more like a demo, so it's a subset of the full game. From what I can tell, it doesn't have saved games and it skips the title screen menu to launch directly into the tutorial. The BS version is also an 8 megabit game, versus 24 megabits for the full thing. If you've played the full game, you've probably experienced everything the BS version has to offer. But, if you're an Ogre-series fanatic, you might want to run through it for completionist bragging rights. :mario:

Cory Parsnipson
Nov 15, 2015
I made a small Angular app to let people disassemble Intel 8080 CPU binaries online...

http://8080dasm.slackerparadise.com



I'm not sure how this would be useful to anyone, but it's letting me learn Angular and about emulators at the same time. v:shobon:v

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!


Level editor 95% ported. Only thing that doesn't work is the map scroll bars and resizing. Only 3 things left on the alpha release milestone, which I'll probably knock out next weekend.

Adbot
ADBOT LOVES YOU

hendersa
Sep 17, 2006

Hey! More progress on the Satellaview project!

I was putting most of my effort into the hardware side of things to flesh out the details of the components and prove that the design is viable:



The amount of time you can spend fiddling around with PCB layout is ridiculous. Luckily, there are some good open-source tools that help out a bunch:



After about 10 hours of work, I came up with a layout scheme that only used a few vias and looked fairly decent (though I did have to extend the cape PCB a bit to get it all to fit nicely):



Since the design fits in the space that I needed, I decided to move forward with the schematic as-is. I got to work breadboarding it out, and I wrote some firmware, device tree overlays, and a Linux userspace test program to make sure everything was getting from point A to point B like I expected:



I've now got the filtered address bus being passed into the BeagleBone Black via a 3.3V line level converter, the bus signals sampled by a PRU, and the resulting address pushed over to Linux userspace. There's a lot of debugging and details I'm omitting, but trust me... it was quite a bit of effort to get things as far along as they are. I'm pretty happy with my progress so far, anyway! :science:

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply