Twitter

Pinboard Bookmarks

Blog Tags

Recommended Productions

Ball-B

Simple 3D game developed in Unity during Global Game Jam 2014.

Play Online

Date: 2014-01-26

Download:
Ball_B_Windows.zip (8.78 MB)
Ball_B_Source.zip (20.49 MB)

Octovirus

Simple 2D game developed during Global Game Jam 2013, for Windows.

Date: 2013-01-27

Download:
Octovirus.zip (6.1 MB)

FX Batch Compiler 1.1

This Windows application supports compilation of FX effect files and HLSL shader files using fxc command line compiler included in DirectX SDK. You can compile many files at time or one file with different settings.

Features:

  • Write compilation scripts in a simple language by specifying parameters for fxc.exe.
  • Compile multiple shaders at time.
  • Compile only shaders that need rebuild checked by file modification time.
  • Review success or failure, warning and error count and compiler output for every task.
  • Compile single HLSL source file with different parameters and preprocessor macros.

Date: 2011-02-09

Block Wizard

My first Flash game. Coded with FlashDevelop in ActionScript 3.

Date: 2010-04-06

CommonLib 9.0

Universal library for C++, created especially with game programmers in mind. Includes: math module (vectors, matrices, quaternions, planes, rich set of collision functions and more), string operations, conversions, smart pointers, configuration files handling, date and time module, exception class hierarchy for error handling, file system handling, stream class hierarchy, FreeList - fast memory allocator, complex logger, profiler, library for threading and synchronization, tokenizer, wrappers for compression with zlib.

Language: C++. Platforms: Windows and Linux. License: GNU LGPL. Optional support for Unicode. Optional integration with D3DX. Documentation made with Doxygen.

Date: 2009-12-16

Download:
CommonLib_9_0.zip (4.92 MB)

Aqua Fish 2

Game for children - clone of PacMan. Player swims as a fish and collects points, as well as special items. Player also have to run away from enemies or destroy them. 60 maps in 6 different titlesets. Low hardware requirements. See also YouTube videos: [1], [2]. Game was published by Play Publishing company.

GameDev Calc

Calculator for game programmers. Basic data unit is a vector of 1-4 floating point numbers, which can be treated as (x,y,z,w) vector or (r,g,b,a) color. Next to basic calculations like addition, multiplication or sinus, vector operations are also available, e.g. vector normalization, conversion between degrees and radians, color conversion between RGB and HSB, finding linear an quadratic function coefficients and much more. Instead of entering single number, here you can see all the history of your calculations in form of stack and all operations are performed on that stack. Data can be entered and retrieved in different formats, like "D3DXVECTOR4(0.0f, 0.5f, 0.752f, 1.0f)" or "0xFF0080C0". Platform: Windows. Language: C#. License: GNU GPL.

Download:
GameDevCalc_1-0.zip (53.06 KB)
GameDevCalc_1-0_src.zip (50.73 KB)

Blog

16:10
Sat
21
May 2016

What software engineering has to do with history, politics or law?

When at school, I always prefered scientific classes (like mathematics) over humanities. Among my most hated classes were: history, geography and language/literature. That's why I chose to become a programmer. But despite computer science is a scientific discipline, I can see that on a higher level, software engineering involves some humanities like, for example, history, politics or law.

History, because in software - just like in real life - you need to know what happened in the past to be able to understand the state of things we have right now. For example, in the field of graphics API-s, someone asked a question on Programmers Stack Exchange: Why do game developers prefer Windows? The best answer is the one that extensively explains how two main API-s - DirectX and OpenGL - evolved over years.

Politics, because top-level decisions are not always made based on purely technical arguments. Going back to graphics API-s, Microsoft decided to push its next-generation low-level Direct3D 12 into Windows 10 only, while Khronos Group defined Vulkan as an open, multiplatform standard. Google was rumored to design its own graphics API, was even asked by John Carmack not to do so, and it finally returned to the negotiation table with Khronos, so Android N will support Vulkan as well. Apple chose different path and did design its own graphics API - Metal. Similarly, in the GPGPU field, OpenCL is a widely supported standard, but NVIDIA succeeded in promoting its own, vendor-specific API: CUDA. HSA is yet another such initiative, led by a foundation. Among its members are: AMD, ARM, Imagination, Qualcomm, Samsung and many others, but the list lacks some big players, like Intel or NVIDIA. So developing software technology is a little bit like doing politics - "Am I strong enough to go against the others or do I need to seek allies?"

And finally, the law. Specifications of programming languages and API-s are somewhat like acts passed by the government. They are written in natual language, but should be as unambiguous as possible, precisely defining each term, specifying what is allowed and what is not. Doing something against the specification is like breaking the law - it may go unnoticed, it may even give you an advantage (like programmers notoriously relying on signed integer overlow in C++, despite formally it's an undefined behavior), but you may also "get caught" (and get a compilation error or invalid results from your program). On the other hand, a compiler or API implementor not complying to the specification is more serious problem - it's like a state official breaking the law against you. You may just accept your fate and go away (equivalent of not using broken feature and looking for some workaround) or you may report it (so the bug will be fixed in new compiler/driver/library version).

So although software engineering is a scientific/technical discipline, I think that on a higher level it can be compared to some degree to humanities like history, politics or law.

Comments (0) | Tags: philosophy | Author: Adam Sawicki | Share

02:15
Sun
03
Apr 2016

RegScript 2 - Parameters Framework

On April 1st I've read a very interesting blog post that doesn't seem like April Fools' joke: Game Development Needs Data Pipeline Middleware. I fully agree with the author. There is a code very much needed in every game engine, game editor and other graphics/music/media applications, written over and over again - the one about storing, editing and serializing data structures of various kinds (basically all objects that make up the state/document/game level of a program), each having a set of parameters of various types (integers, floats, strings, vectors, arrays etc.) - so it makes sense to create a library for it.

I (as probably every game developer) already tried to create such framework many times. Now I decided to share the source of my last attempt: RegScript2 @ GitHub. It is not finished and some design decisions I've made may seem controversial, but at least we could start discussion about the solution. What do you think about it? Feel free to e-mail me at sawickiap__REMOVE__@poczta.onet.pl, comment this post or read and interact with my code on GitHub.

Comments (0) | Tags: libraries | Author: Adam Sawicki | Share

20:34
Thu
31
Mar 2016

Sztukato 2016 - Festival of Arts and Fashion

18-20 March 2016 in Protokultura club in Gdańsk, Poland, an interesting event took place: Sztukato - festival of arts and fashion (Website, Facebook Event). It involved arts gallery, fair of handmade clothes and accessories, fashion shows, concerts and many other activities. I was doing visualizations during the whole event. It was new and interesting experience for me, as I learned a lot during the event, as well as while preparing for it. I especially gained lots of experience in video editing, as I prepared some prerendered video footage. Depending on the circumstances sometimes I played these videos in a loop, sometimes just showed logos of organizers and sponsors and sometimes launched the abstract/psychedelic visuals generated procedurally by my program.

Here is full gallery of my photos from the festival: SZTUKATO 2016 Festiwal Sztuki i Mody @ Facebook.

I can see many VJ-s use Resolume, but for simple displaying images or videos I used Screen Monkey. It's a free program that I came across when browsing VJ Forums. It has some problems (GUI has some minor bugs and it even stops playing videos sometimes), but it also has many useful features (layers, fade in/out, linking clips in a sequence, Schedule and many more).

The biggest problem I had with Screen Monkey is that it didn't want to play any videos after installation. (My environment was: Windows 7 x64 with latest updates, K-Lite Codec Pack Full in latest version, Screen Monkey version 3.7, video files format: MP4 container + MPEG4 Video (H264) video stream) Solution to this turned out to be:

  1. Add any video clip to Screen Monkey Dashboard.
  2. Right-click on this clip, select: Video Options.
  3. Uncheck: Prefer ffdshow Video Decoder.

After going back to my work, I had a thought that there is one big difference between creative work and doing software engineering. When creating something, whether it's an art, writing a book or even coding a small program, you can always come up with SOMETHING even if you lack knowledge, experience or time and the deadline is close. It may be better or worse, client may like it or not, but at least you have SOMETHING and the rest is just a matter of negotiation. When working in software, it's more binary - all-or-nothing. You either meet the specification or not, pass all unit tests or not, you fixed the bug or not. Sure you can also write better or worse code, your solution can be more robust, efficient or better architected, but this has its own problem: Writing bad code increases technical debt, which makes it harder to work with the code in the future while being quite invisible to the client and your manager. On the other hand, when assigned some creative task, you probably launch your editor and start from a blank document every time.

Comments (0) | Tags: vj events | Author: Adam Sawicki | Share

22:36
Wed
17
Feb 2016

Vulkan 1.0 Released!

Yesterday (2016-02-16) was a big day - Vulkan 1.0 has finally been released. The new 3D graphics and compute API from Khronos Group has a chance to be the solution long awaited in the PC world that will:

  • work across different hardware platforms (both desktop and mobile), GPU vendors and operating systems
  • break backward compatibility and provide new, clean API
  • make graphics drivers simpler, less bugged, with smaller CPU overhead
  • give low level access to the features of modern GPU-s
  • allow to squeeze more power out of existing and future GPU-s (again thanks to being closer to the metal, with less overhead and better multithreading possibilities)

Time will tell whether Vulkan becomes popular, common standard. It's not so certain. Microsoft promotes its own Direct3D 12, Apple has its Metal API, NVIDIA develops CUDA, old OpenGL and OpenCL are here to stay. What hardware versions and software platforms will eventually support the new API? What will be the quality and performance of those drivers? Will some good debugging and performance probiling tools become available? Will game developers and game engine developers port their code any time soon? What the reception will be among video/media, CAD/CAM, HPC professionals? I'm very enthusiastic, seeing so many learning materials and code samples available since day one! Just look at #Vulkan and #VulkanAPI hashtags on Twitter.

Some useful links to start with:

Comments (1) | Tags: gpu vulkan | Author: Adam Sawicki | Share

20:23
Sun
07
Feb 2016

How code refactoring can fix stack overflow error?

tl;dr: A very long C++ function with multiple local variables, even if they are not very big and they are placed in separate scopes, can reserve as much as hundreds of kilobytes of stack frame, causing "Stack Overflow" even without bugs like infinite recursion. So you better split your long functions into shorter ones.

Can refactoring (or the lack of thereof) cause application crashes? If we understand refactoring as changes in code layout without changing its logic, we might think that it's just the matter of readability and unreadable code increases chances of introducing bugs. But here is a story in which refactoring actually fixed a bug.

Long time ago in a software project far far away, there was a bug submitted telling that the application crashes with "Stack Overflow" message. It was a Windows app, developed in C++ using Visual Studio. I thought: - I can handle that, it should be easy! Every beginner/intermediate programmer knows about the call stack and surely seen this error at least once when accidentally caused infinite recursion in his code. So my first idea was that infinite recursion happens because of some logical error in the code (that should be easy to fix) or some unfortunate, invalid input data (that should be validated for safety before usage).

As it turned out, this was not the case. After setting up all the test environment and catching the crash in Visual Studio debugger, I looked at Call Stack and noticed that it looks quite normal. Sure the call depth was significant (as for C++, I'm not talking about Java here ;) and there was even some recursion, but 20 or 30 functions is not that much. The stack ended with a call to non-recursive function that seemed correct, so it was not the recursion that caused stack overflow.

My second idea was that some of these functions allocate some big objects (like arrays) by value, as local variables on the stack and this causes the stack to grow too big. I reviewed code of the functions that I found on the stack and used "Immediate Window" panel to quickly check sizeof(xxx) of variables or their types when they used some class, but I didn't find anything particularly big. Local variable sizes varied from few bytes to at most several hundred bytes and I couldn't find any big arrays defined in these functions. I also fetched address of some local variable in a function near the bottom of the stack (which looks like 0x000000000009a370), address of a parameter from the function at the top of the stack and subtracted them to see how big the stack grown over all these calls. The result was around 50 KB - not that much.

My third idea was to check maximum size of the stack. It is 1 MB by default, but it can be changed in Visual Studio project settings, in Linker > System tab, as "Stack Reserve Size" parameter. I check my project and I found this parameter not changed from its default value.

OK, now this became more difficult than I thought. After many debugging sessions, where I looked at various pointers, addresses and numbers trying to spot some memory override, stack corruption, out-of-bounds indexing etc., I finally opened "Disassembly" and "Registers" panels. I'm not a fan of such low level stuff, so it took me some time and few Google queries to understand these RSP, RBP registers and make sense of some x86-64 opcodes. While debugging step-by-step in the assembly, I found something interesting. At the beginning of my function, there was a call to mysterious function __chkstk and the crash occurred inside it. That was a clue I could use to ask Google what this all means. I found this: Description of the stack checking for Windows NT-based applications and this: What is the purpose of the _chkstk() function? These articles say that as the stack grows, next 4 KB pages are reserved. Each next page is allocated by the system on first "touch". I could actually see in my debugger that functions which need less than 1 page (4096 B = 1000h) have an instruction at the beginning similar to this:

sub         rsp,0A9h

While my debugged function had this instead:

mov         eax,26B29h
call        __chkstk (018104AA00h)
sub         rsp,rax

The articles say that when reserving more than one page of stack memory, this function must be called to loop over addresses with 4 KB step and "touch" each page. This is really what it does:

--- f:\dd\vctools\crt\crtw32\startup\amd64\chkstk.asm ---
sub         rsp,10h
mov         qword ptr [rsp],r10
mov         qword ptr [rsp+8],r11
xor         r11,r11
lea         r10,[rsp+18h]
sub         r10,rax
cmovb       r10,r11
mov         r11,qword ptr gs:[10h]
cmp         r10,r11
jae         cs10+10h (018104AA40h)
and         r10w,0F000h
lea         r11,[r11-1000h]
mov         byte ptr [r11],0
cmp         r10,r11
jne         cs10 (018104AA30h)
mov         r10,qword ptr [rsp]
mov         r11,qword ptr [rsp+8]
add         rsp,10h
ret

Key sentence of the second linked article seems to be: "The parameter in rax is size of data you want to add." In my case, eax is set to 26B29h = 158505. Wait, what?! This is more than 150 KB! Is it really how much of the stack the function needs?!

It was finally the right conclusion. The function was more than 3000-lines long, with lots of nested conditions and all kinds of stuff, but mostly an all-encompassing switch with dozens of different cases. I refactored it, extracting code from under each case to a separate function. This fixed the "Stack Overflow" crash.

Apparently if you have a long function and define a lot of local variables, even if they are not particularly big and they are placed inside separate scopes like if-s or switch case-s, the function may need as much as 150 KB of stack frame, at least in Debug configuration. This can cause crash with "Stack Overflow" message even without infinite recursion or bugs like that. So please keep this in mind as additional argument for refactoring your code as soon as you see the need for it.

Comments (2) | Tags: visual studio c++ | Author: Adam Sawicki | Share

19:50
Tue
02
Feb 2016

Global Game Jam 2016 - Postmortem of our project

Last weekend, this year's edition of Global Game Jam took place all around the world. Just like in previous years, I participated in 3City Game Jam - a site in Gdańsk, Poland. It is a big one, with over 150 participants, organized by Playsoft company in their office. Theme this year was "Ritual". Regarding technology, Unity was most popular in our site, with just few games using something else: Unreal Engine, HTML5, GameMaker and C++ with SFML.

We have also used Unity. Our team consisted of 3 programmers. Here you can see our game: Bloody Eclipse, but it is far from being finished or playable. Honestly speaking, in my opinion the project on this jam went exceptionally poor. We didn't even make it to the top 10 best voted games to be presented on a big screen. That's why I'd like to share some conclusions, for you as well as for my future self.

First, it were not environmental issues that caused any problems. We all had our hardware and software set up before the jam, with Unity, Visual Studio, Git client and other tools already in place. Internet worked perfectly with transfer up to 80 Mbps in both directions. Second, it was not a lack of knowledge or skills. Our work in Unity went quite smoothly. We could deal with C#, 3D math and Git pretty well. Third, it was not because of the lack of artists in our team. Sure, graphics is very important for overall experience, but the guys who made The Bad Ritual also didn't have artists in their team and they somehow found a consistent visual style for their game, made it fun and pretty. There are many possibilities to make minimalistic and yet visually pleasant game, just like there are many free assets ready to use in Unity Asset Store.

The biggest thing that was missing in our team was management/leadership. I deliberately don't call it planning or design, because in a hectic environment like a game jam it's not enough to design the game at the beginning and then just execute. Things are changing fast, new ideas come to mind, time is running fast and new obstacles appear (like bugs or difficulties in development), so someone should have an authority to decide what to do next, keep the list of tasks "TODO" and update it constantly with priorities assigned so the most important things are done first. Noone took this role in our team. As the result, we've spent almost whole Saturday developing and polishing algorithm for enemy movement and around half an hour brainstorming and then voting for the game title, while our game used untextured, placeholder cubes and spheres as models until the very end :)

Conclusion: It's not enough to know how to code. It's also important to decide WHAT to code so that best possible result can be achieved with limited time and resources.

But the Global Game Jam as a whole is not a contest (despite our site actually was one, with PlayStation 4 for each team member as first prize) but just a fun, creative event. Despite all the problem we had I think it was fun. I had yet another opportunity to use Unity, which is a great technology. I realized I can handle Git pretty well, despite I don't feel like an expert knowing about "rebase" and such advanced stuff. I realized I still remember how to use the so much unintuitive inteface of Blender, which I learned many years ago to use in my master thesis. I could play many interesting games created on this jam, like my favorite: Witch Rite (it took 3rd place) or the one that won the contest: Acolytes: Ritual of Ascension. And finally, I've met many interesting people who do all sorts of crazy stuff, from running a company that produces medical software and hardware, to visiting escepe rooms and practicing celtic dances :)

Comments (2) | Tags: productions competitions ggj | Author: Adam Sawicki | Share

21:17
Fri
22
Jan 2016

How to quickly convert MKV to MP4 file using VLC?

Do you have a video in MKV file and you can't open it because some program (like Sony Vegas Pro) doesn't support this format? If so, you probably wonder how to convert it into some different format. I just discovered a way to do this.

To understand this method, first you need to know that media file formats are just containers (for example, MKV is Matroska). Each format encapsulates a set of streams, usually one video and one audio stream. Now, each stream is encoded using some specific codec. There may be various codecs used, but for the file I needed to convert, Media Player Classic (my favorite movie player, installed with K-Lite Codec Pack) shows following information after selecting File > Properties:

Type: Matroska
Video: MPEG4 Video (H264) 720x400 25fps [V: English [eng] (h264 main L4.0, yuv420p, 720x400) [default]]
Audio: AAC 44100Hz stereo [A: aac lc, 44100 Hz, stereo [default]]

MPEG4 Video is the same codec that may be used with MP4 file format! It means we could convert ("repack") the file to just different container format, rewriting streams as-is without actually converting video or audio - which should be very fast (converting a long movie takes only few seconds) and wouldn't cause any quality loss.

To do that, I used VLC media player. This program has its own set of codecs for many video and audio formats, so it doesn't depend on codecs installed in Windows. The player is actually just an overlay on top of a powerful library that can also do different things, like streaming video over network (that's probably where the company name "VideoLAN" comes from) or convert files.

So to convert an MKV file to MP4:

  1. Run "VLC media player".
  2. From main menu select "Media" > "Convert / Save...".
  3. On "File" tab, click "Add..." button.
  4. Choose you MKV file. After that, it should be added to the list. (Alternatively, you can drag&drop a file into the list.)
  5. Click "Convert/Save" button.
  6. Select Profile: "Video - H.264 + MP3 (MP4)".
  7. Click on the icon button that has hint: "Edit selected profile".
  8. On "Encapsulation" tab, leave "MP4/MOV" selected.
  9. On "Video codec" tab, check both "Video" and "Keep original video track".
  10. On "Audio codec" tab, similarly select both "Audio" and "Keep original audio track".
  11. Click "Save" button.
  12. In "Destination" selection, click "Browse" button to select directory and file name for you destination MP4 file.
  13. Click "Start" button.
  14. Observe progress bar in the main window as file is converted.
  15. After that, my VLC (version 2.2.1) seems to hang in an infinite loop so I have to kill it using system "Task Manager", but it doesn't matter - the destination file is already created.

Comments (5) | Tags: video | Author: Adam Sawicki | Share

17:07
Sat
09
Jan 2016

ID3D11Device::CreateTexture2D: pInitialData[0].SysMemPitch cannot be 0

The concept of "stride" or "pitch" - a step (in bytes) to be taken to proceed to next element of a data structure - is brilliant, because it gives great flexibility. In 3D graphics for example, explicitly specified number of bytes between vertices in a vertex buffer or rows in a texture can be:

  1. Equal to exact size of vertex structure or texture row, when these entries are laid out next to each other.
  2. Greater, so additional padding can exist at the end of each entry or entries can be interleaved with some other data to be skipped in particular case.
  3. Zero, so that the same single entry will be read over and over.

This is a theory, because I just discovered that option 3 doesn't work in Direct3D 11 when passing pInitialData to created texture. I cannot see any reason why specifying D3D11_SUBRESOURCE_DATA::SysMemPitch == 0 should be considered invalid, other than trying to save developer from possibly unintended mistake. I think it is actually pretty useful for initializing a texture with the same data in each row, so it would be enough to allocate and fill the data for just one row, instead of full texture. And still, following code fails on call to CreateTexture2D:

CD3D11_TEXTURE2D_DESC textureDesc = CD3D11_TEXTURE2D_DESC(
    TEXTURE_FORMAT, // format
    (UINT)TEXTURE_SIZE.x, // width
    (UINT)TEXTURE_SIZE.y, // height
    1, // arraySize
    1, // mipLevels
    D3D11_BIND_SHADER_RESOURCE, // bindFlags
    D3D11_USAGE_DYNAMIC, // usage
    D3D11_CPU_ACCESS_WRITE); // cpuaccessFlags
std::vector<uint32_t> initialTextureRow(TEXTURE_SIZE.x);
ZeroMemory(&initialTextureRow[0], TEXTURE_SIZE.x * sizeof(uint32_t));
D3D11_SUBRESOURCE_DATA textureInitialData = {
    &initialTextureRow[0], // pSysMem
    0, // SysMemPitch
    0 }; // SysMemSlicePitch
ID3D11Texture2D *texture = nullptr;
ERR_GUARD_DIRECTX( m_Dev->CreateTexture2D(&textureDesc, &textureInitialData, &texture) );

DirectX debug layer reports error:

D3D11 ERROR: ID3D11Device::CreateTexture2D: pInitialData[0].SysMemPitch cannot be 0 [ STATE_CREATION ERROR #100: CREATETEXTURE2D_INVALIDINITIALDATA]

Dear Microsoft: Why? :)

Comments (1) | Tags: directx | Author: Adam Sawicki | Share

Older entries >

STAT NO AD [Stat] [Admin] [STAT NO AD] [pub] [Mirror] Copyright © 2004-2016 Adam Sawicki
Copyright © 2004-2016 Adam Sawicki