Laptop vs Hyper-V

Laptop vs Hyper-V

Laptop
Image by Engin_Akyurt from Pixabay

As a way of checking that the stuff I’m posting on GitHub, I’ve been downloading them onto a laptop and testing them.

The laptop is a seven year old Toshiba that was re-purposed from Windows to Ubuntu 18.04 LTS, the same version as I’m running in a Hyper-V session on my main development PC.

Although the laptop is older and only running an i3 chip, it still outperforms the game code running under Hyper-V code on my five year old i7-5930K PC.  I think the difference is purely because the GPU code is run in a software layer not on the real GPU. But I might be wrong.

When I tested it with 255 asteroids on screen the laptop still maintained 60 fps but the Hyper-V running version dropped below 60 fps once there were 125 asteroids on screen. I have a suspicion that C code that isn’t calling any SDL routines would run faster under Hyper-V because it’s virtualised.

How to view disassembled C/C++ code in Visual Studio Code

How to view disassembled C/C++ code in Visual Studio Code

Disassembled C source codeThere are four steps to do this. That’s assuming that you have successfully compiled your C or C++ program and have the source file handy.

  1. Install Disassembly Explorer extension into Visual Studio Code.
  2. Set a configuration setting.
  3. Run a single line command in terminal.
  4. Select a command in the Visual Studio Code command palette.

Install Disassembly Explorer.

In Visual Studio Code just switch to the extension tab and search for Dissassembly Explorer and click the install button.

Disassembly Explorer

 

 

 

Next is configuration

View the installed extensions and click the cogwheel for Disassembly Explorer then click Extension Settings at the bottom of the popup menu. A Settings tab will open, click Edit in settings.json.

You should see a few settings but only this one matters: “compilerexplorer.compilationDirectory”: “${workspaceFolder}/.vscode” . That path is where the compile etc. .json files are located.

Now open a terminal

I’ve assumed that you are running on Linux or Mac. If you are on Windows, you can also use Visual Studio Community Edition which includes disassembly features and why I’m not mentioning it here.

In the folder with your source files issue this command in the terminal.

clang -g -o asteroids.S -S asteroids.c

If OTOH you are running gcc then just substitute gcc for clang.

Finally, back in Visual Studio Code select your source file as the open tab then press F1 and in the menu that appears type in enough of Disassembly Explorer: Show until you can select it and a second tab should open with the disassembly. Click on a function in the source tab and it will jump to the correct place in the disassembled code.

Just a picture post!

Just a picture post!

Lots of collisions here with explosions turned offIn the chapter 42 of both e-books when the first collision detection is introduced, I added a SHOWOVERLAP #define. If this is uncommented, instead of things blowing up, it shows every pixel where two objects pixel’s overlap in bright green.

In the picture above you can see the player ship in the centre and all those green bits where things overlap. You don’t normally see this and it is so intensive that it drops the frame rate from the usual 60 fps to about 3 or 4. But I think it’s quite cool!

 

And the bug is fixed

And the bug is fixed

Showing the comparison of two sources and tracking a bug downHow did I fix it? Did I spend hours debugging, poring over every line? No. I woke up in the middle of the night and thought about it and remembered that

I’d had a similar bug in this chapter when working on the original Ebook.

Stupidly I’d put the fix in the sources for the next chapter (44) but hadn’t applied it to the sources in the chapter where it had occurred (42). So I fired up my favourite code comparison tool (Devart Code Compare) and looked for differences between the source files for each chapter.

This was in the function AddObjectToCells and is part of the collision detection. It’s when an asteroid or player ship is partly on screen and calculating the cell coordinates that the object lies over. The fix was just adding these two lines so it doesn’t try and access the cells array with negative indices.

if (cellx < 0) cellx = 0;
if (celly < 0) celly = 0;
Another Windows vs Linux Difference

Another Windows vs Linux Difference

Bytes
Image From Wikimedia Commons

Once I reached the masks section in chapter 38, I found my C code that I’d copied from Windows failed because of the type byte. MSVC is a little bit more forgiving over somethings and one of those is the byte type which it accepts.  In the Windows code, I had declared the mask arrays like this:

byte bulletmask[1][3][3];
byte plmask[24][64][64];
byte a1mask[24][280][280];
byte a2mask[24][140][140]; 
byte a3mask[24][70][70];
byte a4mask[24][35][35];

But Clang in its wisdom barfed at that, not recognising the type byte. A simple fix was replace byte with char and all was well.

Looking into it, I loaded one of the Windows asteroids projects, built it and then did a ctrl-click on the byte type. It led me to a file called rpcndr.h in a Windows SDK folder and this line (191) of code.

typedef unsigned char byte;

It just shows!  My er bad…

Bugs and crashes!

Bugs and crashes!

A bug!
Image by Ronny Overhate from Pixabay

I’m up to chapter 42 in the Linux e-book. The rest have gone very smoothly though I’m still unable to debug either on my Hyper-V Ubuntu or my Ubuntu running laptop. Both still have the same problem XDG_RUNTIME_DIR not set in the environment.

I’ve been reading up on that and it seems if you switch into root and the value of the environment variable $XAUTHORITY is blank then that is the problem.

My error logging is picking up problems with sound channels not playing. I think the problem is, when I hit the b key to make lots of asteroids explode, it uses up all available sound channels and there’s still explosions happening.  Not really a problem.

But to cap it all, there is a segmentation error happening with a core dump. A segfault which kills the program. But it’s not related to the sound problem. I’ve proved that by commenting out the entire PlayASound function. It now looks like this which I call the sound of silence.

void PlayASound(int soundindex) {
	//int success=Mix_PlayChannel(-1, sounds[soundindex], 0);
	//if (success == -1) {
	//	LogError2("Mix_PlayChannel failed to play audio sound #",SDL_ltoa(soundindex,buffer,10));
	//}
}

So without being able to run the program in a debugger, I’m forced to start putting in lots of logging calls and figure out where the segfault happens that way. It’s an effective way of finding bugs BUT it’s not the fastest! I have also enabled apport to try and get the crash files created in /var/crash so that may be a faster way forward.

Once I have fixed the segmentation fault, I’ll upload the fixed code to Github. It’ll be somewhere in the new code added between chapter 37 and chapter 42, to do with collision detection. Time to put on a deerstalker hat!

Another new page – C Code links

Another new page – C Code links

I’ve added a page (you can see it in the bar just below the banner) for C Code links.  Just because the primary aim of this blog is about Learning C Games (programming), that includes learning C and there’s often no better way than studying or using other people’s source code.

As I come across code, I’ll add it here. I’ve started it off with Awesome-C which is a very comprehensive set of open source links.

 

Visual Studio Vs Visual Studio Code?

Visual Studio Vs Visual Studio Code?

I wrote the first book on Windows and used Visual Studio Community Edition 2017 (VS). For Linux I’m using Visual Studio Code (VSC) but if you are working on Windows you have the choice. So which is better suited to you?

Disassembly of OutputDebugString program

Given that my full time job involved Visual Studio Professional, it wasn’t a difficult choice for me, though having used VSC on Linux, I’m now warming to it.

I found the configuration messy but if you stick at it, you get there. It’s a fairly simple product but once you get into all the configuration and extensions, there’s a lot more to it.

VS (now at 2019 version) is an excellent tool and the navigation features and debugging are better than VSC. You can also view disassembly of C code as the screenshot shows.

But if you are also working on Linux or Mac and using VSC, it might be easier or at least more consistent using it for all platforms. Mind you there’s also the question of MSVC vs Clang to sort as well.

VS has extensions but only 3271 currently compared to 16934 for VSC and many of the VS extensions are trial while it appears that all of VSC are free. There’s also nearly ten times as many programming language extensions for VSC (3427) compared to VS (351).

So there’s no outright clear winner here. YMMV as the saying goes. (Your mileage may vary). Here for your delectation is that disassembly including the original C lines. Don’t worry, I won’t publish too many of these!

int main()
{
00E31700  push        ebp  
00E31701  mov         ebp,esp  
00E31703  sub         esp,0CCh  
00E31709  push        ebx  
00E3170A  push        esi  
00E3170B  push        edi  
00E3170C  lea         edi,[ebp-0CCh]  
00E31712  mov         ecx,33h  
00E31717  mov         eax,0CCCCCCCCh  
00E3171C  rep stos    dword ptr es:[edi]  
00E3171E  mov         ecx,offset _1EF31893_ods@c (0E3C00Ch)  
00E31723  call        @__CheckForDebuggerJustMyCode@4 (0E3120Dh)  
    wchar_t * text=L"Hello World!\n";
00E31728  mov         dword ptr [text],offset string L"Hello World!\n" (0E37B30h)  
    OutputDebugString(text);
00E3172F  mov         esi,esp  
00E31731  mov         eax,dword ptr [text]  
00E31734  push        eax  
00E31735  call        dword ptr [__imp__OutputDebugStringW@4 (0E3B000h)]  
00E3173B  cmp         esi,esp  
00E3173D  call        __RTC_CheckEsp (0E31217h)  
}
00E31742  xor         eax,eax  
00E31744  pop         edi  
00E31745  pop         esi  
00E31746  pop         ebx  
00E31747  add         esp,0CCh  
00E3174D  cmp         ebp,esp  
00E3174F  call        __RTC_CheckEsp (0E31217h)  
00E31754  mov         esp,ebp  
00E31756  pop         ebp  
00E31757  ret  
Logging on Windows – OutputDebugString

Logging on Windows – OutputDebugString

Shows OutputDebugString being calld in the debuggerIn the post about rsyslog three days ago, I explained how to log from Linux programs using the rsyslog daemon.

It’s slightly different in Windows. There’s a built in function called OutputDebugString(LPCWSTR str) that you can call from anywhere in your program. It dumps the string str into the Output window if you are debugging it in Visual Studio.

If you are running this outside of a debugger, the output is lost unless you can capture it with a suitable utility. DebugView from SysInternals.com (it redirects to Microsoft) is one such utility. That’s a screenshot of it below.

Showing DebugView in actionJust run DebugView and leave it there. It might catch other stuff from Windows, but when you run your program from the command line or double click on it, it will execute quickly and you’ll see any strings captured like this one.

 

This is the program that I ran. In Release it compiles to a 9 KB exe! Because OutPutDebugString needs a LPCWSTR  (Long Pointer to a WideString), I declared the text as wchar_t.

#include <Windows.h>

int main()
{
    wchar_t * text=L"Hello World!\n";
    OutputDebugString(text);
}

At work I developed a very large program that only worked running on another computer. I used OutputDebugString extensively and without it, debugging would have been much harder.

Comparing MSVC vs Clang

Comparing MSVC vs Clang

Listing of some C codeI originally created Asteroids for Windows using Visual Studio 2017 Community Edition. Since then I’ve started the Clang version on Ubuntu and there haven’t been too many differences but there are just a few so in this post I’ll list what I’ve found so far.

Include Paths

On Windows, I was able to get away with #include <SDL.h> but on Linux, I’ve had to include the path so it’s #include <SDL2/SDL.h>. This was probably because I included the full path in the MSVC configuration.

Link Failures

The asteroids.c code in chapter 29 uses sin and cos for the first time and the linker was unhappy with that. So in tasks.json, I’ve explicitly had to add it into args, along with SDL2 and SDL2_image,

            "args": [
                "-g",
                "${file}","${workspaceFolder}/Asteroids/hr_time.c",
                "-o",
                "${fileDirname}/asteroids",                
                "-lSDL2",
                "-lSDL2_image",
                "-lm"
            ],

That “-lm” does that for maths.

Safe functions

Microsoft has its own set of safe functions many with an _s and extra length parameter.

On Linux, there don’t seem to be so many.

So sprintf_s on Windows becomes snprintf.

fopen_s just becomes standard fopen

linux/time.h

As well as time.h in the includes, I needed to add linux/time.h as well.