I made some waffles and a small Santa hat for my pet rock.

I made some waffles and a small Santa hat for my pet rock.
So earlier today I was trying out Microsoft’s online office suite and noticed something interesting. Whenever you create a new Word, Excel, or PowerPoint file from the OneDrive interface, it automatically creates it using the OpenDocument file format (odt, ods, odp) as opposed to the Microsoft Office format (docx, xlsx, ppt). Interestingly if you create it from Office.com it uses the Microsoft format instead.
I’ve decided that I’m going to be reformatting my 25 TB of external storage capacity (for storing datasets, backups, etc.) to exFAT. Most of it is currently ext4 or NTFS.
exFAT is great because similar to its predecessor FAT it has read-write compatibility with Linux, Windows, and macOS. But while FAT can only have files as big as 4 GB and partitions of 16 TB, exFAT can do 16 EB for files and 64 ZB for partitions. Lots more room to grow.
It’ll be a slow process since I can only format one drive at a time and need to copy the data to another drive and back again. So far I’ve converted 4 TB of data.
So my university has shutdown the campus for the remainder of the semester due to Coronavirus concerns and asked all students to attend classes remotely (mainly using Zoom for live-streaming lectures). I went looking for an open source cross platform video conferencing solution with a fast onboarding process to keep in touch with fellow students and found Jitsi to fit the bill.
It’s free, it’s FOSS, and there are no accounts required to create a chat session on their website. You just need to enter a name for your room, and they give you a link to share for people to join.
The only officially supported web browser is Google Chrome which kinda sucks. But it seems to work okay in Firefox except I couldn’t get it to detect any of my microphones (your usage may vary). Instead, I’m using it in Falkon and it works flawlessly.
Unfortunately, it also doesn’t appear that video chats are end-to-end encrypted which means whoever runs the server can see the raw footage (but you can self-host).
Overall it’s good enough and it looks like the public service is hosted by 8×8, which is a public VoIP company, so I’m not overly concerned about eavesdropping (due to the lack of end-to-end encryption). I’ll keep an eye out for better options but for now I’m sticking with Jitsi.
Today, I tried out KDE Neon on my PinePhone “Brave Heart” and recorded the following video.
Here is a summary of some of the default apps:
I find this video just remarkable. It’s only been 109 years and yet things are so much different now. I wonder what things will be like in a hundred more years. With any luck I’ll live to see.
I have previously mentioned how I felt that Tor should offer some way for users to pay for bandwidth on its network to incentivize more nodes to join. Well, today I found out about Orchid which is a decentralized VPN that allows users to do just that.
It’s basically a marketplace for bandwidth between clients and VPN providers. Anyone can set up a node and act as exit point. From what I’ve read it seems like exit nodes can even choose what type of content will go through them: torrents, email, specific websites, etc. can all be blocked or allowed. The app will automatically pick providers that support the type of content that you’re trying to access.
Given this dynamic I would imagine that different types of content will start to cost more. For example, bandwidth providers who allow torrents will charge a premium due to the increased legal risk. On the other hand, providers who only allow access to known safe sites like YouTube, Reddit, etc. would be much cheaper.
Orchid even supports multiple hops within the network just like Tor. There are a few concerns I have:
For now, I’m going to continue using Private Internet Access as my VPN, but Orchid is something I’ll keep my eye on.
Cloudron is fascinating piece of software I found out a few days ago. It makes it super easy to self-host a bunch of applications like Nextcloud, GitLab, Wallabag, etc.
They all have one-click installers and SSO with your Cloudron user accounts. Also, it supports encrypted backup to various cloud providers like Amazon S3, DigitalOcean Spaces, Google Cloud, etc.
The only two downsides I’ve found are that it costs $30/mo and isn’t FOSS.
I think I’m going to give it a try on a Linode server.
This is a simple pong game I created for fun for the CICS 290M Makerboard running Arduino software. The board is part of the CS Make course at UMass Amherst.
Below is the source code, it’s also available on GitHub.
// Imports
#include <Adafruit_SSD1306.h>
// Globals
#define UP_BUTTON 34
#define DOWN_BUTTON 0
#define RESET_BUTTON 35
#define BUZZER 17
// Game State
int score = 0;
// Paddle
int paddle_pos = 32;
int paddle_velocity = 1;
int paddle_height = 16;
int paddle_width = 4;
// Ball
volatile int ball_x = random(10, 80);
volatile int ball_y = random(16, 48);
volatile int ball_radius = 3;
volatile int ball_velocity_x = random(1, 3);
volatile int ball_velocity_y = random(1, 3);
Adafruit_SSD1306 lcd(128, 64); // create display object
// Callbacks
void IRAM_ATTR moveUp() {
if (paddle_pos >= 0) {
paddle_pos -= 1;
}
}
void IRAM_ATTR moveDown() {
if (paddle_pos + paddle_height <= 64) {
paddle_pos += 1;
}
}
void IRAM_ATTR restart() {
if (gameOver()) {
score = 0;
ball_x = random(10, 80);
ball_y = random(16, 48);
ball_velocity_x = random(1, 3);
ball_velocity_y = random(1, 3);
}
}
void setup() {
Serial.begin(9600);
pinMode(BUZZER, OUTPUT);
pinMode(UP_BUTTON, INPUT);
pinMode(DOWN_BUTTON, INPUT);
pinMode(RESET_BUTTON, INPUT);
lcd.begin(SSD1306_SWITCHCAPVCC, 0x3C); // init
lcd.setTextColor(WHITE);
lcd.clearDisplay(); // clear software buffer
lcd.display();
attachInterrupt(RESET_BUTTON, restart, FALLING);
}
// Test if coordinates are out of bounds
boolean yIsOutOfBounds(int y) {return y > 63 || y < 0;}
boolean xIsOutOfBounds(int x) {return x > 127 || x < 0;}
boolean outOfBounds(int x, int y) {return xIsOutOfBounds(x) || yIsOutOfBounds(y);}
boolean gameOver() {return ball_x + ball_radius >= 127;}
boolean ballPaddleCollision(int x, int y) {
return (x > 128 - paddle_width) && (y < paddle_pos + paddle_height && y > paddle_pos);
}
void drawPaddle(int x, int y, int width, int height) {
lcd.fillRect(x, y, width, height, WHITE);
}
void ding() {
ledcSetup(0, 5000, 8);
ledcAttachPin(BUZZER, 0);
ledcWriteTone(0, 500);
delay(50); // 500Hz for 0.05 second
ledcWriteTone(0, 0); // buzzer off
}
void drawBall() {
lcd.fillCircle(ball_x, ball_y, ball_radius, BLACK);
if (xIsOutOfBounds(ball_x + ball_radius) || xIsOutOfBounds(ball_x - ball_radius)) {
ball_velocity_x *= -1;
ding();
}
if (yIsOutOfBounds(ball_y + ball_radius) || yIsOutOfBounds(ball_y - ball_radius)) {ball_velocity_y *= -1;}
if (ballPaddleCollision(ball_x + ball_radius, ball_y) || ballPaddleCollision(ball_x - ball_radius, ball_y)) {
ball_velocity_x *= -1;
ding();
score++;
}
ball_x += ball_velocity_x;
ball_y += ball_velocity_y;
lcd.fillCircle(ball_x, ball_y, ball_radius, WHITE);
}
void loop() {
// Check if Game is over
if (gameOver()) {
lcd.clearDisplay();
lcd.setCursor(0,0);
lcd.print("Score: " + String(score) + "\nPress bottom button \nto restart.");
lcd.display();
return;
}
// Check for button presses
if (!digitalRead(UP_BUTTON)) {
moveUp();
}
if (!digitalRead(DOWN_BUTTON)) {
moveDown();
}
lcd.clearDisplay();
drawPaddle(0, ball_y - (paddle_height / 2), paddle_width, paddle_height);
drawPaddle(127 - paddle_width, paddle_pos + paddle_velocity, paddle_width, paddle_height);
drawBall();
lcd.display();
}