Browse Source
* 256 color palette viewer. * usage: ./palview <palette> <vgamode> * If vgamode is omitted or 0, it displays the palette as-is. * If vgamode is 1, it multiplies all palette values by 4.master
Ian Burgmyer
5 years ago
commit
121934c454
21 changed files with 829 additions and 0 deletions
@ -0,0 +1,86 @@
|
||||
# Created by https://www.gitignore.io/api/clion |
||||
# Edit at https://www.gitignore.io/?templates=clion |
||||
|
||||
### CLion ### |
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm |
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 |
||||
|
||||
# User-specific stuff |
||||
.idea/**/workspace.xml |
||||
.idea/**/tasks.xml |
||||
.idea/**/usage.statistics.xml |
||||
.idea/**/dictionaries |
||||
.idea/**/shelf |
||||
|
||||
# Generated files |
||||
.idea/**/contentModel.xml |
||||
|
||||
# Sensitive or high-churn files |
||||
.idea/**/dataSources/ |
||||
.idea/**/dataSources.ids |
||||
.idea/**/dataSources.local.xml |
||||
.idea/**/sqlDataSources.xml |
||||
.idea/**/dynamic.xml |
||||
.idea/**/uiDesigner.xml |
||||
.idea/**/dbnavigator.xml |
||||
|
||||
# Gradle |
||||
.idea/**/gradle.xml |
||||
.idea/**/libraries |
||||
|
||||
# Gradle and Maven with auto-import |
||||
# When using Gradle or Maven with auto-import, you should exclude module files, |
||||
# since they will be recreated, and may cause churn. Uncomment if using |
||||
# auto-import. |
||||
# .idea/modules.xml |
||||
# .idea/*.iml |
||||
# .idea/modules |
||||
|
||||
# CMake |
||||
cmake-build-*/ |
||||
|
||||
# Mongo Explorer plugin |
||||
.idea/**/mongoSettings.xml |
||||
|
||||
# File-based project format |
||||
*.iws |
||||
|
||||
# IntelliJ |
||||
out/ |
||||
|
||||
# mpeltonen/sbt-idea plugin |
||||
.idea_modules/ |
||||
|
||||
# JIRA plugin |
||||
atlassian-ide-plugin.xml |
||||
|
||||
# Cursive Clojure plugin |
||||
.idea/replstate.xml |
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ) |
||||
com_crashlytics_export_strings.xml |
||||
crashlytics.properties |
||||
crashlytics-build.properties |
||||
fabric.properties |
||||
|
||||
# Editor-based Rest Client |
||||
.idea/httpRequests |
||||
|
||||
# Android studio 3.1+ serialized cache file |
||||
.idea/caches/build_file_checksums.ser |
||||
|
||||
### CLion Patch ### |
||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 |
||||
|
||||
# *.iml |
||||
# modules.xml |
||||
# .idea/misc.xml |
||||
# *.ipr |
||||
|
||||
# Sonarlint plugin |
||||
.idea/sonarlint |
||||
|
||||
# End of https://www.gitignore.io/api/clion |
||||
|
||||
# StarLight stuff! |
||||
src/version.h |
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="Encoding" addBOMForNewFiles="with NO BOM" /> |
||||
</project> |
@ -0,0 +1,10 @@
|
||||
<component name="InspectionProjectProfileManager"> |
||||
<profile version="1.0"> |
||||
<option name="myName" value="Project Default" /> |
||||
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false"> |
||||
<option name="processCode" value="true" /> |
||||
<option name="processLiterals" value="true" /> |
||||
<option name="processComments" value="true" /> |
||||
</inspection_tool> |
||||
</profile> |
||||
</component> |
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" /> |
||||
<component name="CidrRootsConfiguration"> |
||||
<sourceRoots> |
||||
<file path="$PROJECT_DIR$/src" /> |
||||
</sourceRoots> |
||||
</component> |
||||
<component name="JavaScriptSettings"> |
||||
<option name="languageLevel" value="ES6" /> |
||||
</component> |
||||
<component name="NodePackageJsonFileManager"> |
||||
<packageJsonPaths /> |
||||
</component> |
||||
</project> |
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="ProjectModuleManager"> |
||||
<modules> |
||||
<module fileurl="file://$PROJECT_DIR$/.idea/palview.iml" filepath="$PROJECT_DIR$/.idea/palview.iml" /> |
||||
</modules> |
||||
</component> |
||||
</project> |
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<module classpath="CMake" type="CPP_MODULE" version="4" /> |
@ -0,0 +1,16 @@
|
||||
cmake_minimum_required(VERSION 3.13) |
||||
project(palview C) |
||||
|
||||
set(CMAKE_C_STANDARD 90) |
||||
|
||||
find_package(SDL2 REQUIRED) |
||||
include_directories(${SDL2_INCLUDE_DIRS}) |
||||
|
||||
add_executable(palview |
||||
src/main.c |
||||
src/event.c |
||||
src/game.c |
||||
src/log.c |
||||
src/video.c) |
||||
|
||||
target_link_libraries(palview ${SDL2_LIBRARIES}) |
@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain. |
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or |
||||
distribute this software, either in source code form or as a compiled |
||||
binary, for any purpose, commercial or non-commercial, and by any |
||||
means. |
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors |
||||
of this software dedicate any and all copyright interest in the |
||||
software to the public domain. We make this dedication for the benefit |
||||
of the public at large and to the detriment of our heirs and |
||||
successors. We intend this dedication to be an overt act of |
||||
relinquishment in perpetuity of all present and future rights to this |
||||
software under copyright law. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||
OTHER DEALINGS IN THE SOFTWARE. |
||||
|
||||
For more information, please refer to <http://unlicense.org> |
@ -0,0 +1,44 @@
|
||||
# A Generic Makefile For Quick and Dirty Projects
|
||||
#
|
||||
# This Makefile has been tested using GNU make and bash. Your mileage may vary
|
||||
# with other make implementations and/or shells.
|
||||
|
||||
CFLAGS = $(shell sdl2-config --cflags)
|
||||
LDFLAGS = $(shell sdl2-config --libs)
|
||||
|
||||
CC = cc
|
||||
MKDIR = mkdir -p
|
||||
|
||||
OBJDIR = ./obj
|
||||
BINDIR = ./bin
|
||||
ASSETDIR = ./assets
|
||||
|
||||
# System-specific Makefile overrides.
|
||||
-include Makefile.override |
||||
|
||||
# The rest of these settings should are automatically configured. Tweak at your
|
||||
# own peril! :P
|
||||
OUTFILE = $(shell basename $(shell pwd))
|
||||
ALL_C := $(shell find . -type f -name '*.c')
|
||||
OBJFILES := $(addprefix $(OBJDIR)/,$(ALL_C:%.c=%.o))
|
||||
|
||||
all: $(OUTFILE) |
||||
|
||||
$(OBJDIR)/%.o: %.c |
||||
$(MKDIR) $(@D)
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
$(OUTFILE): $(OBJFILES) |
||||
$(MKDIR) $(BINDIR)
|
||||
$(CC) $(LDFLAGS) -o $(BINDIR)/$(OUTFILE) $^
|
||||
|
||||
if [ -d $(ASSETDIR) ]; then \
|
||||
cp $(ASSETDIR)/* $(BINDIR); \
|
||||
fi
|
||||
|
||||
test: $(OUTFILE) |
||||
cd $(BINDIR);./$(OUTFILE)
|
||||
|
||||
clean: |
||||
$(RM) -r $(OBJFILES)
|
||||
$(RM) $(BINDIR)/$(OUTFILE)
|
@ -0,0 +1,186 @@
|
||||
# SDL2 Sandbox |
||||
|
||||
## Introduction |
||||
|
||||
I've made quite a few little experimental projects in SDL. As such, I've |
||||
written very similar initialization code multiple times. I decided that it |
||||
would be much easier to put some quick boilerplate code together to give me a |
||||
base to quickly experiment with new ideas without having to keep reinventing |
||||
the wheel. |
||||
|
||||
## Requirements |
||||
|
||||
This project is aimed at people who are programming using a Linux system. A |
||||
compiler toolchain, such as gcc with binutils, and an implementation of Make |
||||
are required to build the project. Please note that the Make implementation |
||||
must support the $(shell) syntax. |
||||
|
||||
If you're running a Linux system with the development tools installed, odds are |
||||
this will work without a hitch. If you're using *BSD, you may have to use GNU |
||||
make (gmake) for this to build properly. |
||||
|
||||
macOS and Windows users will have to do a bit more work to get this running, |
||||
whether it be creating an Xcode/MSVC project, manually compiling SDL, or using |
||||
a third-party package manager and/or toolchain (such as mingw64 on Windows or |
||||
homebrew on macOS). |
||||
|
||||
SDL 2.0 is required. Later versions may work, but earlier versions will not. |
||||
|
||||
## What's Included? |
||||
|
||||
This project includes a Makefile, a working sample project, and ignore files |
||||
for git and Mercurial. It's designed so that you can compile it, watch it work, |
||||
then immediately start making changes. |
||||
|
||||
## How to Use This Project |
||||
|
||||
The first step to using this project is to determine which branch suits your |
||||
skill level. The `master` branch--the default--is very heavily commented, |
||||
intended to help ease beginners into C and SDL2. All major calls and actions |
||||
are commented, and the rationale behind each step is explained in as much |
||||
detail as is feasible. |
||||
|
||||
The `terse` branch is much cleaner, intended for people who just want to be |
||||
able to use this as a base to build other projects. |
||||
|
||||
Since this is intended to be used as a base, it is highly recommended that you |
||||
create your own repository (if you choose to use one) rather than keeping the |
||||
existing one. For example, if you wanted to create a project called "my_game", |
||||
run the following from your terminal emulator of choice: |
||||
|
||||
``` |
||||
git clone https://github.com/Spectere/sdl2_sandbox.git my_game |
||||
cd my_game |
||||
rm -rf .git |
||||
git init |
||||
``` |
||||
|
||||
The above command clones the git repository, changes into the project |
||||
directory, removes the existing git repository, then creates a new one in its |
||||
place. If you prefer to use Mercurial, use `hg init` in place of |
||||
`git init`. |
||||
|
||||
If you are using a repository, be sure to delete the ignore file that does |
||||
not apply to your VCS of choice. For example, if you're using git, you should |
||||
run `rm .hgignore`, while if you're using Mercurial you should run |
||||
`rm .gitignore`. If you don't want to use either, both files can be removed. |
||||
|
||||
After your project directory is prepared, type `make` to build the project. |
||||
If there are no errors, type `make test` to launch it. You should see a window |
||||
pop up with some color shifting. Either press ESC or close the window to exit. |
||||
|
||||
Now, modify `defs.h` to customize the window title text and resolution. The |
||||
application loop is contained in `game.c`, and input handling is done in |
||||
`event.c`. Happy coding! |
||||
|
||||
## Caveats |
||||
|
||||
While this project does provide a quick and easy way to create an SDL2 project, |
||||
it was not intended for large-scale or release-ready projects. Here are a few |
||||
potential issues that you can run into. |
||||
|
||||
* The logger is simple, both in ease-of-use and functionality. It will not |
||||
support all platforms flawlessly. |
||||
|
||||
* The video settings are hardcoded in `defs.h`. |
||||
|
||||
* No provisions have been made for audio input and output, network support, |
||||
or other features. The only things that have been accounted for are video |
||||
and basic input. |
||||
|
||||
* Game logic is tied to the framerate, and vsync is leveraged to limit the |
||||
framerate. This project does not contain any timing routines. |
||||
|
||||
* The Makefile was written to include all C files in the src/ directory, |
||||
and also names the executable after the directory that contains the |
||||
project. Additionally, no automatic configuration is supported, and |
||||
cross-platform support is not guaranteed. |
||||
|
||||
* This has not been tested with C++ projects. |
||||
|
||||
## Contributing |
||||
|
||||
If you can think of any ways to improve this project, feel free to submit a |
||||
pull request. Please note that PRs that push the project too far past its main |
||||
goals will most likely be rejected. The goals are as follows: |
||||
|
||||
1. To provide a base for experimentation and prototyping. |
||||
2. To provide beginners with a means of easing into SDL2 programming. |
||||
|
||||
It's recommended that contributions provide thorough documentation, as seen in |
||||
the master branch, but this is not required. |
||||
|
||||
Also, please take note of the following style guidelines in this section: |
||||
|
||||
### Comments |
||||
|
||||
All source code comments should be C89-style (using `/*` and `*/`), not |
||||
C++-style (using `//`). Comments should be made above the applicable line, |
||||
though inline comments may be used where appropriate. |
||||
|
||||
A brief description of the file should be included on every source and header |
||||
file. |
||||
|
||||
Comments should not exceed 80 columns of width, including whitespace. |
||||
|
||||
### Braces |
||||
|
||||
Open braces should appear at the end of all block statements, including |
||||
function definitions. |
||||
|
||||
### Whitespace and Code Width |
||||
|
||||
Code should be indented using tabs. Total width should be counted counted as if |
||||
each tab were 4 spaces in width, as that is the default with most modern |
||||
graphical IDEs. |
||||
|
||||
Parenthesis should be placed against control statements, function calls, and |
||||
function declarations, with no extra spaces. When pointers are declared, be it |
||||
in function or variable definitions, the asterisk should be placed against the |
||||
name of the pointer. |
||||
|
||||
80 columns of width should be considered a soft cap, as that will allow easy |
||||
code examination when using multiple editor panes and a terminal. 120 columns |
||||
should be considered a hard cap. Where feasible, a single parameter or equation |
||||
should not be broken across multiple lines. |
||||
|
||||
If a function call must span multiple lines, the subsequent lines should be |
||||
indented with a single tab. |
||||
|
||||
If a function definition must span multiple lines, the subsequent lines should |
||||
be aligned with spaces to one character after the open parenthesis. |
||||
|
||||
If a control statement must span multiple lines, the subsequent lines should be |
||||
indented with two tabs. That said, this probably should never occur on a |
||||
project with this scope. |
||||
|
||||
### Include Guards |
||||
|
||||
`#ifndef/#define/#endif` should be used for all include guards. At this time, |
||||
`#pragma once` should be avoided. The definition format that should be used is |
||||
the include filename, in all caps, with underscores surrounding it and |
||||
replacing dots. The `#endif` must have the definition stated in an inline |
||||
comment. |
||||
|
||||
For example, if you're working on a header file called `foo.h`, it should look |
||||
like the following: |
||||
|
||||
```c |
||||
/* foo.h |
||||
* |
||||
* Exposes public functions related to the foo subsystem. |
||||
*/ |
||||
|
||||
#ifndef _FOO_H_ |
||||
#define _FOO_H_ |
||||
|
||||
void foo_bar(); |
||||
|
||||
#endif /* _FOO_H_ */ |
||||
``` |
||||
|
||||
## Licensing |
||||
|
||||
This project is released under the Unlicense, effectively putting it into the |
||||
public domain. Feel free to use, modify, and even relicense it to best suit |
||||
your needs. No attribution is required. |
@ -0,0 +1,19 @@
|
||||
/* defs.h - Global definitions and constants. */ |
||||
|
||||
/* The default caption of the SDL2 window. */ |
||||
#define PROJECT_NAME "SDL2 Sandbox" |
||||
|
||||
/* The size of the pixmap. */ |
||||
#define RENDER_WIDTH 322 |
||||
#define RENDER_HEIGHT 322 |
||||
|
||||
/* The SDL window size. */ |
||||
#define WINDOW_WIDTH 966 |
||||
#define WINDOW_HEIGHT 966 |
||||
|
||||
/* Maximum length of the log format screen, including the severity tag. */ |
||||
#define LOG_LEN 160 |
||||
|
||||
/* How the color box things get displayed. */ |
||||
#define BOX_SIZE 20 |
||||
#define BOX_SPACING 2 |
@ -0,0 +1,68 @@
|
||||
/* event.c - Event handler functions. */ |
||||
|
||||
#include <SDL.h> |
||||
|
||||
#include "event.h" |
||||
|
||||
event_result_t event_keyboard(const SDL_Event e) { |
||||
SDL_KeyboardEvent kb = e.key; |
||||
|
||||
if(kb.type == SDL_KEYUP) { |
||||
switch(kb.keysym.sym) { |
||||
case SDLK_ESCAPE: |
||||
return EV_QUIT; |
||||
} |
||||
} |
||||
|
||||
return EV_NONE; |
||||
} |
||||
|
||||
event_result_t event_mouse_button(const SDL_Event e) { |
||||
SDL_MouseButtonEvent btn = e.button; |
||||
return EV_NONE; |
||||
} |
||||
|
||||
event_result_t event_mouse_wheel(const SDL_Event e) { |
||||
SDL_MouseWheelEvent wheel = e.wheel; |
||||
return EV_NONE; |
||||
} |
||||
|
||||
event_result_t event_mouse_motion(const SDL_Event e) { |
||||
SDL_MouseMotionEvent motion = e.motion; |
||||
return EV_NONE; |
||||
} |
||||
|
||||
event_result_t event_window(const SDL_Event e) { |
||||
SDL_WindowEvent wnd = e.window; |
||||
return EV_NONE; |
||||
} |
||||
|
||||
/* Main event processor. */ |
||||
event_result_t event_process() { |
||||
SDL_Event e; |
||||
SDL_PollEvent(&e); |
||||
|
||||
switch(e.type) { |
||||
case SDL_KEYDOWN: |
||||
case SDL_KEYUP: |
||||
return event_keyboard(e); |
||||
|
||||
case SDL_MOUSEBUTTONDOWN: |
||||
case SDL_MOUSEBUTTONUP: |
||||
return event_mouse_button(e); |
||||
|
||||
case SDL_MOUSEWHEEL: |
||||
return event_mouse_wheel(e); |
||||
|
||||
case SDL_MOUSEMOTION: |
||||
return event_mouse_motion(e); |
||||
|
||||
case SDL_WINDOWEVENT: |
||||
return event_window(e); |
||||
|
||||
case SDL_QUIT: |
||||
return EV_QUIT; |
||||
} |
||||
|
||||
return EV_NONE; |
||||
} |
@ -0,0 +1,15 @@
|
||||
/* event.h - Event handler functions. */ |
||||
|
||||
#ifndef _EVENT_H_ |
||||
#define _EVENT_H_ |
||||
|
||||
/* Values that can be sent to the main game loop. */ |
||||
typedef enum { |
||||
EV_NONE, |
||||
EV_QUIT |
||||
} event_result_t; |
||||
|
||||
/* Main event processor. */ |
||||
event_result_t event_process(); |
||||
|
||||
#endif /* _EVENT_H_ */ |
@ -0,0 +1,101 @@
|
||||
/* game.c - Main game loop. */ |
||||
|
||||
#include <errno.h> |
||||
#include <SDL.h> |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <sys/stat.h> |
||||
#include <sys/types.h> |
||||
#include <unistd.h> |
||||
|
||||
#include "defs.h" |
||||
#include "event.h" |
||||
#include "video.h" |
||||
|
||||
Uint32 palette[256]; |
||||
|
||||
void load_palette(char* palfile, SDL_bool vga) { |
||||
struct stat st; |
||||
FILE *f; |
||||
int i; |
||||
|
||||
stat(palfile, &st); |
||||
if(errno) { |
||||
printf("unable to stat file: %s\n", strerror(errno)); |
||||
exit(1); |
||||
} |
||||
|
||||
if(st.st_size != 768) { |
||||
printf("invalid size (expected 768 byes, got %li bytes)\n", st.st_size); |
||||
exit(1); |
||||
} |
||||
|
||||
f = fopen(palfile, "rb"); |
||||
if(f == NULL) { |
||||
printf("unable to open file: %s\n", strerror(errno)); |
||||
exit(1); |
||||
} |
||||
|
||||
for(i = 0; i < 256; i++) { |
||||
Uint8 r, g, b; |
||||
|
||||
r = (Uint8)fgetc(f); |
||||
g = (Uint8)fgetc(f); |
||||
b = (Uint8)fgetc(f); |
||||
|
||||
if(!vga) |
||||
palette[i] = RGB(r, g, b); |
||||
else |
||||
palette[i] = RGB(r * 4, g * 4, b * 4); |
||||
} |
||||
|
||||
fclose(f); |
||||
} |
||||
|
||||
void game_loop(char *palfile, SDL_bool vga) { |
||||
event_result_t ev = EV_NONE; |
||||
SDL_bool running = SDL_TRUE; |
||||
int cx, cy; |
||||
|
||||
load_palette(palfile, vga); |
||||
|
||||
if(video_init(PROJECT_NAME, RENDER_WIDTH, RENDER_HEIGHT, WINDOW_WIDTH, |
||||
WINDOW_HEIGHT) != 0) { |
||||
printf("error initializing video\n"); |
||||
exit(1); |
||||
} |
||||
|
||||
/* Clear the framebuffer. */ |
||||
memset(pixels, 0x00, RENDER_WIDTH * RENDER_HEIGHT * 4); |
||||
|
||||
/* Plot things! */ |
||||
for(cy = 0; cy < 16; cy++) { |
||||
for(cx = 0; cx < 16; cx++) { |
||||
int i = (cy * 16) + cx; |
||||
int c = palette[i]; |
||||
|
||||
int sx, sy; |
||||
for(sy = BOX_SPACING; sy < BOX_SIZE; sy++) { |
||||
for(sx = BOX_SPACING; sx < BOX_SIZE; sx++) { |
||||
int x = (BOX_SIZE) * cx + sx; |
||||
int y = (BOX_SIZE) * cy + sy; |
||||
|
||||
pixels[POS(x, y)] = c; |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
while(running) { |
||||
ev = event_process(); |
||||
|
||||
switch(ev) { |
||||
case EV_QUIT: |
||||
running = SDL_FALSE; |
||||
break; |
||||
} |
||||
|
||||
video_update(); |
||||
} |
||||
} |
@ -0,0 +1,10 @@
|
||||
/* game.h - Main game loop. */ |
||||
|
||||
#ifndef _GAME_H_ |
||||
#define _GAME_H_ |
||||
|
||||
#include <SDL_types.h> |
||||
|
||||
void game_loop(char* palfile, SDL_bool vga); |
||||
|
||||
#endif /* _GAME_H_ */ |
@ -0,0 +1,52 @@
|
||||
/* log.c - Application logging functionality. */ |
||||
|
||||
#include <stdio.h> |
||||
#include <stdarg.h> |
||||
#include <string.h> |
||||
|
||||
#include "defs.h" |
||||
#include "log.h" |
||||
|
||||
void lprint(log_level_t level, const char *format, ...) { |
||||
char output_format[LOG_LEN]; |
||||
|
||||
va_list args; |
||||
va_start(args, format); |
||||
|
||||
if(strlen(format) + 10 > LOG_LEN) { |
||||
fprintf(stderr, "[!!!] Log string is too long!\n"); |
||||
vfprintf(stdout, format, args); |
||||
fprintf(stdout, "\n"); |
||||
va_end(args); |
||||
return; |
||||
} |
||||
|
||||
switch(level) { |
||||
case DEBUG: |
||||
strcpy(output_format, "[DEBUG] "); |
||||
break; |
||||
case INFO: |
||||
strcpy(output_format, "[INFO] "); |
||||
break; |
||||
case WARN: |
||||
strcpy(output_format, "[WARN] "); |
||||
break; |
||||
case ERROR: |
||||
strcpy(output_format, "[ERROR] "); |
||||
break; |
||||
default: |
||||
/* If no valid severity was passed, initialize the string. */ |
||||
strcpy(output_format, ""); |
||||
break; |
||||
} |
||||
|
||||
strcat(output_format, format); |
||||
strcat(output_format, "\n"); |
||||
|
||||
if(level == ERROR) |
||||
vfprintf(stderr, output_format, args); |
||||
else |
||||
vfprintf(stdout, output_format, args); |
||||
|
||||
va_end(args); |
||||
} |
@ -0,0 +1,16 @@
|
||||
/* log.h - Application logging functionality. */ |
||||
|
||||
#ifndef _LOG_H_ |
||||
#define _LOG_H_ |
||||
|
||||
/* Severity levels used by lprint(). */ |
||||
typedef enum { |
||||
DEBUG, |
||||
INFO, |
||||
WARN, |
||||
ERROR |
||||
} log_level_t; |
||||
|
||||
void lprint(log_level_t level, const char *format, ...); |
||||
|
||||
#endif /* _LOG_H_ */ |
@ -0,0 +1,31 @@
|
||||
/* main.c - Program entry point. */ |
||||
|
||||
#include <stdio.h> |
||||
|
||||
#include "defs.h" |
||||
#include "game.h" |
||||
#include "video.h" |
||||
|
||||
int main(int argc, char **argv) { |
||||
SDL_bool vga = SDL_FALSE; |
||||
|
||||
if(argc < 2) { |
||||
printf("\n usage: palview (palette file) [vga]\n\n"); |
||||
printf(" vga should be 1 if the palette is a VGA palette (color range: 0x00-0x3F,\n"); |
||||
printf(" otherwise it should be 0. If not specified, it will default to 0.\n\n"); |
||||
return 1; |
||||
} |
||||
|
||||
if(argc > 2) { |
||||
printf("vga: %s\n", argv[2]); |
||||
if(strncmp(argv[2], "1", 1) == 0) |
||||
vga = SDL_TRUE; |
||||
} |
||||
|
||||
game_loop(argv[1], vga); |
||||
|
||||
video_close(); |
||||
SDL_Quit(); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,80 @@
|
||||
/* video.c - Initializes and updates the window. */ |
||||
|
||||
#include <stdlib.h> |
||||
|
||||
#include "log.h" |
||||
#include "video.h" |
||||
|
||||
int tex_width, tex_height, wnd_width, wnd_height; |
||||
|
||||
Uint32 *pixels; |
||||
|
||||
SDL_Window *window = NULL; |
||||
SDL_Renderer *renderer = NULL; |
||||
SDL_Texture *texture = NULL; |
||||
|
||||
void video_close() { |
||||
lprint(INFO, "Closing video subsystem"); |
||||
|
||||
SDL_DestroyTexture(texture); |
||||
SDL_DestroyRenderer(renderer); |
||||
SDL_DestroyWindow(window); |
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO); |
||||
} |
||||
|
||||
int video_init(const char *title, int render_width, int render_height, |
||||
int window_width, int window_height) { |
||||
tex_width = render_width; |
||||
tex_height = render_height; |
||||
wnd_width = window_width; |
||||
wnd_height = window_height; |
||||
|
||||
SDL_Init(SDL_INIT_VIDEO); |
||||
|
||||
lprint(INFO, "Initializing video (%ix%i surface, %ix%i window)...", |
||||
tex_width, tex_height, wnd_width, wnd_height); |
||||
|
||||
/* Create an SDL window. */ |
||||
lprint(DEBUG, "Creating window"); |
||||
window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, |
||||
SDL_WINDOWPOS_CENTERED, window_width, window_height, 0); |
||||
if(window == NULL) { |
||||
lprint(ERROR, "Error creating window: %s", SDL_GetError()); |
||||
return 1; |
||||
} |
||||
|
||||
/* Create the renderer. */ |
||||
lprint(DEBUG, "Creating hardware accelerated renderer"); |
||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); |
||||
if(renderer == NULL) { |
||||
/* Attempt to fall back to software rendering. */ |
||||
lprint(WARN, "Failed to create hardware accelerated renderer: %s", SDL_GetError()); |
||||
lprint(WARN, "Attempting to create a software renderer"); |
||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE | SDL_RENDERER_PRESENTVSYNC); |
||||
if(renderer == NULL) { |
||||
lprint(ERROR, "Error creating renderer: %s", SDL_GetError()); |
||||
return 1; |
||||
} |
||||
} |
||||
|
||||
/* Create an ARGB8888 texture. */ |
||||
lprint(DEBUG, "Creating texture"); |
||||
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, |
||||
SDL_TEXTUREACCESS_STREAMING, tex_width, tex_height); |
||||
if(texture == NULL) { |
||||
lprint(ERROR, "Error creating texture: %s", SDL_GetError()); |
||||
return 1; |
||||
} |
||||
|
||||
pixels = malloc(sizeof(Uint32) * tex_width * tex_height); |
||||
|
||||
lprint(INFO, "Video subsystem initialized successfully"); |
||||
return 0; |
||||
} |
||||
|
||||
void video_update() { |
||||
SDL_UpdateTexture(texture, NULL, pixels, tex_width * sizeof(Uint32)); |
||||
SDL_RenderCopy(renderer, texture, NULL, NULL); |
||||
SDL_RenderPresent(renderer); |
||||
} |
@ -0,0 +1,19 @@
|
||||
/* video.h - Initializes and updates the window. */ |
||||
|
||||
#ifndef _VIDEO_H_ |
||||
#define _VIDEO_H_ |
||||
|
||||
#include <SDL.h> |
||||
#include "defs.h" |
||||
|
||||
#define RGB(r, g, b) (0xFF000000 | (r << 16) | (g << 8) | b) |
||||
#define POS(x, y) ((RENDER_WIDTH * y) + x) |
||||
|
||||
extern Uint32 *pixels; |
||||
|
||||
void video_close(); |
||||
int video_init(const char *title, int render_width, int render_height, |
||||
int window_width, int window_height); |
||||
void video_update(); |
||||
|
||||
#endif /* _VIDEO_H_ */ |
@ -0,0 +1,23 @@
|
||||
{ |
||||
"folders": |
||||
[ |
||||
{ |
||||
"name": "Project Files", |
||||
"path": "..", |
||||
"file_include_patterns": [ |
||||
"Makefile", |
||||
"LICENSE", |
||||
"README.md", |
||||
".gitignore", |
||||
".hgignore" |
||||
], |
||||
"folder_exclude_patterns": [ |
||||
"*" |
||||
] |
||||
}, |
||||
{ |
||||
"name": "Source", |
||||
"path": "../src" |
||||
} |
||||
] |
||||
} |
Loading…
Reference in new issue