A cross-platform, top-down 2D space shooter written in C using only system libraries.

Overview

space-shooter.c

A cross-platform, top-down 2D space shooter written in C using only system libraries.

gif

Dependencies

  • Window management: Win32 (Windows), Xlib (Linux)
  • Rendering: OpenGL
  • Audio: XAudio2 (Windows), ALSA/pthread (Linux)
  • Gamepad: XInput (Windows), evdev (Linux)

Description

space-shooter.c is a cross-platform, top-down 2D space shooter written in standard C11 using only system libraries (with system libraries defined as anything included in the C standard library or supported operating systems). space-shooter.c has been tested on Windows 10 and Ubuntu Linux 16.04. This project drew heavy inspiration from Handmade Hero and pacman.c.

The design and architecture of space-shooter.c is described here [WIP].

Caveat

I am not a professional game developer, nor a professional C programmer, so the design may be unconventional or sub-optimal in many ways. Happy to take feedback from any pros out there!

Building

Windows

  • In a shell with cl set up, run build.bat for a debug build or build.bat release for an optimized build.
  • Run space-shooter.exe from the build/ directory.

Linux

  • Make sure development headers for the Linux kernel, Xlib, glx and ALSA are installed.
    • E.g. on Ubuntu, run the following: sudo apt install linux-libc-dev libx11-dev mesa-common-dev libasound2-dev
  • Run make for a debug build or make release for an optimized build.
  • Run ./space-shooter from the build/ directory.

Asset Credits

Issues
  • Issue compiling on Windows - error C2220 and warning C4204

    Issue compiling on Windows - error C2220 and warning C4204

    Hi Tarek, thank you for making this project!

    For anyone trying to compile this project on windows (Windows 10 Home for me), I ran into a slight problem. After running build.bat in a shell with cl setup, I got an error:

    ....
    ..\src\game\entities.c(135): error C2220: the following warning is treated as an error
    ..\src\game\entities.c(135): warning C4204: nonstandard extension used: non-constant aggregate initializer
    ...More of these warnings...
    

    The way I solved this for now was to remove the /WX compile option from the build.bat script (basically replace line 8 with the line below):

    @set shared_args=/std:c11 /W4 /wd5105 /wd4201 /wd4100 /D SOGL_MAJOR_VERSION=3 /D SOGL_MINOR_VERSION=3 /Fespace-shooter
    

    /WX tells the compiler to treat all warnings as errors, so this probably isn't the best solution! But it's a workaround for now. Im not a C/C++ dev so not sure how to solve "non-constant aggregate initializer". If I figure it out I will post here.

    opened by mawaldne 3
  • "error: GLSL 3.30 is not supported"

    A continuation of #2. A new update came to my qemu fork, and they added support for OpenGL 4.1. However, running with MESA_GL_VERSION_OVERRIDE=3.3 build/sp* (because the version string is for some reason, still at 2.1), fails with

    Program failed to link!
    Vertex shader failed to compile!
    0:1(10): error: GLSL 3.30 is not supported. Supported versions are: 1.10, 1.20, 1.30, 1.00 ES, and 3.00 ES
    
    Fragment shader failed to compile!
    0:1(10): error: GLSL 3.30 is not supported. Supported versions are: 1.10, 1.20, 1.30, 1.00 ES, and 3.00 ES
    
    opened by DUOLabs333 3
  • windows-audio.c compilation error with VS2019, VS2022

    windows-audio.c compilation error with VS2019, VS2022

    C:\git\space-shooter>build.bat
    assets\audio\Explode1.wav
    assets\audio\Hit_Hurt2.wav
    assets\audio\Jump1.wav
    assets\audio\Laser_002.wav
    assets\audio\music.wav
    assets\shaders\fs.glsl
    assets\shaders\vs.glsl
    assets\sprites\enemy-big.bmp
    assets\sprites\enemy-medium.bmp
    assets\sprites\enemy-small.bmp
    assets\sprites\explosion.bmp
    assets\sprites\laser-bolts.bmp
    assets\sprites\pixelspritefont32.bmp
    assets\sprites\ship.bmp
    14 File(s) copied
    
    C:\git\space-shooter\build>cl /std:c11 /W4 /WX /wd5105 /wd4201 /wd4100 /D SOGL_MAJOR_VERSION=3 /D SOGL_MINOR_VERSION=3 /Fespace-shooter /Zi /D SPACE_SHOOTER_DEBUG ..\src\shared\*.c ..\src\game\*.c ..\src\platform\windows\*.c user32.lib gdi32.lib opengl32.lib xinput.lib ole32.lib
    Microsoft (R) C/C++ Optimizing Compiler Version 19.30.30705 for x86
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    data.c
    entities.c
    events.c
    game.c
    renderer.c
    sprites.c
    utils.c
    windows-audio.c
    ..\src\platform\windows\windows-audio.c(81): error C2440: 'initializing': cannot convert from 'void (__cdecl *)(IXAudio2VoiceCallback *,UINT32)' to 'void (__stdcall *)(IXAudio2VoiceCallback *,UINT32)'
    ..\src\platform\windows\windows-audio.c(81): error C2440: 'initializing': cannot convert from 'void (__cdecl *)(IXAudio2VoiceCallback *)' to 'void (__stdcall *)(IXAudio2VoiceCallback *)'
    ..\src\platform\windows\windows-audio.c(81): error C2440: 'initializing': cannot convert from 'void (__cdecl *)(IXAudio2VoiceCallback *,void *)' to 'void (__stdcall *)(IXAudio2VoiceCallback *,void *)'
    ..\src\platform\windows\windows-audio.c(81): error C2440: 'initializing': cannot convert from 'void (__cdecl *)(IXAudio2VoiceCallback *,void *,HRESULT)' to 'void (__stdcall *)(IXAudio2VoiceCallback *,void *,HRESULT)'
    windows.c
    Generating Code...
    C:\git\space-shooter>dir build
    
    
     Directory of C:\git\space-shooter\build
    
    12/12/2021  01:41 PM    <DIR>          .
    12/12/2021  01:41 PM    <DIR>          ..
    12/12/2021  01:41 PM    <DIR>          assets
    12/12/2021  01:41 PM             2,962 data.obj
    12/12/2021  01:41 PM             8,044 entities.obj
    12/12/2021  01:41 PM             7,104 events.obj
    12/12/2021  01:41 PM           190,256 game.obj
    12/12/2021  01:41 PM            30,857 renderer.obj
    12/12/2021  01:41 PM            25,528 sprites.obj
    12/12/2021  01:41 PM            12,625 utils.obj
    12/12/2021  01:41 PM           118,784 vc140.pdb
    12/12/2021  01:41 PM           154,138 windows.obj
    
    opened by voltagex 3
  • 'SPACE_SHOOTER_MIN_FRAME_TIME' is undeclared identifier

    'SPACE_SHOOTER_MIN_FRAME_TIME' is undeclared identifier

    The windows.c needs SPACE_SHOOTER_MIN_FRAME_TIME but the constants.h define it as SPACE_SHOOTER_MIN_FRAME_TIME_NS. I also tried to remove the _NS part but then the game just freeze. After looking through the startup code, I saw this:

            if (useSleep && SPACE_SHOOTER_MIN_FRAME_TIME - elapsedTime > 1.0f) {
                DWORD sleepMs = (DWORD) (SPACE_SHOOTER_MIN_FRAME_TIME - elapsedTime);
                Sleep(sleepMs);
    

    The sleepMs was a very high number. If I replace the macro with something else like 1/60 then it would work just fine.

    opened by longtran2904 2
  • Set a max refresh rate

    Set a max refresh rate

    If vsync isn't enabled, the game loop will currently run as fast as possible, which is pointless since game state updates are fixed at 60Hz. Setting the loop to max out at a high refresh rate (e.g. 300Hz) would let vsync do its thing but prevent overusing resources when it's not available.

    opened by tsherif 2
  • Added fast shoot rockets

    Added fast shoot rockets

    Using the keypad-a button, the player can shoot double bullet shoots that fly faster than a regular bullet. The player gains fast bullets every time a ship is being destroyed.

    opened by uritsvi 1
  • Gamepad polling should be time-based.

    Gamepad polling should be time-based.

    It's currently based on number of ticks, which means it will poll at a different rate on how fast the game loop is running. Set it to a constant rate of 1Hz.

    opened by tsherif 1
  • Clean up error handling in main platform functions

    Clean up error handling in main platform functions

    main and WinMain in the top-level platform files currently return on error without doing any cleanup. Set up a goto chain to handle cleanup depending on which resources have been allocated (like in platform_loadFile).

    opened by tsherif 1
  • Test for asset directory presence

    Test for asset directory presence

    Related to #3

    Some people like to move the executable out of the repo without realizing that the asset directory needs to be moved too. Right now, this results in a cryptic error message about the renderer failing to initialize. Check if asset directory is present and print a useful error message if not.

    opened by tsherif 1
  • Check for GPU errors after initialization.

    Check for GPU errors after initialization.

    The only check currently performed is for shader compilation. I should probably have at least a glGetError after all initialization to make sure resources were allocated properly.

    opened by tsherif 0
  • Allocate buffers in renderer_init

    Allocate buffers in renderer_init

    Currently buffers are allocated on the first draw using glBufferData. Move the allocations to renderer_init and update them in game_draw using glBufferSubData.

    opened by tsherif 0
  • docs: Fix a few typos

    docs: Fix a few typos

    There are small typos in:

    • src/game/events.h
    • src/game/game.c
    • src/game/renderer.h

    Fixes:

    • Should read entity rather than entitiy.
    • Should read conditionally rather than condionally.

    Semi-automated pull request generated by https://github.com/timgates42/meticulous/blob/master/docs/NOTE.md

    opened by timgates42 0
  • Not checking the 'dead' entity flag while iterating over entities.

    Not checking the 'dead' entity flag while iterating over entities.

    As far as I understand, dead entities are only filtered before calling the drawing/rendering functions. While iterating over entities we don't seem to be skipping those with their ->dead[i] flag set. I am not sure if that's correct though.

    In the function src/game/game.c/mainGame we call simWorld, which checks for collisions between player bullets and enemies (i.e it sets the ->dead[i] flag), later 'mainGame' also calls simPlayer which checks for collisions between the player and the enemies using the checkPlayerCollision function. But the checkPlayerCollision function doesn't skip "dead" enemies, which makes it possible for "dead" enemies to collide with the player.

    opened by luauser32167 0
Owner
Tarek Sherif
Coloring pixels
Tarek Sherif
Project 1945 is a top down scroller game made with SDL2, CMake and programmed in C as a project of study for the Italian Videogames Academy for the 3rd year course of Videogames programming.

Project 1945 is a top down scroller game made with SDL2, CMake and programmed in C as a project of study for the Italian Videogames Academy for the 3rd year course of Videogames programming. The game is based on the old videogame 1945: The Final Front of the 2002.

null 17 Sep 27, 2021
Cross-platform version of Heboris C7EX using a hardware-accelerated SDL 2.0 renderer

Heboris C7EX - unofficial version (YGS2K EX) This version contains the source code for Heboris C7EX. It requires a C compiler, SDL 2.0, SDL 2.0 mixer,

Brandon McGriff 9 May 27, 2022
VERY simple cross-platform C++ analytics for games (using Google Analytics)

Tiniest Analytics is a very simple to use, cross-platform (tested on win/osx/linux/ios/android) and basically very tiny analytics system written in C++ (less than 100 lines of code), made specifically for games. It uses libcurl to post events to your Google Analytics account.

Mihai Gosa 95 Jan 31, 2022
A set of libraries and tools to make MSX games using the C programming language.

ubox MSX lib This is a set of libraries and tools to make MSX games using the C programming language. There are three main components: ubox: thin wrap

Juan J. Martínez 42 May 30, 2022
Open-source repository of Orbiter Space Flight Simulator

Orbiter Space Flight Simulator Orbiter is a spaceflight simulator based on Newtonian mechanics. Its playground is our solar system with many of its ma

Orbiter Space Flight Simulator 1.3k Jul 1, 2022
A text-based space adventure role-playing game developed by a team of 5.

SpaceAdventureRPG - Text-Based Game A text-based space adventure role-playing game developed by a team of 5. Module: 4007CEM, Class: B, Group: 3 Contr

Jonas Djondo 1 Nov 18, 2021
Space exploration, trading, and combat game.

Endless Sky Explore other star systems. Earn money by trading, carrying passengers, or completing missions. Use your earnings to buy a better ship or

Endless Sky 3.5k Jun 23, 2022
Remake of the original Space Invaders game.

Space-invaders Remake of the original Space Invaders game.

Kofybrek 20 May 13, 2022
Open-source, cross-platform, C++ game engine for creating 2D/3D games.

GamePlay v3.0.0 GamePlay is an open-source, cross-platform, C++ game framework/engine for creating 2D/3D mobile and desktop games. Website Wiki API De

gameplay3d 3.7k Jun 28, 2022
KlayGE is a cross-platform open source game engine with plugin-based architecture.

KlayGE KlayGE is a cross-platform open source game engine with plugin-based architecture. It's started since 2003. The explicit goal of KlayGE is: to

Minmin Gong 1.7k Jun 22, 2022
A cross-platform 2D game engine

nCine nCine is a cross-platform 2D game engine. It is released under the MIT License, Copyright (c) 2011-2021 Angelo Theodorou. For additional informa

nCine 703 Jul 1, 2022
Powerful, mature open-source cross-platform game engine for Python and C++, developed by Disney and CMU

Panda3D Panda3D is a game engine, a framework for 3D rendering and game development for Python and C++ programs. Panda3D is open-source and free for a

Panda3D 3.4k Jul 2, 2022
Polycode is a cross-platform framework for creative code.

Polycode is a cross-platform framework for creative code. You can use it as a C++ API or as a standalone scripting language to get easy and simple acc

Ivan Safrin 2.4k Jun 25, 2022
A powerful free cross-platform RTS game engine

Spring RTS game engine README Spring (formerly TASpring) is an Open Source Real Time Strategy game engine. Visit our project homepage for help, sugges

Spring RTS 2.6k Jun 25, 2022
Cross-platform, sophisticated frontend for the libretro API. Licensed GPLv3.

RetroArch RetroArch is the reference frontend for the libretro API. Popular examples of implementations for this API includes video game system emulat

null 6.8k Jul 3, 2022
MAZE (My AmaZing Engine) - 🎮 Personal open-source cross-platform game engine

MAZE (My AmaZing Engine) is the self-written open-source cross-platform game engine in the active development stage. At the moment it is my main pet project, developed for the purpose of learning and preserving different game dev technologies.

Dmitriy Nosov 11 Jan 9, 2022
TrenchBroom is a modern cross-platform level editor for Quake-engine based games.

TrenchBroom is a modern cross-platform level editor for Quake-engine based games.

TrenchBroom 1.2k Jul 1, 2022
CSEngine is a cross-platform 3D game engine.

CSEngine - Cross Platform C++ Game Engine CSEngine is a cross-platform 3D game engine. ?? As it is under development, it is not yet suitable for pract

ounols 45 Jun 27, 2022
Intrinsic is a Vulkan based cross-platform game and rendering engine

Intrinsic is a Vulkan based cross-platform game and rendering engine

Benjamin Wrensch 1k Jul 1, 2022