Category: linux

Hyper-V VMs are not all the same

Hyper-V VMs are not all the same

Hyper-V Ubuntu installOne of the big problems with Hyper-V and Ubuntu in particular is the clipboard or lack of it. I had 18.04 LTS installed with an X Org RDP login. This worked perfectly and I could have a full screen in my Monitor and could copy/paste.  Don’t underestimate copy/paste.

It’s a real PITA if you have to use say WinSCP to copy files over. I think WinSCP is excellent BTW but the amount of labour saving that copy/paste has done since some genius thought it up is immeasurable. That and allowing the full screen of the monitor are two highly important things.

Sadly the 20.04 LTS didn’t seem to allow it. Copy/paste didn’t work between my Windows PC (host) and Ubuntu (guest). There’s nothing worse than losing a feature you’ve grown fond of.

If you follow these instructions for creating a Hyper-V 18.04, you get the screen size popup but not with 20.04 LTS. For that you have to follow these instructions!

It’s things like this that suggest why Linux Desktop has never been that successful. You can waste many hours getting simple things working and sometimes like Copy/Paste they break between versions. And this is with Ubuntu, probably the biggest and best known and supported Distro.

 

And my Hyper-V Raspi error

And my Hyper-V Raspi error

Scary apt messageSeems to be with Visual Studio Code. I said yesterday that it had got into a funny state. Well I created a new VM and installed the Raspberry Pi OS that runs in a VM and after it updated tried installing VS Code on it.

It would have had the same problem had I let it. The problem is it when you install VS Code, it has some unmet dependencies and in fixing them it wants to remove 8 essential packages and this breaks apt which then gets in a funny state.

No one wants to see this scary message! So I think I may have to use the Code.headmelted.com version on Hyper-V for a while and see if this gets resolved with the next update of VS Code. Ah the jots of software development…

 

An example of what you can do with MonoGame

An example of what you can do with MonoGame

OpenVIII screenshotMonoGame is not just for mobile, as I’ve been doing. Open VIII is a Final Fantasy VIII game engine written in C#/MonoGame and currently works on Windows and Linux (not sure about Mac). Other games in the series have been ported to other platforms but not FFVIII, so that’s why the project was started.

The instructions for Open VIII on Windows suggest Visual Studio 2017 but I imagine 2019 might also work as MonoGame 3.8 has templates for it.  As the project says “OpenVIII is an open-source complete Final Fantasy VIII game engine rewrite from scratch powered in OpenGL making it possible to play the vanilla game on wide variety of platforms including Windows 32/64 bitLinux 32/64 bit and even mobile!

As with virtually all open source reimplementations, you will have to provide your own game assets such as images and sound. You can do this apparently by buying the original game on Steam. I took a look and sure enough it’s there and there’s an official remastering by Square Enix. I’m not sure why the Steam search brings up FF VII as well but hey that’s search for you… I’ve added a permanent link to the C#/MonoGame links page.

Steam Final Fantasy VIII

How to install WSL 2 and Linux on Windows 10

How to install WSL 2 and Linux on Windows 10

Winver commandThis assumes that you have the version 2004 of Windows 10. Run the command Winver (open a command line then type winver) to see what version you have.

WSL is Windows Subsystem for Linux and lets you run one of several Linuxes (after installing) in Windows. For now it is terminal only but you can debug programs using Visual Studio. WSL 2 is the current version of WSL though you can run the older WSL 1.

Your computer also needs to support Hyper-V Virtualization to run WSL 2. If it doesn’t you can run WSL 1.

Steps.

  1. Open a PowerShell windows in Admin mode. My way of doing this is open the search window and type Powershell. Then right-click run as Admin.

 

When I mean Search Window, I mean the one on the Toolbar that looks like this like a magnifying glass: (highlighted in the red square)

Search Window

 

 

2. In the Powershell Windows, copy and paste this command:

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

3. Next run this command in the same Windows:

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

4. Set WSL 2 as default with this Powershell command:

wsl --set-default-version 2

Now close the Powershell Window and in the search box type Store. You should see Microsoft Store.  It’s an app on your PC. Click it to run it and type in Linux in the search box. Click Show all and you should see something like this. Pick one like Ubuntu, Debian etc.  Apart from the ones with a price against them, the rest are free. Cl;ick Get and it will install.

Linux in Microsoft Store

After it has installed, you can run it from your Start Menu. I dragged it onto the square so I have a nice clickable icon.

Windows Start MenuJust click it and your Ubuntu (or whatever) Linux will open at a terminal prompt like this.

Ubuntu Terminal

 

Space Invaders done faithfully in C

Space Invaders done faithfully in C

Si78 Space InvadersI was around when space invaders came out in the late 70s and played it a bit, although I preferred Galaxian, Gorf, Defender and Battle Zone (3D Tanks on the moon- vector graphics).

This project (catchily named si78) though is a memory accurate re-implementation of the 1978 arcade game Space Invaders in C.

To build and run this (on a Linux box) you’ll need to download the invaders ROM which is available in one of the Mame sets. The game is written in the subset of C99 that is compatible with C++, and uses no compiler extensions apart from attribute packed.

 

On apt vs apt-get

On apt vs apt-get

Linux
Image by Donald Clark from Pixabay

This is the command you use to update your system, fetch and install software. Some people use apt-get, others plain apt and the two appear interchangeable but they are NOT the same. As it’s making a change to the system, you almost always have to run it via sudo.

They are different?

Well yes. Try these.

apt --help

apt-get --help

Those give different help messages. And as for these:

apt check

apt-get check

It’s curious that apt-get check works, but apt check gives an invalid operation! I’m not sure why they are so similar yet subtly different. If anyone knows, drop me a line.

Having created this post, I subsequently did find out the differences- explained on this page. The simplified version is the apt is a simpler subset and also shows a progress bar when you do sudo apt upgrade. Try sudo apt-get upgrade next time to see it without the progress bar!

 

Here’s the Raspberry Pi temperature code

Here’s the Raspberry Pi temperature code

To add temperature to the frame caption, I first do a check to see that it is running on a Raspberry Pi. This function does that.

void SetPiFlag() {
	struct utsname buffer;
	tempFlag = 0;
    if (uname(&buffer) != 0) return;
    if (strcmp(buffer.nodename,"raspberrypi") !=0) return;
	if (strcmp(buffer.machine,"armv7l") != 0) return;
	piFlag=1;
}

Note you have to add this include

#include <sys/utsname.h>

Now you need to call this function to return the temperature as a float.

float ReadPiTemperature() {
    char buffer[10]; 
	char * end; 
	if (!piFlag) return 0.0f;
	if (SDL_GetTicks() - tempCount < 1000) {	
		return lastTemp;
	}
	tempCount = SDL_GetTicks() ;
	FILE * temp = fopen("/sys/class/thermal/thermal_zone0/temp","rt"); 
	int numread = fread(buffer,10,1,temp); 
	fclose(temp); 
	lastTemp = strtol(buffer,&end,10)/1000.0f;
	return lastTemp;
}

Things to notice.

  1. If it’s not running on a Pi it always returns 0.0C.
  2. No matter how often it’s called, it only reads the temperature once a second.
  3. In between reads it caches the temperature in a variable lastTemp

When I first wrote this, it was reading the temperature on every frame. It actually changes that quickly but that made it hard to read. So once a second is fine.

How to read a Raspberry PI temperature in C code

How to read a Raspberry PI temperature in C code

Raspberry PiReading the temperature of a Raspberry PI can be done in a couple of ways. This command:

vcgencmd measure_temp

Outputs something like temp=32.7’C. My 3B+ PI has heatsinks and a cooling fan so runs cool. Even with asteroids it only peaked at 50.5C. Well below the throtle back temperature of 85C.

Another way (I suspect they are the same) is to do

cat /sys/class/thermal/thermal_zone0/temp

Which outputs values like 32705. Just divide by 1000 to get the temperature in Celsius.

But how do we do it in code? Well I’ve tested this code below and it seems to work.

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

int main(void) {
  char buffer[10];
  char * end;
  FILE * temp = fopen("/sys/class/thermal/thermal_zone0/temp","rt");
  int numread = fread(buffer,10,1,temp);
  fclose(temp);
  printf("Temp = %5.2fC\n",strtol(buffer,&end,10)/1000.0);
}

It reads the device as a string then converts to a long using strtol and divides that by 1000 then prints it. Output is something like:

Temp (C) = 34.88C

Now it just needs combined with the code to detect that it’s running on a Pi and you’re good.

Identifying a Linux system in code

Identifying a Linux system in code

Since I got asteroids running on a Raspberry Pi, I have decided I want to incorporate the temperature in the window caption when you switch it to debug mod by pressing Tab. Currently all that does is display position info on moving objects and bounding boxes.

But if I include that code in, I want to be sure that it only works when running on a Raspberry Pi. So I need some code to identify the system. A bit of digging and I discovered the Linux uname command. That link goes to an online man page for uname.

If I run uname -a on my Ubuntu 18.04LTS I get this.

Linux david-Virtual-Machine 4.15.0-96-generic #97-Ubuntu SMP Wed Apr 1 03:25:46 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

And on my PI.

Linux raspberrypi 4.19.97-v7+ #1294 SMP Thu Jan 30 13:15:58 GMT 2020 armv7l GNU/Linux

In fact the uname -n command gives david-Virtual-Machine on Ubuntu and raspberrypi on the PI. These are the names though names are often changeable and what if someone is running ubuntu on a PI? Yes it is a thing. But the uname -m identifies the CPU.  x86-64 on my Ubuntu and armv71 on the pi.

I did a bit of digging and found a C program on stackoverflow that will do the same as uname.

#include 
#include 
#include 
#include <sys/utsname.h>

int main(void) {

   struct utsname buffer;

   errno = 0;
   if (uname(&buffer) != 0) {
      perror("uname");
      exit(EXIT_FAILURE);
   }

   printf("system name = %s\n", buffer.sysname);
   printf("node name   = %s\n", buffer.nodename);
   printf("release     = %s\n", buffer.release);
   printf("version     = %s\n", buffer.version);
   printf("machine     = %s\n", buffer.machine);

   #ifdef _GNU_SOURCE
      printf("domain name = %s\n", buffer.domainname);
   #endif

   return EXIT_SUCCESS;
}

And this is what it outputs on a PI.


system name = Linux
node name   = raspberrypi
release     = 4.19.97-v7+
version     = #1294 SMP Thu Jan 30 13:15:58 GMT 2020
machine     = armv7l

So that bit is easy to do. Next is getting the temperature, but that’s for another blog entry…

New version of Visual Studio Code

New version of Visual Studio Code

Update to Visual Studio codeNormally I wouldn’t mention it, as there’s nothing really outstanding about the update (accessibility improvements, Timeline view, Better quick open for files etc.) You can read all about it here.

But the online documentation has improved and more importantly there’s a new tutorial using C++ on Linux. I could have done with this a few weeks back; everything there I had to figure out for myself! In our case I’ve used clang not gcc and C not C++ but those are very minor differences.

But it does have better explanations for many of the fields in the various .json files. Also the changes to tasks.json to allow multiple files. I just added them in based on gcc.